this repo has no description
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Use wa once again

+1306 -4058
+1
.gitignore
··· 2 2 !/bin/tmux-airline 3 3 4 4 /vim/backups 5 + /vim/spell 5 6 /vim/.netrwhist 6 7 7 8 /vim/bundle
+4
fish/functions/b.fish
··· 1 + function b --wrap bundle 2 + bundle $argv 3 + end 4 +
+3
fish/functions/be.fish
··· 1 + function be --wrap 'bundle exec' 2 + bundle exec $argv 3 + end
+3
fish/functions/e.fish
··· 1 + function e --wraps "$EDITOR" 2 + eval "$EDITOR $argv" 3 + end
+3
fish/functions/g.fish
··· 1 + function g --description 'Less typing more work!' --wrap git 2 + git $argv 3 + end
+4
fish/functions/work.fish
··· 1 + function work 2 + set project (basename (command git rev-parse --show-toplevel)) 3 + time -f '%E' -- tmux new -s $project; or time -f '%E' -- tmux attach -t $project 4 + end
+12
fish/init.fish
··· 1 + set fish_greeting (fortune zen) 2 + # set fish_key_bindings fish_vi_key_bindings 3 + 4 + set -gx PATH $HOME/.bin $PATH 5 + 6 + if [ -z "$TMUX" ] 7 + set -gx TERM xterm-256color 8 + else 9 + set -gx TERM screen-256color 10 + end 11 + 12 + agnoster_powerline
functions/-.fish fish/functions/-.fish
-3
functions/_.fish
··· 1 - function _ 2 - less -IRXNx4 $argv 3 - end
-4
functions/b.fish
··· 1 - function b --wraps bundle 2 - bundle $argv 3 - end 4 -
-3
functions/be.fish
··· 1 - function be 2 - bundle exec $argv 3 - end
functions/ca.fish fish/functions/ca.fish
functions/color-test.fish fish/functions/color-test.fish
functions/compose.fish fish/functions/compose.fish
-3
functions/e.fish
··· 1 - function e -d "Run $EDITOR with given file" --wraps $EDITOR 2 - eval "$EDITOR $argv" 3 - end
-3
functions/g.fish
··· 1 - function g --description 'Less typing more work!' --wraps 'git' 2 - git $argv 3 - end
functions/grep.fish fish/functions/grep.fish
functions/map.fish fish/functions/map.fish
functions/mcd.fish fish/functions/mcd.fish
functions/most-used.fish fish/functions/most-used.fish
functions/p.fish fish/functions/p.fish
functions/paste.fish fish/functions/paste.fish
functions/pretty.fish fish/functions/pretty.fish
functions/rails.fish fish/functions/rails.fish
functions/rake.fish fish/functions/rake.fish
functions/rawk.fish fish/functions/rawk.fish
functions/rzlib-base64.fish fish/functions/rzlib-base64.fish
functions/serve.fish fish/functions/serve.fish
functions/stop.fish fish/functions/stop.fish
-4
functions/work.fish
··· 1 - function work 2 - set project (basename (git rev-parse --show-toplevel)) 3 - time -f '%E' -- tmux new -s $project ; or time -f '%E' -- tmux attach -t $project 4 - end
+1093 -3874
gdbinit
··· 1 - # INSTALL INSTRUCTIONS: save as ~/.gdbinit 2 - # 3 - # DESCRIPTION: A user-friendly gdb configuration file, for x86/x86_64 and ARM platforms. 4 - # 5 - # REVISION : 8.0.5 (18/08/2013) 6 - # 7 - # CONTRIBUTORS: mammon_, elaine, pusillus, mong, zhang le, l0kit, 8 - # truthix the cyberpunk, fG!, gln 9 - # 10 - # FEEDBACK: http://reverse.put.as - reverser@put.as 11 - # 12 - # NOTES: 'help user' in gdb will list the commands/descriptions in this file 13 - # 'context on' now enables auto-display of context screen 14 - # 15 - # MAC OS X NOTES: If you are using this on Mac OS X, you must either attach gdb to a process 16 - # or launch gdb without any options and then load the binary file you want to analyse with "exec-file" option 17 - # If you load the binary from the command line, like $gdb binary-name, this will not work as it should 18 - # For more information, read it here http://reverse.put.as/2008/11/28/apples-gdb-bug/ 19 - # 20 - # UPDATE: This bug can be fixed in gdb source. Refer to http://reverse.put.as/2009/08/10/fix-for-apples-gdb-bug-or-why-apple-forks-are-bad/ 21 - # and http://reverse.put.as/2009/08/26/gdb-patches/ (if you want the fixed binary for i386) 22 - # 23 - # An updated version of the patch and binary is available at http://reverse.put.as/2011/02/21/update-to-gdb-patches-fix-a-new-bug/ 24 - # 25 - # iOS NOTES: iOS gdb from Cydia (and Apple's) suffer from the same OS X bug. 26 - # If you are using this on Mac OS X or iOS, you must either attach gdb to a process 27 - # or launch gdb without any options and then load the binary file you want to analyse with "exec-file" option 28 - # If you load the binary from the command line, like $gdb binary-name, this will not work as it should 29 - # For more information, read it here http://reverse.put.as/2008/11/28/apples-gdb-bug/ 30 - # 31 - # CHANGELOG: (older changes at the end of the file) 32 - # 33 - # Version 8.0.6 (05/09/2013) 34 - # - Add patch command to convert bytes to little-endian and patch memory 35 - # 36 - # Version 8.0.5 (18/08/2013) 37 - # - Add commands header and loadcmds to dump Mach-O header information 38 - # - Other fixes and additions from previous commits 39 - # 40 - # Version 8.0.4 (08/05/2013) 41 - # - Detect automatically 32 or 64 bits archs using sizeof(void*). 42 - # Thanks to Tyilo for the simple but very effective idea! 43 - # - Typo in hexdump command also fixed by vuquangtrong. 44 - # - Add shortcuts to attach to VMware kernel debugging gdb stub (kernel32 and kernel64) 45 - # 46 - # Version 8.0.3 (21/03/2013) 47 - # - Add option to colorize or not output (thanks to argp and skier for the request and ideas!) 48 - # - Convert the escape codes into functions so colors can be easily customized 49 - # - Other enhancements available at git commit logs 50 - # Thanks to Plouj, argp, xristos for their ideas and fixes! 51 - # 52 - # Version 8.0.2 (31/07/2012) 53 - # - Merge pull request from mheistermann to support local modifications in a .gdbinit.local file 54 - # - Add a missing opcode to the stepo command 55 - # 56 - # Version 8.0.1 (23/04/2012) 57 - # - Small bug fix to the attsyntax and intelsyntax commands (changing X86 flavor variable was missing) 58 - # 59 - # Version 8.0 (13/04/2012) 60 - # - Merged x86/x64 and ARM versions 61 - # - Added commands intelsyntax and attsyntax to switch between x86 disassembly flavors 62 - # - Added new configuration variables ARM, ARMOPCODES, and X86FLAVOR 63 - # - Code cleanups and fixes to the indentation 64 - # - Bug fixes to some ARM related code 65 - # - Added the dumpmacho command to memory dump the mach-o header to a file 66 - # 67 - # TODO: 68 - # 69 - 70 - # __________________gdb options_________________ 71 - 72 - # set to 1 to have ARM target debugging as default, use the "arm" command to switch inside gdb 73 - set $ARM = 0 74 - # set to 0 if you have problems with the colorized prompt - reported by Plouj with Ubuntu gdb 7.2 75 - set $COLOREDPROMPT = 1 76 - # color the first line of the disassembly - default is green, if you want to change it search for 77 - # SETCOLOR1STLINE and modify it :-) 78 - set $SETCOLOR1STLINE = 0 79 - # set to 0 to remove display of objectivec messages (default is 1) 80 - set $SHOWOBJECTIVEC = 1 81 - # set to 0 to remove display of cpu registers (default is 1) 82 - set $SHOWCPUREGISTERS = 1 83 - # set to 1 to enable display of stack (default is 0) 84 - set $SHOWSTACK = 0 85 - # set to 1 to enable display of data window (default is 0) 86 - set $SHOWDATAWIN = 0 87 - # set to 0 to disable colored display of changed registers 88 - set $SHOWREGCHANGES = 1 89 - # set to 1 so skip command to execute the instruction at the new location 90 - # by default it EIP/RIP will be modified and update the new context but not execute the instruction 91 - set $SKIPEXECUTE = 0 92 - # if $SKIPEXECUTE is 1 configure the type of execution 93 - # 1 = use stepo (do not get into calls), 0 = use stepi (step into calls) 94 - set $SKIPSTEP = 1 95 - # show the ARM opcodes - change to 0 if you don't want such thing (in x/i command) 96 - set $ARMOPCODES = 1 97 - # x86 disassembly flavor: 0 for Intel, 1 for AT&T 98 - set $X86FLAVOR = 0 99 - # use colorized output or not 100 - set $USECOLOR = 1 101 - # to use with remote KDP 102 - set $KDP64BITS = -1 103 - set $64BITS = 0 104 - 105 - set confirm off 106 - set verbose off 107 - set history filename ~/.gdb_history 108 - set history save 109 - 110 - set output-radix 0x10 111 - set input-radix 0x10 112 - 113 - # These make gdb never pause in its output 114 - set height 0 115 - set width 0 116 - 117 - set $SHOW_CONTEXT = 1 118 - set $SHOW_NEST_INSN = 0 119 - 120 - set $CONTEXTSIZE_STACK = 6 121 - set $CONTEXTSIZE_DATA = 8 122 - set $CONTEXTSIZE_CODE = 8 1 + python 123 2 124 - # __________________end gdb options_________________ 3 + # GDB dashboard - Modular visual interface for GDB in Python. 125 4 # 5 + # https://github.com/cyrus-and/gdb-dashboard 126 6 127 - # __________________color functions_________________ 128 - # 129 - # color codes 130 - set $BLACK = 0 131 - set $RED = 1 132 - set $GREEN = 2 133 - set $YELLOW = 3 134 - set $BLUE = 4 135 - set $MAGENTA = 5 136 - set $CYAN = 6 137 - set $WHITE = 7 7 + import ast 8 + import fcntl 9 + import os 10 + import re 11 + import struct 12 + import termios 138 13 139 - # CHANGME: If you want to modify the "theme" change the colors here 140 - # or just create a ~/.gdbinit.local and set these variables there 141 - set $COLOR_REGNAME = $GREEN 142 - set $COLOR_REGVAL = $BLACK 143 - set $COLOR_REGVAL_MODIFIED = $RED 144 - set $COLOR_SEPARATOR = $BLUE 145 - set $COLOR_CPUFLAGS = $RED 14 + # Common attributes ------------------------------------------------------------ 146 15 147 - # this is ugly but there's no else if available :-( 148 - define color 149 - if $USECOLOR == 1 150 - # BLACK 151 - if $arg0 == 0 152 - echo \033[30m 153 - else 154 - # RED 155 - if $arg0 == 1 156 - echo \033[31m 157 - else 158 - # GREEN 159 - if $arg0 == 2 160 - echo \033[32m 161 - else 162 - # YELLOW 163 - if $arg0 == 3 164 - echo \033[33m 165 - else 166 - # BLUE 167 - if $arg0 == 4 168 - echo \033[34m 169 - else 170 - # MAGENTA 171 - if $arg0 == 5 172 - echo \033[35m 173 - else 174 - # CYAN 175 - if $arg0 == 6 176 - echo \033[36m 177 - else 178 - # WHITE 179 - if $arg0 == 7 180 - echo \033[37m 181 - end 182 - end 183 - end 184 - end 185 - end 186 - end 187 - end 188 - end 189 - end 190 - end 16 + class R(): 191 17 192 - define color_reset 193 - if $USECOLOR == 1 194 - echo \033[0m 195 - end 196 - end 18 + @staticmethod 19 + def attributes(): 20 + return { 21 + # miscellaneous 22 + 'ansi': { 23 + 'doc': 'Control the ANSI output of the dashboard.', 24 + 'default': True, 25 + 'type': bool 26 + }, 27 + # prompt 28 + 'prompt': { 29 + 'doc': """Command prompt. 30 + This value is parsed as a Python format string in which `{status}` is expanded 31 + with the substitution of either `prompt_running` or `prompt_not_running` 32 + attributes, according to the target program status. The resulting string must be 33 + a valid GDB prompt, see the command `python print(gdb.prompt.prompt_help())`""", 34 + 'default': '{status}' 35 + }, 36 + 'prompt_running': { 37 + 'doc': """`{status}` when the target program is running. 38 + See the `prompt` attribute. This value is parsed as a Python format string in 39 + which `{pid}` is expanded with the process identifier of the target program.""", 40 + 'default': '\[\e[1;35m\]>>>\[\e[0m\]' 41 + }, 42 + 'prompt_not_running': { 43 + 'doc': '`{status}` when the target program is not running.', 44 + 'default': '\[\e[1;30m\]>>>\[\e[0m\]' 45 + }, 46 + # divider 47 + 'divider_fill_char_primary': { 48 + 'doc': 'Filler around the label for primary dividers', 49 + 'default': '─' 50 + }, 51 + 'divider_fill_char_secondary': { 52 + 'doc': 'Filler around the label for secondary dividers', 53 + 'default': '─' 54 + }, 55 + 'divider_fill_style_primary': { 56 + 'doc': 'Style for `divider_fill_char_primary`', 57 + 'default': '36' 58 + }, 59 + 'divider_fill_style_secondary': { 60 + 'doc': 'Style for `divider_fill_char_secondary`', 61 + 'default': '1;30' 62 + }, 63 + 'divider_label_style_on_primary': { 64 + 'doc': 'Label style for non-empty primary dividers', 65 + 'default': '1;33' 66 + }, 67 + 'divider_label_style_on_secondary': { 68 + 'doc': 'Label style for non-empty secondary dividers', 69 + 'default': '0' 70 + }, 71 + 'divider_label_style_off_primary': { 72 + 'doc': 'Label style for empty primary dividers', 73 + 'default': '33' 74 + }, 75 + 'divider_label_style_off_secondary': { 76 + 'doc': 'Label style for empty secondary dividers', 77 + 'default': '1;30' 78 + }, 79 + 'divider_label_skip': { 80 + 'doc': 'Gap between the aligning border and the label.', 81 + 'default': 3, 82 + 'type': int, 83 + 'check': check_ge_zero 84 + }, 85 + 'divider_label_margin': { 86 + 'doc': 'Number of spaces around the label.', 87 + 'default': 1, 88 + 'type': int, 89 + 'check': check_ge_zero 90 + }, 91 + 'divider_label_align_right': { 92 + 'doc': 'Label alignment flag.', 93 + 'default': False, 94 + 'type': bool 95 + }, 96 + # common styles 97 + 'style_selected_1': { 98 + 'default': '1;32' 99 + }, 100 + 'style_selected_2': { 101 + 'default': '32' 102 + }, 103 + 'style_low': { 104 + 'default': '1;30' 105 + }, 106 + 'style_high': { 107 + 'default': '1;37' 108 + }, 109 + 'style_error': { 110 + 'default': '31' 111 + } 112 + } 197 113 198 - define color_bold 199 - if $USECOLOR == 1 200 - echo \033[1m 201 - end 202 - end 114 + # Common ----------------------------------------------------------------------- 203 115 204 - define color_underline 205 - if $USECOLOR == 1 206 - echo \033[4m 207 - end 208 - end 116 + def run(command): 117 + return gdb.execute(command, to_string=True) 209 118 210 - # this way anyone can have their custom prompt - argp's idea :-) 211 - # can also be used to redefine anything else in particular the colors aka theming 212 - # just remap the color variables defined above 213 - source ~/.gdbinit.local 119 + def ansi(string, style): 120 + if R.ansi: 121 + return '\x1b[{}m{}\x1b[0m'.format(style, string) 122 + else: 123 + return string 214 124 215 - # can't use the color functions because we are using the set command 216 - if $COLOREDPROMPT == 1 217 - set prompt \033[31mgdb$ \033[0m 218 - end 125 + def divider(label='', primary=False, active=True): 126 + width = Dashboard.term_width 127 + if primary: 128 + divider_fill_style = R.divider_fill_style_primary 129 + divider_fill_char = R.divider_fill_char_primary 130 + divider_label_style_on = R.divider_label_style_on_primary 131 + divider_label_style_off = R.divider_label_style_off_primary 132 + else: 133 + divider_fill_style = R.divider_fill_style_secondary 134 + divider_fill_char = R.divider_fill_char_secondary 135 + divider_label_style_on = R.divider_label_style_on_secondary 136 + divider_label_style_off = R.divider_label_style_off_secondary 137 + if label: 138 + if active: 139 + divider_label_style = divider_label_style_on 140 + else: 141 + divider_label_style = divider_label_style_off 142 + skip = R.divider_label_skip 143 + margin = R.divider_label_margin 144 + before = ansi(divider_fill_char * skip, divider_fill_style) 145 + middle = ansi(label, divider_label_style) 146 + after_length = width - len(label) - skip - 2 * margin 147 + after = ansi(divider_fill_char * after_length, divider_fill_style) 148 + if R.divider_label_align_right: 149 + before, after = after, before 150 + return ''.join([before, ' ' * margin, middle, ' ' * margin, after]) 151 + else: 152 + return ansi(divider_fill_char * width, divider_fill_style) 219 153 220 - # Initialize these variables else comparisons will fail for coloring 221 - # we must initialize all of them at once, 32 and 64 bits, and ARM. 222 - set $oldrax = 0 223 - set $oldrbx = 0 224 - set $oldrcx = 0 225 - set $oldrdx = 0 226 - set $oldrsi = 0 227 - set $oldrdi = 0 228 - set $oldrbp = 0 229 - set $oldrsp = 0 230 - set $oldr8 = 0 231 - set $oldr9 = 0 232 - set $oldr10 = 0 233 - set $oldr11 = 0 234 - set $oldr12 = 0 235 - set $oldr13 = 0 236 - set $oldr14 = 0 237 - set $oldr15 = 0 238 - set $oldeax = 0 239 - set $oldebx = 0 240 - set $oldecx = 0 241 - set $oldedx = 0 242 - set $oldesi = 0 243 - set $oldedi = 0 244 - set $oldebp = 0 245 - set $oldesp = 0 246 - set $oldr0 = 0 247 - set $oldr1 = 0 248 - set $oldr2 = 0 249 - set $oldr3 = 0 250 - set $oldr4 = 0 251 - set $oldr5 = 0 252 - set $oldr6 = 0 253 - set $oldr7 = 0 254 - set $oldsp = 0 255 - set $oldlr = 0 154 + def check_gt_zero(x): 155 + return x > 0 256 156 257 - # used by ptraceme/rptraceme 258 - set $ptrace_bpnum = 0 157 + def check_ge_zero(x): 158 + return x >= 0 259 159 260 - # ______________window size control___________ 261 - define contextsize-stack 262 - if $argc != 1 263 - help contextsize-stack 264 - else 265 - set $CONTEXTSIZE_STACK = $arg0 266 - end 267 - end 268 - document contextsize-stack 269 - Syntax: contextsize-stack NUM 270 - | Set stack dump window size to NUM lines. 271 - end 160 + def to_unsigned(value, size=8): 161 + # values from GDB can be used transparently but are not suitable for 162 + # being printed as unsigned integers, so a conversion is needed 163 + return int(value.cast(gdb.Value(0).type)) % (2 ** (size * 8)) 272 164 165 + def to_string(value): 166 + # attempt to convert an inferior value to string; OK when (Python 3 || 167 + # simple ASCII); otherwise (Python 2.7 && not ASCII) encode the string as 168 + # utf8 169 + try: 170 + value_string = str(value) 171 + except UnicodeEncodeError: 172 + value_string = unicode(value).encode('utf8') 173 + return value_string 273 174 274 - define contextsize-data 275 - if $argc != 1 276 - help contextsize-data 277 - else 278 - set $CONTEXTSIZE_DATA = $arg0 279 - end 280 - end 281 - document contextsize-data 282 - Syntax: contextsize-data NUM 283 - | Set data dump window size to NUM lines. 284 - end 175 + def format_address(address): 176 + pointer_size = gdb.parse_and_eval('$pc').type.sizeof 177 + return ('0x{{:0{}x}}').format(pointer_size * 2).format(address) 285 178 179 + # Dashboard -------------------------------------------------------------------- 286 180 287 - define contextsize-code 288 - if $argc != 1 289 - help contextsize-code 290 - else 291 - set $CONTEXTSIZE_CODE = $arg0 292 - end 293 - end 294 - document contextsize-code 295 - Syntax: contextsize-code NUM 296 - | Set code window size to NUM lines. 297 - end 181 + class Dashboard(gdb.Command): 182 + """Redisplay the dashboard.""" 298 183 184 + def __init__(self): 185 + gdb.Command.__init__(self, 'dashboard', 186 + gdb.COMMAND_USER, gdb.COMPLETE_NONE, True) 187 + self.output = None # main terminal 188 + self.enabled = True 189 + # setup subcommands 190 + Dashboard.OutputCommand(self) 191 + Dashboard.EnabledCommand(self) 192 + Dashboard.LayoutCommand(self) 193 + # setup style commands 194 + Dashboard.StyleCommand(self, 'dashboard', R, R.attributes()) 195 + # setup events 196 + gdb.events.cont.connect(lambda _: self.on_continue()) 197 + gdb.events.stop.connect(lambda _: self.on_stop()) 198 + gdb.events.exited.connect(lambda _: self.on_exit()) 299 199 300 - # _____________breakpoint aliases_____________ 301 - define bpl 302 - info breakpoints 303 - end 304 - document bpl 305 - Syntax: bpl 306 - | List all breakpoints. 307 - end 200 + def on_continue(self): 201 + # try to contain the GDB messages is a specified are unless the 202 + # dashboard is printed to a separate file 203 + if self.enabled and self.is_running() and not self.output: 204 + Dashboard.update_term_width() 205 + gdb.write(Dashboard.clear_screen()) 206 + gdb.write(divider('Output/messages', True)) 207 + gdb.write('\n') 208 + gdb.flush() 308 209 210 + def on_stop(self): 211 + # redisplay the dashboard when the target program stops (the screen is 212 + # cleared by on_continue when the dashboard is printed to a separate 213 + # file) 214 + if self.enabled and self.is_running(): 215 + clear = Dashboard.clear_screen() if self.output else '' 216 + self.display(clear, self.build(), '\n') 309 217 310 - define bp 311 - if $argc != 1 312 - help bp 313 - else 314 - break $arg0 315 - end 316 - end 317 - document bp 318 - Syntax: bp LOCATION 319 - | Set breakpoint. 320 - | LOCATION may be a line number, function name, or "*" and an address. 321 - | To break on a symbol you must enclose symbol name inside "". 322 - | Example: 323 - | bp "[NSControl stringValue]" 324 - | Or else you can use directly the break command (break [NSControl stringValue]) 325 - end 218 + def on_exit(self): 219 + pass 326 220 221 + def load_modules(self, modules): 222 + self.modules = [] 223 + for module in modules: 224 + info = Dashboard.ModuleInfo(self, module) 225 + self.modules.append(info) 327 226 328 - define bpc 329 - if $argc != 1 330 - help bpc 331 - else 332 - clear $arg0 333 - end 334 - end 335 - document bpc 336 - Syntax: bpc LOCATION 337 - | Clear breakpoint. 338 - | LOCATION may be a line number, function name, or "*" and an address. 339 - end 227 + def redisplay(self): 228 + # manually redisplay the dashboard 229 + if self.is_running(): 230 + self.display(Dashboard.clear_screen(), self.build(), '') 340 231 232 + def inferior_pid(self): 233 + return gdb.selected_inferior().pid 341 234 342 - define bpe 343 - if $argc != 1 344 - help bpe 345 - else 346 - enable $arg0 347 - end 348 - end 349 - document bpe 350 - Syntax: bpe NUM 351 - | Enable breakpoint with number NUM. 352 - end 235 + def is_running(self): 236 + return self.inferior_pid() != 0 353 237 238 + def build(self): 239 + # fetch the output width 240 + try: 241 + fd = self.output.fileno() if self.output else 1 # main terminal 242 + Dashboard.update_term_width(fd) 243 + except: 244 + # fall back to the main terminal 245 + Dashboard.update_term_width() 246 + # fetch lines 247 + lines = [] 248 + for module in self.modules: 249 + if not module.enabled: 250 + continue 251 + module = module.instance 252 + # active if more than zero lines 253 + module_lines = module.lines() 254 + lines.append(divider(module.label(), True, module_lines)) 255 + lines.extend(module_lines) 256 + if len(lines) == 0: 257 + lines.append(divider('Error', True)) 258 + if len(self.modules) == 0: 259 + lines.append('No module loaded') 260 + else: 261 + lines.append('No module to display (see `help dashboard`)') 262 + lines.append(divider(primary=True)) 263 + # print the dashboard 264 + return '\n'.join(lines) 354 265 355 - define bpd 356 - if $argc != 1 357 - help bpd 358 - else 359 - disable $arg0 360 - end 361 - end 362 - document bpd 363 - Syntax: bpd NUM 364 - | Disable breakpoint with number NUM. 365 - end 266 + def display(self, *data): 267 + # gdb module has both write() and flush() 268 + try: 269 + output = self.output or gdb 270 + for string in data: 271 + output.write(string) 272 + output.flush() 273 + except: 274 + Dashboard.err('Cannot write the dashboard') 366 275 276 + # Utility methods -------------------------------------------------------------- 367 277 368 - define bpt 369 - if $argc != 1 370 - help bpt 371 - else 372 - tbreak $arg0 373 - end 374 - end 375 - document bpt 376 - Syntax: bpt LOCATION 377 - | Set a temporary breakpoint. 378 - | This breakpoint will be automatically deleted when hit!. 379 - | LOCATION may be a line number, function name, or "*" and an address. 380 - end 278 + @staticmethod 279 + def start(): 280 + # initialize the dashboard 281 + dashboard = Dashboard() 282 + Dashboard.set_custom_prompt(dashboard) 283 + # parse Python inits, load modules then parse GDB inits 284 + Dashboard.parse_inits(True) 285 + modules = Dashboard.get_modules() 286 + dashboard.load_modules(modules) 287 + Dashboard.parse_inits(False) 288 + # GDB overrides 289 + run('set pagination off') 290 + run('alias -a db = dashboard') 381 291 292 + @staticmethod 293 + def update_term_width(fd=1): # defaults to the main terminal 294 + # first 2 shorts (4 byte) of struct winsize 295 + raw = fcntl.ioctl(fd, termios.TIOCGWINSZ, ' ' * 4) 296 + height, width = struct.unpack('hh', raw) 297 + Dashboard.term_width = int(width) 382 298 383 - define bpm 384 - if $argc != 1 385 - help bpm 386 - else 387 - awatch $arg0 388 - end 389 - end 390 - document bpm 391 - Syntax: bpm EXPRESSION 392 - | Set a read/write breakpoint on EXPRESSION, e.g. *address. 393 - end 299 + @staticmethod 300 + def set_custom_prompt(dashboard): 301 + def custom_prompt(_): 302 + # render thread status indicator 303 + if dashboard.is_running(): 304 + pid = dashboard.inferior_pid() 305 + status = R.prompt_running.format(pid=pid) 306 + else: 307 + status = R.prompt_not_running 308 + # build prompt 309 + prompt = R.prompt.format(status=status) 310 + prompt = gdb.prompt.substitute_prompt(prompt) 311 + return prompt + ' ' # force trailing space 312 + gdb.prompt_hook = custom_prompt 394 313 314 + @staticmethod 315 + def parse_inits(python): 316 + for root, dirs, files in os.walk(os.path.expanduser('~/.gdbinit.d/')): 317 + dirs.sort() 318 + for init in sorted(files): 319 + path = os.path.join(root, init) 320 + _, ext = os.path.splitext(path) 321 + # either load Python files or GDB 322 + if python ^ (ext != '.py'): 323 + gdb.execute('source ' + path) 395 324 396 - define bhb 397 - if $argc != 1 398 - help bhb 399 - else 400 - hb $arg0 401 - end 402 - end 403 - document bhb 404 - Syntax: bhb LOCATION 405 - | Set hardware assisted breakpoint. 406 - | LOCATION may be a line number, function name, or "*" and an address. 407 - end 325 + @staticmethod 326 + def get_modules(): 327 + # scan the scope for modules 328 + modules = [] 329 + for name in globals(): 330 + obj = globals()[name] 331 + try: 332 + if issubclass(obj, Dashboard.Module): 333 + modules.append(obj) 334 + except TypeError: 335 + continue 336 + # sort modules alphabetically 337 + modules.sort(key=lambda x: x.__name__) 338 + return modules 408 339 340 + @staticmethod 341 + def create_command(name, invoke, doc, is_prefix, complete=None): 342 + Class = type('', (gdb.Command,), {'invoke': invoke, '__doc__': doc}) 343 + Class(name, gdb.COMMAND_USER, complete or gdb.COMPLETE_NONE, is_prefix) 409 344 410 - define bht 411 - if $argc != 1 412 - help bht 413 - else 414 - thbreak $arg0 415 - end 416 - end 417 - document bht 418 - Usage: bht LOCATION 419 - | Set a temporary hardware breakpoint. 420 - | This breakpoint will be automatically deleted when hit! 421 - | LOCATION may be a line number, function name, or "*" and an address. 422 - end 345 + @staticmethod 346 + def err(string): 347 + print(ansi(string, R.style_error)) 423 348 349 + @staticmethod 350 + def complete(word, candidates): 351 + matching = [] 352 + for candidate in candidates: 353 + if candidate.startswith(word): 354 + matching.append(candidate) 355 + return matching 424 356 425 - # ______________process information____________ 426 - define argv 427 - show args 428 - end 429 - document argv 430 - Syntax: argv 431 - | Print program arguments. 432 - end 357 + @staticmethod 358 + def parse_arg(arg): 359 + # encode unicode GDB command arguments as utf8 in Python 2.7 360 + if type(arg) is not str: 361 + arg = arg.encode('utf8') 362 + return arg 433 363 364 + @staticmethod 365 + def clear_screen(): 366 + return '\x1b[H\x1b[2J' 434 367 435 - define stack 436 - if $argc == 0 437 - info stack 438 - end 439 - if $argc == 1 440 - info stack $arg0 441 - end 442 - if $argc > 1 443 - help stack 444 - end 445 - end 446 - document stack 447 - Syntax: stack <COUNT> 448 - | Print backtrace of the call stack, or innermost COUNT frames. 449 - end 368 + # Module descriptor ------------------------------------------------------------ 450 369 370 + class ModuleInfo: 451 371 452 - define frame 453 - info frame 454 - info args 455 - info locals 456 - end 457 - document frame 458 - Syntax: frame 459 - | Print stack frame. 460 - end 372 + def __init__(self, dashboard, module): 373 + self.name = module.__name__.lower() # from class to module name 374 + self.enabled = True 375 + self.instance = module() 376 + self.doc = self.instance.__doc__ or '(no documentation)' 377 + self.prefix = 'dashboard {}'.format(self.name) 378 + # add GDB commands 379 + self.add_main_command(dashboard) 380 + self.add_style_command(dashboard) 381 + self.add_subcommands(dashboard) 461 382 383 + def add_main_command(self, dashboard): 384 + module = self 385 + def invoke(self, arg, from_tty, info=self): 386 + arg = Dashboard.parse_arg(arg) 387 + if arg == '': 388 + info.enabled ^= True 389 + if dashboard.is_running(): 390 + dashboard.redisplay() 391 + else: 392 + status = 'enabled' if info.enabled else 'disabled' 393 + print('{} module {}'.format(module.name, status)) 394 + else: 395 + Dashboard.err('Wrong argument "{}"'.format(arg)) 396 + doc_brief = 'Configure the {} module.'.format(self.name) 397 + doc_extended = 'Toggle the module visibility.' 398 + doc = '{}\n{}\n\n{}'.format(doc_brief, doc_extended, self.doc) 399 + Dashboard.create_command(self.prefix, invoke, doc, True) 462 400 463 - define flagsarm 464 - # conditional flags are 465 - # negative/less than (N), bit 31 of CPSR 466 - # zero (Z), bit 30 467 - # Carry/Borrow/Extend (C), bit 29 468 - # Overflow (V), bit 28 469 - # negative/less than (N), bit 31 of CPSR 470 - if (($cpsr >> 0x1f) & 1) 471 - printf "N " 472 - set $_n_flag = 1 473 - else 474 - printf "n " 475 - set $_n_flag = 0 476 - end 477 - # zero (Z), bit 30 478 - if (($cpsr >> 0x1e) & 1) 479 - printf "Z " 480 - set $_z_flag = 1 481 - else 482 - printf "z " 483 - set $_z_flag = 0 484 - end 485 - # Carry/Borrow/Extend (C), bit 29 486 - if (($cpsr >> 0x1d) & 1) 487 - printf "C " 488 - set $_c_flag = 1 489 - else 490 - printf "c " 491 - set $_c_flag = 0 492 - end 493 - # Overflow (V), bit 28 494 - if (($cpsr >> 0x1c) & 1) 495 - printf "V " 496 - set $_v_flag = 1 497 - else 498 - printf "v " 499 - set $_v_flag = 0 500 - end 501 - # Sticky overflow (Q), bit 27 502 - if (($cpsr >> 0x1b) & 1) 503 - printf "Q " 504 - set $_q_flag = 1 505 - else 506 - printf "q " 507 - set $_q_flag = 0 508 - end 509 - # Java state bit (J), bit 24 510 - # When T=1: 511 - # J = 0 The processor is in Thumb state. 512 - # J = 1 The processor is in ThumbEE state. 513 - if (($cpsr >> 0x18) & 1) 514 - printf "J " 515 - set $_j_flag = 1 516 - else 517 - printf "j " 518 - set $_j_flag = 0 519 - end 520 - # Data endianness bit (E), bit 9 521 - if (($cpsr >> 9) & 1) 522 - printf "E " 523 - set $_e_flag = 1 524 - else 525 - printf "e " 526 - set $_e_flag = 0 527 - end 528 - # Imprecise abort disable bit (A), bit 8 529 - # The A bit is set to 1 automatically. It is used to disable imprecise data aborts. 530 - # It might not be writable in the Nonsecure state if the AW bit in the SCR register is reset. 531 - if (($cpsr >> 8) & 1) 532 - printf "A " 533 - set $_a_flag = 1 534 - else 535 - printf "a " 536 - set $_a_flag = 0 537 - end 538 - # IRQ disable bit (I), bit 7 539 - # When the I bit is set to 1, IRQ interrupts are disabled. 540 - if (($cpsr >> 7) & 1) 541 - printf "I " 542 - set $_i_flag = 1 543 - else 544 - printf "i " 545 - set $_i_flag = 0 546 - end 547 - # FIQ disable bit (F), bit 6 548 - # When the F bit is set to 1, FIQ interrupts are disabled. 549 - # FIQ can be nonmaskable in the Nonsecure state if the FW bit in SCR register is reset. 550 - if (($cpsr >> 6) & 1) 551 - printf "F " 552 - set $_f_flag = 1 553 - else 554 - printf "f " 555 - set $_f_flag = 0 556 - end 557 - # Thumb state bit (F), bit 5 558 - # if 1 then the processor is executing in Thumb state or ThumbEE state depending on the J bit 559 - if (($cpsr >> 5) & 1) 560 - printf "T " 561 - set $_t_flag = 1 562 - else 563 - printf "t " 564 - set $_t_flag = 0 565 - end 566 - # TODO: GE bit ? 567 - end 568 - document flagsarm 569 - Syntax: flagsarm 570 - | Auxiliary function to set ARM cpu flags. 571 - end 401 + def add_style_command(self, dashboard): 402 + if 'attributes' in dir(self.instance): 403 + Dashboard.StyleCommand(dashboard, self.prefix, self.instance, 404 + self.instance.attributes()) 572 405 406 + def add_subcommands(self, dashboard): 407 + if 'commands' in dir(self.instance): 408 + for name, command in self.instance.commands().items(): 409 + self.add_subcommand(dashboard, name, command) 573 410 574 - define flagsx86 575 - # OF (overflow) flag 576 - if (((unsigned int)$eflags >> 0xB) & 1) 577 - printf "O " 578 - set $_of_flag = 1 579 - else 580 - printf "o " 581 - set $_of_flag = 0 582 - end 583 - # DF (direction) flag 584 - if (((unsigned int)$eflags >> 0xA) & 1) 585 - printf "D " 586 - else 587 - printf "d " 588 - end 589 - # IF (interrupt enable) flag 590 - if (((unsigned int)$eflags >> 9) & 1) 591 - printf "I " 592 - else 593 - printf "i " 594 - end 595 - # TF (trap) flag 596 - if (((unsigned int)$eflags >> 8) & 1) 597 - printf "T " 598 - else 599 - printf "t " 600 - end 601 - # SF (sign) flag 602 - if (((unsigned int)$eflags >> 7) & 1) 603 - printf "S " 604 - set $_sf_flag = 1 605 - else 606 - printf "s " 607 - set $_sf_flag = 0 608 - end 609 - # ZF (zero) flag 610 - if (((unsigned int)$eflags >> 6) & 1) 611 - printf "Z " 612 - set $_zf_flag = 1 613 - else 614 - printf "z " 615 - set $_zf_flag = 0 616 - end 617 - # AF (adjust) flag 618 - if (((unsigned int)$eflags >> 4) & 1) 619 - printf "A " 620 - else 621 - printf "a " 622 - end 623 - # PF (parity) flag 624 - if (((unsigned int)$eflags >> 2) & 1) 625 - printf "P " 626 - set $_pf_flag = 1 627 - else 628 - printf "p " 629 - set $_pf_flag = 0 630 - end 631 - # CF (carry) flag 632 - if ((unsigned int)$eflags & 1) 633 - printf "C " 634 - set $_cf_flag = 1 635 - else 636 - printf "c " 637 - set $_cf_flag = 0 638 - end 639 - printf "\n" 640 - end 641 - document flagsx86 642 - Syntax: flagsx86 643 - | Auxiliary function to set X86/X64 cpu flags. 644 - end 411 + def add_subcommand(self, dashboard, name, command): 412 + action = command['action'] 413 + doc = command['doc'] 414 + complete = command.get('complete') 415 + def invoke(self, arg, from_tty, info=self): 416 + arg = Dashboard.parse_arg(arg) 417 + if info.enabled: 418 + try: 419 + action(arg) 420 + except Exception as e: 421 + Dashboard.err(e) 422 + return 423 + # don't catch redisplay errors 424 + dashboard.redisplay() 425 + else: 426 + Dashboard.err('Module disabled') 427 + prefix = '{} {}'.format(self.prefix, name) 428 + Dashboard.create_command(prefix, invoke, doc, False, complete) 645 429 430 + # GDB commands ----------------------------------------------------------------- 646 431 647 - define flags 648 - # call the auxiliary functions based on target cpu 649 - if $ARM == 1 650 - flagsarm 651 - else 652 - flagsx86 653 - end 654 - end 655 - document flags 656 - Syntax: flags 657 - | Print flags register. 658 - end 432 + def invoke(self, arg, from_tty): 433 + arg = Dashboard.parse_arg(arg) 434 + if arg == '': 435 + if self.is_running(): 436 + self.redisplay() 437 + else: 438 + Dashboard.err('Is the target program running?') 439 + else: 440 + Dashboard.err('Wrong argument "{}"'.format(arg)) 659 441 442 + class OutputCommand(gdb.Command): 443 + """Set the dashboard output file/TTY. 444 + The dashboard will be appended to the specified file, which will be created if 445 + it does not exists. If the specified file identifies a terminal then its width 446 + will be used to format the dashboard, otherwise falls back to the width of the 447 + main GDB terminal. Without argument the dashboard will be printed on standard 448 + output (default).""" 660 449 661 - define eflags 662 - if $ARM == 1 663 - # http://www.heyrick.co.uk/armwiki/The_Status_register 664 - printf " N <%d> Z <%d> C <%d> V <%d>",\ 665 - (($cpsr >> 0x1f) & 1), (($cpsr >> 0x1e) & 1), \ 666 - (($cpsr >> 0x1d) & 1), (($cpsr >> 0x1c) & 1) 667 - printf " Q <%d> J <%d> GE <%d> E <%d> A <%d>",\ 668 - (($cpsr >> 0x1b) & 1), (($cpsr >> 0x18) & 1),\ 669 - (($cpsr >> 0x10) & 7), (($cpsr >> 9) & 1), (($cpsr >> 8) & 1) 670 - printf " I <%d> F <%d> T <%d> \n",\ 671 - (($cpsr >> 7) & 1), (($cpsr >> 6) & 1), \ 672 - (($cpsr >> 5) & 1) 673 - else 674 - printf " OF <%d> DF <%d> IF <%d> TF <%d>",\ 675 - (((unsigned int)$eflags >> 0xB) & 1), (((unsigned int)$eflags >> 0xA) & 1), \ 676 - (((unsigned int)$eflags >> 9) & 1), (((unsigned int)$eflags >> 8) & 1) 677 - printf " SF <%d> ZF <%d> AF <%d> PF <%d> CF <%d>\n",\ 678 - (((unsigned int)$eflags >> 7) & 1), (((unsigned int)$eflags >> 6) & 1),\ 679 - (((unsigned int)$eflags >> 4) & 1), (((unsigned int)$eflags >> 2) & 1), ((unsigned int)$eflags & 1) 680 - printf " ID <%d> VIP <%d> VIF <%d> AC <%d>",\ 681 - (((unsigned int)$eflags >> 0x15) & 1), (((unsigned int)$eflags >> 0x14) & 1), \ 682 - (((unsigned int)$eflags >> 0x13) & 1), (((unsigned int)$eflags >> 0x12) & 1) 683 - printf " VM <%d> RF <%d> NT <%d> IOPL <%d>\n",\ 684 - (((unsigned int)$eflags >> 0x11) & 1), (((unsigned int)$eflags >> 0x10) & 1),\ 685 - (((unsigned int)$eflags >> 0xE) & 1), (((unsigned int)$eflags >> 0xC) & 3) 686 - end 687 - end 688 - document eflags 689 - Syntax: eflags 690 - | Print eflags register. 691 - end 450 + def __init__(self, dashboard): 451 + gdb.Command.__init__(self, 'dashboard -output', 452 + gdb.COMMAND_USER, gdb.COMPLETE_FILENAME) 453 + self.dashboard = dashboard 692 454 455 + def invoke(self, arg, from_tty): 456 + arg = Dashboard.parse_arg(arg) 457 + # close the previous output file, if any 458 + if self.dashboard.output: 459 + self.dashboard.output.close() 460 + # set or open the output file 461 + if arg == '': 462 + self.dashboard.output = None 463 + else: 464 + try: 465 + self.dashboard.output = open(arg, 'w') 466 + except: 467 + Dashboard.err('Cannot open "{}"'.format(arg)) 468 + # redisplay the dashboard in the new output 469 + self.dashboard.redisplay() 693 470 694 - define cpsr 695 - eflags 696 - end 697 - document cpsr 698 - Syntax: cpsr 699 - | Print cpsr register. 700 - end 471 + class EnabledCommand(gdb.Command): 472 + """Enable or disable the dashboard [on|off]. 473 + The current status is printed if no argument is present.""" 701 474 702 - define regarm 703 - printf " " 704 - # R0 705 - color $COLOR_REGNAME 706 - printf "R0:" 707 - if ($r0 != $oldr0 && $SHOWREGCHANGES == 1) 708 - color $COLOR_REGVAL_MODIFIED 709 - else 710 - color $COLOR_REGVAL 711 - end 712 - printf " 0x%08X ", $r0 713 - # R1 714 - color $COLOR_REGNAME 715 - printf "R1:" 716 - if ($r1 != $oldr1 && $SHOWREGCHANGES == 1) 717 - color $COLOR_REGVAL_MODIFIED 718 - else 719 - color $COLOR_REGVAL 720 - end 721 - printf " 0x%08X ", $r1 722 - # R2 723 - color $COLOR_REGNAME 724 - printf "R2:" 725 - if ($r2 != $oldr2 && $SHOWREGCHANGES == 1) 726 - color $COLOR_REGVAL_MODIFIED 727 - else 728 - color $COLOR_REGVAL 729 - end 730 - printf " 0x%08X ", $r2 731 - # R3 732 - color $COLOR_REGNAME 733 - printf "R3:" 734 - if ($r3 != $oldr3 && $SHOWREGCHANGES == 1) 735 - color $COLOR_REGVAL_MODIFIED 736 - else 737 - color $COLOR_REGVAL 738 - end 739 - printf " 0x%08X\n", $r3 740 - printf " " 741 - # R4 742 - color $COLOR_REGNAME 743 - printf "R4:" 744 - if ($r4 != $oldr4 && $SHOWREGCHANGES == 1) 745 - color $COLOR_REGVAL_MODIFIED 746 - else 747 - color $COLOR_REGVAL 748 - end 749 - printf " 0x%08X ", $r4 750 - # R5 751 - color $COLOR_REGNAME 752 - printf "R5:" 753 - if ($r5 != $oldr5 && $SHOWREGCHANGES == 1) 754 - color $COLOR_REGVAL_MODIFIED 755 - else 756 - color $COLOR_REGVAL 757 - end 758 - printf " 0x%08X ", $r5 759 - # R6 760 - color $COLOR_REGNAME 761 - printf "R6:" 762 - if ($r6 != $oldr6 && $SHOWREGCHANGES == 1) 763 - color $COLOR_REGVAL_MODIFIED 764 - else 765 - color $COLOR_REGVAL 766 - end 767 - printf " 0x%08X ", $r6 768 - # R7 769 - color $COLOR_REGNAME 770 - printf "R7:" 771 - if ($r7 != $oldr7 && $SHOWREGCHANGES == 1) 772 - color $COLOR_REGVAL_MODIFIED 773 - else 774 - color $COLOR_REGVAL 775 - end 776 - printf " 0x%08X\n", $r7 777 - printf " " 778 - # R8 779 - color $COLOR_REGNAME 780 - printf "R8:" 781 - if ($r8 != $oldr8 && $SHOWREGCHANGES == 1) 782 - color $COLOR_REGVAL_MODIFIED 783 - else 784 - color $COLOR_REGVAL 785 - end 786 - printf " 0x%08X ", $r8 787 - # R9 788 - color $COLOR_REGNAME 789 - printf "R9:" 790 - if ($r9 != $oldr9 && $SHOWREGCHANGES == 1) 791 - color $COLOR_REGVAL_MODIFIED 792 - else 793 - color $COLOR_REGVAL 794 - end 795 - printf " 0x%08X ", $r9 796 - # R10 797 - color $COLOR_REGNAME 798 - printf "R10:" 799 - if ($r10 != $oldr10 && $SHOWREGCHANGES == 1) 800 - color $COLOR_REGVAL_MODIFIED 801 - else 802 - color $COLOR_REGVAL 803 - end 804 - printf " 0x%08X ", $r10 805 - # R11 806 - color $COLOR_REGNAME 807 - printf "R11:" 808 - if ($r11 != $oldr11 && $SHOWREGCHANGES == 1) 809 - color $COLOR_REGVAL_MODIFIED 810 - else 811 - color $COLOR_REGVAL 812 - end 813 - printf " 0x%08X ", $r11 814 - dumpjump 815 - printf "\n" 816 - # R12 817 - color $COLOR_REGNAME 818 - printf " R12:" 819 - if ($r12 != $oldr12 && $SHOWREGCHANGES == 1) 820 - color $COLOR_REGVAL_MODIFIED 821 - else 822 - color $COLOR_REGVAL 823 - end 824 - printf " 0x%08X", $r12 825 - printf " " 826 - # SP 827 - color $COLOR_REGNAME 828 - printf "SP:" 829 - if ($sp != $oldsp && $SHOWREGCHANGES == 1) 830 - color $COLOR_REGVAL_MODIFIED 831 - else 832 - color $COLOR_REGVAL 833 - end 834 - printf " 0x%08X ", $sp 835 - # LR 836 - color $COLOR_REGNAME 837 - printf "LR:" 838 - if ($lr != $oldlr && $SHOWREGCHANGES == 1) 839 - color $COLOR_REGVAL_MODIFIED 840 - else 841 - color $COLOR_REGVAL 842 - end 843 - printf " 0x%08X ", $lr 844 - # PC 845 - color $COLOR_REGNAME 846 - printf "PC:" 847 - color $COLOR_REGVAL_MODIFIED 848 - printf " 0x%08X ", $pc 849 - color_bold 850 - color_underline 851 - color $COLOR_CPUFLAGS 852 - flags 853 - color_reset 854 - printf "\n" 855 - end 856 - document regarm 857 - Syntax: regarm 858 - | Auxiliary function to display ARM registers. 859 - end 475 + def __init__(self, dashboard): 476 + gdb.Command.__init__(self, 'dashboard -enabled', gdb.COMMAND_USER) 477 + self.dashboard = dashboard 860 478 861 - define regx64 862 - # 64bits stuff 863 - printf " " 864 - # RAX 865 - color $COLOR_REGNAME 866 - printf "RAX:" 867 - if ($rax != $oldrax && $SHOWREGCHANGES == 1) 868 - color $COLOR_REGVAL_MODIFIED 869 - else 870 - color $COLOR_REGVAL 871 - end 872 - printf " 0x%016lX ", $rax 873 - # RBX 874 - color $COLOR_REGNAME 875 - printf "RBX:" 876 - if ($rbx != $oldrbx && $SHOWREGCHANGES == 1) 877 - color $COLOR_REGVAL_MODIFIED 878 - else 879 - color $COLOR_REGVAL 880 - end 881 - printf " 0x%016lX ", $rbx 882 - # RBP 883 - color $COLOR_REGNAME 884 - printf "RBP:" 885 - if ($rbp != $oldrbp && $SHOWREGCHANGES == 1) 886 - color $COLOR_REGVAL_MODIFIED 887 - else 888 - color $COLOR_REGVAL 889 - end 890 - printf " 0x%016lX ", $rbp 891 - # RSP 892 - color $COLOR_REGNAME 893 - printf "RSP:" 894 - if ($rsp != $oldrsp && $SHOWREGCHANGES == 1) 895 - color $COLOR_REGVAL_MODIFIED 896 - else 897 - color $COLOR_REGVAL 898 - end 899 - printf " 0x%016lX ", $rsp 900 - color_bold 901 - color_underline 902 - color $COLOR_CPUFLAGS 903 - flags 904 - color_reset 905 - printf " " 906 - # RDI 907 - color $COLOR_REGNAME 908 - printf "RDI:" 909 - if ($rdi != $oldrdi && $SHOWREGCHANGES == 1) 910 - color $COLOR_REGVAL_MODIFIED 911 - else 912 - color $COLOR_REGVAL 913 - end 914 - printf " 0x%016lX ", $rdi 915 - # RSI 916 - color $COLOR_REGNAME 917 - printf "RSI:" 918 - if ($rsi != $oldrsi && $SHOWREGCHANGES == 1) 919 - color $COLOR_REGVAL_MODIFIED 920 - else 921 - color $COLOR_REGVAL 922 - end 923 - printf " 0x%016lX ", $rsi 924 - # RDX 925 - color $COLOR_REGNAME 926 - printf "RDX:" 927 - if ($rdx != $oldrdx && $SHOWREGCHANGES == 1) 928 - color $COLOR_REGVAL_MODIFIED 929 - else 930 - color $COLOR_REGVAL 931 - end 932 - printf " 0x%016lX ", $rdx 933 - # RCX 934 - color $COLOR_REGNAME 935 - printf "RCX:" 936 - if ($rcx != $oldrcx && $SHOWREGCHANGES == 1) 937 - color $COLOR_REGVAL_MODIFIED 938 - else 939 - color $COLOR_REGVAL 940 - end 941 - printf " 0x%016lX ", $rcx 942 - # RIP 943 - color $COLOR_REGNAME 944 - printf "RIP:" 945 - color $COLOR_REGVAL_MODIFIED 946 - printf " 0x%016lX\n ", $rip 947 - # R8 948 - color $COLOR_REGNAME 949 - printf "R8 :" 950 - if ($r8 != $oldr8 && $SHOWREGCHANGES == 1) 951 - color $COLOR_REGVAL_MODIFIED 952 - else 953 - color $COLOR_REGVAL 954 - end 955 - printf " 0x%016lX ", $r8 956 - # R9 957 - color $COLOR_REGNAME 958 - printf "R9 :" 959 - if ($r9 != $oldr9 && $SHOWREGCHANGES == 1) 960 - color $COLOR_REGVAL_MODIFIED 961 - else 962 - color $COLOR_REGVAL 963 - end 964 - printf " 0x%016lX ", $r9 965 - # R10 966 - color $COLOR_REGNAME 967 - printf "R10:" 968 - if ($r10 != $oldr10 && $SHOWREGCHANGES == 1) 969 - color $COLOR_REGVAL_MODIFIED 970 - else 971 - color $COLOR_REGVAL 972 - end 973 - printf " 0x%016lX ", $r10 974 - # R11 975 - color $COLOR_REGNAME 976 - printf "R11:" 977 - if ($r11 != $oldr11 && $SHOWREGCHANGES == 1) 978 - color $COLOR_REGVAL_MODIFIED 979 - else 980 - color $COLOR_REGVAL 981 - end 982 - printf " 0x%016lX ", $r11 983 - # R12 984 - color $COLOR_REGNAME 985 - printf "R12:" 986 - if ($r12 != $oldr12 && $SHOWREGCHANGES == 1) 987 - color $COLOR_REGVAL_MODIFIED 988 - else 989 - color $COLOR_REGVAL 990 - end 991 - printf " 0x%016lX\n ", $r12 992 - # R13 993 - color $COLOR_REGNAME 994 - printf "R13:" 995 - if ($r13 != $oldr13 && $SHOWREGCHANGES == 1) 996 - color $COLOR_REGVAL_MODIFIED 997 - else 998 - color $COLOR_REGVAL 999 - end 1000 - printf " 0x%016lX ", $r13 1001 - # R14 1002 - color $COLOR_REGNAME 1003 - printf "R14:" 1004 - if ($r14 != $oldr14 && $SHOWREGCHANGES == 1) 1005 - color $COLOR_REGVAL_MODIFIED 1006 - else 1007 - color $COLOR_REGVAL 1008 - end 1009 - printf " 0x%016lX ", $r14 1010 - # R15 1011 - color $COLOR_REGNAME 1012 - printf "R15:" 1013 - if ($r15 != $oldr15 && $SHOWREGCHANGES == 1) 1014 - color $COLOR_REGVAL_MODIFIED 1015 - else 1016 - color $COLOR_REGVAL 1017 - end 1018 - printf " 0x%016lX\n ", $r15 1019 - color $COLOR_REGNAME 1020 - printf "CS:" 1021 - color $COLOR_REGVAL 1022 - printf " %04X ", $cs 1023 - color $COLOR_REGNAME 1024 - printf "DS:" 1025 - color $COLOR_REGVAL 1026 - printf " %04X ", $ds 1027 - color $COLOR_REGNAME 1028 - printf "ES:" 1029 - color $COLOR_REGVAL 1030 - printf " %04X ", $es 1031 - color $COLOR_REGNAME 1032 - printf "FS:" 1033 - color $COLOR_REGVAL 1034 - printf " %04X ", $fs 1035 - color $COLOR_REGNAME 1036 - printf "GS:" 1037 - color $COLOR_REGVAL 1038 - printf " %04X ", $gs 1039 - color $COLOR_REGNAME 1040 - printf "SS:" 1041 - color $COLOR_REGVAL 1042 - printf " %04X", $ss 1043 - color_reset 1044 - end 1045 - document regx64 1046 - Syntax: regx64 1047 - | Auxiliary function to display X86_64 registers. 1048 - end 479 + def invoke(self, arg, from_tty): 480 + arg = Dashboard.parse_arg(arg) 481 + if arg == '': 482 + status = 'enabled' if self.dashboard.enabled else 'disabled' 483 + print('The dashboard is {}'.format(status)) 484 + elif arg == 'on': 485 + self.dashboard.enabled = True 486 + self.dashboard.redisplay() 487 + elif arg == 'off': 488 + self.dashboard.enabled = False 489 + else: 490 + msg = 'Wrong argument "{}"; expecting "on" or "off"' 491 + Dashboard.err(msg.format(arg)) 1049 492 493 + def complete(self, text, word): 494 + return Dashboard.complete(word, ['on', 'off']) 1050 495 1051 - define regx86 1052 - printf " " 1053 - # EAX 1054 - color $COLOR_REGNAME 1055 - printf "EAX:" 1056 - if ($eax != $oldeax && $SHOWREGCHANGES == 1) 1057 - color $COLOR_REGVAL_MODIFIED 1058 - else 1059 - color $COLOR_REGVAL 1060 - end 1061 - printf " 0x%08X ", $eax 1062 - # EBX 1063 - color $COLOR_REGNAME 1064 - printf "EBX:" 1065 - if ($ebx != $oldebx && $SHOWREGCHANGES == 1) 1066 - color $COLOR_REGVAL_MODIFIED 1067 - else 1068 - color $COLOR_REGVAL 1069 - end 1070 - printf " 0x%08X ", $ebx 1071 - # ECX 1072 - color $COLOR_REGNAME 1073 - printf "ECX:" 1074 - if ($ecx != $oldecx && $SHOWREGCHANGES == 1) 1075 - color $COLOR_REGVAL_MODIFIED 1076 - else 1077 - color $COLOR_REGVAL 1078 - end 1079 - printf " 0x%08X ", $ecx 1080 - # EDX 1081 - color $COLOR_REGNAME 1082 - printf "EDX:" 1083 - if ($edx != $oldedx && $SHOWREGCHANGES == 1) 1084 - color $COLOR_REGVAL_MODIFIED 1085 - else 1086 - color $COLOR_REGVAL 1087 - end 1088 - printf " 0x%08X ", $edx 1089 - color_bold 1090 - color_underline 1091 - color $COLOR_CPUFLAGS 1092 - flags 1093 - color_reset 1094 - printf " " 1095 - # ESI 1096 - color $COLOR_REGNAME 1097 - printf "ESI:" 1098 - if ($esi != $oldesi && $SHOWREGCHANGES == 1) 1099 - color $COLOR_REGVAL_MODIFIED 1100 - else 1101 - color $COLOR_REGVAL 1102 - end 1103 - printf " 0x%08X ", $esi 1104 - # EDI 1105 - color $COLOR_REGNAME 1106 - printf "EDI:" 1107 - if ($edi != $oldedi && $SHOWREGCHANGES == 1) 1108 - color $COLOR_REGVAL_MODIFIED 1109 - else 1110 - color $COLOR_REGVAL 1111 - end 1112 - printf " 0x%08X ", $edi 1113 - # EBP 1114 - color $COLOR_REGNAME 1115 - printf "EBP:" 1116 - if ($ebp != $oldebp && $SHOWREGCHANGES == 1) 1117 - color $COLOR_REGVAL_MODIFIED 1118 - else 1119 - color $COLOR_REGVAL 1120 - end 1121 - printf " 0x%08X ", $ebp 1122 - # ESP 1123 - color $COLOR_REGNAME 1124 - printf "ESP:" 1125 - if ($esp != $oldesp && $SHOWREGCHANGES == 1) 1126 - color $COLOR_REGVAL_MODIFIED 1127 - else 1128 - color $COLOR_REGVAL 1129 - end 1130 - printf " 0x%08X ", $esp 1131 - # EIP 1132 - color $COLOR_REGNAME 1133 - printf "EIP:" 1134 - color $COLOR_REGVAL_MODIFIED 1135 - printf " 0x%08X\n ", $eip 1136 - color $COLOR_REGNAME 1137 - printf "CS:" 1138 - color $COLOR_REGVAL 1139 - printf " %04X ", $cs 1140 - color $COLOR_REGNAME 1141 - printf "DS:" 1142 - color $COLOR_REGVAL 1143 - printf " %04X ", $ds 1144 - color $COLOR_REGNAME 1145 - printf "ES:" 1146 - color $COLOR_REGVAL 1147 - printf " %04X ", $es 1148 - color $COLOR_REGNAME 1149 - printf "FS:" 1150 - color $COLOR_REGVAL 1151 - printf " %04X ", $fs 1152 - color $COLOR_REGNAME 1153 - printf "GS:" 1154 - color $COLOR_REGVAL 1155 - printf " %04X ", $gs 1156 - color $COLOR_REGNAME 1157 - printf "SS:" 1158 - color $COLOR_REGVAL 1159 - printf " %04X", $ss 1160 - color_reset 1161 - end 1162 - document regx86 1163 - Syntax: regx86 1164 - | Auxiliary function to display X86 registers. 1165 - end 496 + class LayoutCommand(gdb.Command): 497 + """Set or show the dashboard layout. 498 + Accepts a space-separated list of directive. Each directive is in the form 499 + "[!]<module>". Modules in the list are placed in the dashboard in the same order 500 + as they appear and those prefixed by "!" are disabled by default. Omitted 501 + modules are hidden and placed at the bottom in alphabetical order. Without 502 + arguments the current layout is shown; enabled and disabled modules are properly 503 + marked.""" 1166 504 505 + def __init__(self, dashboard): 506 + gdb.Command.__init__(self, 'dashboard -layout', gdb.COMMAND_USER) 507 + self.dashboard = dashboard 1167 508 1168 - define reg 1169 - if $ARM == 1 1170 - regarm 1171 - if ($SHOWREGCHANGES == 1) 1172 - set $oldr0 = $r0 1173 - set $oldr1 = $r1 1174 - set $oldr2 = $r2 1175 - set $oldr3 = $r3 1176 - set $oldr4 = $r4 1177 - set $oldr5 = $r5 1178 - set $oldr6 = $r6 1179 - set $oldr7 = $r7 1180 - set $oldr8 = $r8 1181 - set $oldr9 = $r9 1182 - set $oldr10 = $r10 1183 - set $oldr11 = $r11 1184 - set $oldr12 = $r12 1185 - set $oldsp = $sp 1186 - set $oldlr = $lr 1187 - end 1188 - else 1189 - if ($64BITS == 1) 1190 - regx64 1191 - else 1192 - regx86 1193 - end 1194 - # call smallregisters 1195 - smallregisters 1196 - # display conditional jump routine 1197 - if ($64BITS == 1) 1198 - printf "\t\t\t\t" 1199 - end 1200 - dumpjump 1201 - printf "\n" 1202 - if ($SHOWREGCHANGES == 1) 1203 - if ($64BITS == 1) 1204 - set $oldrax = $rax 1205 - set $oldrbx = $rbx 1206 - set $oldrcx = $rcx 1207 - set $oldrdx = $rdx 1208 - set $oldrsi = $rsi 1209 - set $oldrdi = $rdi 1210 - set $oldrbp = $rbp 1211 - set $oldrsp = $rsp 1212 - set $oldr8 = $r8 1213 - set $oldr9 = $r9 1214 - set $oldr10 = $r10 1215 - set $oldr11 = $r11 1216 - set $oldr12 = $r12 1217 - set $oldr13 = $r13 1218 - set $oldr14 = $r14 1219 - set $oldr15 = $r15 1220 - else 1221 - set $oldeax = $eax 1222 - set $oldebx = $ebx 1223 - set $oldecx = $ecx 1224 - set $oldedx = $edx 1225 - set $oldesi = $esi 1226 - set $oldedi = $edi 1227 - set $oldebp = $ebp 1228 - set $oldesp = $esp 1229 - end 1230 - end 1231 - end 1232 - end 1233 - document reg 1234 - Syntax: reg 1235 - | Print CPU registers. 1236 - end 509 + def invoke(self, arg, from_tty): 510 + arg = Dashboard.parse_arg(arg) 511 + directives = str(arg).split() 512 + if directives: 513 + self.layout(directives) 514 + if from_tty and not self.dashboard.is_running(): 515 + self.show() 516 + else: 517 + self.show() 1237 518 519 + def show(self): 520 + for module in self.dashboard.modules: 521 + style = R.style_high if module.enabled else R.style_low 522 + print(ansi(module.name, style)) 1238 523 1239 - define smallregisters 1240 - if ($64BITS == 1) 1241 - #64bits stuff 1242 - # from rax 1243 - set $eax = $rax & 0xffffffff 1244 - set $ax = $rax & 0xffff 1245 - set $al = $ax & 0xff 1246 - set $ah = $ax >> 8 1247 - # from rbx 1248 - set $ebx = $rbx & 0xffffffff 1249 - set $bx = $rbx & 0xffff 1250 - set $bl = $bx & 0xff 1251 - set $bh = $bx >> 8 1252 - # from rcx 1253 - set $ecx = $rcx & 0xffffffff 1254 - set $cx = $rcx & 0xffff 1255 - set $cl = $cx & 0xff 1256 - set $ch = $cx >> 8 1257 - # from rdx 1258 - set $edx = $rdx & 0xffffffff 1259 - set $dx = $rdx & 0xffff 1260 - set $dl = $dx & 0xff 1261 - set $dh = $dx >> 8 1262 - # from rsi 1263 - set $esi = $rsi & 0xffffffff 1264 - set $si = $rsi & 0xffff 1265 - # from rdi 1266 - set $edi = $rdi & 0xffffffff 1267 - set $di = $rdi & 0xffff 1268 - #32 bits stuff 1269 - else 1270 - # from eax 1271 - set $ax = $eax & 0xffff 1272 - set $al = $ax & 0xff 1273 - set $ah = $ax >> 8 1274 - # from ebx 1275 - set $bx = $ebx & 0xffff 1276 - set $bl = $bx & 0xff 1277 - set $bh = $bx >> 8 1278 - # from ecx 1279 - set $cx = $ecx & 0xffff 1280 - set $cl = $cx & 0xff 1281 - set $ch = $cx >> 8 1282 - # from edx 1283 - set $dx = $edx & 0xffff 1284 - set $dl = $dx & 0xff 1285 - set $dh = $dx >> 8 1286 - # from esi 1287 - set $si = $esi & 0xffff 1288 - # from edi 1289 - set $di = $edi & 0xffff 1290 - end 1291 - end 1292 - document smallregisters 1293 - Syntax: smallregisters 1294 - | Create the 16 and 8 bit cpu registers (gdb doesn't have them by default). 1295 - | And 32bits if we are dealing with 64bits binaries. 1296 - end 524 + def layout(self, directives): 525 + modules = self.dashboard.modules 526 + # reset visibility 527 + for module in modules: 528 + module.enabled = False 529 + # move and enable the selected modules on top 530 + last = 0 531 + n_enabled = 0 532 + for directive in directives: 533 + # parse next directive 534 + enabled = (directive[0] != '!') 535 + name = directive[not enabled:] 536 + try: 537 + # it may actually start from last, but in this way repeated 538 + # modules can be handler transparently and without error 539 + todo = enumerate(modules[last:], start=last) 540 + index = next(i for i, m in todo if name == m.name) 541 + modules[index].enabled = enabled 542 + modules.insert(last, modules.pop(index)) 543 + last += 1 544 + n_enabled += enabled 545 + except StopIteration: 546 + def find_module(x): 547 + return x.name == name 548 + first_part = modules[:last] 549 + if len(filter(find_module, first_part)) == 0: 550 + Dashboard.err('Cannot find module "{}"'.format(name)) 551 + else: 552 + Dashboard.err('Module "{}" already set'.format(name)) 553 + continue 554 + # redisplay the dashboard 555 + if n_enabled: 556 + self.dashboard.redisplay() 1297 557 558 + def complete(self, text, word): 559 + all_modules = (m.name for m in self.dashboard.modules) 560 + return Dashboard.complete(word, all_modules) 1298 561 1299 - define func 1300 - if $argc == 0 1301 - info functions 1302 - end 1303 - if $argc == 1 1304 - info functions $arg0 1305 - end 1306 - if $argc > 1 1307 - help func 1308 - end 1309 - end 1310 - document func 1311 - Syntax: func <REGEXP> 1312 - | Print all function names in target, or those matching REGEXP. 1313 - end 562 + class StyleCommand(gdb.Command): 563 + """Access the stylable attributes. 564 + Without arguments print all the stylable attributes. Subcommands are used to set 565 + or print (when the value is omitted) individual attributes.""" 1314 566 567 + def __init__(self, dashboard, prefix, obj, attributes): 568 + self.prefix = prefix + ' -style' 569 + gdb.Command.__init__(self, self.prefix, 570 + gdb.COMMAND_USER, gdb.COMPLETE_NONE, True) 571 + self.dashboard = dashboard 572 + self.obj = obj 573 + self.attributes = attributes 574 + self.add_styles() 1315 575 1316 - define var 1317 - if $argc == 0 1318 - info variables 1319 - end 1320 - if $argc == 1 1321 - info variables $arg0 1322 - end 1323 - if $argc > 1 1324 - help var 1325 - end 1326 - end 1327 - document var 1328 - Syntax: var <REGEXP> 1329 - | Print all global and static variable names (symbols), or those matching REGEXP. 1330 - end 576 + def add_styles(self): 577 + this = self 578 + for name, attribute in self.attributes.items(): 579 + # fetch fields 580 + attr_name = attribute.get('name', name) 581 + attr_type = attribute.get('type', str) 582 + attr_check = attribute.get('check', lambda _: True) 583 + attr_default = attribute['default'] 584 + # set the default value (coerced to the type) 585 + value = attr_type(attr_default) 586 + setattr(self.obj, attr_name, value) 587 + # create the command 588 + def invoke(self, arg, from_tty, name=name, attr_name=attr_name, 589 + attr_type=attr_type, attr_check=attr_check): 590 + new_value = Dashboard.parse_arg(arg) 591 + if new_value == '': 592 + # print the current value 593 + value = getattr(this.obj, attr_name) 594 + print('{} = {!r}'.format(name, value)) 595 + else: 596 + try: 597 + # convert and check the new value 598 + parsed = ast.literal_eval(new_value) 599 + value = attr_type(parsed) 600 + if not attr_check(value): 601 + msg = 'Invalid value "{}" for "{}"' 602 + raise Exception(msg.format(new_value, name)) 603 + except Exception as e: 604 + Dashboard.err(e) 605 + else: 606 + # set and redisplay 607 + setattr(this.obj, attr_name, value) 608 + this.dashboard.redisplay() 609 + prefix = self.prefix + ' ' + name 610 + doc = attribute.get('doc', 'This style is self-documenting') 611 + Dashboard.create_command(prefix, invoke, doc, False) 1331 612 613 + def invoke(self, arg, from_tty): 614 + # print all the pairs 615 + for name, attribute in self.attributes.items(): 616 + attr_name = attribute.get('name', name) 617 + value = getattr(self.obj, attr_name) 618 + print('{} = {!r}'.format(name, value)) 1332 619 1333 - define lib 1334 - info sharedlibrary 1335 - end 1336 - document lib 1337 - Syntax: lib 1338 - | Print shared libraries linked to target. 1339 - end 620 + # Base module ------------------------------------------------------------------ 1340 621 622 + # just a tag 623 + class Module(): 624 + pass 1341 625 1342 - define sig 1343 - if $argc == 0 1344 - info signals 1345 - end 1346 - if $argc == 1 1347 - info signals $arg0 1348 - end 1349 - if $argc > 1 1350 - help sig 1351 - end 1352 - end 1353 - document sig 1354 - Syntax: sig <SIGNAL> 1355 - | Print what debugger does when program gets various signals. 1356 - | Specify a SIGNAL as argument to print info on that signal only. 1357 - end 626 + # Default modules -------------------------------------------------------------- 1358 627 628 + class Source(Dashboard.Module): 629 + """Show the program source code, if available.""" 1359 630 1360 - define threads 1361 - info threads 1362 - end 1363 - document threads 1364 - Syntax: threads 1365 - | Print threads in target. 1366 - end 631 + def __init__(self): 632 + self.file_name = None 633 + self.source_lines = [] 1367 634 635 + def label(self): 636 + return 'Source' 1368 637 1369 - define dis 1370 - if $argc == 0 1371 - disassemble 1372 - end 1373 - if $argc == 1 1374 - disassemble $arg0 1375 - end 1376 - if $argc == 2 1377 - disassemble $arg0 $arg1 1378 - end 1379 - if $argc > 2 1380 - help dis 1381 - end 1382 - end 1383 - document dis 1384 - Syntax: dis <ADDR1> <ADDR2> 1385 - | Disassemble a specified section of memory. 1386 - | Default is to disassemble the function surrounding the PC (program counter) of selected frame. 1387 - | With one argument, ADDR1, the function surrounding this address is dumped. 1388 - | Two arguments are taken as a range of memory to dump. 1389 - end 638 + def lines(self): 639 + # try to fetch the current line (skip if no line information) 640 + sal = gdb.selected_frame().find_sal() 641 + current_line = sal.line 642 + if current_line == 0: 643 + return [] 644 + # reload the source file if changed 645 + file_name = sal.symtab.fullname() 646 + if file_name != self.file_name: 647 + self.file_name = file_name 648 + try: 649 + with open(self.file_name) as source: 650 + self.source_lines = source.readlines() 651 + except: 652 + msg = 'Cannot access "{}"'.format(self.file_name) 653 + return [ansi(msg, R.style_error)] 654 + # compute the line range 655 + start = max(current_line - 1 - self.context, 0) 656 + end = min(current_line - 1 + self.context, len(self.source_lines)) 657 + # return the source code listing 658 + out = [] 659 + number_format = '{{:>{}}}'.format(len(str(end))) 660 + for number, line in enumerate(self.source_lines[start:end], start + 1): 661 + if int(number) == current_line: 662 + line_format = ansi(number_format + ' {}', R.style_selected_1) 663 + else: 664 + line_format = ansi(number_format, R.style_low) + ' {}' 665 + out.append(line_format.format(number, line.rstrip('\n'))) 666 + return out 1390 667 668 + def set_context(self, arg): 669 + msg = 'expecting a positive integer' 670 + self.context = parse_value(arg, int, check_ge_zero, msg) 1391 671 1392 - # __________hex/ascii dump an address_________ 1393 - define ascii_char 1394 - if $argc != 1 1395 - help ascii_char 1396 - else 1397 - # thanks elaine :) 1398 - set $_c = *(unsigned char *)($arg0) 1399 - if ($_c < 0x20 || $_c > 0x7E) 1400 - printf "." 1401 - else 1402 - printf "%c", $_c 1403 - end 1404 - end 1405 - end 1406 - document ascii_char 1407 - Syntax: ascii_char ADDR 1408 - | Print ASCII value of byte at address ADDR. 1409 - | Print "." if the value is unprintable. 1410 - end 672 + def attributes(self): 673 + return { 674 + 'context': { 675 + 'doc': 'Number of context lines.', 676 + 'default': 5, 677 + 'type': int, 678 + 'check': check_ge_zero 679 + } 680 + } 1411 681 682 + class Assembly(Dashboard.Module): 683 + """Show the disassembled code surrounding the program counter. The 684 + instructions constituting the current statement are marked, if available.""" 1412 685 1413 - define hex_quad 1414 - if $argc != 1 1415 - help hex_quad 1416 - else 1417 - printf "%02X %02X %02X %02X %02X %02X %02X %02X", \ 1418 - *(unsigned char*)($arg0), *(unsigned char*)($arg0 + 1), \ 1419 - *(unsigned char*)($arg0 + 2), *(unsigned char*)($arg0 + 3), \ 1420 - *(unsigned char*)($arg0 + 4), *(unsigned char*)($arg0 + 5), \ 1421 - *(unsigned char*)($arg0 + 6), *(unsigned char*)($arg0 + 7) 1422 - end 1423 - end 1424 - document hex_quad 1425 - Syntax: hex_quad ADDR 1426 - | Print eight hexadecimal bytes starting at address ADDR. 1427 - end 686 + def label(self): 687 + return 'Assembly' 1428 688 689 + def lines(self): 690 + line_info = None 691 + frame = gdb.selected_frame() # PC is here 692 + disassemble = frame.architecture().disassemble 693 + try: 694 + # try to fetch the function boundaries using the disassemble command 695 + output = run('disassemble').split('\n') 696 + start = int(re.split('[ :]', output[1][3:], 1)[0], 16) 697 + end = int(re.split('[ :]', output[-3][3:], 1)[0], 16) 698 + asm = disassemble(start, end_pc=end) 699 + # find the location of the PC 700 + pc_index = next(index for index, instr in enumerate(asm) 701 + if instr['addr'] == frame.pc()) 702 + start = max(pc_index - self.context, 0) 703 + end = pc_index + self.context + 1 704 + asm = asm[start:end] 705 + # if there are line information then use it, it may be that 706 + # line_info is not None but line_info.last is None 707 + line_info = gdb.find_pc_line(frame.pc()) 708 + line_info = line_info if line_info.last else None 709 + except gdb.error: 710 + # if it is not possible (stripped binary) start from PC and end 711 + # after twice the context 712 + asm = disassemble(frame.pc(), count=2 * self.context + 1) 713 + # fetch function start if available 714 + func_start = None 715 + if self.show_function and frame.name(): 716 + try: 717 + value = gdb.parse_and_eval(frame.name()).address 718 + func_start = to_unsigned(value) 719 + except gdb.error: 720 + pass # e.g., @plt 721 + # return the machine code 722 + max_length = max(instr['length'] for instr in asm) 723 + inferior = gdb.selected_inferior() 724 + out = [] 725 + for index, instr in enumerate(asm): 726 + addr = instr['addr'] 727 + length = instr['length'] 728 + text = instr['asm'] 729 + addr_str = format_address(addr) 730 + if self.show_opcodes: 731 + # fetch and format opcode 732 + region = inferior.read_memory(addr, length) 733 + opcodes = (' '.join('{:02x}'.format(ord(byte)) 734 + for byte in region)) 735 + opcodes += (max_length - len(region)) * 3 * ' ' + ' ' 736 + else: 737 + opcodes = '' 738 + # compute the offset if available 739 + if self.show_function: 740 + if func_start: 741 + max_offset = len(str(asm[-1]['addr'] - func_start)) 742 + offset = str(addr - func_start).ljust(max_offset) 743 + func_info = '{}+{} '.format(frame.name(), offset) 744 + else: 745 + func_info = '? ' 746 + else: 747 + func_info = '' 748 + format_string = '{} {}{}{}' 749 + if addr == frame.pc(): 750 + addr_str = ansi(addr_str, R.style_selected_1) 751 + opcodes = ansi(opcodes, R.style_selected_1) 752 + func_info = ansi(func_info, R.style_selected_1) 753 + text = ansi(text, R.style_selected_1) 754 + elif line_info and line_info.pc <= addr < line_info.last: 755 + addr_str = ansi(addr_str, R.style_selected_2) 756 + opcodes = ansi(opcodes, R.style_selected_2) 757 + func_info = ansi(func_info, R.style_selected_2) 758 + text = ansi(text, R.style_selected_2) 759 + else: 760 + addr_str = ansi(addr_str, R.style_low) 761 + func_info = ansi(func_info, R.style_low) 762 + out.append(format_string.format(addr_str, opcodes, func_info, text)) 763 + return out 1429 764 1430 - define hexdump 1431 - if $argc == 1 1432 - hexdump_aux $arg0 1433 - else 1434 - if $argc == 2 1435 - set $_count = 0 1436 - while ($_count < $arg1) 1437 - set $_i = ($_count * 0x10) 1438 - hexdump_aux $arg0+$_i 1439 - set $_count++ 1440 - end 1441 - else 1442 - help hexdump 1443 - end 1444 - end 1445 - end 1446 - document hexdump 1447 - Syntax: hexdump ADDR <NR_LINES> 1448 - | Display a 16-byte hex/ASCII dump of memory starting at address ADDR. 1449 - | Optional parameter is the number of lines to display if you want more than one. 1450 - end 765 + def attributes(self): 766 + return { 767 + 'context': { 768 + 'doc': 'Number of context instructions.', 769 + 'default': 3, 770 + 'type': int, 771 + 'check': check_ge_zero 772 + }, 773 + 'opcodes': { 774 + 'doc': 'Opcodes visibility flag.', 775 + 'default': False, 776 + 'name': 'show_opcodes', 777 + 'type': bool 778 + }, 779 + 'function': { 780 + 'doc': 'Function information visibility flag.', 781 + 'default': True, 782 + 'name': 'show_function', 783 + 'type': bool 784 + } 785 + } 1451 786 787 + class Stack(Dashboard.Module): 788 + """Show the current stack trace including the function name and the file 789 + location, if available. Optionally list the frame arguments and locals too.""" 1452 790 1453 - define hexdump_aux 1454 - if $argc != 1 1455 - help hexdump_aux 1456 - else 1457 - color_bold 1458 - if ($64BITS == 1) 1459 - printf "0x%016lX : ", $arg0 1460 - else 1461 - printf "0x%08X : ", $arg0 1462 - end 1463 - color_reset 1464 - hex_quad $arg0 1465 - color_bold 1466 - printf " - " 1467 - color_reset 1468 - hex_quad $arg0+8 1469 - printf " " 1470 - color_bold 1471 - ascii_char $arg0+0x0 1472 - ascii_char $arg0+0x1 1473 - ascii_char $arg0+0x2 1474 - ascii_char $arg0+0x3 1475 - ascii_char $arg0+0x4 1476 - ascii_char $arg0+0x5 1477 - ascii_char $arg0+0x6 1478 - ascii_char $arg0+0x7 1479 - ascii_char $arg0+0x8 1480 - ascii_char $arg0+0x9 1481 - ascii_char $arg0+0xA 1482 - ascii_char $arg0+0xB 1483 - ascii_char $arg0+0xC 1484 - ascii_char $arg0+0xD 1485 - ascii_char $arg0+0xE 1486 - ascii_char $arg0+0xF 1487 - color_reset 1488 - printf "\n" 1489 - end 1490 - end 1491 - document hexdump_aux 1492 - Syntax: hexdump_aux ADDR 1493 - | Display a 16-byte hex/ASCII dump of memory at address ADDR. 1494 - end 791 + def label(self): 792 + return 'Stack' 1495 793 794 + def lines(self): 795 + frames = [] 796 + number = 0 797 + selected_index = 0 798 + frame = gdb.newest_frame() 799 + while frame: 800 + frame_lines = [] 801 + # fetch frame info 802 + selected = (frame == gdb.selected_frame()) 803 + if selected: 804 + selected_index = number 805 + style = R.style_selected_1 if selected else R.style_selected_2 806 + frame_id = ansi(str(number), style) 807 + info = Stack.get_pc_line(frame, style) 808 + frame_lines.append('[{}] {}'.format(frame_id, info)) 809 + # fetch frame arguments and locals 810 + decorator = gdb.FrameDecorator.FrameDecorator(frame) 811 + if self.show_arguments: 812 + frame_args = decorator.frame_args() 813 + args_lines = self.fetch_frame_info(frame, frame_args, 'arg') 814 + if args_lines: 815 + frame_lines.extend(args_lines) 816 + else: 817 + frame_lines.append(ansi('(no arguments)', R.style_low)) 818 + if self.show_locals: 819 + frame_locals = decorator.frame_locals() 820 + locals_lines = self.fetch_frame_info(frame, frame_locals, 'loc') 821 + if locals_lines: 822 + frame_lines.extend(locals_lines) 823 + else: 824 + frame_lines.append(ansi('(no locals)', R.style_low)) 825 + # add frame 826 + frames.append(frame_lines) 827 + # next 828 + frame = frame.older() 829 + number += 1 830 + # format the output 831 + if not self.limit or self.limit >= len(frames): 832 + start = 0 833 + end = len(frames) 834 + more = False 835 + else: 836 + start = selected_index 837 + end = min(len(frames), start + self.limit) 838 + more = (len(frames) - start > self.limit) 839 + lines = [] 840 + for frame_lines in frames[start:end]: 841 + lines.extend(frame_lines) 842 + # add the placeholder 843 + if more: 844 + lines.append('[{}]'.format(ansi('+', R.style_selected_2))) 845 + return lines 1496 846 1497 - # _______________data window__________________ 1498 - define ddump 1499 - if $argc != 1 1500 - help ddump 1501 - else 1502 - color $COLOR_SEPARATOR 1503 - if $ARM == 1 1504 - printf "[0x%08X]", $data_addr 1505 - else 1506 - if ($64BITS == 1) 1507 - printf "[0x%04X:0x%016lX]", $ds, $data_addr 1508 - else 1509 - printf "[0x%04X:0x%08X]", $ds, $data_addr 1510 - end 1511 - end 847 + def fetch_frame_info(self, frame, data, prefix): 848 + prefix = ansi(prefix, R.style_low) 849 + lines = [] 850 + for elem in data or []: 851 + name = elem.sym 852 + value = to_string(elem.sym.value(frame)) 853 + lines.append('{} {} = {}'.format(prefix, name, value)) 854 + return lines 1512 855 1513 - color $COLOR_SEPARATOR 1514 - printf "------------------------" 1515 - printf "-------------------------------" 1516 - if ($64BITS == 1) 1517 - printf "-------------------------------------" 1518 - end 1519 - color_bold 1520 - color $COLOR_SEPARATOR 1521 - printf "[data]\n" 1522 - color_reset 1523 - set $_count = 0 1524 - while ($_count < $arg0) 1525 - set $_i = ($_count * 0x10) 1526 - hexdump $data_addr+$_i 1527 - set $_count++ 1528 - end 1529 - end 1530 - end 1531 - document ddump 1532 - Syntax: ddump NUM 1533 - | Display NUM lines of hexdump for address in $data_addr global variable. 1534 - end 856 + @staticmethod 857 + def get_pc_line(frame, style): 858 + frame_pc = ansi(format_address(frame.pc()), style) 859 + info = 'from {}'.format(frame_pc) 860 + if frame.name(): 861 + frame_name = ansi(frame.name(), style) 862 + try: 863 + # try to compute the offset relative to the current function 864 + value = gdb.parse_and_eval(frame.name()).address 865 + # it can be None even if it is part of the "stack" (C++) 866 + if value: 867 + func_start = to_unsigned(value) 868 + offset = frame.pc() - func_start 869 + frame_name += '+' + ansi(str(offset), style) 870 + except gdb.error: 871 + pass # e.g., @plt 872 + info += ' in {}'.format(frame_name) 873 + sal = frame.find_sal() 874 + if sal.symtab: 875 + file_name = ansi(sal.symtab.filename, style) 876 + file_line = ansi(str(sal.line), style) 877 + info += ' at {}:{}'.format(file_name, file_line) 878 + return info 1535 879 880 + def attributes(self): 881 + return { 882 + 'limit': { 883 + 'doc': 'Maximum number of displayed frames (0 means no limit).', 884 + 'default': 2, 885 + 'type': int, 886 + 'check': check_ge_zero 887 + }, 888 + 'arguments': { 889 + 'doc': 'Frame arguments visibility flag.', 890 + 'default': True, 891 + 'name': 'show_arguments', 892 + 'type': bool 893 + }, 894 + 'locals': { 895 + 'doc': 'Frame locals visibility flag.', 896 + 'default': False, 897 + 'name': 'show_locals', 898 + 'type': bool 899 + } 900 + } 1536 901 1537 - define dd 1538 - if $argc != 1 1539 - help dd 1540 - else 1541 - set $data_addr = $arg0 1542 - ddump 0x10 1543 - end 1544 - end 1545 - document dd 1546 - Syntax: dd ADDR 1547 - | Display 16 lines of a hex dump of address starting at ADDR. 1548 - end 902 + class History(Dashboard.Module): 903 + """List the last entries of the value history.""" 1549 904 905 + def label(self): 906 + return 'History' 1550 907 1551 - define datawin 1552 - if $ARM == 1 1553 - if ((($r0 >> 0x18) == 0x40) || (($r0 >> 0x18) == 0x08) || (($r0 >> 0x18) == 0xBF)) 1554 - set $data_addr = $r0 1555 - else 1556 - if ((($r1 >> 0x18) == 0x40) || (($r1 >> 0x18) == 0x08) || (($r1 >> 0x18) == 0xBF)) 1557 - set $data_addr = $r1 1558 - else 1559 - if ((($r2 >> 0x18) == 0x40) || (($r2 >> 0x18) == 0x08) || (($r2 >> 0x18) == 0xBF)) 1560 - set $data_addr = $r2 1561 - else 1562 - set $data_addr = $sp 1563 - end 1564 - end 1565 - end 1566 - ################################# X86 1567 - else 1568 - if ($64BITS == 1) 1569 - if ((($rsi >> 0x18) == 0x40) || (($rsi >> 0x18) == 0x08) || (($rsi >> 0x18) == 0xBF)) 1570 - set $data_addr = $rsi 1571 - else 1572 - if ((($rdi >> 0x18) == 0x40) || (($rdi >> 0x18) == 0x08) || (($rdi >> 0x18) == 0xBF)) 1573 - set $data_addr = $rdi 1574 - else 1575 - if ((($rax >> 0x18) == 0x40) || (($rax >> 0x18) == 0x08) || (($rax >> 0x18) == 0xBF)) 1576 - set $data_addr = $rax 1577 - else 1578 - set $data_addr = $rsp 1579 - end 1580 - end 1581 - end 1582 - else 1583 - if ((($esi >> 0x18) == 0x40) || (($esi >> 0x18) == 0x08) || (($esi >> 0x18) == 0xBF)) 1584 - set $data_addr = $esi 1585 - else 1586 - if ((($edi >> 0x18) == 0x40) || (($edi >> 0x18) == 0x08) || (($edi >> 0x18) == 0xBF)) 1587 - set $data_addr = $edi 1588 - else 1589 - if ((($eax >> 0x18) == 0x40) || (($eax >> 0x18) == 0x08) || (($eax >> 0x18) == 0xBF)) 1590 - set $data_addr = $eax 1591 - else 1592 - set $data_addr = $esp 1593 - end 1594 - end 1595 - end 1596 - end 1597 - end 1598 - ddump $CONTEXTSIZE_DATA 1599 - end 1600 - document datawin 1601 - Syntax: datawin 1602 - | Display valid address from one register in data window. 1603 - | Registers to choose are: esi, edi, eax, or esp. 1604 - end 908 + def lines(self): 909 + out = [] 910 + # fetch last entries 911 + for i in range(-self.limit + 1, 1): 912 + try: 913 + value = to_string(gdb.history(i)) 914 + value_id = ansi('$${}', R.style_low).format(abs(i)) 915 + line = '{} = {}'.format(value_id, value) 916 + out.append(line) 917 + except gdb.error: 918 + continue 919 + return out 1605 920 921 + def attributes(self): 922 + return { 923 + 'limit': { 924 + 'doc': 'Maximum number of values to show.', 925 + 'default': 3, 926 + 'type': int, 927 + 'check': check_gt_zero 928 + } 929 + } 1606 930 1607 - ################################ 1608 - ##### ALERT ALERT ALERT ######## 1609 - ################################ 1610 - # Huge mess going here :) HAHA # 1611 - ################################ 1612 - define dumpjump 1613 - if $ARM == 1 1614 - ## Most ARM and Thumb instructions are conditional! 1615 - # each instruction is 32 bits long 1616 - # 4 bits are for condition codes (16 in total) (bits 31:28 in ARM contain the condition or 1111 if instruction is unconditional) 1617 - # 2x4 bits for destination and first operand registers 1618 - # one for the set-status flag 1619 - # an assorted number for other stuff 1620 - # 12 bits for any immediate value 1621 - # $_t_flag == 0 => ARM mode 1622 - # $_t_flag == 1 => Thumb or ThumbEE 1623 - # State bit (T), bit 5 1624 - if (($cpsr >> 5) & 1) 1625 - set $_t_flag = 1 1626 - else 1627 - set $_t_flag = 0 1628 - end 931 + class Memory(Dashboard.Module): 932 + """Allow to inspect memory regions.""" 1629 933 1630 - if $_t_flag == 0 1631 - set $_lastbyte = *(unsigned char *)($pc+3) 1632 - #set $_bit31 = ($_lastbyte >> 7) & 1 1633 - #set $_bit30 = ($_lastbyte >> 6) & 1 1634 - #set $_bit29 = ($_lastbyte >> 5) & 1 1635 - #set $_bit28 = ($_lastbyte >> 4) & 1 1636 - set $_conditional = $_lastbyte >> 4 1637 - dumpjumphelper 1638 - else 1639 - # if bits 15-12 (opcode in Thumb instructions) are equal to 1 1 0 1 (0xD) then we have a conditional branch 1640 - # bits 11-8 for the conditional execution code (check ARMv7 manual A8.3) 1641 - if ( (*(unsigned char *)($pc+1) >> 4) == 0xD ) 1642 - set $_conditional = *(unsigned char *)($pc+1) ^ 0xD0 1643 - dumpjumphelper 1644 - end 1645 - end 1646 - ##################### X86 1647 - else 1648 - ## grab the first two bytes from the instruction so we can determine the jump instruction 1649 - set $_byte1 = *(unsigned char *)$pc 1650 - set $_byte2 = *(unsigned char *)($pc+1) 1651 - ## and now check what kind of jump we have (in case it's a jump instruction) 1652 - ## I changed the flags routine to save the flag into a variable, so we don't need to repeat the process :) (search for "define flags") 934 + @staticmethod 935 + def format_byte(byte): 936 + # `type(byte) is bytes` in Python 3 937 + if byte.isspace(): 938 + return ' ' 939 + elif 0x20 < ord(byte) < 0x7e: 940 + return chr(ord(byte)) 941 + else: 942 + return '.' 1653 943 1654 - ## opcode 0x77: JA, JNBE (jump if CF=0 and ZF=0) 1655 - ## opcode 0x0F87: JNBE, JA 1656 - if ( ($_byte1 == 0x77) || ($_byte1 == 0x0F && $_byte2 == 0x87) ) 1657 - # cf=0 and zf=0 1658 - if ($_cf_flag == 0 && $_zf_flag == 0) 1659 - color $RED 1660 - printf " Jump is taken (c=0 and z=0)" 1661 - else 1662 - # cf != 0 or zf != 0 1663 - color $RED 1664 - printf " Jump is NOT taken (c!=0 or z!=0)" 1665 - end 1666 - end 1667 - ## opcode 0x73: JAE, JNB, JNC (jump if CF=0) 1668 - ## opcode 0x0F83: JNC, JNB, JAE (jump if CF=0) 1669 - if ( ($_byte1 == 0x73) || ($_byte1 == 0x0F && $_byte2 == 0x83) ) 1670 - # cf=0 1671 - if ($_cf_flag == 0) 1672 - color $RED 1673 - printf " Jump is taken (c=0)" 1674 - else 1675 - # cf != 0 1676 - color $RED 1677 - printf " Jump is NOT taken (c!=0)" 1678 - end 1679 - end 1680 - ## opcode 0x72: JB, JC, JNAE (jump if CF=1) 1681 - ## opcode 0x0F82: JNAE, JB, JC 1682 - if ( ($_byte1 == 0x72) || ($_byte1 == 0x0F && $_byte2 == 0x82) ) 1683 - # cf=1 1684 - if ($_cf_flag == 1) 1685 - color $RED 1686 - printf " Jump is taken (c=1)" 1687 - else 1688 - # cf != 1 1689 - color $RED 1690 - printf " Jump is NOT taken (c!=1)" 1691 - end 1692 - end 1693 - ## opcode 0x76: JBE, JNA (jump if CF=1 or ZF=1) 1694 - ## opcode 0x0F86: JBE, JNA 1695 - if ( ($_byte1 == 0x76) || ($_byte1 == 0x0F && $_byte2 == 0x86) ) 1696 - # cf=1 or zf=1 1697 - if (($_cf_flag == 1) || ($_zf_flag == 1)) 1698 - color $RED 1699 - printf " Jump is taken (c=1 or z=1)" 1700 - else 1701 - # cf != 1 or zf != 1 1702 - color $RED 1703 - printf " Jump is NOT taken (c!=1 or z!=1)" 1704 - end 1705 - end 1706 - ## opcode 0xE3: JCXZ, JECXZ, JRCXZ (jump if CX=0 or ECX=0 or RCX=0) 1707 - if ($_byte1 == 0xE3) 1708 - # cx=0 or ecx=0 1709 - if (($ecx == 0) || ($cx == 0)) 1710 - color $RED 1711 - printf " Jump is taken (cx=0 or ecx=0)" 1712 - else 1713 - color $RED 1714 - printf " Jump is NOT taken (cx!=0 or ecx!=0)" 1715 - end 1716 - end 1717 - ## opcode 0x74: JE, JZ (jump if ZF=1) 1718 - ## opcode 0x0F84: JZ, JE, JZ (jump if ZF=1) 1719 - if ( ($_byte1 == 0x74) || ($_byte1 == 0x0F && $_byte2 == 0x84) ) 1720 - # ZF = 1 1721 - if ($_zf_flag == 1) 1722 - color $RED 1723 - printf " Jump is taken (z=1)" 1724 - else 1725 - # ZF = 0 1726 - color $RED 1727 - printf " Jump is NOT taken (z!=1)" 1728 - end 1729 - end 1730 - ## opcode 0x7F: JG, JNLE (jump if ZF=0 and SF=OF) 1731 - ## opcode 0x0F8F: JNLE, JG (jump if ZF=0 and SF=OF) 1732 - if ( ($_byte1 == 0x7F) || ($_byte1 == 0x0F && $_byte2 == 0x8F) ) 1733 - # zf = 0 and sf = of 1734 - if (($_zf_flag == 0) && ($_sf_flag == $_of_flag)) 1735 - color $RED 1736 - printf " Jump is taken (z=0 and s=o)" 1737 - else 1738 - color $RED 1739 - printf " Jump is NOT taken (z!=0 or s!=o)" 1740 - end 1741 - end 1742 - ## opcode 0x7D: JGE, JNL (jump if SF=OF) 1743 - ## opcode 0x0F8D: JNL, JGE (jump if SF=OF) 1744 - if ( ($_byte1 == 0x7D) || ($_byte1 == 0x0F && $_byte2 == 0x8D) ) 1745 - # sf = of 1746 - if ($_sf_flag == $_of_flag) 1747 - color $RED 1748 - printf " Jump is taken (s=o)" 1749 - else 1750 - color $RED 1751 - printf " Jump is NOT taken (s!=o)" 1752 - end 1753 - end 1754 - ## opcode: 0x7C: JL, JNGE (jump if SF != OF) 1755 - ## opcode: 0x0F8C: JNGE, JL (jump if SF != OF) 1756 - if ( ($_byte1 == 0x7C) || ($_byte1 == 0x0F && $_byte2 == 0x8C) ) 1757 - # sf != of 1758 - if ($_sf_flag != $_of_flag) 1759 - color $RED 1760 - printf " Jump is taken (s!=o)" 1761 - else 1762 - color $RED 1763 - printf " Jump is NOT taken (s=o)" 1764 - end 1765 - end 1766 - ## opcode 0x7E: JLE, JNG (jump if ZF = 1 or SF != OF) 1767 - ## opcode 0x0F8E: JNG, JLE (jump if ZF = 1 or SF != OF) 1768 - if ( ($_byte1 == 0x7E) || ($_byte1 == 0x0F && $_byte2 == 0x8E) ) 1769 - # zf = 1 or sf != of 1770 - if (($_zf_flag == 1) || ($_sf_flag != $_of_flag)) 1771 - color $RED 1772 - printf " Jump is taken (zf=1 or sf!=of)" 1773 - else 1774 - color $RED 1775 - printf " Jump is NOT taken (zf!=1 or sf=of)" 1776 - end 1777 - end 1778 - ## opcode 0x75: JNE, JNZ (jump if ZF = 0) 1779 - ## opcode 0x0F85: JNE, JNZ (jump if ZF = 0) 1780 - if ( ($_byte1 == 0x75) || ($_byte1 == 0x0F && $_byte2 == 0x85) ) 1781 - # ZF = 0 1782 - if ($_zf_flag == 0) 1783 - color $RED 1784 - printf " Jump is taken (z=0)" 1785 - else 1786 - # ZF = 1 1787 - color $RED 1788 - printf " Jump is NOT taken (z!=0)" 1789 - end 1790 - end 1791 - ## opcode 0x71: JNO (OF = 0) 1792 - ## opcode 0x0F81: JNO (OF = 0) 1793 - if ( ($_byte1 == 0x71) || ($_byte1 == 0x0F && $_byte2 == 0x81) ) 1794 - # OF = 0 1795 - if ($_of_flag == 0) 1796 - color $RED 1797 - printf " Jump is taken (o=0)" 1798 - else 1799 - # OF != 0 1800 - color $RED 1801 - printf " Jump is NOT taken (o!=0)" 1802 - end 1803 - end 1804 - ## opcode 0x7B: JNP, JPO (jump if PF = 0) 1805 - ## opcode 0x0F8B: JPO (jump if PF = 0) 1806 - if ( ($_byte1 == 0x7B) || ($_byte1 == 0x0F && $_byte2 == 0x8B) ) 1807 - # PF = 0 1808 - if ($_pf_flag == 0) 1809 - color $RED 1810 - printf " Jump is NOT taken (p=0)" 1811 - else 1812 - # PF != 0 1813 - color $RED 1814 - printf " Jump is taken (p!=0)" 1815 - end 1816 - end 1817 - ## opcode 0x79: JNS (jump if SF = 0) 1818 - ## opcode 0x0F89: JNS (jump if SF = 0) 1819 - if ( ($_byte1 == 0x79) || ($_byte1 == 0x0F && $_byte2 == 0x89) ) 1820 - # SF = 0 1821 - if ($_sf_flag == 0) 1822 - color $RED 1823 - printf " Jump is taken (s=0)" 1824 - else 1825 - # SF != 0 1826 - color $RED 1827 - printf " Jump is NOT taken (s!=0)" 1828 - end 1829 - end 1830 - ## opcode 0x70: JO (jump if OF=1) 1831 - ## opcode 0x0F80: JO (jump if OF=1) 1832 - if ( ($_byte1 == 0x70) || ($_byte1 == 0x0F && $_byte2 == 0x80) ) 1833 - # OF = 1 1834 - if ($_of_flag == 1) 1835 - color $RED 1836 - printf " Jump is taken (o=1)" 1837 - else 1838 - # OF != 1 1839 - color $RED 1840 - printf " Jump is NOT taken (o!=1)" 1841 - end 1842 - end 1843 - ## opcode 0x7A: JP, JPE (jump if PF=1) 1844 - ## opcode 0x0F8A: JP, JPE (jump if PF=1) 1845 - if ( ($_byte1 == 0x7A) || ($_byte1 == 0x0F && $_byte2 == 0x8A) ) 1846 - # PF = 1 1847 - if ($_pf_flag == 1) 1848 - color $RED 1849 - printf " Jump is taken (p=1)" 1850 - else 1851 - # PF = 0 1852 - color $RED 1853 - printf " Jump is NOT taken (p!=1)" 1854 - end 1855 - end 1856 - ## opcode 0x78: JS (jump if SF=1) 1857 - ## opcode 0x0F88: JS (jump if SF=1) 1858 - if ( ($_byte1 == 0x78) || ($_byte1 == 0x0F && $_byte2 == 0x88) ) 1859 - # SF = 1 1860 - if ($_sf_flag == 1) 1861 - color $RED 1862 - printf " Jump is taken (s=1)" 1863 - else 1864 - # SF != 1 1865 - color $RED 1866 - printf " Jump is NOT taken (s!=1)" 1867 - end 1868 - end 1869 - end 1870 - end 1871 - document dumpjump 1872 - Syntax: dumpjump 1873 - | Display if conditional jump will be taken or not. 1874 - end 944 + @staticmethod 945 + def parse_as_address(expression): 946 + value = gdb.parse_and_eval(expression) 947 + return to_unsigned(value) 1875 948 1876 - define dumpjumphelper 1877 - # 0000 - EQ: Z == 1 1878 - if ($_conditional == 0x0) 1879 - if ($_z_flag == 1) 1880 - color $RED 1881 - printf " Jump is taken (z==1)" 1882 - else 1883 - color $RED 1884 - printf " Jump is NOT taken (z!=1)" 1885 - end 1886 - end 1887 - # 0001 - NE: Z == 0 1888 - if ($_conditional == 0x1) 1889 - if ($_z_flag == 0) 1890 - color $RED 1891 - printf " Jump is taken (z==0)" 1892 - else 1893 - color $RED 1894 - printf " Jump is NOT taken (z!=0)" 1895 - end 1896 - end 1897 - # 0010 - CS: C == 1 1898 - if ($_conditional == 0x2) 1899 - if ($_c_flag == 1) 1900 - color $RED 1901 - printf " Jump is taken (c==1)" 1902 - else 1903 - color $RED 1904 - printf " Jump is NOT taken (c!=1)" 1905 - end 1906 - end 1907 - # 0011 - CC: C == 0 1908 - if ($_conditional == 0x3) 1909 - if ($_c_flag == 0) 1910 - color $RED 1911 - printf " Jump is taken (c==0)" 1912 - else 1913 - color $RED 1914 - printf " Jump is NOT taken (c!=0)" 1915 - end 1916 - end 1917 - # 0100 - MI: N == 1 1918 - if ($_conditional == 0x4) 1919 - if ($_n_flag == 1) 1920 - color $RED 1921 - printf " Jump is taken (n==1)" 1922 - else 1923 - color $RED 1924 - printf " Jump is NOT taken (n!=1)" 1925 - end 1926 - end 1927 - # 0101 - PL: N == 0 1928 - if ($_conditional == 0x5) 1929 - if ($_n_flag == 0) 1930 - color $RED 1931 - printf " Jump is taken (n==0)" 1932 - else 1933 - color $RED 1934 - printf " Jump is NOT taken (n!=0)" 1935 - end 1936 - end 1937 - # 0110 - VS: V == 1 1938 - if ($_conditional == 0x6) 1939 - if ($_v_flag == 1) 1940 - color $RED 1941 - printf " Jump is taken (v==1)" 1942 - else 1943 - color $RED 1944 - printf " Jump is NOT taken (v!=1)" 1945 - end 1946 - end 1947 - # 0111 - VC: V == 0 1948 - if ($_conditional == 0x7) 1949 - if ($_v_flag == 0) 1950 - color $RED 1951 - printf " Jump is taken (v==0)" 1952 - else 1953 - color $RED 1954 - printf " Jump is NOT taken (v!=0)" 1955 - end 1956 - end 1957 - # 1000 - HI: C == 1 and Z == 0 1958 - if ($_conditional == 0x8) 1959 - if ($_c_flag == 1 && $_z_flag == 0) 1960 - color $RED 1961 - printf " Jump is taken (c==1 and z==0)" 1962 - else 1963 - color $RED 1964 - printf " Jump is NOT taken (c!=1 or z!=0)" 1965 - end 1966 - end 1967 - # 1001 - LS: C == 0 or Z == 1 1968 - if ($_conditional == 0x9) 1969 - if ($_c_flag == 0 || $_z_flag == 1) 1970 - color $RED 1971 - printf " Jump is taken (c==0 or z==1)" 1972 - else 1973 - color $RED 1974 - printf " Jump is NOT taken (c!=0 or z!=1)" 1975 - end 1976 - end 1977 - # 1010 - GE: N == V 1978 - if ($_conditional == 0xA) 1979 - if ($_n_flag == $_v_flag) 1980 - color $RED 1981 - printf " Jump is taken (n==v)" 1982 - else 1983 - color $RED 1984 - printf " Jump is NOT taken (n!=v)" 1985 - end 1986 - end 1987 - # 1011 - LT: N != V 1988 - if ($_conditional == 0xB) 1989 - if ($_n_flag != $_v_flag) 1990 - color $RED 1991 - printf " Jump is taken (n!=v)" 1992 - else 1993 - color $RED 1994 - printf " Jump is NOT taken (n==v)" 1995 - end 1996 - end 1997 - # 1100 - GT: Z == 0 and N == V 1998 - if ($_conditional == 0xC) 1999 - if ($_z_flag == 0 && $_n_flag == $_v_flag) 2000 - color $RED 2001 - printf " Jump is taken (z==0 and n==v)" 2002 - else 2003 - color $RED 2004 - printf " Jump is NOT taken (z!=0 or n!=v)" 2005 - end 2006 - end 2007 - # 1101 - LE: Z == 1 or N != V 2008 - if ($_conditional == 0xD) 2009 - if ($_z_flag == 1 || $_n_flag != $_v_flag) 2010 - color $RED 2011 - printf " Jump is taken (z==1 or n!=v)" 2012 - else 2013 - color $RED 2014 - printf " Jump is NOT taken (z!=1 or n==v)" 2015 - end 2016 - end 2017 - end 2018 - document dumpjumphelper 2019 - Syntax: dumpjumphelper 2020 - | Helper function to decide if conditional jump will be taken or not, for ARM and Thumb. 2021 - end 2022 - 2023 - 2024 - # _______________process context______________ 2025 - # initialize variable 2026 - set $displayobjectivec = 0 2027 - 2028 - define context 2029 - color $COLOR_SEPARATOR 2030 - if $SHOWCPUREGISTERS == 1 2031 - printf "----------------------------------------" 2032 - printf "----------------------------------" 2033 - if ($64BITS == 1) 2034 - printf "---------------------------------------------" 2035 - end 2036 - color $COLOR_SEPARATOR 2037 - color_bold 2038 - printf "[regs]\n" 2039 - color_reset 2040 - reg 2041 - color $CYAN 2042 - end 2043 - if $SHOWSTACK == 1 2044 - color $COLOR_SEPARATOR 2045 - if $ARM == 1 2046 - printf "[0x%08X]", $sp 2047 - else 2048 - if ($64BITS == 1) 2049 - printf "[0x%04X:0x%016lX]", $ss, $rsp 2050 - else 2051 - printf "[0x%04X:0x%08X]", $ss, $esp 2052 - end 2053 - end 2054 - color $COLOR_SEPARATOR 2055 - printf "-------------------------" 2056 - printf "-----------------------------" 2057 - if ($64BITS == 1) 2058 - printf "-------------------------------------" 2059 - end 2060 - color $COLOR_SEPARATOR 2061 - color_bold 2062 - printf "[stack]\n" 2063 - color_reset 2064 - set $context_i = $CONTEXTSIZE_STACK 2065 - while ($context_i > 0) 2066 - set $context_t = $sp + 0x10 * ($context_i - 1) 2067 - hexdump $context_t 2068 - set $context_i-- 2069 - end 2070 - end 2071 - # show the objective C message being passed to msgSend 2072 - if $SHOWOBJECTIVEC == 1 2073 - #FIXME: X64 and ARM 2074 - # What a piece of crap that's going on here :) 2075 - # detect if it's the correct opcode we are searching for 2076 - if $ARM == 0 2077 - set $__byte1 = *(unsigned char *)$pc 2078 - set $__byte = *(int *)$pc 2079 - if ($__byte == 0x4244489) 2080 - set $objectivec = $eax 2081 - set $displayobjectivec = 1 2082 - end 2083 - 2084 - if ($__byte == 0x4245489) 2085 - set $objectivec = $edx 2086 - set $displayobjectivec = 1 2087 - end 2088 - 2089 - if ($__byte == 0x4244c89) 2090 - set $objectivec = $ecx 2091 - set $displayobjectivec = 1 2092 - end 2093 - else 2094 - set $__byte1 = 0 2095 - end 2096 - # and now display it or not (we have no interest in having the info displayed after the call) 2097 - if $__byte1 == 0xE8 2098 - if $displayobjectivec == 1 2099 - color $COLOR_SEPARATOR 2100 - printf "--------------------------------------------------------------------" 2101 - if ($64BITS == 1) 2102 - printf "---------------------------------------------" 2103 - end 2104 - color $COLOR_SEPARATOR 2105 - color_bold 2106 - printf "[ObjectiveC]\n" 2107 - color_reset 2108 - color $BLACK 2109 - x/s $objectivec 2110 - end 2111 - set $displayobjectivec = 0 2112 - end 2113 - if $displayobjectivec == 1 2114 - color $COLOR_SEPARATOR 2115 - printf "--------------------------------------------------------------------" 2116 - if ($64BITS == 1) 2117 - printf "---------------------------------------------" 2118 - end 2119 - color $COLOR_SEPARATOR 2120 - color_bold 2121 - printf "[ObjectiveC]\n" 2122 - color_reset 2123 - color $BLACK 2124 - x/s $objectivec 2125 - end 2126 - end 2127 - color_reset 2128 - # and this is the end of this little crap 2129 - 2130 - if $SHOWDATAWIN == 1 2131 - datawin 2132 - end 2133 - 2134 - color $COLOR_SEPARATOR 2135 - printf "--------------------------------------------------------------------------" 2136 - if ($64BITS == 1) 2137 - printf "---------------------------------------------" 2138 - end 2139 - color $COLOR_SEPARATOR 2140 - color_bold 2141 - printf "[code]\n" 2142 - color_reset 2143 - set $context_i = $CONTEXTSIZE_CODE 2144 - if ($context_i > 0) 2145 - if ($SETCOLOR1STLINE == 1) 2146 - color $GREEN 2147 - if ($ARM == 1) 2148 - # | $cpsr.t (Thumb flag) 2149 - x/i (unsigned int)$pc | (($cpsr >> 5) & 1) 2150 - else 2151 - x/i $pc 2152 - end 2153 - color_reset 2154 - else 2155 - if ($ARM == 1) 2156 - # | $cpsr.t (Thumb flag) 2157 - x/i (unsigned int)$pc | (($cpsr >> 5) & 1) 2158 - else 2159 - x/i $pc 2160 - end 2161 - end 2162 - set $context_i-- 2163 - end 2164 - while ($context_i > 0) 2165 - x /i 2166 - set $context_i-- 2167 - end 2168 - color $COLOR_SEPARATOR 2169 - printf "----------------------------------------" 2170 - printf "----------------------------------------" 2171 - if ($64BITS == 1) 2172 - printf "---------------------------------------------\n" 2173 - else 2174 - printf "\n" 2175 - end 2176 - color_reset 2177 - end 2178 - document context 2179 - Syntax: context 2180 - | Print context window, i.e. regs, stack, ds:esi and disassemble cs:eip. 2181 - end 2182 - 2183 - 2184 - define context-on 2185 - set $SHOW_CONTEXT = 1 2186 - printf "Displaying of context is now ON\n" 2187 - end 2188 - document context-on 2189 - Syntax: context-on 2190 - | Enable display of context on every program break. 2191 - end 2192 - 2193 - 2194 - define context-off 2195 - set $SHOW_CONTEXT = 0 2196 - printf "Displaying of context is now OFF\n" 2197 - end 2198 - document context-off 2199 - Syntax: context-off 2200 - | Disable display of context on every program break. 2201 - end 2202 - 2203 - 2204 - # _______________process control______________ 2205 - define n 2206 - if $argc == 0 2207 - nexti 2208 - end 2209 - if $argc == 1 2210 - nexti $arg0 2211 - end 2212 - if $argc > 1 2213 - help n 2214 - end 2215 - end 2216 - document n 2217 - Syntax: n <NUM> 2218 - | Step one instruction, but proceed through subroutine calls. 2219 - | If NUM is given, then repeat it NUM times or till program stops. 2220 - | This is alias for nexti. 2221 - end 2222 - 2223 - 2224 - define go 2225 - if $argc == 0 2226 - stepi 2227 - end 2228 - if $argc == 1 2229 - stepi $arg0 2230 - end 2231 - if $argc > 1 2232 - help go 2233 - end 2234 - end 2235 - document go 2236 - Syntax: go <NUM> 2237 - | Step one instruction exactly. 2238 - | If NUM is given, then repeat it NUM times or till program stops. 2239 - | This is alias for stepi. 2240 - end 2241 - 2242 - 2243 - define pret 2244 - finish 2245 - end 2246 - document pret 2247 - Syntax: pret 2248 - | Execute until selected stack frame returns (step out of current call). 2249 - | Upon return, the value returned is printed and put in the value history. 2250 - end 2251 - 2252 - 2253 - define init 2254 - set $SHOW_NEST_INSN = 0 2255 - tbreak _init 2256 - r 2257 - end 2258 - document init 2259 - Syntax: init 2260 - | Run program and break on _init(). 2261 - end 2262 - 2263 - 2264 - define start 2265 - set $SHOW_NEST_INSN = 0 2266 - tbreak _start 2267 - r 2268 - end 2269 - document start 2270 - Syntax: start 2271 - | Run program and break on _start(). 2272 - end 2273 - 2274 - 2275 - define sstart 2276 - set $SHOW_NEST_INSN = 0 2277 - tbreak __libc_start_main 2278 - r 2279 - end 2280 - document sstart 2281 - Syntax: sstart 2282 - | Run program and break on __libc_start_main(). 2283 - | Useful for stripped executables. 2284 - end 2285 - 2286 - 2287 - define main 2288 - set $SHOW_NEST_INSN = 0 2289 - tbreak main 2290 - r 2291 - end 2292 - document main 2293 - Syntax: main 2294 - | Run program and break on main(). 2295 - end 2296 - 2297 - 2298 - # FIXME64 2299 - #### WARNING ! WARNING !! 2300 - #### More more messy stuff starting !!! 2301 - #### I was thinking about how to do this and then it ocurred me that it could be as simple as this ! :) 2302 - define stepoframework 2303 - if $ARM == 1 2304 - # bl and bx opcodes 2305 - # bx Rn => ARM bits 27-20: 0 0 0 1 0 0 1 0 , bits 7-4: 0 0 0 1 ; Thumb bits: 15-7: 0 1 0 0 0 1 1 1 0 2306 - # blx Rn => ARM bits 27-20: 0 0 0 1 0 0 1 0 , bits 7-4: 0 0 1 1 ; Thumb bits: 15-7: 0 1 0 0 0 1 1 1 1 2307 - # bl # => ARM bits 27-24: 1 0 1 1 ; Thumb bits: 15-11: 1 1 1 1 0 2308 - # blx # => ARM bits 31-25: 1 1 1 1 1 0 1 ; Thumb bits: 15-11: 1 1 1 1 0 2309 - set $_nextaddress = 0 2310 - 2311 - # ARM Mode 2312 - if ($_t_flag == 0) 2313 - set $_branchesint = *(unsigned int*)$pc 2314 - set $_bit31 = ($_branchesint >> 0x1F) & 1 2315 - set $_bit30 = ($_branchesint >> 0x1E) & 1 2316 - set $_bit29 = ($_branchesint >> 0x1D) & 1 2317 - set $_bit28 = ($_branchesint >> 0x1C) & 1 2318 - set $_bit27 = ($_branchesint >> 0x1B) & 1 2319 - set $_bit26 = ($_branchesint >> 0x1A) & 1 2320 - set $_bit25 = ($_branchesint >> 0x19) & 1 2321 - set $_bit24 = ($_branchesint >> 0x18) & 1 2322 - set $_bit23 = ($_branchesint >> 0x17) & 1 2323 - set $_bit22 = ($_branchesint >> 0x16) & 1 2324 - set $_bit21 = ($_branchesint >> 0x15) & 1 2325 - set $_bit20 = ($_branchesint >> 0x14) & 1 2326 - set $_bit7 = ($_branchesint >> 0x7) & 1 2327 - set $_bit6 = ($_branchesint >> 0x6) & 1 2328 - set $_bit5 = ($_branchesint >> 0x5) & 1 2329 - set $_bit4 = ($_branchesint >> 0x4) & 1 2330 - 2331 - # set $_lastbyte = *(unsigned char *)($pc+3) 2332 - # set $_bits2724 = $_lastbyte & 0x1 2333 - # set $_bits3128 = $_lastbyte >> 4 2334 - # if ($_bits3128 == 0xF) 2335 - # set $_bits2724 = $_lastbyte & 0xA 2336 - # set $_bits2724 = $_bits2724 >> 1 2337 - # end 2338 - # set $_previousbyte = *(unsigned char *)($pc+2) 2339 - # set $_bits2320 = $_previousbyte >> 4 2340 - # printf "bits2724: %x bits2320: %x\n", $_bits2724, $_bits2320 949 + def __init__(self): 950 + self.row_length = 16 951 + self.table = {} 2341 952 2342 - if ($_bit27 == 0 && $_bit26 == 0 && $_bit25 == 0 && $_bit24 == 1 && $_bit23 == 0 && $_bit22 == 0 && $_bit21 == 1 && $_bit20 == 0 && $_bit7 == 0 && $_bit6 == 0 && $_bit5 == 0 && $_bit4 == 1) 2343 - printf "Found a bx Rn\n" 2344 - set $_nextaddress = $pc+0x4 2345 - end 2346 - if ($_bit27 == 0 && $_bit26 == 0 && $_bit25 == 0 && $_bit24 == 1 && $_bit23 == 0 && $_bit22 == 0 && $_bit21 == 1 && $_bit20 == 0 && $_bit7 == 0 && $_bit6 == 0 && $_bit5 == 1 && $_bit4 == 1) 2347 - printf "Found a blx Rn\n" 2348 - set $_nextaddress = $pc+0x4 2349 - end 2350 - if ($_bit27 == 1 && $_bit26 == 0 && $_bit25 == 1 && $_bit24 == 1) 2351 - printf "Found a bl #\n" 2352 - set $_nextaddress = $pc+0x4 2353 - end 2354 - if ($_bit31 == 1 && $_bit30 == 1 && $_bit29 == 1 && $_bit28 == 1 && $_bit27 == 1 && $_bit26 == 0 && $_bit25 == 1) 2355 - printf "Found a blx #\n" 2356 - set $_nextaddress = $pc+0x4 2357 - end 2358 - # Thumb Mode 2359 - else 2360 - # 32 bits instructions in Thumb are divided into two half words 2361 - set $_hw1 = *(unsigned short*)($pc) 2362 - set $_hw2 = *(unsigned short*)($pc+2) 953 + def format_memory(self, start, memory): 954 + out = [] 955 + for i in range(0, len(memory), self.row_length): 956 + region = memory[i:i + self.row_length] 957 + pad = self.row_length - len(region) 958 + address = format_address(start + i) 959 + hexa = (' '.join('{:02x}'.format(ord(byte)) for byte in region)) 960 + text = (''.join(Memory.format_byte(byte) for byte in region)) 961 + out.append('{} {}{} {}{}'.format(ansi(address, R.style_low), 962 + hexa, 963 + ansi(pad * ' --', R.style_low), 964 + ansi(text, R.style_high), 965 + ansi(pad * '.', R.style_low))) 966 + return out 2363 967 2364 - # bl/blx (immediate) 2365 - # hw1: bits 15-11: 1 1 1 1 0 2366 - # hw2: bits 15-14: 1 1 ; BL bit 12: 1 ; BLX bit 12: 0 2367 - if ( ($_hw1 >> 0xC) == 0xF && (($_hw1 >> 0xB) & 1) == 0) 2368 - if ( ((($_hw2 >> 0xF) & 1) == 1) && ((($_hw2 >> 0xE) & 1) == 1) ) 2369 - set $_nextaddress = $pc+0x4 2370 - end 2371 - end 2372 - end 2373 - # if we have found a call to bypass we set a temporary breakpoint on next instruction and continue 2374 - if ($_nextaddress != 0) 2375 - tbreak *$_nextaddress 2376 - continue 2377 - printf "[StepO] Next address will be %x\n", $_nextaddress 2378 - # else we just single step 2379 - else 2380 - nexti 2381 - end 2382 - ###################################### X86 2383 - else 2384 - ## we know that an opcode starting by 0xE8 has a fixed length 2385 - ## for the 0xFF opcodes, we can enumerate what is possible to have 2386 - # first we grab the first 3 bytes from the current program counter 2387 - set $_byte1 = *(unsigned char *)$pc 2388 - set $_byte2 = *(unsigned char *)($pc+1) 2389 - set $_byte3 = *(unsigned char *)($pc+2) 2390 - # and start the fun 2391 - # if it's a 0xE8 opcode, the total instruction size will be 5 bytes 2392 - # so we can simply calculate the next address and use a temporary breakpoint ! Voila :) 2393 - set $_nextaddress = 0 2394 - # this one is the must useful for us !!! 2395 - if ($_byte1 == 0xE8) 2396 - set $_nextaddress = $pc + 0x5 2397 - else 2398 - # just other cases we might be interested in... maybe this should be removed since the 0xE8 opcode is the one we will use more 2399 - # this is a big fucking mess and can be improved for sure :) I don't like the way it is ehehehe 2400 - if ($_byte1 == 0xFF) 2401 - # call *%eax (0xFFD0) || call *%edx (0xFFD2) || call *(%ecx) (0xFFD1) || call (%eax) (0xFF10) || call *%esi (0xFFD6) || call *%ebx (0xFFD3) || call DWORD PTR [edx] (0xFF12) 2402 - if ($_byte2 == 0xD0 || $_byte2 == 0xD1 || $_byte2 == 0xD2 || $_byte2 == 0xD3 || $_byte2 == 0xD6 || $_byte2 == 0x10 || $_byte2 == 0x11 || $_byte2 == 0xD7 || $_byte2 == 0x12) 2403 - set $_nextaddress = $pc + 0x2 2404 - end 2405 - # call *0x??(%ebp) (0xFF55??) || call *0x??(%esi) (0xFF56??) || call *0x??(%edi) (0xFF5F??) || call *0x??(%ebx) 2406 - # call *0x??(%edx) (0xFF52??) || call *0x??(%ecx) (0xFF51??) || call *0x??(%edi) (0xFF57??) || call *0x??(%eax) (0xFF50??) 2407 - if ($_byte2 == 0x55 || $_byte2 == 0x56 || $_byte2 == 0x5F || $_byte2 == 0x53 || $_byte2 == 0x52 || $_byte2 == 0x51 || $_byte2 == 0x57 || $_byte2 == 0x50) 2408 - set $_nextaddress = $pc + 0x3 2409 - end 2410 - # call *0x????????(%ebx) (0xFF93????????) || 2411 - if ($_byte2 == 0x93 || $_byte2 == 0x94 || $_byte2 == 0x90 || $_byte2 == 0x92 || $_byte2 == 0x95 || $_byte2 == 0x15) 2412 - set $_nextaddress = $pc + 6 2413 - end 2414 - # call *0x????????(%ebx,%eax,4) (0xFF94??????????) 2415 - if ($_byte2 == 0x94) 2416 - set $_nextaddress = $pc + 7 2417 - end 2418 - end 2419 - # FIXME: still missing a few? 2420 - if ($_byte1 == 0x41 || $_byte1 == 0x40) 2421 - if ($_byte2 == 0xFF) 2422 - if ($_byte3 == 0xD0 || $_byte3 == 0xD1 || $_byte3 == 0xD2 || $_byte3 == 0xD3 || $_byte3 == 0xD4 || $_byte3 == 0xD5 || $_byte3 == 0xD6 || $_byte3 == 0xD7) 2423 - set $_nextaddress = $pc + 0x3 2424 - end 2425 - end 2426 - end 2427 - end 2428 - # if we have found a call to bypass we set a temporary breakpoint on next instruction and continue 2429 - if ($_nextaddress != 0) 2430 - if ($arg0 == 1) 2431 - thbreak *$_nextaddress 2432 - else 2433 - tbreak *$_nextaddress 2434 - end 2435 - continue 2436 - # else we just single step 2437 - else 2438 - nexti 2439 - end 2440 - end 2441 - end 2442 - document stepoframework 2443 - Syntax: stepoframework 2444 - | Auxiliary function to stepo command. 2445 - end 968 + def label(self): 969 + return 'Memory' 2446 970 2447 - define stepo 2448 - stepoframework 0 2449 - end 2450 - document stepo 2451 - Syntax: stepo 2452 - | Step over calls (interesting to bypass the ones to msgSend). 2453 - | This function will set a temporary breakpoint on next instruction after the call so the call will be bypassed. 2454 - | You can safely use it instead nexti or n since it will single step code if it's not a call instruction (unless you want to go into the call function). 2455 - end 971 + def lines(self): 972 + out = [] 973 + inferior = gdb.selected_inferior() 974 + for address, length in sorted(self.table.items()): 975 + try: 976 + memory = inferior.read_memory(address, length) 977 + out.extend(self.format_memory(address, memory)) 978 + except gdb.error: 979 + msg = 'Cannot access {} bytes starting at {}' 980 + msg = msg.format(length, format_address(address)) 981 + out.append(ansi(msg, R.style_error)) 982 + out.append(divider()) 983 + # drop last divider 984 + if out: 985 + del out[-1] 986 + return out 2456 987 988 + def watch(self, arg): 989 + if arg: 990 + address, _, length = arg.partition(' ') 991 + address = Memory.parse_as_address(address) 992 + if length: 993 + length = Memory.parse_as_address(length) 994 + else: 995 + length = self.row_length 996 + self.table[address] = length 997 + else: 998 + raise Exception('Specify an address') 2457 999 2458 - define stepoh 2459 - stepoframework 1 2460 - end 2461 - document stepoh 2462 - Syntax: stepoh 2463 - | Same as stepo command but uses temporary hardware breakpoints. 2464 - end 1000 + def unwatch(self, arg): 1001 + if arg: 1002 + try: 1003 + del self.table[Memory.parse_as_address(arg)] 1004 + except KeyError: 1005 + raise Exception('Memory region not watched') 1006 + else: 1007 + raise Exception('Specify an address') 2465 1008 1009 + def clear(self, arg): 1010 + self.table.clear() 2466 1011 2467 - # FIXME: ARM 2468 - define skip 2469 - x/2i $pc 2470 - set $instruction_size = (int)($_ - $pc) 2471 - set $pc = $pc + $instruction_size 2472 - if ($SKIPEXECUTE == 1) 2473 - if ($SKIPSTEP == 1) 2474 - stepo 2475 - else 2476 - stepi 2477 - end 2478 - else 2479 - context 2480 - end 2481 - end 2482 - document skip 2483 - Syntax: skip 2484 - | Skip over the instruction located at EIP/RIP. By default, the instruction will not be executed! 2485 - | Some configurable options are available on top of gdbinit to override this. 2486 - end 1012 + def commands(self): 1013 + return { 1014 + 'watch': { 1015 + 'action': self.watch, 1016 + 'doc': 'Watch a memory region by address and length.\n' 1017 + 'The length defaults to 16 byte.', 1018 + 'complete': gdb.COMPLETE_EXPRESSION 1019 + }, 1020 + 'unwatch': { 1021 + 'action': self.unwatch, 1022 + 'doc': 'Stop watching a memory region by address.', 1023 + 'complete': gdb.COMPLETE_EXPRESSION 1024 + }, 1025 + 'clear': { 1026 + 'action': self.clear, 1027 + 'doc': 'Clear all the watched regions.' 1028 + } 1029 + } 2487 1030 1031 + class Registers(Dashboard.Module): 1032 + """Show the CPU registers and their values.""" 2488 1033 2489 - # _______________eflags commands______________ 2490 - # conditional flags are 2491 - # negative/less than (N), bit 31 of CPSR 2492 - # zero (Z), bit 30 2493 - # Carry/Borrow/Extend (C), bit 29 2494 - # Overflow (V), bit 28 1034 + def __init__(self): 1035 + self.table = {} 2495 1036 2496 - # negative/less than (N), bit 31 of CPSR 2497 - define cfn 2498 - if $ARM == 1 2499 - set $tempflag = $cpsr->n 2500 - if ($tempflag & 1) 2501 - set $cpsr->n = $tempflag&~0x1 2502 - else 2503 - set $cpsr->n = $tempflag|0x1 2504 - end 2505 - end 2506 - end 2507 - document cfn 2508 - Syntax: cfn 2509 - | Change Negative/Less Than Flag. 2510 - end 1037 + def label(self): 1038 + return 'Registers' 2511 1039 1040 + def lines(self): 1041 + # fetch registers status 1042 + registers = [] 1043 + for reg_info in run('info registers').strip().split('\n'): 1044 + # fetch register and update the table 1045 + name = reg_info.split(None, 1)[0] 1046 + value = gdb.parse_and_eval('${}'.format(name)) 1047 + string_value = self.format_value(value) 1048 + changed = self.table and (self.table.get(name, '') != string_value) 1049 + self.table[name] = string_value 1050 + registers.append((name, string_value, changed)) 1051 + # split registers in rows and columns, each column is composed of name, 1052 + # space, value and another trailing space which is skipped in the last 1053 + # column (hence term_width + 1) 1054 + max_name = max(len(name) for name, _, _ in registers) 1055 + max_value = max(len(value) for _, value, _ in registers) 1056 + max_width = max_name + max_value + 2 1057 + per_line = int((Dashboard.term_width + 1) / max_width) or 1 1058 + # redistribute extra space among columns 1059 + extra = int((Dashboard.term_width + 1 - 1060 + max_width * per_line) / per_line) 1061 + if per_line == 1: 1062 + # center when there is only one column 1063 + max_name += int(extra / 2) 1064 + max_value += int(extra / 2) 1065 + else: 1066 + max_value += extra 1067 + # format registers info 1068 + partial = [] 1069 + for name, value, changed in registers: 1070 + styled_name = ansi(name.rjust(max_name), R.style_low) 1071 + value_style = R.style_selected_1 if changed else '' 1072 + styled_value = ansi(value.ljust(max_value), value_style) 1073 + partial.append(styled_name + ' ' + styled_value) 1074 + out = [] 1075 + for i in range(0, len(partial), per_line): 1076 + out.append(' '.join(partial[i:i + per_line]).rstrip()) 1077 + return out 2512 1078 2513 - define cfc 2514 - # Carry/Borrow/Extend (C), bit 29 2515 - if $ARM == 1 2516 - set $tempflag = $cpsr->c 2517 - if ($tempflag & 1) 2518 - set $cpsr->c = $tempflag&~0x1 2519 - else 2520 - set $cpsr->c = $tempflag|0x1 2521 - end 2522 - else 2523 - if ((unsigned int)$eflags & 1) 2524 - set $eflags = (unsigned int)$eflags&~0x1 2525 - else 2526 - set $eflags = (unsigned int)$eflags|0x1 2527 - end 2528 - end 2529 - end 2530 - document cfc 2531 - Syntax: cfc 2532 - | Change Carry Flag. 2533 - end 1079 + def format_value(self, value): 1080 + try: 1081 + if value.type.code in [gdb.TYPE_CODE_INT, gdb.TYPE_CODE_PTR]: 1082 + int_value = to_unsigned(value, value.type.sizeof) 1083 + value_format = '0x{{:0{}x}}'.format(2 * value.type.sizeof) 1084 + return value_format.format(int_value) 1085 + except (gdb.error, ValueError): 1086 + # convert to unsigned but preserve code and flags information 1087 + pass 1088 + return str(value) 2534 1089 1090 + class Threads(Dashboard.Module): 1091 + """List the currently available threads.""" 2535 1092 2536 - define cfp 2537 - if (((unsigned int)$eflags >> 2) & 1) 2538 - set $eflags = (unsigned int)$eflags&~0x4 2539 - else 2540 - set $eflags = (unsigned int)$eflags|0x4 2541 - end 2542 - end 2543 - document cfp 2544 - Syntax: cfp 2545 - | Change Parity Flag. 2546 - end 1093 + def label(self): 1094 + return 'Threads' 2547 1095 1096 + def lines(self): 1097 + out = [] 1098 + selected_thread = gdb.selected_thread() 1099 + selected_frame = gdb.selected_frame() 1100 + for thread in gdb.Inferior.threads(gdb.selected_inferior()): 1101 + is_selected = (thread.ptid == selected_thread.ptid) 1102 + style = R.style_selected_1 if is_selected else R.style_selected_2 1103 + number = ansi(str(thread.num), style) 1104 + tid = ansi(str(thread.ptid[1] or thread.ptid[2]), style) 1105 + info = '[{}] id {}'.format(number, tid) 1106 + if thread.name: 1107 + info += ' name {}'.format(ansi(thread.name, style)) 1108 + # switch thread to fetch frame info 1109 + thread.switch() 1110 + frame = gdb.newest_frame() 1111 + info += ' ' + Stack.get_pc_line(frame, style) 1112 + out.append(info) 1113 + # restore thread and frame 1114 + selected_thread.switch() 1115 + selected_frame.select() 1116 + return out 2548 1117 2549 - define cfa 2550 - if (((unsigned int)$eflags >> 4) & 1) 2551 - set $eflags = (unsigned int)$eflags&~0x10 2552 - else 2553 - set $eflags = (unsigned int)$eflags|0x10 2554 - end 2555 - end 2556 - document cfa 2557 - Syntax: cfa 2558 - | Change Auxiliary Carry Flag. 2559 - end 1118 + class Expressions(Dashboard.Module): 1119 + """Watch user expressions.""" 2560 1120 1121 + def __init__(self): 1122 + self.number = 1 1123 + self.table = {} 2561 1124 2562 - define cfz 2563 - # zero (Z), bit 30 2564 - if $ARM == 1 2565 - set $tempflag = $cpsr->z 2566 - if ($tempflag & 1) 2567 - set $cpsr->z = $tempflag&~0x1 2568 - else 2569 - set $cpsr->z = $tempflag|0x1 2570 - end 2571 - else 2572 - if (((unsigned int)$eflags >> 6) & 1) 2573 - set $eflags = (unsigned int)$eflags&~0x40 2574 - else 2575 - set $eflags = (unsigned int)$eflags|0x40 2576 - end 2577 - end 2578 - end 2579 - document cfz 2580 - Syntax: cfz 2581 - | Change Zero Flag. 2582 - end 1125 + def label(self): 1126 + return 'Expressions' 2583 1127 1128 + def lines(self): 1129 + out = [] 1130 + for number, expression in sorted(self.table.items()): 1131 + try: 1132 + value = to_string(gdb.parse_and_eval(expression)) 1133 + except gdb.error as e: 1134 + value = ansi(e, R.style_error) 1135 + number = ansi(number, R.style_selected_2) 1136 + expression = ansi(expression, R.style_low) 1137 + out.append('[{}] {} = {}'.format(number, expression, value)) 1138 + return out 2584 1139 2585 - define cfs 2586 - if (((unsigned int)$eflags >> 7) & 1) 2587 - set $eflags = (unsigned int)$eflags&~0x80 2588 - else 2589 - set $eflags = (unsigned int)$eflags|0x80 2590 - end 2591 - end 2592 - document cfs 2593 - Syntax: cfs 2594 - | Change Sign Flag. 2595 - end 2596 - 2597 - 2598 - define cft 2599 - if (((unsigned int)$eflags >>8) & 1) 2600 - set $eflags = (unsigned int)$eflags&~0x100 2601 - else 2602 - set $eflags = (unsigned int)$eflags|0x100 2603 - end 2604 - end 2605 - document cft 2606 - Syntax: cft 2607 - | Change Trap Flag. 2608 - end 2609 - 2610 - 2611 - define cfi 2612 - if (((unsigned int)$eflags >> 9) & 1) 2613 - set $eflags = (unsigned int)$eflags&~0x200 2614 - else 2615 - set $eflags = (unsigned int)$eflags|0x200 2616 - end 2617 - end 2618 - document cfi 2619 - Syntax: cfi 2620 - | Change Interrupt Flag. 2621 - | Only privileged applications (usually the OS kernel) may modify IF. 2622 - | This only applies to protected mode (real mode code may always modify IF). 2623 - end 2624 - 2625 - 2626 - define cfd 2627 - if (((unsigned int)$eflags >>0xA) & 1) 2628 - set $eflags = (unsigned int)$eflags&~0x400 2629 - else 2630 - set $eflags = (unsigned int)$eflags|0x400 2631 - end 2632 - end 2633 - document cfd 2634 - Syntax: cfd 2635 - | Change Direction Flag. 2636 - end 2637 - 2638 - 2639 - define cfo 2640 - if (((unsigned int)$eflags >> 0xB) & 1) 2641 - set $eflags = (unsigned int)$eflags&~0x800 2642 - else 2643 - set $eflags = (unsigned int)$eflags|0x800 2644 - end 2645 - end 2646 - document cfo 2647 - Syntax: cfo 2648 - | Change Overflow Flag. 2649 - end 2650 - 1140 + def watch(self, arg): 1141 + if arg: 1142 + self.table[self.number] = arg 1143 + self.number += 1 1144 + else: 1145 + raise Exception('Specify an expression') 2651 1146 2652 - # Overflow (V), bit 28 2653 - define cfv 2654 - if $ARM == 1 2655 - set $tempflag = $cpsr->v 2656 - if ($tempflag & 1) 2657 - set $cpsr->v = $tempflag&~0x1 2658 - else 2659 - set $cpsr->v = $tempflag|0x1 2660 - end 2661 - end 2662 - end 2663 - document cfv 2664 - Syntax: cfv 2665 - | Change Overflow Flag. 2666 - end 1147 + def unwatch(self, arg): 1148 + if arg: 1149 + try: 1150 + del self.table[int(arg)] 1151 + except: 1152 + raise Exception('Expression not watched') 1153 + else: 1154 + raise Exception('Specify an identifier') 2667 1155 1156 + def clear(self, arg): 1157 + self.table.clear() 2668 1158 2669 - # ____________________patch___________________ 2670 - # the usual nops are mov r0,r0 for arm (0xe1a00000) 2671 - # and mov r8,r8 in Thumb (0x46c0) 2672 - # armv7 has other nops 2673 - # FIXME: make sure that the interval fits the 32bits address for arm and 16bits for thumb 2674 - # status: works, fixme 2675 - define nop 2676 - if ($argc > 2 || $argc == 0) 2677 - help nop 2678 - end 1159 + def commands(self): 1160 + return { 1161 + 'watch': { 1162 + 'action': self.watch, 1163 + 'doc': 'Watch an expression.', 1164 + 'complete': gdb.COMPLETE_EXPRESSION 1165 + }, 1166 + 'unwatch': { 1167 + 'action': self.unwatch, 1168 + 'doc': 'Stop watching an expression by id.', 1169 + 'complete': gdb.COMPLETE_EXPRESSION 1170 + }, 1171 + 'clear': { 1172 + 'action': self.clear, 1173 + 'doc': 'Clear all the watched expressions.' 1174 + } 1175 + } 2679 1176 2680 - if $ARM == 1 2681 - if ($argc == 1) 2682 - if ($cpsr->t &1) 2683 - # thumb 2684 - set *(short *)$arg0 = 0x46c0 2685 - else 2686 - # arm 2687 - set *(int *)$arg0 = 0xe1a00000 2688 - end 2689 - else 2690 - set $addr = $arg0 2691 - if ($cpsr->t & 1) 2692 - # thumb 2693 - while ($addr < $arg1) 2694 - set *(short *)$addr = 0x46c0 2695 - set $addr = $addr + 2 2696 - end 2697 - else 2698 - # arm 2699 - while ($addr < $arg1) 2700 - set *(int *)$addr = 0xe1a00000 2701 - set $addr = $addr + 4 2702 - end 2703 - end 2704 - end 2705 - else 2706 - if ($argc == 1) 2707 - set *(unsigned char *)$arg0 = 0x90 2708 - else 2709 - set $addr = $arg0 2710 - while ($addr < $arg1) 2711 - set *(unsigned char *)$addr = 0x90 2712 - set $addr = $addr + 1 2713 - end 2714 - end 2715 - end 2716 - end 2717 - document nop 2718 - Syntax: nop ADDR1 [ADDR2] 2719 - | Patch a single byte at address ADDR1, or a series of bytes between ADDR1 and ADDR2 to a NOP (0x90) instruction. 2720 - | ARM or Thumb code will be patched accordingly. 2721 1177 end 2722 1178 1179 + # Better GDB defaults ---------------------------------------------------------- 2723 1180 2724 - define null 2725 - if ( $argc >2 || $argc == 0) 2726 - help null 2727 - end 1181 + set history save 1182 + set confirm off 1183 + set verbose off 1184 + set print pretty on 1185 + set print array off 1186 + set print array-indexes on 1187 + set python print-stack full 2728 1188 2729 - if ($argc == 1) 2730 - set *(unsigned char *)$arg0 = 0 2731 - else 2732 - set $addr = $arg0 2733 - while ($addr < $arg1) 2734 - set *(unsigned char *)$addr = 0 2735 - set $addr = $addr +1 2736 - end 2737 - end 2738 - end 2739 - document null 2740 - Syntax: null ADDR1 [ADDR2] 2741 - | Patch a single byte at address ADDR1 to NULL (0x00), or a series of bytes between ADDR1 and ADDR2. 2742 - end 1189 + # Start ------------------------------------------------------------------------ 2743 1190 2744 - # FIXME: thumb breakpoint ? 2745 - define int3 2746 - if $argc != 1 2747 - help int3 2748 - else 2749 - if $ARM == 1 2750 - set $ORIGINAL_INT3 = *(unsigned int *)$arg0 2751 - set $ORIGINAL_INT3ADDRESS = $arg0 2752 - set *(unsigned int*)$arg0 = 0xe7ffdefe 2753 - else 2754 - # save original bytes and address 2755 - set $ORIGINAL_INT3 = *(unsigned char *)$arg0 2756 - set $ORIGINAL_INT3ADDRESS = $arg0 2757 - # patch 2758 - set *(unsigned char *)$arg0 = 0xCC 2759 - end 2760 - end 2761 - end 2762 - document int3 2763 - Syntax int3 ADDR 2764 - | Patch byte at address ADDR to an INT3 (0xCC) instruction or the equivalent software breakpoint for ARM. 2765 - end 1191 + python Dashboard.start() 2766 1192 2767 - 2768 - define rint3 2769 - if $ARM == 1 2770 - set *(unsigned int *)$ORIGINAL_INT3ADDRESS = $ORIGINAL_INT3 2771 - set $pc = $ORIGINAL_INT3ADDRESS 2772 - else 2773 - set *(unsigned char *)$ORIGINAL_INT3ADDRESS = $ORIGINAL_INT3 2774 - if ($64BITS == 1) 2775 - set $rip = $ORIGINAL_INT3ADDRESS 2776 - else 2777 - set $eip = $ORIGINAL_INT3ADDRESS 2778 - end 2779 - end 2780 - end 2781 - document rint3 2782 - Syntax: rint3 2783 - | Restore the original byte previous to int3 patch issued with "int3" command. 2784 - end 2785 - 2786 - define patch 2787 - if $argc != 3 2788 - help patch 2789 - end 2790 - set $patchaddr = $arg0 2791 - set $patchbytes = $arg1 2792 - set $patchsize = $arg2 2793 - 2794 - if ($patchsize == 1) 2795 - set *(unsigned char*)$patchaddr = $patchbytes 2796 - end 2797 - if ($patchsize == 2) 2798 - set $lendianbytes = (unsigned short)(($patchbytes << 8) | ($patchbytes >> 8)) 2799 - set *(unsigned short*)$patchaddr = $lendianbytes 2800 - end 2801 - if ($patchsize == 4) 2802 - set $lendianbytes = (unsigned int)( (($patchbytes << 8) & 0xFF00FF00 ) | (($patchbytes >> 8) & 0xFF00FF )) 2803 - set $lendianbytes = (unsigned int)($lendianbytes << 0x10 | $lendianbytes >> 0x10) 2804 - set *(unsigned int*)$patchaddr = $lendianbytes 2805 - end 2806 - if ($patchsize == 8) 2807 - set $lendianbytes = (unsigned long long)( (($patchbytes << 8) & 0xFF00FF00FF00FF00ULL ) | (($patchbytes >> 8) & 0x00FF00FF00FF00FFULL ) ) 2808 - set $lendianbytes = (unsigned long long)( (($lendianbytes << 0x10) & 0xFFFF0000FFFF0000ULL ) | (($lendianbytes >> 0x10) & 0x0000FFFF0000FFFFULL ) ) 2809 - set $lendianbytes = (unsigned long long)( ($lendianbytes << 0x20) | ($lendianbytes >> 0x20) ) 2810 - set *(unsigned long long*)$patchaddr = $lendianbytes 2811 - end 2812 - end 2813 - document patch 2814 - Syntax: patch address bytes size 2815 - | Patch a given address, converting the bytes to little-endian. 2816 - | Assumes input bytes are unsigned values and should be in hexadecimal format (0x...). 2817 - | Size must be 1, 2, 4, 8 bytes. 2818 - | Main purpose is to be used with the output from the asm commands. 2819 - end 2820 - 2821 - # ____________________cflow___________________ 2822 - define print_insn_type 2823 - if $argc != 1 2824 - help print_insn_type 2825 - else 2826 - if ($arg0 < 0 || $arg0 > 5) 2827 - printf "UNDEFINED/WRONG VALUE" 2828 - end 2829 - if ($arg0 == 0) 2830 - printf "UNKNOWN" 2831 - end 2832 - if ($arg0 == 1) 2833 - printf "JMP" 2834 - end 2835 - if ($arg0 == 2) 2836 - printf "JCC" 2837 - end 2838 - if ($arg0 == 3) 2839 - printf "CALL" 2840 - end 2841 - if ($arg0 == 4) 2842 - printf "RET" 2843 - end 2844 - if ($arg0 == 5) 2845 - printf "INT" 2846 - end 2847 - end 2848 - end 2849 - document print_insn_type 2850 - Syntax: print_insn_type INSN_TYPE_NUMBER 2851 - | Print human-readable mnemonic for the instruction type (usually $INSN_TYPE). 2852 - end 2853 - 2854 - 2855 - define get_insn_type 2856 - if $argc != 1 2857 - help get_insn_type 2858 - else 2859 - set $INSN_TYPE = 0 2860 - set $_byte1 = *(unsigned char *)$arg0 2861 - if ($_byte1 == 0x9A || $_byte1 == 0xE8) 2862 - # "call" 2863 - set $INSN_TYPE = 3 2864 - end 2865 - if ($_byte1 >= 0xE9 && $_byte1 <= 0xEB) 2866 - # "jmp" 2867 - set $INSN_TYPE = 1 2868 - end 2869 - if ($_byte1 >= 0x70 && $_byte1 <= 0x7F) 2870 - # "jcc" 2871 - set $INSN_TYPE = 2 2872 - end 2873 - if ($_byte1 >= 0xE0 && $_byte1 <= 0xE3 ) 2874 - # "jcc" 2875 - set $INSN_TYPE = 2 2876 - end 2877 - if ($_byte1 == 0xC2 || $_byte1 == 0xC3 || $_byte1 == 0xCA || \ 2878 - $_byte1 == 0xCB || $_byte1 == 0xCF) 2879 - # "ret" 2880 - set $INSN_TYPE = 4 2881 - end 2882 - if ($_byte1 >= 0xCC && $_byte1 <= 0xCE) 2883 - # "int" 2884 - set $INSN_TYPE = 5 2885 - end 2886 - if ($_byte1 == 0x0F ) 2887 - # two-byte opcode 2888 - set $_byte2 = *(unsigned char *)($arg0 + 1) 2889 - if ($_byte2 >= 0x80 && $_byte2 <= 0x8F) 2890 - # "jcc" 2891 - set $INSN_TYPE = 2 2892 - end 2893 - end 2894 - if ($_byte1 == 0xFF) 2895 - # opcode extension 2896 - set $_byte2 = *(unsigned char *)($arg0 + 1) 2897 - set $_opext = ($_byte2 & 0x38) 2898 - if ($_opext == 0x10 || $_opext == 0x18) 2899 - # "call" 2900 - set $INSN_TYPE = 3 2901 - end 2902 - if ($_opext == 0x20 || $_opext == 0x28) 2903 - # "jmp" 2904 - set $INSN_TYPE = 1 2905 - end 2906 - end 2907 - end 2908 - end 2909 - document get_insn_type 2910 - Syntax: get_insn_type ADDR 2911 - | Recognize instruction type at address ADDR. 2912 - | Take address ADDR and set the global $INSN_TYPE variable to 2913 - | 0, 1, 2, 3, 4, 5 if the instruction at that address is 2914 - | unknown, a jump, a conditional jump, a call, a return, or an interrupt. 2915 - end 2916 - 2917 - 2918 - define step_to_call 2919 - set $_saved_ctx = $SHOW_CONTEXT 2920 - set $SHOW_CONTEXT = 0 2921 - set $SHOW_NEST_INSN = 0 2922 - 2923 - set logging file /dev/null 2924 - set logging redirect on 2925 - set logging on 2926 - 2927 - set $_cont = 1 2928 - while ($_cont > 0) 2929 - stepi 2930 - get_insn_type $pc 2931 - if ($INSN_TYPE == 3) 2932 - set $_cont = 0 2933 - end 2934 - end 2935 - 2936 - set logging off 2937 - 2938 - if ($_saved_ctx > 0) 2939 - context 2940 - end 2941 - 2942 - set $SHOW_CONTEXT = $_saved_ctx 2943 - set $SHOW_NEST_INSN = 0 2944 - 2945 - set logging file ~/gdb.txt 2946 - set logging redirect off 2947 - set logging on 2948 - 2949 - printf "step_to_call command stopped at:\n " 2950 - x/i $pc 2951 - printf "\n" 2952 - set logging off 2953 - 2954 - end 2955 - document step_to_call 2956 - Syntax: step_to_call 2957 - | Single step until a call instruction is found. 2958 - | Stop before the call is taken. 2959 - | Log is written into the file ~/gdb.txt. 2960 - end 2961 - 2962 - 2963 - define trace_calls 2964 - 2965 - printf "Tracing...please wait...\n" 2966 - 2967 - set $_saved_ctx = $SHOW_CONTEXT 2968 - set $SHOW_CONTEXT = 0 2969 - set $SHOW_NEST_INSN = 0 2970 - set $_nest = 1 2971 - set listsize 0 2972 - 2973 - set logging overwrite on 2974 - set logging file ~/gdb_trace_calls.txt 2975 - set logging on 2976 - set logging off 2977 - set logging overwrite off 2978 - 2979 - while ($_nest > 0) 2980 - get_insn_type $pc 2981 - # handle nesting 2982 - if ($INSN_TYPE == 3) 2983 - set $_nest = $_nest + 1 2984 - else 2985 - if ($INSN_TYPE == 4) 2986 - set $_nest = $_nest - 1 2987 - end 2988 - end 2989 - # if a call, print it 2990 - if ($INSN_TYPE == 3) 2991 - set logging file ~/gdb_trace_calls.txt 2992 - set logging redirect off 2993 - set logging on 2994 - 2995 - set $x = $_nest - 2 2996 - while ($x > 0) 2997 - printf "\t" 2998 - set $x = $x - 1 2999 - end 3000 - x/i $pc 3001 - end 3002 - 3003 - set logging off 3004 - set logging file /dev/null 3005 - set logging redirect on 3006 - set logging on 3007 - stepi 3008 - set logging redirect off 3009 - set logging off 3010 - end 3011 - 3012 - set $SHOW_CONTEXT = $_saved_ctx 3013 - set $SHOW_NEST_INSN = 0 3014 - 3015 - printf "Done, check ~/gdb_trace_calls.txt\n" 3016 - end 3017 - document trace_calls 3018 - Syntax: trace_calls 3019 - | Create a runtime trace of the calls made by target. 3020 - | Log overwrites(!) the file ~/gdb_trace_calls.txt. 3021 - end 3022 - 3023 - 3024 - define trace_run 3025 - 3026 - printf "Tracing...please wait...\n" 3027 - 3028 - set $_saved_ctx = $SHOW_CONTEXT 3029 - set $SHOW_CONTEXT = 0 3030 - set $SHOW_NEST_INSN = 1 3031 - set logging overwrite on 3032 - set logging file ~/gdb_trace_run.txt 3033 - set logging redirect on 3034 - set logging on 3035 - set $_nest = 1 3036 - 3037 - while ( $_nest > 0 ) 3038 - 3039 - get_insn_type $pc 3040 - # jmp, jcc, or cll 3041 - if ($INSN_TYPE == 3) 3042 - set $_nest = $_nest + 1 3043 - else 3044 - # ret 3045 - if ($INSN_TYPE == 4) 3046 - set $_nest = $_nest - 1 3047 - end 3048 - end 3049 - stepi 3050 - end 3051 - 3052 - printf "\n" 3053 - 3054 - set $SHOW_CONTEXT = $_saved_ctx 3055 - set $SHOW_NEST_INSN = 0 3056 - set logging redirect off 3057 - set logging off 3058 - 3059 - # clean up trace file 3060 - shell grep -v ' at ' ~/gdb_trace_run.txt > ~/gdb_trace_run.1 3061 - shell grep -v ' in ' ~/gdb_trace_run.1 > ~/gdb_trace_run.txt 3062 - shell rm -f ~/gdb_trace_run.1 3063 - printf "Done, check ~/gdb_trace_run.txt\n" 3064 - end 3065 - document trace_run 3066 - Syntax: trace_run 3067 - | Create a runtime trace of target. 3068 - | Log overwrites(!) the file ~/gdb_trace_run.txt. 3069 - end 3070 - 3071 - define entry_point 3072 - 3073 - set logging redirect on 3074 - set logging file /tmp/gdb-entry_point 3075 - set logging on 3076 - 3077 - info files 3078 - 3079 - set logging off 3080 - 3081 - shell entry_point="$(/usr/bin/grep 'Entry point:' /tmp/gdb-entry_point | /usr/bin/awk '{ print $3 }')"; echo "$entry_point"; echo 'set $entry_point_address = '"$entry_point" > /tmp/gdb-entry_point 3082 - source /tmp/gdb-entry_point 3083 - shell /bin/rm -f /tmp/gdb-entry_point 3084 - end 3085 - document entry_point 3086 - Syntax: entry_point 3087 - | Prints the entry point address of the target and stores it in the variable entry_point. 3088 - end 3089 - 3090 - define break_entrypoint 3091 - entry_point 3092 - break *$entry_point_address 3093 - end 3094 - document break_entrypoint 3095 - Syntax: break_entrypoint 3096 - | Sets a breakpoint on the entry point of the target. 3097 - end 3098 - 3099 - define objc_symbols 3100 - 3101 - set logging redirect on 3102 - set logging file /tmp/gdb-objc_symbols 3103 - set logging on 3104 - 3105 - info target 3106 - 3107 - set logging off 3108 - # XXX: define paths for objc-symbols and SymTabCreator 3109 - shell target="$(/usr/bin/head -1 /tmp/gdb-objc_symbols | /usr/bin/head -1 | /usr/bin/awk -F '"' '{ print $2 }')"; objc-symbols "$target" | SymTabCreator -o /tmp/gdb-symtab 3110 - 3111 - set logging on 3112 - add-symbol-file /tmp/gdb-symtab 3113 - set logging off 3114 - shell /bin/rm -f /tmp/gdb-objc_symbols 3115 - end 3116 - document objc_symbols 3117 - Syntax: objc_symbols 3118 - | Loads stripped objc symbols into gdb using objc-symbols and SymTabCreator 3119 - | See http://stackoverflow.com/questions/17554070/import-class-dump-info-into-gdb 3120 - | and https://github.com/0xced/class-dump/tree/objc-symbols (for the required utils) 3121 - end 3122 - 3123 - #define ptraceme 3124 - # catch syscall ptrace 3125 - # commands 3126 - # if ($64BITS == 0) 3127 - # if ($ebx == 0) 3128 - # set $eax = 0 3129 - # continue 3130 - # end 3131 - # else 3132 - # if ($rdi == 0) 3133 - # set $rax = 0 3134 - # continue 3135 - # end 3136 - # end 3137 - # end 3138 - # set $ptrace_bpnum = $bpnum 3139 - #end 3140 - #document ptraceme 3141 - #Syntax: ptraceme 3142 - #| Hook ptrace to bypass PTRACE_TRACEME anti debugging technique 3143 - #end 3144 - 3145 - define rptraceme 3146 - if ($ptrace_bpnum != 0) 3147 - delete $ptrace_bpnum 3148 - set $ptrace_bpnum = 0 3149 - end 3150 - end 3151 - document rptraceme 3152 - Syntax: rptraceme 3153 - | Remove ptrace hook. 3154 - end 3155 - 3156 - 3157 - # ____________________misc____________________ 3158 - define hook-stop 3159 - if (sizeof(void*) == 8) 3160 - set $64BITS = 1 3161 - else 3162 - set $64BITS = 0 3163 - end 3164 - 3165 - if ($KDP64BITS != -1) 3166 - if ($KDP64BITS == 0) 3167 - set $64BITS = 0 3168 - else 3169 - set $64BITS = 1 3170 - end 3171 - end 3172 - 3173 - # Display instructions formats 3174 - if $ARM == 1 3175 - if $ARMOPCODES == 1 3176 - set arm show-opcode-bytes 1 3177 - end 3178 - else 3179 - if $X86FLAVOR == 0 3180 - set disassembly-flavor intel 3181 - else 3182 - set disassembly-flavor att 3183 - end 3184 - end 3185 - 3186 - # this makes 'context' be called at every BP/step 3187 - if ($SHOW_CONTEXT > 0) 3188 - context 3189 - end 3190 - if ($SHOW_NEST_INSN > 0) 3191 - set $x = $_nest 3192 - while ($x > 0) 3193 - printf "\t" 3194 - set $x = $x - 1 3195 - end 3196 - end 3197 - end 3198 - document hook-stop 3199 - Syntax: hook-stop 3200 - | !!! FOR INTERNAL USE ONLY - DO NOT CALL !!! 3201 - end 3202 - 3203 - 3204 - # original by Tavis Ormandy (http://my.opera.com/taviso/blog/index.dml/tag/gdb) (great fix!) 3205 - # modified to work with Mac OS X by fG! 3206 - # seems nasm shipping with Mac OS X has problems accepting input from stdin or heredoc 3207 - # input is read into a variable and sent to a temporary file which nasm can read 3208 - define assemble 3209 - # dont enter routine again if user hits enter 3210 - dont-repeat 3211 - if ($argc) 3212 - if (*$arg0 = *$arg0) 3213 - # check if we have a valid address by dereferencing it, 3214 - # if we havnt, this will cause the routine to exit. 3215 - end 3216 - printf "Instructions will be written to %#x.\n", $arg0 3217 - else 3218 - printf "Instructions will be written to stdout.\n" 3219 - end 3220 - printf "Type instructions, one per line." 3221 - color_bold 3222 - printf " Do not forget to use NASM assembler syntax!\n" 3223 - color_reset 3224 - printf "End with a line saying just \"end\".\n" 3225 - 3226 - if ($argc) 3227 - if ($64BITS == 1) 3228 - # argument specified, assemble instructions into memory at address specified. 3229 - shell ASMOPCODE="$(while read -ep '>' r && test "$r" != end ; do echo -E "$r"; done)" ; GDBASMFILENAME=$RANDOM; \ 3230 - echo -e "BITS 64\n$ASMOPCODE" >/tmp/$GDBASMFILENAME ; /usr/local/bin/nasm -f bin -o /dev/stdout /tmp/$GDBASMFILENAME | /usr/bin/hexdump -ve '1/1 "set *((unsigned char *) $arg0 + %#2_ax) = %#02x\n"' >/tmp/gdbassemble ; /bin/rm -f /tmp/$GDBASMFILENAME 3231 - source /tmp/gdbassemble 3232 - # all done. clean the temporary file 3233 - shell /bin/rm -f /tmp/gdbassemble 3234 - else 3235 - # argument specified, assemble instructions into memory at address specified. 3236 - shell ASMOPCODE="$(while read -ep '>' r && test "$r" != end ; do echo -E "$r"; done)" ; GDBASMFILENAME=$RANDOM; \ 3237 - echo -e "BITS 32\n$ASMOPCODE" >/tmp/$GDBASMFILENAME ; /usr/bin/nasm -f bin -o /dev/stdout /tmp/$GDBASMFILENAME | /usr/bin/hexdump -ve '1/1 "set *((unsigned char *) $arg0 + %#2_ax) = %#02x\n"' >/tmp/gdbassemble ; /bin/rm -f /tmp/$GDBASMFILENAME 3238 - source /tmp/gdbassemble 3239 - # all done. clean the temporary file 3240 - shell /bin/rm -f /tmp/gdbassemble 3241 - end 3242 - else 3243 - if ($64BITS == 1) 3244 - # no argument, assemble instructions to stdout 3245 - shell ASMOPCODE="$(while read -ep '>' r && test "$r" != end ; do echo -E "$r"; done)" ; GDBASMFILENAME=$RANDOM; \ 3246 - echo -e "BITS 64\n$ASMOPCODE" >/tmp/$GDBASMFILENAME ; /usr/local/bin/nasm -f bin -o /dev/stdout /tmp/$GDBASMFILENAME | /usr/local/bin/ndisasm -i -b64 /dev/stdin ; \ 3247 - /bin/rm -f /tmp/$GDBASMFILENAME 3248 - else 3249 - # no argument, assemble instructions to stdout 3250 - shell ASMOPCODE="$(while read -ep '>' r && test "$r" != end ; do echo -E "$r"; done)" ; GDBASMFILENAME=$RANDOM; \ 3251 - echo -e "BITS 32\n$ASMOPCODE" >/tmp/$GDBASMFILENAME ; /usr/bin/nasm -f bin -o /dev/stdout /tmp/$GDBASMFILENAME | /usr/bin/ndisasm -i -b32 /dev/stdin ; \ 3252 - /bin/rm -f /tmp/$GDBASMFILENAME 3253 - end 3254 - end 3255 - end 3256 - document assemble 3257 - Syntax: assemble <ADDR> 3258 - | Assemble instructions using nasm. 3259 - | Type a line containing "end" to indicate the end. 3260 - | If an address is specified, insert/modify instructions at that address. 3261 - | If no address is specified, assembled instructions are printed to stdout. 3262 - | Use the pseudo instruction "org ADDR" to set the base address. 3263 - end 3264 - 3265 - define assemble32 3266 - # dont enter routine again if user hits enter 3267 - dont-repeat 3268 - if ($argc) 3269 - if (*$arg0 = *$arg0) 3270 - # check if we have a valid address by dereferencing it, 3271 - # if we havnt, this will cause the routine to exit. 3272 - end 3273 - printf "Instructions will be written to %#x.\n", $arg0 3274 - else 3275 - printf "Instructions will be written to stdout.\n" 3276 - end 3277 - printf "Type instructions, one per line." 3278 - color_bold 3279 - printf " Do not forget to use NASM assembler syntax!\n" 3280 - color_reset 3281 - printf "End with a line saying just \"end\".\n" 3282 - 3283 - if ($argc) 3284 - # argument specified, assemble instructions into memory at address specified. 3285 - shell ASMOPCODE="$(while read -ep '>' r && test "$r" != end ; do echo -E "$r"; done)" ; GDBASMFILENAME=$RANDOM; \ 3286 - echo -e "BITS 32\n$ASMOPCODE" >/tmp/$GDBASMFILENAME ; /usr/bin/nasm -f bin -o /dev/stdout /tmp/$GDBASMFILENAME | /usr/bin/hexdump -ve '1/1 "set *((unsigned char *) $arg0 + %#2_ax) = %#02x\n"' >/tmp/gdbassemble ; /bin/rm -f /tmp/$GDBASMFILENAME 3287 - source /tmp/gdbassemble 3288 - # all done. clean the temporary file 3289 - shell /bin/rm -f /tmp/gdbassemble 3290 - else 3291 - # no argument, assemble instructions to stdout 3292 - shell ASMOPCODE="$(while read -ep '>' r && test "$r" != end ; do echo -E "$r"; done)" ; GDBASMFILENAME=$RANDOM; \ 3293 - echo -e "BITS 32\n$ASMOPCODE" >/tmp/$GDBASMFILENAME ; /usr/bin/nasm -f bin -o /dev/stdout /tmp/$GDBASMFILENAME | /usr/bin/ndisasm -i -b32 /dev/stdin ; \ 3294 - /bin/rm -f /tmp/$GDBASMFILENAME 3295 - end 3296 - end 3297 - document assemble32 3298 - Syntax: assemble32 <ADDR> 3299 - | Assemble 32 bits instructions using nasm. 3300 - | Type a line containing "end" to indicate the end. 3301 - | If an address is specified, insert/modify instructions at that address. 3302 - | If no address is specified, assembled instructions are printed to stdout. 3303 - | Use the pseudo instruction "org ADDR" to set the base address. 3304 - end 3305 - 3306 - define assemble64 3307 - # dont enter routine again if user hits enter 3308 - dont-repeat 3309 - if ($argc) 3310 - if (*$arg0 = *$arg0) 3311 - # check if we have a valid address by dereferencing it, 3312 - # if we havnt, this will cause the routine to exit. 3313 - end 3314 - printf "Instructions will be written to %#x.\n", $arg0 3315 - else 3316 - printf "Instructions will be written to stdout.\n" 3317 - end 3318 - printf "Type instructions, one per line." 3319 - color_bold 3320 - printf " Do not forget to use NASM assembler syntax!\n" 3321 - color_reset 3322 - printf "End with a line saying just \"end\".\n" 3323 - 3324 - if ($argc) 3325 - # argument specified, assemble instructions into memory at address specified. 3326 - shell ASMOPCODE="$(while read -ep '>' r && test "$r" != end ; do echo -E "$r"; done)" ; GDBASMFILENAME=$RANDOM; \ 3327 - echo -e "BITS 64\n$ASMOPCODE" >/tmp/$GDBASMFILENAME ; /usr/local/bin/nasm -f bin -o /dev/stdout /tmp/$GDBASMFILENAME | /usr/bin/hexdump -ve '1/1 "set *((unsigned char *) $arg0 + %#2_ax) = %#02x\n"' >/tmp/gdbassemble ; /bin/rm -f /tmp/$GDBASMFILENAME 3328 - source /tmp/gdbassemble 3329 - # all done. clean the temporary file 3330 - shell /bin/rm -f /tmp/gdbassemble 3331 - else 3332 - # no argument, assemble instructions to stdout 3333 - shell ASMOPCODE="$(while read -ep '>' r && test "$r" != end ; do echo -E "$r"; done)" ; GDBASMFILENAME=$RANDOM; \ 3334 - echo -e "BITS 64\n$ASMOPCODE" >/tmp/$GDBASMFILENAME ; /usr/local/bin/nasm -f bin -o /dev/stdout /tmp/$GDBASMFILENAME | /usr/local/bin/ndisasm -i -b64 /dev/stdin ; \ 3335 - /bin/rm -f /tmp/$GDBASMFILENAME 3336 - end 3337 - end 3338 - document assemble64 3339 - Syntax: assemble64 <ADDR> 3340 - | Assemble 64 bits instructions using nasm. 3341 - | Type a line containing "end" to indicate the end. 3342 - | If an address is specified, insert/modify instructions at that address. 3343 - | If no address is specified, assembled instructions are printed to stdout. 3344 - | Use the pseudo instruction "org ADDR" to set the base address. 3345 - end 3346 - 3347 - define asm 3348 - if $argc == 1 3349 - assemble $arg0 3350 - else 3351 - assemble 3352 - end 3353 - end 3354 - document asm 3355 - Syntax: asm <ADDR> 3356 - | Shortcut to the asssemble command. 3357 - end 3358 - 3359 - define asm32 3360 - if $argc == 1 3361 - assemble32 $arg0 3362 - else 3363 - assemble32 3364 - end 3365 - end 3366 - document asm32 3367 - Syntax: asm32 <ADDR> 3368 - | Shortcut to the assemble32 command. 3369 - end 3370 - 3371 - define asm64 3372 - if $argc == 1 3373 - assemble64 $arg0 3374 - else 3375 - assemble64 3376 - end 3377 - end 3378 - document asm64 3379 - Syntax: asm64 <ADDR> 3380 - | Shortcut to the assemble64 command. 3381 - end 3382 - 3383 - define assemble_gas 3384 - printf "\nType code to assemble and hit Ctrl-D when finished.\n" 3385 - printf "You must use GNU assembler (AT&T) syntax.\n" 3386 - 3387 - shell filename=$(mktemp); \ 3388 - binfilename=$(mktemp); \ 3389 - echo -e "Writing into: ${filename}\n"; \ 3390 - cat > $filename; echo ""; \ 3391 - as -o $binfilename < $filename; \ 3392 - objdump -d -j .text $binfilename; \ 3393 - rm -f $binfilename; \ 3394 - rm -f $filename; \ 3395 - echo -e "temporaly files deleted.\n" 3396 - end 3397 - document assemble_gas 3398 - Syntax: assemble_gas 3399 - | Assemble instructions to binary opcodes. Uses GNU as and objdump. 3400 - end 3401 - 3402 - 3403 - define dump_hexfile 3404 - dump ihex memory $arg0 $arg1 $arg2 3405 - end 3406 - document dump_hexfile 3407 - Syntax: dump_hexfile FILENAME ADDR1 ADDR2 3408 - | Write a range of memory to a file in Intel ihex (hexdump) format. 3409 - | The range is specified by ADDR1 and ADDR2 addresses. 3410 - end 3411 - 3412 - 3413 - define dump_binfile 3414 - dump memory $arg0 $arg1 $arg2 3415 - end 3416 - document dump_binfile 3417 - Syntax: dump_binfile FILENAME ADDR1 ADDR2 3418 - | Write a range of memory to a binary file. 3419 - | The range is specified by ADDR1 and ADDR2 addresses. 3420 - end 3421 - 3422 - 3423 - define dumpmacho 3424 - if $argc != 2 3425 - help dumpmacho 3426 - end 3427 - set $headermagic = *$arg0 3428 - # the || operator isn't working as it should, wtf!!! 3429 - if $headermagic != 0xfeedface 3430 - if $headermagic != 0xfeedfacf 3431 - printf "[Error] Target address doesn't contain a valid Mach-O binary!\n" 3432 - help dumpmacho 3433 - end 3434 - end 3435 - set $headerdumpsize = *($arg0+0x14) 3436 - if $headermagic == 0xfeedface 3437 - dump memory $arg1 $arg0 ($arg0+0x1c+$headerdumpsize) 3438 - end 3439 - if $headermagic == 0xfeedfacf 3440 - dump memory $arg1 $arg0 ($arg0+0x20+$headerdumpsize) 3441 - end 3442 - end 3443 - document dumpmacho 3444 - Syntax: dumpmacho STARTADDRESS FILENAME 3445 - | Dump the Mach-O header to a file. 3446 - | You need to input the start address (use info shared command to find it). 3447 - end 3448 - 3449 - 3450 - define cls 3451 - shell clear 3452 - end 3453 - document cls 3454 - Syntax: cls 3455 - | Clear screen. 3456 - end 3457 - 3458 - 3459 - define search 3460 - set $start = (char *) $arg0 3461 - set $end = (char *) $arg1 3462 - set $pattern = (short) $arg2 3463 - set $p = $start 3464 - while $p < $end 3465 - if (*(short *) $p) == $pattern 3466 - printf "pattern 0x%hx found at 0x%x\n", $pattern, $p 3467 - end 3468 - set $p++ 3469 - end 3470 - end 3471 - document search 3472 - Syntax: search <START> <END> <PATTERN> 3473 - | Search for the given pattern beetween $start and $end address. 3474 - end 3475 - 3476 - 3477 - # _________________user tips_________________ 3478 - # The 'tips' command is used to provide tutorial-like info to the user 3479 - define tips 3480 - printf "Tip Topic Commands:\n" 3481 - printf "\ttip_display : Automatically display values on each break\n" 3482 - printf "\ttip_patch : Patching binaries\n" 3483 - printf "\ttip_strip : Dealing with stripped binaries\n" 3484 - printf "\ttip_syntax : AT&T vs Intel syntax\n" 3485 - end 3486 - document tips 3487 - Syntax: tips 3488 - | Provide a list of tips from users on various topics. 3489 - end 3490 - 3491 - 3492 - define tip_patch 3493 - printf "\n" 3494 - printf " PATCHING MEMORY\n" 3495 - printf "Any address can be patched using the 'set' command:\n" 3496 - printf "\t`set ADDR = VALUE` \te.g. `set *0x8049D6E = 0x90`\n" 3497 - printf "\n" 3498 - printf " PATCHING BINARY FILES\n" 3499 - printf "Use `set write` in order to patch the target executable\n" 3500 - printf "directly, instead of just patching memory\n" 3501 - printf "\t`set write on` \t`set write off`\n" 3502 - printf "Note that this means any patches to the code or data segments\n" 3503 - printf "will be written to the executable file\n" 3504 - printf "When either of these commands has been issued,\n" 3505 - printf "the file must be reloaded.\n" 3506 - printf "\n" 3507 - end 3508 - document tip_patch 3509 - Syntax: tip_patch 3510 - | Tips on patching memory and binary files. 3511 - end 3512 - 3513 - 3514 - define tip_strip 3515 - printf "\n" 3516 - printf " STOPPING BINARIES AT ENTRY POINT\n" 3517 - printf "Stripped binaries have no symbols, and are therefore tough to\n" 3518 - printf "start automatically. To debug a stripped binary, use\n" 3519 - printf "\tinfo file\n" 3520 - printf "to get the entry point of the file\n" 3521 - printf "The first few lines of output will look like this:\n" 3522 - printf "\tSymbols from '/tmp/a.out'\n" 3523 - printf "\tLocal exec file:\n" 3524 - printf "\t `/tmp/a.out', file type elf32-i386.\n" 3525 - printf "\t Entry point: 0x80482e0\n" 3526 - printf "Use this entry point to set an entry point:\n" 3527 - printf "\t`tbreak *0x80482e0`\n" 3528 - printf "The breakpoint will delete itself after the program stops as\n" 3529 - printf "the entry point\n" 3530 - printf "\n" 3531 - end 3532 - document tip_strip 3533 - Syntax: tip_strip 3534 - | Tips on dealing with stripped binaries. 3535 - end 3536 - 3537 - 3538 - define tip_syntax 3539 - printf "\n" 3540 - printf "\t INTEL SYNTAX AT&T SYNTAX\n" 3541 - printf "\tmnemonic dest, src, imm mnemonic src, dest, imm\n" 3542 - printf "\t[base+index*scale+disp] disp(base, index, scale)\n" 3543 - printf "\tregister: eax register: %%eax\n" 3544 - printf "\timmediate: 0xFF immediate: $0xFF\n" 3545 - printf "\tdereference: [addr] dereference: addr(,1)\n" 3546 - printf "\tabsolute addr: addr absolute addr: *addr\n" 3547 - printf "\tbyte insn: mov byte ptr byte insn: movb\n" 3548 - printf "\tword insn: mov word ptr word insn: movw\n" 3549 - printf "\tdword insn: mov dword ptr dword insn: movd\n" 3550 - printf "\tfar call: call far far call: lcall\n" 3551 - printf "\tfar jump: jmp far far jump: ljmp\n" 3552 - printf "\n" 3553 - printf "Note that order of operands in reversed, and that AT&T syntax\n" 3554 - printf "requires that all instructions referencing memory operands \n" 3555 - printf "use an operand size suffix (b, w, d, q)\n" 3556 - printf "\n" 3557 - end 3558 - document tip_syntax 3559 - Syntax: tip_syntax 3560 - | Summary of Intel and AT&T syntax differences. 3561 - end 3562 - 3563 - 3564 - define tip_display 3565 - printf "\n" 3566 - printf "Any expression can be set to automatically be displayed every time\n" 3567 - printf "the target stops. The commands for this are:\n" 3568 - printf "\t`display expr' : automatically display expression 'expr'\n" 3569 - printf "\t`display' : show all displayed expressions\n" 3570 - printf "\t`undisplay num' : turn off autodisplay for expression # 'num'\n" 3571 - printf "Examples:\n" 3572 - printf "\t`display/x *(int *)$esp` : print top of stack\n" 3573 - printf "\t`display/x *(int *)($ebp+8)` : print first parameter\n" 3574 - printf "\t`display (char *)$esi` : print source string\n" 3575 - printf "\t`display (char *)$edi` : print destination string\n" 3576 - printf "\n" 3577 - end 3578 - document tip_display 3579 - Syntax: tip_display 3580 - | Tips on automatically displaying values when a program stops. 3581 - end 3582 - 3583 - # bunch of semi-useless commands 3584 - 3585 - # enable and disable shortcuts for stop-on-solib-events fantastic trick! 3586 - define enablesolib 3587 - set stop-on-solib-events 1 3588 - printf "Stop-on-solib-events is enabled!\n" 3589 - end 3590 - document enablesolib 3591 - Syntax: enablesolib 3592 - | Shortcut to enable stop-on-solib-events trick. 3593 - end 3594 - 3595 - 3596 - define disablesolib 3597 - set stop-on-solib-events 0 3598 - printf "Stop-on-solib-events is disabled!\n" 3599 - end 3600 - document disablesolib 3601 - Syntax: disablesolib 3602 - | Shortcut to disable stop-on-solib-events trick. 3603 - end 3604 - 3605 - 3606 - # enable commands for different displays 3607 - define enableobjectivec 3608 - set $SHOWOBJECTIVEC = 1 3609 - end 3610 - document enableobjectivec 3611 - Syntax: enableobjectivec 3612 - | Enable display of objective-c information in the context window. 3613 - end 3614 - 3615 - 3616 - define enablecpuregisters 3617 - set $SHOWCPUREGISTERS = 1 3618 - end 3619 - document enablecpuregisters 3620 - Syntax: enablecpuregisters 3621 - | Enable display of cpu registers in the context window. 3622 - end 3623 - 3624 - 3625 - define enablestack 3626 - set $SHOWSTACK = 1 3627 - end 3628 - document enablestack 3629 - Syntax: enablestack 3630 - | Enable display of stack in the context window. 3631 - end 3632 - 3633 - 3634 - define enabledatawin 3635 - set $SHOWDATAWIN = 1 3636 - end 3637 - document enabledatawin 3638 - Syntax: enabledatawin 3639 - | Enable display of data window in the context window. 3640 - end 3641 - 3642 - 3643 - # disable commands for different displays 3644 - define disableobjectivec 3645 - set $SHOWOBJECTIVEC = 0 3646 - end 3647 - document disableobjectivec 3648 - Syntax: disableobjectivec 3649 - | Disable display of objective-c information in the context window. 3650 - end 3651 - 3652 - 3653 - define disablecpuregisters 3654 - set $SHOWCPUREGISTERS = 0 3655 - end 3656 - document disablecpuregisters 3657 - Syntax: disablecpuregisters 3658 - | Disable display of cpu registers in the context window. 3659 - end 3660 - 3661 - 3662 - define disablestack 3663 - set $SHOWSTACK = 0 3664 - end 3665 - document disablestack 3666 - Syntax: disablestack 3667 - | Disable display of stack information in the context window. 3668 - end 3669 - 3670 - 3671 - define disabledatawin 3672 - set $SHOWDATAWIN = 0 3673 - end 3674 - document disabledatawin 3675 - Syntax: disabledatawin 3676 - | Disable display of data window in the context window. 3677 - end 3678 - 3679 - 3680 - define arm 3681 - if $ARMOPCODES == 1 3682 - set arm show-opcode-bytes 1 3683 - end 3684 - set $ARM = 1 3685 - end 3686 - document arm 3687 - Syntax: arm 3688 - | Set gdb to work with ARM binaries. 3689 - end 3690 - 3691 - define ioskdp 3692 - set $SHOW_CONTEXT = 0 3693 - set $SHOW_NEST_INSN = 0 3694 - end 3695 - document ioskdp 3696 - Syntax: ioskdp 3697 - | Disable dumping context information for iOS KDP debugging 3698 - end 3699 - 3700 - define intelsyntax 3701 - if $ARM == 0 3702 - set disassembly-flavor intel 3703 - set $X86FLAVOR = 0 3704 - end 3705 - end 3706 - document intelsyntax 3707 - Syntax: intelsyntax 3708 - | Change disassembly syntax to intel flavor. 3709 - end 3710 - 3711 - 3712 - define attsyntax 3713 - if $ARM == 0 3714 - set disassembly-flavor att 3715 - set $X86FLAVOR = 1 3716 - end 3717 - end 3718 - document attsyntax 3719 - Syntax: attsyntax 3720 - | Change disassembly syntax to at&t flavor. 3721 - end 3722 - 3723 - define kernel32 3724 - if $argc != 0 3725 - # try to load kgmacros files 3726 - # failure is silent if non-existent... 3727 - source $arg0 3728 - set architecture i386 3729 - if $argc == 2 3730 - target remote localhost:$arg1 3731 - else 3732 - target remote localhost:8832 3733 - end 3734 - else 3735 - help kernel32 3736 - end 3737 - end 3738 - document kernel32 3739 - Syntax: kernel32 PATH_TO_KGMACROS <PORT> 3740 - | Attach to VMware gdb stub for 32 bits kernel. 3741 - | The path to kgmacros must be supplied as first parameter. 3742 - | If you don't want to load kgmacros just put something as the first parameter. 3743 - | Optional parameter is the port to connect to, in case you are not using the default 8832 3744 - | or want to kernel debug more than one active virtual machine. 3745 - | By supplying a bogus kgmacros this command should be compatible with any OS. 3746 - end 3747 - 3748 - define kernel64 3749 - if $argc != 0 3750 - # try to load kgmacros files 3751 - # failure is silent if non-existent... 3752 - source $arg0 3753 - set architecture i386:x86-64 3754 - if $argc == 2 3755 - target remote localhost:$arg1 3756 - else 3757 - target remote localhost:8864 3758 - end 3759 - else 3760 - help kernel64 3761 - end 3762 - end 3763 - document kernel64 3764 - Syntax: kernel64 PATH_TO_KGMACROS <PORT> 3765 - | Attach to VMware gdb stub for 64 bits kernel. 3766 - | The path to kgmacros must be supplied as first parameter. 3767 - | If you don't want to load kgmacros just put something as the first parameter. 3768 - | Optional parameter is the port to connect to, in case you are not using the default 8864 3769 - | or want to kernel debug more than one active virtual machine. 3770 - | By supplying a bogus kgmacros this command should be compatible with any OS. 3771 - end 3772 - 3773 - define 32bits 3774 - set $KDP64BITS = 0 3775 - set $64BITS = 0 3776 - end 3777 - 3778 - define 64bits 3779 - set $KDP64BITS = 1 3780 - set $64BITS = 1 3781 - end 3782 - 3783 - define resetkdp 3784 - set $KDP64BITS = -1 3785 - end 3786 - 3787 - define header 3788 - if $argc != 1 3789 - help header 3790 - else 3791 - dump memory /tmp/gdbinit_header_dump $arg0 $arg0 + 4096 3792 - shell /usr/bin/otool -h /tmp/gdbinit_header_dump 3793 - shell /bin/rm -f /tmp/gdbinit_header_dump 3794 - end 3795 - end 3796 - document header 3797 - Syntax: header MACHO_HEADER_START_ADDRESS 3798 - | Dump the Mach-O header located at given address 3799 - end 3800 - 3801 - define loadcmds 3802 - if $argc != 1 3803 - help loadcmds 3804 - else 3805 - # this size should be good enough for most binaries 3806 - dump memory /tmp/gdbinit_header_dump $arg0 $arg0 + 4096 * 10 3807 - shell /usr/bin/otool -l /tmp/gdbinit_header_dump 3808 - shell /bin/rm -f /tmp/gdbinit_header_dump 3809 - end 3810 - end 3811 - document loadcmds 3812 - Syntax: loadcmds MACHO_HEADER_START_ADDRESS 3813 - | Dump the Mach-O load commands 3814 - end 3815 - 3816 - # defining it here doesn't get the space #$#$%"#! 3817 - define disablecolorprompt 3818 - set prompt gdb$ 3819 - end 3820 - document disablecolorprompt 3821 - | Remove color from prompt 3822 - end 3823 - 3824 - define enablecolorprompt 3825 - set prompt \033[31mgdb$ \033[0m 3826 - end 3827 - document enablecolorprompt 3828 - | Enable color prompt 3829 - end 3830 - 3831 - #EOF 3832 - 3833 - # Older change logs: 1193 + # ------------------------------------------------------------------------------ 1194 + # Copyright (c) 2015 Andrea Cardaci <cyrus.and@gmail.com> 3834 1195 # 3835 - # Version 7.4.4 (02/01/2012) 3836 - # - Added the "skip" command. This will jump to the next instruction after EIP/RIP without executing the current one. 3837 - # Thanks to @bSr43 for the tip to retrieve the current instruction size. 3838 - # 3839 - # Version 7.4.3 (04/11/2011) 3840 - # - Modified "hexdump" command to support a variable number of lines (optional parameter) 3841 - # - Removed restrictions on type of addresses in the "dd" command - Thanks to Plouj for the warning :-) 3842 - # I don't know what was the original thinking behind those :-) 3843 - # - Modified the assemble command to support 64bits - You will need to recompile nasm since the version shipped with OS X doesn't supports 64bits (www.nasm.us). 3844 - # Assumes that the new binary is installed at /usr/local/bin - modify the variable at the top if you need so. 3845 - # It will assemble based on the target arch being debugged. If you want to use gdb for a quick asm just use the 32bits or 64bits commands to set your target. 3846 - # Thanks to snare for the warning and original patch :-) 3847 - # - Added "asm" command - it's a shortcut to the "assemble" command. 3848 - # - Added configuration variable for colorized prompt. Plouj reported some issues with Ubuntu's gdb 7.2 if prompt is colorized. 3849 - # 3850 - # Version 7.4.2 (11/08/2011) 3851 - # Small fix to a weird bug happening on FreeBSD 8.2. It doesn't like a "if(" instruction, needs to be "if (". Weird! 3852 - # Many thanks to Evan for reporting and sending the patch :-) 3853 - # Added the ptraceme/rptraceme commands to bypass PTRACE_TRACME anti-debugging technique. 3854 - # Grabbed this from http://falken.tuxfamily.org/?p=171 3855 - # It's commented out due to a gdb problem in OS X (refer to http://reverse.put.as/2011/08/20/another-patch-for-apples-gdb-the-definecommands-problem/ ) 3856 - # Just uncomment it if you want to use in ptrace enabled systems. 3857 - # 3858 - # Version 7.4.1 (21/06/2011) - fG! 3859 - # Added patch sent by sbz, more than 1 year ago, which I forgot to add :-/ 3860 - # This will allow to search for a given pattern between start and end address. 3861 - # On sbz words: "It's usefull to find call, ret or everything like that." :-) 3862 - # New command is "search" 3863 - # 3864 - # Version 7.4 (20/06/2011) - fG! 3865 - # When registers change between instructions the color will change to red (like it happens in OllyDBG) 3866 - # This is the default behavior, if you don't like it, modify the variable SHOWREGCHANGES 3867 - # Added patch sent by Philippe Langlois 3868 - # color the first disassembly line - change the setting below on SETCOLOR1STLINE - by default it's disabled 3869 - # 3870 - # Version 7.3.2 (21/02/2011) - fG! 3871 - # Added the command rint3 and modified the int3 command. The new command will restore the byte in previous int3 patch. 3872 - # 3873 - # Version 7.3.1 (29/06/2010) - fG! 3874 - # Added enablelib/disablelib command to quickly set the stop-on-solib-events trick 3875 - # Implemented the stepoh command equivalent to the stepo but using hardware breakpoints 3876 - # More fixes to stepo 3877 - # 3878 - # Version 7.3 (16/04/2010) - fG! 3879 - # Support for 64bits targets. Default is 32bits, you should modify the variable or use the 32bits or 64bits to choose the mode. 3880 - # I couldn't find another way to recognize the type of binary… Testing the register doesn't work that well. 3881 - # TODO: fix objectivec messages and stepo for 64bits 3882 - # Version 7.2.1 (24/11/2009) - fG! 3883 - # Another fix to stepo (0xFF92 missing) 3884 - # 3885 - # Version 7.2 (11/10/2009) - fG! 3886 - # Added the smallregisters function to create 16 and 8 bit versions from the registers EAX, EBX, ECX, EDX 3887 - # Revised and fixed all the dumpjump stuff, following Intel manuals. There were some errors (thx to rev who pointed the jle problem). 3888 - # Small fix to stepo command (missed a few call types) 3889 - # 3890 - # Version 7.1.7 - fG! 3891 - # Added the possibility to modify what's displayed with the context window. You can change default options at the gdb options part. For example, kernel debugging is much slower if the stack display is enabled... 3892 - # New commands enableobjectivec, enablecpuregisters, enablestack, enabledatawin and their disable equivalents (to support realtime change of default options) 3893 - # Fixed problem with the assemble command. I was calling /bin/echo which doesn't support the -e option ! DUH ! Should have used bash internal version. 3894 - # Small fixes to colors... 3895 - # New commands enablesolib and disablesolib . Just shortcuts for the stop-on-solib-events fantastic trick ! Hey... I'm lazy ;) 3896 - # Fixed this: Possible removal of "u" command, info udot is missing in gdb 6.8-debian . Doesn't exist on OS X so bye bye !!! 3897 - # Displays affected flags in jump decisions 3898 - # 3899 - # Version 7.1.6 - fG! 3900 - # Added modified assemble command from Tavis Ormandy (further modified to work with Mac OS X) (shell commands used use full path name, working for Leopard, modify for others if necessary) 3901 - # Renamed thread command to threads because thread is an internal gdb command that allows to move between program threads 1196 + # Permission is hereby granted, free of charge, to any person obtaining a copy 1197 + # of this software and associated documentation files (the "Software"), to deal 1198 + # in the Software without restriction, including without limitation the rights 1199 + # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 1200 + # copies of the Software, and to permit persons to whom the Software is 1201 + # furnished to do so, subject to the following conditions: 3902 1202 # 3903 - # Version 7.1.5 (04/01/2009) - fG! 3904 - # Fixed crash on Leopard ! There was a If Else condition where the else had no code and that made gdb crash on Leopard (CRAZY!!!!) 3905 - # Better code indention 1203 + # The above copyright notice and this permission notice shall be included in all 1204 + # copies or substantial portions of the Software. 3906 1205 # 3907 - # Version 7.1.4 (02/01/2009) - fG! 3908 - # Bug in show objective c messages with Leopard ??? 3909 - # Nop routine support for single address or range (contribution from gln [ghalen at hack.se]) 3910 - # Used the same code from nop to null routine 3911 - # 3912 - # Version 7.1.3 (31/12/2008) - fG! 3913 - # Added a new command 'stepo'. This command will step a temporary breakpoint on next instruction after the call, so you can skip over 3914 - # the call. Did this because normal commands not always skip over (mainly with objc_msgSend) 3915 - # 3916 - # Version 7.1.2 (31/12/2008) - fG! 3917 - # Support for the jump decision (will display if a conditional jump will be taken or not) 3918 - # 3919 - # Version 7.1.1 (29/12/2008) - fG! 3920 - # Moved gdb options to the beginning (makes more sense) 3921 - # Added support to dump message being sent to msgSend (easier to understand what's going on) 3922 - # 3923 - # Version 7.1 3924 - # Fixed serious (and old) bug in dd and datawin, causing dereference of 3925 - # obviously invalid address. See below: 3926 - # gdb$ dd 0xffffffff 3927 - # FFFFFFFF : Cannot access memory at address 0xffffffff 3928 - # 3929 - # Version 7.0 3930 - # Added cls command. 3931 - # Improved documentation of many commands. 3932 - # Removed bp_alloc, was neither portable nor usefull. 3933 - # Checking of passed argument(s) in these commands: 3934 - # contextsize-stack, contextsize-data, contextsize-code 3935 - # bp, bpc, bpe, bpd, bpt, bpm, bhb,... 3936 - # Fixed bp and bhb inconsistencies, look at * signs in Version 6.2 3937 - # Bugfix in bhb command, changed "break" to "hb" command body 3938 - # Removed $SHOW_CONTEXT=1 from several commands, this variable 3939 - # should only be controlled globally with context-on and context-off 3940 - # Improved stack, func, var and sig, dis, n, go,... 3941 - # they take optional argument(s) now 3942 - # Fixed wrong $SHOW_CONTEXT assignment in context-off 3943 - # Fixed serious bug in cft command, forgotten ~ sign 3944 - # Fixed these bugs in step_to_call: 3945 - # 1) the correct logging sequence is: 3946 - # set logging file > set logging redirect > set logging on 3947 - # 2) $SHOW_CONTEXT is now correctly restored from $_saved_ctx 3948 - # Fixed these bugs in trace_calls: 3949 - # 1) the correct logging sequence is: 3950 - # set logging file > set logging overwrite > 3951 - # set logging redirect > set logging on 3952 - # 2) removed the "clean up trace file" part, which is not needed now, 3953 - # stepi output is properly redirected to /dev/null 3954 - # 3) $SHOW_CONTEXT is now correctly restored from $_saved_ctx 3955 - # Fixed bug in trace_run: 3956 - # 1) $SHOW_CONTEXT is now correctly restored from $_saved_ctx 3957 - # Fixed print_insn_type -- removed invalid semicolons!, wrong value checking, 3958 - # Added TODO entry regarding the "u" command 3959 - # Changed name from gas_assemble to assemble_gas due to consistency 3960 - # Output from assemble and assemble_gas is now similar, because i made 3961 - # both of them to use objdump, with respect to output format (AT&T|Intel). 3962 - # Whole code was checked and made more consistent, readable/maintainable. 3963 - # 3964 - # Version 6.2 3965 - # Add global variables to allow user to control stack, data and code window sizes 3966 - # Increase readability for registers 3967 - # Some corrections (hexdump, ddump, context, cfp, assemble, gas_asm, tips, prompt) 3968 - # 3969 - # Version 6.1-color-user 3970 - # Took the Gentoo route and ran sed s/user/user/g 3971 - # 3972 - # Version 6.1-color 3973 - # Added color fixes from 3974 - # http://gnurbs.blogsome.com/2006/12/22/colorizing-mamons-gdbinit/ 3975 - # 3976 - # Version 6.1 3977 - # Fixed filename in step_to_call so it points to /dev/null 3978 - # Changed location of logfiles from /tmp to ~ 3979 - # 3980 - # Version 6 3981 - # Added print_insn_type, get_insn_type, context-on, context-off commands 3982 - # Added trace_calls, trace_run, step_to_call commands 3983 - # Changed hook-stop so it checks $SHOW_CONTEXT variable 3984 - # 3985 - # Version 5 3986 - # Added bpm, dump_bin, dump_hex, bp_alloc commands 3987 - # Added 'assemble' by elaine, 'gas_asm' by mong 3988 - # Added Tip Topics for aspiring users ;) 3989 - # 3990 - # Version 4 3991 - # Added eflags-changing insns by pusillus 3992 - # Added bp, nop, null, and int3 patch commands, also hook-stop 3993 - # 3994 - # Version 3 3995 - # Incorporated elaine's if/else goodness into the hex/ascii dump 3996 - # 3997 - # Version 2 3998 - # Radix bugfix by elaine 1206 + # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 1207 + # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 1208 + # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 1209 + # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 1210 + # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 1211 + # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 1212 + # SOFTWARE. 1213 + # ------------------------------------------------------------------------------ 1214 + # vi:syntax=python 1215 + # Local Variables: 1216 + # mode: python 1217 + # End:
-2
init.fish
··· 1 - set fish_greeting (fortune zen) 2 - set fish_key_bindings fish_vi_key_bindings
+3 -9
packages.json
··· 6 6 "pathogen.vim": { "type": "curl", "url": "https://tpo.pe/pathogen.vim" } 7 7 }, 8 8 "vim/bundle": { 9 - "airline": { "type": "git", "url": "https://github.com/bling/vim-airline.git" }, 10 9 "bufferline": { "type": "git", "url": "https://github.com/bling/vim-bufferline.git" }, 11 - "bundler": { "type": "git", "url": "https://github.com/tpope/vim-bundler.git" }, 12 10 "commentary": { "type": "git", "url": "https://github.com/tpope/vim-commentary.git" }, 13 11 "delimmate": { "type": "git", "url": "https://github.com/Raimondi/delimitMate.git" }, 14 12 "docker": { "type": "git", "url": "https://github.com/ekalinin/Dockerfile.vim.git" }, 15 - "editorconfig": { "type": "git", "url": "https://github.com/editorconfig/editorconfig-vim.git" }, 16 13 "elixir": { "type": "git", "url": "https://github.com/elixir-lang/vim-elixir.git" }, 17 14 "emmet": { "type": "git", "url": "https://github.com/mattn/emmet-vim.git" }, 18 15 "fish": { "type": "git", "url": "https://github.com/dag/vim-fish.git" }, ··· 20 17 "gitgutter": { "type": "git", "url": "https://github.com/airblade/vim-gitgutter.git" }, 21 18 "gitv": { "type": "git", "url": "https://github.com/gregsexton/gitv.git" }, 22 19 "indent-guides": { "type": "git", "url": "https://github.com/nathanaelkane/vim-indent-guides.git" }, 23 - "latex": { "type": "git", "url": "https://github.com/lervag/vim-latex.git" }, 20 + "lightline": { "type": "git", "url": "https://github.com/itchyny/lightline.vim.git" }, 24 21 "multiple-cursors": { "type": "git", "url": "https://github.com/terryma/vim-multiple-cursors.git" }, 25 22 "numbers": { "type": "git", "url": "https://github.com/myusuf3/numbers.vim.git" }, 26 - "racer": { "type": "git", "url": "https://github.com/phildawes/racer.git", "build": "cargo build --release" }, 27 - "rails": { "type": "git", "url": "https://github.com/tpope/vim-rails.git" }, 28 - "rbenv": { "type": "git", "url": "https://github.com/tpope/vim-rbenv.git" }, 23 + "projectionist": { "type": "git", "url": "https://github.com/tpope/vim-projectionist.git" }, 24 + "racer": { "type": "git", "url": "https://github.com/racer-rust/vim-racer.git" }, 29 25 "repeat": { "type": "git", "url": "https://github.com/tpope/vim-repeat.git" }, 30 26 "rhubarb": { "type": "git", "url": "https://github.com/tpope/vim-rhubarb.git" }, 31 27 "rust": { "type": "git", "url": "https://github.com/rust-lang/rust.vim.git" }, 32 28 "sensible": { "type": "git", "url": "https://github.com/tpope/vim-sensible.git" }, 33 - "slim": { "type": "git", "url": "https://github.com/slim-template/vim-slim.git" }, 34 29 "solarized": { "type": "git", "url": "https://github.com/altercation/vim-colors-solarized.git" }, 35 30 "supertab": { "type": "git", "url": "https://github.com/ervandew/supertab.git" }, 36 31 "surround": { "type": "git", "url": "https://github.com/tpope/vim-surround.git" }, 37 32 "swapit": { "type": "git", "url": "https://github.com/mjbrownie/swapit.git" }, 38 33 "syntastic": { "type": "git", "url": "https://github.com/scrooloose/syntastic.git" }, 39 34 "tabular": { "type": "git", "url": "https://github.com/godlygeek/tabular.git" }, 40 - "tagbar": { "type": "git", "url": "https://github.com/majutsushi/tagbar.git" }, 41 35 "tmux-navigator": { "type": "git", "url": "https://github.com/christoomey/vim-tmux-navigator.git" }, 42 36 "toml": { "type": "git", "url": "https://github.com/cespare/vim-toml.git" }, 43 37 "undotree": { "type": "git", "url": "https://github.com/mbbill/undotree.git" },
+2 -1
tmux.conf
··· 4 4 set -g status on 5 5 set -g status-utf8 on 6 6 set -g status-interval 1 7 + set -g escape-time 0 7 8 8 9 source "$HOME/.tmux/themes/agnoster.tmux" 9 10 ··· 12 13 set-window-option -g utf8 on 13 14 set-option -g status-utf8 on 14 15 15 - set -g default-terminal screen-256color 16 + # set -g default-terminal screen-256color 16 17 17 18 set -g mouse-resize-pane on 18 19 set -g mouse-select-pane on
+1 -1
vim/autoload/pathogen.vim
··· 108 108 function! pathogen#surround(path) abort 109 109 let sep = pathogen#slash() 110 110 let rtp = pathogen#split(&rtp) 111 - let path = fnamemodify(a:path, ':p:?[\\/]\=$??') 111 + let path = fnamemodify(a:path, ':p:s?[\\/]\=$??') 112 112 let before = filter(pathogen#expand(path), '!pathogen#is_disabled(v:val)') 113 113 let after = filter(reverse(pathogen#expand(path.sep.'after')), '!pathogen#is_disabled(v:val[0:-7])') 114 114 call filter(rtp, 'index(before + after, v:val) == -1')
-5
vim/ftplugin/eruby.vim
··· 1 - setlocal omnifunc=rubycomplete#Complete 2 - 3 - let g:rubycomplete_buffer_loading = 0 4 - let g:rubycomplete_rails = 1 5 - let g:rubycomplete_classes_in_global = 1
-6
vim/ftplugin/ruby.vim
··· 1 1 noremap <F9> :w !ruby -cw<CR> 2 2 noremap <F12> :!ripper-tags -f .tags -R . --exclude vendor<CR> 3 3 4 - setlocal omnifunc=rubycomplete#Complete 5 - 6 - let g:rubycomplete_buffer_loading = 0 7 - let g:rubycomplete_rails = 1 8 - let g:rubycomplete_classes_in_global = 1 9 - 10 4 imap ,, => 11 5 12 6 let g:syntastic_ruby_checkers = ['rubocop', 'jruby', 'mri']
-15
vim/plugin/airline.vim
··· 1 - """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" 2 - " => Airline 3 - """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" 4 - " Use Powerline fonts 5 - let g:airline_powerline_fonts = 1 6 - 7 - " Show branch in Airline status bar 8 - let g:airline#extensions#branch#enabled = 1 9 - let g:airline#extensions#branch#empty_message = '×' 10 - 11 - " Show syntax errors 12 - let g:airline#extensions#syntastic#enabled = 1 13 - 14 - " Work with Tagbar 15 - let g:airline#extensions#tagbar#enabled = 1
+3 -1
vim/plugin/bufferline.vim
··· 1 - let g:bufferline_modified = '+' 1 + let g:bufferline_echo = 0 2 + " let g:bufferline_active_buffer_left = '' 3 + " let g:bufferline_active_buffer_right = ''
+115
vim/plugin/lightline.vim
··· 1 + let g:lightline = { 2 + \ 'colorscheme': 'solarized_dark', 3 + \ 'active': { 4 + \ 'left': [ 5 + \ [ 'mode', 'paste' ], 6 + \ [ 'fugitive', 'filename' ], 7 + \ [ 'bufferline' ], 8 + \ ], 9 + \ 'right': [ 10 + \ [ 'syntastic', 'lineinfo' ], 11 + \ [ 'percent' ], 12 + \ [ 'fileformat', 'fileencoding', 'filetype' ] 13 + \ ] 14 + \ }, 15 + \ 'enable': { 16 + \ 'statusline': 1, 17 + \ 'tabline': 1, 18 + \ }, 19 + \ 'component_function': { 20 + \ 'modified': 'LightLineModified', 21 + \ 'readonly': 'LightLineReadonly', 22 + \ 'fugitive': 'LightLineFugitive', 23 + \ 'filename': 'LightLineFilename', 24 + \ 'fileformat': 'LightLineFileformat', 25 + \ 'filetype': 'LightLineFiletype', 26 + \ 'fileencoding': 'LightLineFileencoding', 27 + \ 'bufferline': 'LightLineBufferline', 28 + \ 'mode': 'LightLineMode', 29 + \ }, 30 + \ 'component': { 31 + \ 'lineinfo': '%3l:%-2v', 32 + \ }, 33 + \ 'component_expand': { 34 + \ 'syntastic': 'SyntasticStatuslineFlag', 35 + \ }, 36 + \ 'component_type': { 37 + \ 'syntastic': 'error', 38 + \ }, 39 + \ 'separator': { 'left': '', 'right': '' }, 40 + \ 'subseparator': { 'left': '', 'right': '' } 41 + \ } 42 + 43 + function! LightLineModified() 44 + return &ft =~ 'help\|undotree' ? '' : &modified ? '+' : &modifiable ? '' : '-' 45 + endfunction 46 + 47 + function! LightLineReadonly() 48 + return &ft !~? 'help\|undotree' && &readonly ? '' : '' 49 + endfunction 50 + 51 + function! LightLineFilename() 52 + let fname = expand('%:t') 53 + return fname =~ 'undotree' ? '' : 54 + \ &ft == 'unite' ? unite#get_status_string() : 55 + \ ('' != LightLineReadonly() ? LightLineReadonly() . ' ' : '') . 56 + \ ('' != fname ? fname : '[No Name]') . 57 + \ ('' != LightLineModified() ? ' ' . LightLineModified() : '') 58 + endfunction 59 + 60 + function! LightLineFugitive() 61 + if &ft !~? 'undotree' && exists("*fugitive#head") 62 + let _ = fugitive#head() 63 + return strlen(_) ? ' '._ : '' 64 + endif 65 + return '' 66 + endfunction 67 + 68 + function! LightLineBufferline() 69 + if &ft !~? 'undotree' 70 + call bufferline#refresh_status() 71 + let b = g:bufferline_status_info.before 72 + let c = g:bufferline_status_info.current 73 + let a = g:bufferline_status_info.after 74 + let alen = strlen(a) 75 + let blen = strlen(b) 76 + let clen = strlen(c) 77 + let w = winwidth(0) * 4 / 11 78 + if w < alen+blen+clen 79 + let whalf = (w - strlen(c)) / 2 80 + let aa = alen > whalf && blen > whalf ? a[:whalf] : alen + blen < w - clen || alen < whalf ? a : a[:(w - clen - blen)] 81 + let bb = alen > whalf && blen > whalf ? b[-(whalf):] : alen + blen < w - clen || blen < whalf ? b : b[-(w - clen - alen):] 82 + return (strlen(bb) < strlen(b) ? '...' : '') . bb . c . aa . (strlen(aa) < strlen(a) ? '...' : '') 83 + else 84 + return b . c . a 85 + endif 86 + endif 87 + return '' 88 + endfunction 89 + 90 + function! LightLineFileformat() 91 + return winwidth(0) > 70 ? &fileformat : '' 92 + endfunction 93 + 94 + function! LightLineFiletype() 95 + return winwidth(0) > 70 ? (strlen(&filetype) ? &filetype : 'no ft') : '' 96 + endfunction 97 + 98 + function! LightLineFileencoding() 99 + return winwidth(0) > 70 ? (strlen(&fenc) ? &fenc : &enc) : '' 100 + endfunction 101 + 102 + function! LightLineMode() 103 + return winwidth(0) > 60 ? lightline#mode() : '' 104 + endfunction 105 + 106 + augroup AutoSyntastic 107 + autocmd! 108 + autocmd BufWritePost * call s:syntastic() 109 + augroup END 110 + function! s:syntastic() 111 + SyntasticCheck 112 + call lightline#update() 113 + endfunction 114 + 115 + let g:unite_force_overwrite_statusline = 0
-10
vim/plugin/screenfix.vim
··· 1 - """""""""""""" 2 - " tmux fixes " 3 - """""""""""""" 4 - " Handle tmux $TERM quirks in vim 5 - if $TERM =~ '^screen-256color' 6 - map <Esc>OH <Home> 7 - map! <Esc>OH <Home> 8 - map <Esc>OF <End> 9 - map! <Esc>OF <End> 10 - endif
-6
vim/plugin/tagbar.vim
··· 1 - """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" 2 - " => Tagbar 3 - """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" 4 - let g:tagbar_userarrows = 1 5 - 6 - nnoremap <F10> :TagbarToggle<CR>
-6
vim/plugin/tmux.vim
··· 5 5 nnoremap <silent> <C-j> :TmuxNavigateDown<cr> 6 6 nnoremap <silent> <C-l> :TmuxNavigateRight<cr> 7 7 nnoremap <silent> <C-\> :TmuxNavigatePrevious<cr> 8 - 9 - noremap <leader>vl :VimuxRunLastCommand<CR> 10 - noremap <leader>vi :VimuxInspectPanel<CR> 11 - noremap <leader>vq :VimuxCloseRunner<CR> 12 - noremap <leader>vx :VimuxInterruptRunner<CR> 13 - noremap <leader>vz :call VimuxZoomRunner()<CR>
-2
vim/plugin/unite.vim
··· 2 2 call unite#custom#source('buffer,file,file_rec', 'sorters', 'sorter_selecta') 3 3 4 4 let g:unite_split_rule = "botright" 5 - let g:unite_force_overwrite_statusline = 1 6 - " let g:unite_winheight = 10 7 5 8 6 let g:unite_prompt = '» ' 9 7
+8
vim/plugin/vimux.vim
··· 1 + let g:VimuxOrientation = 'h' 2 + let g:VimuxHeight = '40' 3 + 4 + noremap <leader>vl :VimuxRunLastCommand<CR> 5 + noremap <leader>vi :VimuxInspectPanel<CR> 6 + noremap <leader>vq :VimuxCloseRunner<CR> 7 + noremap <leader>vx :VimuxInterruptRunner<CR> 8 + noremap <leader>vz :call VimuxZoomRunner()<CR>
+51 -100
vimrc
··· 1 - " Infect Vim with pathogen 1 + " vim:foldmethod=marker:foldlevel=0:foldenable 2 + 3 + " Pathogen {{{ 2 4 call pathogen#infect() 3 5 call pathogen#helptags() 6 + " }}} 7 + " Colors {{{ 8 + " Show 80 column 9 + set colorcolumn=80 10 + set cursorline 4 11 5 - set nocompatible 6 - 7 - " Enable per-directory .vimrc files 12 + " Use Dark Solarized theme 13 + set background=dark 14 + let g:solarized_termtrans=1 15 + colorscheme solarized 16 + " }}} 17 + " Per directory .nvimrc {{{ 8 18 set exrc 9 19 " Disable unsafe commands in local .vimrc 10 20 set secure 11 - 12 - """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" 13 - " => VIM user interface 14 - """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" 15 - " Set 7 lines to the cursor - when moving vertically using j/k 16 - set so=7 17 - 21 + " }}} 22 + " User interface {{{ 18 23 " Ignore all automatic files and folders 19 24 set wildignore=*.o,*~,*.pyc,.git,*/tmp/* 20 25 21 - " Height of the command bar 22 - set cmdheight=1 26 + " Display tabs and trailing spaces visually 27 + set list listchars=tab:→\ ,trail:· 23 28 24 - " Ignore case when searching 29 + " Smart case searches 25 30 set ignorecase 26 - 27 - " When searching try to be smart about cases 28 31 set smartcase 29 32 30 - " Highlight search results 33 + " Better search 31 34 set hlsearch 32 - 33 - " Don't redraw while executing macros (good performance config) 34 - set lazyredraw 35 - 36 - " For regular expressions turn magic on 37 35 set magic 38 36 39 37 " Line numbers are good 40 38 set number 41 39 42 - " Allow backspace in insert mode 43 - set whichwrap+=<,>,h,l 44 - 45 40 " Show current mode down the bottom 46 - set showmode 47 - 48 - " Disable cursor blink 49 - set gcr=a:blinkon0 50 - 51 - " No annoying sound on errors 52 - set noerrorbells 53 - set novisualbell 54 - set t_vb= 55 - 56 - " Use mouse 57 - set mouse=a 58 - 59 - " Use tabs instead of buffers 60 - " set switchbuf=usetab,newtab 61 - 62 - " Use system clipboard as default 63 - " set clipboard+=unnamedplus 64 - 65 - " Set fold method 66 - set foldmethod=syntax "fold based on indent 67 - set foldnestmax=10 "deepest fold is 10 levels 68 - set nofoldenable "dont fold by default 69 - set foldlevel=1 "this is just what i use 70 - 71 - """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" 72 - " => Colors 73 - """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" 74 - " Turn on syntax highlighting 75 - syntax on 76 - 77 - " Show 80 column 78 - set colorcolumn=80 79 - 80 - " Use Dark Solarized theme 81 - set background=dark 82 - let g:solarized_termtrans=1 83 - colorscheme solarized 41 + set noshowmode 84 42 85 43 " Set utf8 as standard encoding and en_US as the standard language 86 44 set encoding=utf8 87 45 46 + " Shorten interruptive command output 47 + set shortmess=atI 48 + 88 49 " This makes vim act like all other editors, buffers can 89 50 " exist in the background without being in a window. 90 - " http://items.sjbach.com/319/configuring-vim-right 91 51 set hidden 92 - 93 - """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" 94 - " => Files, backups and undo 95 - """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" 52 + " }}} 53 + " Files, backups and undo {{{ 96 54 " Turn backup off, since most stuff is in SVN, git et.c anyway... 97 55 set nobackup 98 56 set nowb ··· 100 58 101 59 " Keep undo history across sessions, by storing in file. 102 60 " Only works all the time. 103 - silent !mkdir ~/.vim/backups > /dev/null 2>&1 104 - set undodir=~/.vim/backups 61 + silent !mkdir -p ~/.backups > /dev/null 2>&1 62 + set undodir=~/.backups 105 63 set undofile 106 - 107 - """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" 108 - " => Identation 109 - """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" 64 + " }}} 65 + " Identation and folding {{{ 110 66 set smartindent 111 67 set shiftwidth=2 112 68 set softtabstop=2 ··· 115 71 au FileType Makefile set noexpandtab 116 72 au FileType snippet set noexpandtab 117 73 118 - " Display tabs and trailing spaces visually 119 - set list listchars=tab:→\ ,trail:· 120 - 74 + set textwidth=80 121 75 set nowrap " Don't wrap lines 122 - set linebreak " Wrap lines at convenient points 76 + set linebreak " Break lines at convenient points 77 + set formatoptions+=t 123 78 124 - set foldnestmax=3 " Deepest fold is 3 levels 125 - set nofoldenable " Don't fold by default 79 + " Set fold method 80 + set foldmethod=syntax 81 + set foldlevel=3 82 + set foldnestmax=5 83 + " }}} 84 + " Key mappings {{{ 85 + let mapleader = ',' 126 86 127 - """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" 128 - " => Key mappings 129 - """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" 130 - let mapleader = ',' 87 + " Swap 'go to marger' mappings 88 + nnoremap ' ` 89 + nnoremap ` ' 131 90 132 91 " FuzzySearch 133 92 nnoremap <silent> <C-p> :Unite -start-insert -buffer-name=files file_rec/async<CR> 134 - nnoremap <silent> <space>/ :Ag<CR> 135 - 136 - " Tabs 137 - noremap <silent> <F7> :tabprev<CR> 138 - noremap <silent> <F8> :tabnext<CR> 139 - noremap <silent> <leader>tn :tabnew<CR> 140 - noremap <silent> <leader>tc :tabclose<CR> 93 + nnoremap <silent> <leader>/ :Ag<CR> 141 94 142 95 " Buffers 143 96 noremap <F5> :bprev<CR> ··· 147 100 " Formatting and cleaning 148 101 noremap <leader>ff mzgg=G`z<CR> 149 102 noremap <leader>fc :Clean<CR> 103 + 104 + nnoremap gV `[v`] 150 105 151 106 " Closing 152 107 nnoremap ZS :xa<CR> ··· 188 143 noremap <leader>gst :Gstatus<CR> 189 144 noremap <leader>gci :Gcommit<CR> 190 145 noremap <leader>gd :Gdiff<CR> 191 - 192 - """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" 193 - " => Extras 194 - """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" 146 + " }}} 147 + " Extras {{{ 195 148 let g:markdown_extensions=["md", "markdown"] 196 149 let g:gist_clip_command = 'xsel -bi' 197 150 let g:AutoCloseProtectedRegions = ["Comment", "String", "Character"] 198 - 199 - """""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" 200 - " => Extra commands 201 - """""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" 202 - 151 + " }}} 152 + " Extra commands {{{ 203 153 command! Ag Unite -auto-preview -no-split -buffer-name=Ag grep:. 204 154 205 155 " Remove all trailing whitespaces ··· 207 157 208 158 " Save as root 209 159 command! W w !sudo tee % > /dev/null 160 + " }}}