You've already forked mariadb-columnstore-engine
							
							
				mirror of
				https://github.com/mariadb-corporation/mariadb-columnstore-engine.git
				synced 2025-10-30 07:25:34 +03:00 
			
		
		
		
	
		
			
				
	
	
		
			3830 lines
		
	
	
		
			103 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
			
		
		
	
	
			3830 lines
		
	
	
		
			103 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
| # INSTALL INSTRUCTIONS: save as ~/.gdbinit
 | |
| #
 | |
| # DESCRIPTION: A user-friendly gdb configuration file, for x86/x86_64 and ARM platforms.
 | |
| #
 | |
| # REVISION : 9.01 (31/03/2024)
 | |
| #
 | |
| # CONTRIBUTORS: mammon_, elaine, pusillus, mong, zhang le, l0kit,
 | |
| #               truthix the cyberpunk, fG!, gln
 | |
| #
 | |
| # LICENSE: No idea about original authors, I guess it's public domain (at least all my changes are public domain)
 | |
| #
 | |
| # FEEDBACK: https://reverse.put.as - reverser@put.as
 | |
| # GITHUB: https://github.com/gdbinit/Gdbinit
 | |
| #
 | |
| # NOTES: 'help user' in gdb will list the commands/descriptions in this file
 | |
| #        'context on' now enables auto-display of context screen
 | |
| #
 | |
| # MAC OS X NOTES: If you are using this on Mac OS X, you must either attach gdb to a process
 | |
| #                 or launch gdb without any options and then load the binary file you want to analyse with "exec-file" option
 | |
| #                 If you load the binary from the command line, like $gdb binary-name, this will not work as it should
 | |
| #                 For more information, read it here https://reverse.put.as/2008/11/28/apples-gdb-bug/
 | |
| #
 | |
| # UPDATE: This bug can be fixed in gdb source. Refer to https://reverse.put.as/2009/08/10/fix-for-apples-gdb-bug-or-why-apple-forks-are-bad/
 | |
| #         and https://reverse.put.as/2009/08/26/gdb-patches/ (if you want the fixed binary for i386)
 | |
| #
 | |
| #         An updated version of the patch and binary is available at https://reverse.put.as/2011/02/21/update-to-gdb-patches-fix-a-new-bug/
 | |
| #
 | |
| # iOS NOTES: iOS gdb from Cydia (and Apple's) suffer from the same OS X bug.
 | |
| #			 If you are using this on Mac OS X or iOS, you must either attach gdb to a process
 | |
| #            or launch gdb without any options and then load the binary file you want to analyse with "exec-file" option
 | |
| #            If you load the binary from the command line, like $gdb binary-name, this will not work as it should
 | |
| #            For more information, read it here https://reverse.put.as/2008/11/28/apples-gdb-bug/
 | |
| #
 | |
| # RECENT CHANGELOG:
 | |
| #
 | |
| #   Version 9.0
 | |
| #     Fixes to make everything work with GNU/GDB 8.3+
 | |
| #
 | |
| #   Version 9.01
 | |
| #     Revert the ascii code changes (not working on gdb 12)
 | |
| #     Fix the remaining tabs mess
 | |
| #
 | |
| #   TODO:
 | |
| #
 | |
| 
 | |
| # __________________gdb options_________________
 | |
| 
 | |
| # set to 1 to have ARM target debugging as default, use the "arm" command to switch inside gdb
 | |
| set $ARM = 0
 | |
| # set to 0 if you have problems with the colorized prompt - reported by Plouj with Ubuntu gdb 7.2
 | |
| set $COLOREDPROMPT = 1
 | |
| # color the first line of the disassembly - default is green, if you want to change it search for
 | |
| # SETCOLOR1STLINE and modify it :-)
 | |
| set $SETCOLOR1STLINE = 0
 | |
| # set to 0 to remove disassembly display (useful for scripted commands mass dumping)
 | |
| set $SHOWDISASM = 1
 | |
| # set to 0 to remove display of objectivec messages (default is 1)
 | |
| set $SHOWOBJECTIVEC = 1
 | |
| # set to 0 to remove display of cpu registers (default is 1)
 | |
| set $SHOWCPUREGISTERS = 1
 | |
| # set to 1 to enable display of stack (default is 0)
 | |
| set $SHOWSTACK = 0
 | |
| # set to 1 to enable display of data window (default is 0)
 | |
| set $SHOWDATAWIN = 0
 | |
| # set to 0 to disable colored display of changed registers
 | |
| set $SHOWREGCHANGES = 1
 | |
| # set to 1 so skip command to execute the instruction at the new location
 | |
| # by default it EIP/RIP will be modified and update the new context but not execute the instruction
 | |
| set $SKIPEXECUTE = 0
 | |
| # if $SKIPEXECUTE is 1 configure the type of execution
 | |
| # 1 = use stepo (do not get into calls), 0 = use stepi (step into calls)
 | |
| set $SKIPSTEP = 1
 | |
| # show the ARM opcodes - change to 0 if you don't want such thing (in x/i command)
 | |
| set $ARMOPCODES = 0
 | |
| # x86 disassembly flavor: 0 for Intel, 1 for AT&T
 | |
| set $X86FLAVOR = 0
 | |
| # use colorized output or not
 | |
| set $USECOLOR = 1
 | |
| # to use with remote KDP
 | |
| set $KDP64BITS = -1
 | |
| set $64BITS = 0
 | |
| 
 | |
| # macOS version works better with this setting off
 | |
| set startup-with-shell off
 | |
| 
 | |
| set confirm off
 | |
| set verbose off
 | |
| set history filename ~/.gdb_history
 | |
| set history save
 | |
| 
 | |
| set output-radix 0x10
 | |
| set input-radix 0x10
 | |
| 
 | |
| # These make gdb never pause in its output
 | |
| set height 0
 | |
| set width 0
 | |
| 
 | |
| set $SHOW_CONTEXT = 1
 | |
| set $SHOW_NEST_INSN = 0
 | |
| 
 | |
| set $CONTEXTSIZE_STACK = 6
 | |
| set $CONTEXTSIZE_DATA  = 8
 | |
| set $CONTEXTSIZE_CODE  = 8
 | |
| 
 | |
| # __________________end gdb options_________________
 | |
| #
 | |
| 
 | |
| # __________________color functions_________________
 | |
| #
 | |
| # color codes
 | |
| set $BLACK = 0
 | |
| set $RED = 1
 | |
| set $GREEN = 2
 | |
| set $YELLOW = 3
 | |
| set $BLUE = 4
 | |
| set $MAGENTA = 5
 | |
| set $CYAN = 6
 | |
| set $WHITE = 7
 | |
| 
 | |
| # CHANGME: If you want to modify the "theme" change the colors here
 | |
| #          or just create a ~/.gdbinit.local and set these variables there
 | |
| set $COLOR_REGNAME = $GREEN
 | |
| set $COLOR_REGVAL = $BLACK
 | |
| set $COLOR_REGVAL_MODIFIED  = $RED
 | |
| set $COLOR_SEPARATOR = $BLUE
 | |
| set $COLOR_CPUFLAGS = $RED
 | |
| 
 | |
| # this is ugly but there's no else if available :-(
 | |
| define color
 | |
|  if $USECOLOR == 1
 | |
|     # BLACK
 | |
|     if $arg0 == 0
 | |
|         echo \033[30m
 | |
|     else
 | |
|         # RED
 | |
|         if $arg0 == 1
 | |
|             echo \033[31m
 | |
|         else
 | |
|             # GREEN
 | |
|             if $arg0 == 2
 | |
|                 echo \033[32m
 | |
|             else
 | |
|                 # YELLOW
 | |
|                 if $arg0 == 3
 | |
|                     echo \033[33m
 | |
|                 else
 | |
|                     # BLUE
 | |
|                     if $arg0 == 4
 | |
|                         echo \033[34m
 | |
|                     else
 | |
|                         # MAGENTA
 | |
|                         if $arg0 == 5
 | |
|                             echo \033[35m
 | |
|                         else
 | |
|                             # CYAN
 | |
|                             if $arg0 == 6
 | |
|                                 echo \033[36m
 | |
|                             else
 | |
|                                 # WHITE
 | |
|                                 if $arg0 == 7
 | |
|                                     echo \033[37m
 | |
|                                 end
 | |
|                             end
 | |
|                         end
 | |
|                     end
 | |
|                 end
 | |
|             end
 | |
|         end
 | |
|     end
 | |
|  end
 | |
| end
 | |
| 
 | |
| define color_reset
 | |
|     if $USECOLOR == 1
 | |
|         echo \033[0m
 | |
|     end
 | |
| end
 | |
| 
 | |
| define color_bold
 | |
|     if $USECOLOR == 1
 | |
|         echo \033[1m
 | |
|        #echo \[\e[1m\]
 | |
|     end
 | |
| end
 | |
| 
 | |
| define color_underline
 | |
|     if $USECOLOR == 1
 | |
|         echo \033[4m
 | |
|     end
 | |
| end
 | |
| 
 | |
| # create ~/.gdbinit.local if file not present
 | |
| # suppresses any warning about not finding the file
 | |
| shell if ! test -f ~/.gdbinit.local; then touch ~/.gdbinit.local; fi
 | |
| 
 | |
| # this way anyone can have their custom prompt - argp's idea :-)
 | |
| # can also be used to redefine anything else in particular the colors aka theming
 | |
| # just remap the color variables defined above
 | |
| source ~/.gdbinit.local
 | |
| 
 | |
| # can't use the color functions because we are using the set command
 | |
| if $COLOREDPROMPT == 1
 | |
|     set extended-prompt \[\e[0;31m\]gdb$ \[\e[0m\]
 | |
| end
 | |
| 
 | |
| # Initialize these variables else comparisons will fail for coloring
 | |
| # we must initialize all of them at once, 32 and 64 bits, and ARM.
 | |
| set $oldrax = 0
 | |
| set $oldrbx = 0
 | |
| set $oldrcx = 0
 | |
| set $oldrdx = 0
 | |
| set $oldrsi = 0
 | |
| set $oldrdi = 0
 | |
| set $oldrbp = 0
 | |
| set $oldrsp = 0
 | |
| set $oldr8  = 0
 | |
| set $oldr9  = 0
 | |
| set $oldr10 = 0
 | |
| set $oldr11 = 0
 | |
| set $oldr12 = 0
 | |
| set $oldr13 = 0
 | |
| set $oldr14 = 0
 | |
| set $oldr15 = 0
 | |
| set $oldeax = 0
 | |
| set $oldebx = 0
 | |
| set $oldecx = 0
 | |
| set $oldedx = 0
 | |
| set $oldesi = 0
 | |
| set $oldedi = 0
 | |
| set $oldebp = 0
 | |
| set $oldesp = 0
 | |
| set $oldr0  = 0
 | |
| set $oldr1  = 0
 | |
| set $oldr2  = 0
 | |
| set $oldr3  = 0
 | |
| set $oldr4  = 0
 | |
| set $oldr5  = 0
 | |
| set $oldr6  = 0
 | |
| set $oldr7  = 0
 | |
| set $oldsp  = 0
 | |
| set $oldlr  = 0
 | |
| 
 | |
| # used by ptraceme/rptraceme
 | |
| set $ptrace_bpnum = 0
 | |
| 
 | |
| # ______________window size control___________
 | |
| define contextsize-stack
 | |
|     if $argc != 1
 | |
|         help contextsize-stack
 | |
|     else
 | |
|         set $CONTEXTSIZE_STACK = $arg0
 | |
|     end
 | |
| end
 | |
| document contextsize-stack
 | |
| Syntax: contextsize-stack NUM
 | |
| | Set stack dump window size to NUM lines.
 | |
| end
 | |
| 
 | |
| 
 | |
| define contextsize-data
 | |
|     if $argc != 1
 | |
|         help contextsize-data
 | |
|     else
 | |
|         set $CONTEXTSIZE_DATA = $arg0
 | |
|     end
 | |
| end
 | |
| document contextsize-data
 | |
| Syntax: contextsize-data NUM
 | |
| | Set data dump window size to NUM lines.
 | |
| end
 | |
| 
 | |
| 
 | |
| define contextsize-code
 | |
|     if $argc != 1
 | |
|         help contextsize-code
 | |
|     else
 | |
|         set $CONTEXTSIZE_CODE = $arg0
 | |
|     end
 | |
| end
 | |
| document contextsize-code
 | |
| Syntax: contextsize-code NUM
 | |
| | Set code window size to NUM lines.
 | |
| end
 | |
| 
 | |
| 
 | |
| # _____________breakpoint aliases_____________
 | |
| define bpl
 | |
|     info breakpoints
 | |
| end
 | |
| document bpl
 | |
| Syntax: bpl
 | |
| | List all breakpoints.
 | |
| end
 | |
| 
 | |
| 
 | |
| define bp
 | |
|     if $argc != 1
 | |
|         help bp
 | |
|     else
 | |
|         if $ASLR != 0
 | |
|             break ($arg0 + $ASLR)
 | |
|         else
 | |
|             break $arg0
 | |
|         end
 | |
|     end
 | |
| end
 | |
| document bp
 | |
| Syntax: bp LOCATION
 | |
| | Set breakpoint.
 | |
| | LOCATION may be a line number, function name, or "*" and an address.
 | |
| | To break on a symbol you must enclose symbol name inside "".
 | |
| | Example:
 | |
| | bp "[NSControl stringValue]"
 | |
| | Or else you can use directly the break command (break [NSControl stringValue])
 | |
| end
 | |
| 
 | |
| 
 | |
| define bpc 
 | |
|     if $argc != 1
 | |
|         help bpc
 | |
|     else
 | |
|         clear $arg0
 | |
|     end
 | |
| end
 | |
| document bpc
 | |
| Syntax: bpc LOCATION
 | |
| | Clear breakpoint.
 | |
| | LOCATION may be a line number, function name, or "*" and an address.
 | |
| end
 | |
| 
 | |
| 
 | |
| define bpe
 | |
|     if $argc != 1
 | |
|         help bpe
 | |
|     else
 | |
|         enable $arg0
 | |
|     end
 | |
| end
 | |
| document bpe
 | |
| Syntax: bpe NUM
 | |
| | Enable breakpoint with number NUM.
 | |
| end
 | |
| 
 | |
| 
 | |
| define bpd
 | |
|     if $argc != 1
 | |
|         help bpd
 | |
|     else
 | |
|         disable $arg0
 | |
|     end
 | |
| end
 | |
| document bpd
 | |
| Syntax: bpd NUM
 | |
| | Disable breakpoint with number NUM.
 | |
| end
 | |
| 
 | |
| 
 | |
| define bpt
 | |
|     if $argc != 1
 | |
|         help bpt
 | |
|     else
 | |
|         tbreak $arg0
 | |
|     end
 | |
| end
 | |
| document bpt
 | |
| Syntax: bpt LOCATION
 | |
| | Set a temporary breakpoint.
 | |
| | This breakpoint will be automatically deleted when hit!.
 | |
| | LOCATION may be a line number, function name, or "*" and an address.
 | |
| end
 | |
| 
 | |
| 
 | |
| define bpm
 | |
|     if $argc != 1
 | |
|         help bpm
 | |
|     else
 | |
|         awatch $arg0
 | |
|     end
 | |
| end
 | |
| document bpm
 | |
| Syntax: bpm EXPRESSION
 | |
| | Set a read/write breakpoint on EXPRESSION, e.g. *address.
 | |
| end
 | |
| 
 | |
| 
 | |
| define bhb
 | |
|     if $argc != 1
 | |
|         help bhb
 | |
|     else
 | |
|         hb $arg0
 | |
|     end
 | |
| end
 | |
| document bhb
 | |
| Syntax: bhb LOCATION
 | |
| | Set hardware assisted breakpoint.
 | |
| | LOCATION may be a line number, function name, or "*" and an address.
 | |
| end
 | |
| 
 | |
| 
 | |
| define bht
 | |
|     if $argc != 1
 | |
|         help bht
 | |
|     else
 | |
|         thbreak $arg0
 | |
|     end
 | |
| end
 | |
| document bht
 | |
| Usage: bht LOCATION
 | |
| | Set a temporary hardware breakpoint.
 | |
| | This breakpoint will be automatically deleted when hit!
 | |
| | LOCATION may be a line number, function name, or "*" and an address.
 | |
| end
 | |
| 
 | |
| 
 | |
| # ______________process information____________
 | |
| define argv
 | |
|     show args
 | |
| end
 | |
| document argv
 | |
| Syntax: argv
 | |
| | Print program arguments.
 | |
| end
 | |
| 
 | |
| 
 | |
| define stack
 | |
|     if $argc == 0
 | |
|         info stack
 | |
|     end
 | |
|     if $argc == 1
 | |
|         info stack $arg0
 | |
|     end
 | |
|     if $argc > 1
 | |
|         help stack
 | |
|     end
 | |
| end
 | |
| document stack
 | |
| Syntax: stack <COUNT>
 | |
| | Print backtrace of the call stack, or innermost COUNT frames.
 | |
| end
 | |
| 
 | |
| 
 | |
| define frame
 | |
|     info frame
 | |
|     info args
 | |
|     info locals
 | |
| end
 | |
| document frame
 | |
| Syntax: frame
 | |
| | Print stack frame.
 | |
| end
 | |
| 
 | |
| 
 | |
| define flagsarm
 | |
| # conditional flags are
 | |
| # negative/less than (N), bit 31 of CPSR
 | |
| # zero (Z), bit 30
 | |
| # Carry/Borrow/Extend (C), bit 29
 | |
| # Overflow (V), bit 28
 | |
|     # negative/less than (N), bit 31 of CPSR
 | |
|     if (($cpsr >> 0x1f) & 1)
 | |
|         printf "N "
 | |
|         set $_n_flag = 1
 | |
|     else
 | |
|         printf "n "
 | |
|         set $_n_flag = 0
 | |
|     end
 | |
|     # zero (Z), bit 30
 | |
|     if (($cpsr >> 0x1e) & 1)
 | |
|         printf "Z "
 | |
|         set $_z_flag = 1
 | |
|     else
 | |
|         printf "z "
 | |
|         set $_z_flag = 0
 | |
|     end
 | |
|     # Carry/Borrow/Extend (C), bit 29
 | |
|     if (($cpsr >> 0x1d) & 1)
 | |
|         printf "C "
 | |
|         set $_c_flag = 1
 | |
|     else
 | |
|         printf "c "
 | |
|         set $_c_flag = 0
 | |
|     end
 | |
|     # Overflow (V), bit 28
 | |
|     if (($cpsr >> 0x1c) & 1)
 | |
|         printf "V "
 | |
|         set $_v_flag = 1
 | |
|     else
 | |
|         printf "v "
 | |
|         set $_v_flag = 0
 | |
|     end
 | |
|     # Sticky overflow (Q), bit 27    
 | |
|     if (($cpsr >> 0x1b) & 1)
 | |
|         printf "Q "
 | |
|         set $_q_flag = 1
 | |
|     else
 | |
|         printf "q "
 | |
|         set $_q_flag = 0
 | |
|     end
 | |
|     # Java state bit (J), bit 24
 | |
|     # When T=1:
 | |
|     # J = 0 The processor is in Thumb state.
 | |
|     # J = 1 The processor is in ThumbEE state.
 | |
|     if (($cpsr >> 0x18) & 1)
 | |
|         printf "J "
 | |
|         set $_j_flag = 1
 | |
|     else
 | |
|         printf "j "
 | |
|         set $_j_flag = 0
 | |
|     end
 | |
|     # Data endianness bit (E), bit 9
 | |
|     if (($cpsr >> 9) & 1)
 | |
|         printf "E "
 | |
|         set $_e_flag = 1
 | |
|     else
 | |
|         printf "e "
 | |
|         set $_e_flag = 0
 | |
|     end
 | |
|     # Imprecise abort disable bit (A), bit 8
 | |
|     # The A bit is set to 1 automatically. It is used to disable imprecise data aborts. 
 | |
|     # It might not be writable in the Nonsecure state if the AW bit in the SCR register is reset.
 | |
|     if (($cpsr >> 8) & 1)
 | |
|         printf "A "
 | |
|         set $_a_flag = 1
 | |
|     else
 | |
|         printf "a "
 | |
|         set $_a_flag = 0
 | |
|     end
 | |
|     # IRQ disable bit (I), bit 7
 | |
|     # When the I bit is set to 1, IRQ interrupts are disabled.
 | |
|     if (($cpsr >> 7) & 1)
 | |
|         printf "I "
 | |
|         set $_i_flag = 1
 | |
|     else
 | |
|         printf "i "
 | |
|         set $_i_flag = 0
 | |
|     end
 | |
|     # FIQ disable bit (F), bit 6
 | |
|     # When the F bit is set to 1, FIQ interrupts are disabled. 
 | |
|     # FIQ can be nonmaskable in the Nonsecure state if the FW bit in SCR register is reset.
 | |
|     if (($cpsr >> 6) & 1)
 | |
|         printf "F "
 | |
|         set $_f_flag = 1
 | |
|     else
 | |
|         printf "f "
 | |
|         set $_f_flag = 0
 | |
|     end
 | |
|     # Thumb state bit (F), bit 5
 | |
|     # if 1 then the processor is executing in Thumb state or ThumbEE state depending on the J bit
 | |
|     if (($cpsr >> 5) & 1)
 | |
|         printf "T "
 | |
|         set $_t_flag = 1
 | |
|     else
 | |
|         printf "t "
 | |
|         set $_t_flag = 0
 | |
|     end
 | |
|     # TODO: GE bit ?
 | |
| end
 | |
| document flagsarm
 | |
| Syntax: flagsarm
 | |
| | Auxiliary function to set ARM cpu flags.
 | |
| end
 | |
| 
 | |
| 
 | |
| define flagsx86
 | |
|     # OF (overflow) flag
 | |
|     if (((unsigned int)$eflags >> 0xB) & 1)
 | |
|         printf "O "
 | |
|         set $_of_flag = 1
 | |
|     else
 | |
|         printf "o "
 | |
|         set $_of_flag = 0
 | |
|     end
 | |
|     # DF (direction) flag
 | |
|     if (((unsigned int)$eflags >> 0xA) & 1)
 | |
|         printf "D "
 | |
|     else
 | |
|         printf "d "
 | |
|     end
 | |
|     # IF (interrupt enable) flag
 | |
|     if (((unsigned int)$eflags >> 9) & 1)
 | |
|         printf "I "
 | |
|     else
 | |
|         printf "i "
 | |
|     end
 | |
|     # TF (trap) flag
 | |
|     if (((unsigned int)$eflags >> 8) & 1)
 | |
|         printf "T "
 | |
|     else
 | |
|         printf "t "
 | |
|     end
 | |
|     # SF (sign) flag
 | |
|     if (((unsigned int)$eflags >> 7) & 1)
 | |
|         printf "S "
 | |
|         set $_sf_flag = 1
 | |
|     else
 | |
|         printf "s "
 | |
|         set $_sf_flag = 0
 | |
|     end
 | |
|     # ZF (zero) flag
 | |
|     if (((unsigned int)$eflags >> 6) & 1)
 | |
|         printf "Z "
 | |
|         set $_zf_flag = 1
 | |
|     else
 | |
|         printf "z "
 | |
|         set $_zf_flag = 0
 | |
|     end
 | |
|     # AF (adjust) flag
 | |
|     if (((unsigned int)$eflags >> 4) & 1)
 | |
|         printf "A "
 | |
|     else
 | |
|         printf "a "
 | |
|     end
 | |
|     # PF (parity) flag
 | |
|     if (((unsigned int)$eflags >> 2) & 1)
 | |
|         printf "P "
 | |
|         set $_pf_flag = 1
 | |
|     else
 | |
|         printf "p "
 | |
|         set $_pf_flag = 0
 | |
|     end
 | |
|     # CF (carry) flag
 | |
|     if ((unsigned int)$eflags & 1)
 | |
|         printf "C "
 | |
|         set $_cf_flag = 1
 | |
|     else
 | |
|         printf "c "
 | |
|         set $_cf_flag = 0
 | |
|     end
 | |
|     printf "\n"
 | |
| end
 | |
| document flagsx86
 | |
| Syntax: flagsx86
 | |
| | Auxiliary function to set X86/X64 cpu flags.
 | |
| end
 | |
| 
 | |
| 
 | |
| define flags
 | |
|     # call the auxiliary functions based on target cpu
 | |
|     if $ARM == 1
 | |
|         flagsarm
 | |
|     else
 | |
|         flagsx86
 | |
|     end
 | |
| end
 | |
| document flags
 | |
| Syntax: flags
 | |
| | Print flags register.
 | |
| end
 | |
| 
 | |
| 
 | |
| define eflags
 | |
|     if $ARM == 1
 | |
|         # http://www.heyrick.co.uk/armwiki/The_Status_register
 | |
|         printf "     N <%d>  Z <%d>  C <%d>  V <%d>",\
 | |
|                (($cpsr >> 0x1f) & 1), (($cpsr >> 0x1e) & 1), \
 | |
|                (($cpsr >> 0x1d) & 1), (($cpsr >> 0x1c) & 1)
 | |
|         printf "  Q <%d>  J <%d>  GE <%d>  E <%d>  A <%d>",\
 | |
|                (($cpsr >> 0x1b) & 1), (($cpsr >> 0x18) & 1),\
 | |
|                (($cpsr >> 0x10) & 7), (($cpsr >> 9) & 1), (($cpsr >> 8) & 1)
 | |
|         printf "  I <%d>  F <%d>  T <%d> \n",\
 | |
|                (($cpsr >> 7) & 1), (($cpsr >> 6) & 1), \
 | |
|                (($cpsr >> 5) & 1)
 | |
|      else
 | |
|         printf "     OF <%d>  DF <%d>  IF <%d>  TF <%d>",\
 | |
|                (((unsigned int)$eflags >> 0xB) & 1), (((unsigned int)$eflags >> 0xA) & 1), \
 | |
|                (((unsigned int)$eflags >> 9) & 1), (((unsigned int)$eflags >> 8) & 1)
 | |
|         printf "  SF <%d>  ZF <%d>  AF <%d>  PF <%d>  CF <%d>\n",\
 | |
|                (((unsigned int)$eflags >> 7) & 1), (((unsigned int)$eflags >> 6) & 1),\
 | |
|                (((unsigned int)$eflags >> 4) & 1), (((unsigned int)$eflags >> 2) & 1), ((unsigned int)$eflags & 1)
 | |
|         printf "     ID <%d>  VIP <%d> VIF <%d> AC <%d>",\
 | |
|                (((unsigned int)$eflags >> 0x15) & 1), (((unsigned int)$eflags >> 0x14) & 1), \
 | |
|                (((unsigned int)$eflags >> 0x13) & 1), (((unsigned int)$eflags >> 0x12) & 1)
 | |
|         printf "  VM <%d>  RF <%d>  NT <%d>  IOPL <%d>\n",\
 | |
|                (((unsigned int)$eflags >> 0x11) & 1), (((unsigned int)$eflags >> 0x10) & 1),\
 | |
|                (((unsigned int)$eflags >> 0xE) & 1), (((unsigned int)$eflags >> 0xC) & 3)
 | |
|      end
 | |
| end
 | |
| document eflags
 | |
| Syntax: eflags
 | |
| | Print eflags register.
 | |
| end
 | |
| 
 | |
| 
 | |
| define cpsr
 | |
|     eflags
 | |
| end
 | |
| document cpsr
 | |
| Syntax: cpsr
 | |
| | Print cpsr register.
 | |
| end
 | |
| 
 | |
| define regarm
 | |
|     printf "  "
 | |
|     # R0
 | |
|     color $COLOR_REGNAME
 | |
|     printf "R0:"
 | |
|     if ($r0 != $oldr0 && $SHOWREGCHANGES == 1)
 | |
|         color $COLOR_REGVAL_MODIFIED
 | |
|     else
 | |
|         color $COLOR_REGVAL
 | |
|     end
 | |
|     printf "  0x%08X  ", $r0
 | |
|     # R1
 | |
|     color $COLOR_REGNAME
 | |
|     printf "R1:"
 | |
|     if ($r1 != $oldr1 && $SHOWREGCHANGES == 1)
 | |
|         color $COLOR_REGVAL_MODIFIED
 | |
|     else
 | |
|         color $COLOR_REGVAL
 | |
|     end
 | |
|     printf " 0x%08X  ", $r1
 | |
|     # R2
 | |
|     color $COLOR_REGNAME
 | |
|     printf "R2:"
 | |
|     if ($r2 != $oldr2 && $SHOWREGCHANGES == 1)
 | |
|         color $COLOR_REGVAL_MODIFIED
 | |
|     else
 | |
|         color $COLOR_REGVAL
 | |
|     end
 | |
|     printf "  0x%08X  ", $r2
 | |
|     # R3
 | |
|     color $COLOR_REGNAME
 | |
|     printf "R3:"
 | |
|     if ($r3 != $oldr3 && $SHOWREGCHANGES == 1)
 | |
|         color $COLOR_REGVAL_MODIFIED
 | |
|     else
 | |
|         color $COLOR_REGVAL
 | |
|     end
 | |
|     printf "  0x%08X\n", $r3
 | |
|     printf "  "
 | |
|     # R4
 | |
|     color $COLOR_REGNAME
 | |
|     printf "R4:"
 | |
|     if ($r4 != $oldr4 && $SHOWREGCHANGES == 1)
 | |
|         color $COLOR_REGVAL_MODIFIED
 | |
|     else
 | |
|         color $COLOR_REGVAL
 | |
|     end
 | |
|     printf "  0x%08X  ", $r4
 | |
|     # R5
 | |
|     color $COLOR_REGNAME
 | |
|     printf "R5:"
 | |
|     if ($r5 != $oldr5 && $SHOWREGCHANGES == 1)
 | |
|         color $COLOR_REGVAL_MODIFIED
 | |
|     else
 | |
|         color $COLOR_REGVAL
 | |
|     end
 | |
|     printf " 0x%08X  ", $r5
 | |
|     # R6
 | |
|     color $COLOR_REGNAME
 | |
|     printf "R6:"
 | |
|     if ($r6 != $oldr6 && $SHOWREGCHANGES == 1)
 | |
|         color $COLOR_REGVAL_MODIFIED
 | |
|     else
 | |
|         color $COLOR_REGVAL
 | |
|     end
 | |
|     printf "  0x%08X  ", $r6
 | |
|     # R7
 | |
|     color $COLOR_REGNAME
 | |
|     printf "R7:"
 | |
|     if ($r7 != $oldr7 && $SHOWREGCHANGES == 1)
 | |
|         color $COLOR_REGVAL_MODIFIED
 | |
|     else
 | |
|         color $COLOR_REGVAL
 | |
|     end
 | |
|     printf "  0x%08X\n", $r7
 | |
|     printf "  "
 | |
|     # R8
 | |
|     color $COLOR_REGNAME
 | |
|     printf "R8:"
 | |
|     if ($r8 != $oldr8 && $SHOWREGCHANGES == 1)
 | |
|         color $COLOR_REGVAL_MODIFIED
 | |
|     else
 | |
|         color $COLOR_REGVAL
 | |
|     end
 | |
|     printf "  0x%08X  ", $r8
 | |
|     # R9
 | |
|     color $COLOR_REGNAME
 | |
|     printf "R9:"
 | |
|     if ($r9 != $oldr9 && $SHOWREGCHANGES == 1)
 | |
|         color $COLOR_REGVAL_MODIFIED
 | |
|     else
 | |
|         color $COLOR_REGVAL
 | |
|     end
 | |
|     printf " 0x%08X  ", $r9
 | |
|     # R10
 | |
|     color $COLOR_REGNAME
 | |
|     printf "R10:"
 | |
|     if ($r10 != $oldr10 && $SHOWREGCHANGES == 1)
 | |
|         color $COLOR_REGVAL_MODIFIED
 | |
|     else
 | |
|         color $COLOR_REGVAL
 | |
|     end
 | |
|     printf " 0x%08X  ", $r10
 | |
|     # R11
 | |
|     color $COLOR_REGNAME
 | |
|     printf "R11:"
 | |
|     if ($r11 != $oldr11 && $SHOWREGCHANGES == 1)
 | |
|         color $COLOR_REGVAL_MODIFIED
 | |
|     else
 | |
|         color $COLOR_REGVAL
 | |
|     end
 | |
|     printf " 0x%08X ", $r11
 | |
|     dumpjump
 | |
|     printf "\n"
 | |
|     # R12
 | |
|     color $COLOR_REGNAME
 | |
|     printf "  R12:"
 | |
|     if ($r12 != $oldr12 && $SHOWREGCHANGES == 1)
 | |
|         color $COLOR_REGVAL_MODIFIED
 | |
|     else
 | |
|         color $COLOR_REGVAL
 | |
|     end
 | |
|     printf " 0x%08X", $r12
 | |
|     printf "  "
 | |
|     # SP
 | |
|     color $COLOR_REGNAME
 | |
|     printf "SP:"
 | |
|     if ($sp != $oldsp && $SHOWREGCHANGES == 1)
 | |
|         color $COLOR_REGVAL_MODIFIED
 | |
|     else
 | |
|         color $COLOR_REGVAL
 | |
|     end
 | |
|     printf " 0x%08X  ", $sp
 | |
| 	# LR
 | |
|     color $COLOR_REGNAME
 | |
|     printf "LR:"
 | |
|     if ($lr != $oldlr && $SHOWREGCHANGES == 1)
 | |
|         color $COLOR_REGVAL_MODIFIED
 | |
|     else
 | |
|         color $COLOR_REGVAL
 | |
|     end
 | |
|     printf "  0x%08X  ", $lr
 | |
|     # PC
 | |
|     color $COLOR_REGNAME
 | |
|     printf "PC:"
 | |
|     color $COLOR_REGVAL_MODIFIED
 | |
|     printf "  0x%08X  ", $pc
 | |
|     color_bold
 | |
|     color_underline
 | |
|     color $COLOR_CPUFLAGS
 | |
|     flags
 | |
|     color_reset
 | |
|     printf "\n"
 | |
| end
 | |
| document regarm
 | |
| Syntax: regarm
 | |
| | Auxiliary function to display ARM registers.
 | |
| end
 | |
| 
 | |
| define regx64
 | |
|     # 64bits stuff
 | |
|     printf "  "
 | |
|     # RAX
 | |
|     color $COLOR_REGNAME
 | |
|     printf "RAX:"
 | |
|     if ($rax != $oldrax && $SHOWREGCHANGES == 1)
 | |
|         color $COLOR_REGVAL_MODIFIED
 | |
|     else
 | |
|         color $COLOR_REGVAL
 | |
|     end
 | |
|     printf " 0x%016lX  ", $rax
 | |
|     # RBX
 | |
|     color $COLOR_REGNAME
 | |
|     printf "RBX:"
 | |
|     if ($rbx != $oldrbx && $SHOWREGCHANGES == 1)
 | |
|         color $COLOR_REGVAL_MODIFIED
 | |
|     else
 | |
|         color $COLOR_REGVAL
 | |
|     end
 | |
|     printf " 0x%016lX  ", $rbx
 | |
|     # RBP
 | |
|     color $COLOR_REGNAME
 | |
|     printf "RBP:"
 | |
|     if ($rbp != $oldrbp && $SHOWREGCHANGES == 1)
 | |
|         color $COLOR_REGVAL_MODIFIED
 | |
|     else
 | |
|         color $COLOR_REGVAL
 | |
|     end
 | |
|     printf " 0x%016lX  ", $rbp
 | |
|     # RSP
 | |
|     color $COLOR_REGNAME
 | |
|     printf "RSP:"
 | |
|     if ($rsp != $oldrsp && $SHOWREGCHANGES == 1)
 | |
|         color $COLOR_REGVAL_MODIFIED
 | |
|     else
 | |
|         color $COLOR_REGVAL
 | |
|     end
 | |
|     printf " 0x%016lX  ", $rsp
 | |
|     color_bold
 | |
|     color_underline
 | |
|     color $COLOR_CPUFLAGS
 | |
|     flags
 | |
|     color_reset
 | |
|     printf "  "
 | |
|     # RDI
 | |
|     color $COLOR_REGNAME
 | |
|     printf "RDI:"
 | |
|     if ($rdi != $oldrdi && $SHOWREGCHANGES == 1)
 | |
|         color $COLOR_REGVAL_MODIFIED
 | |
|     else
 | |
|         color $COLOR_REGVAL
 | |
|     end
 | |
|     printf " 0x%016lX  ", $rdi
 | |
|     # RSI
 | |
|     color $COLOR_REGNAME
 | |
|    	printf "RSI:"
 | |
|     if ($rsi != $oldrsi && $SHOWREGCHANGES == 1)
 | |
|         color $COLOR_REGVAL_MODIFIED
 | |
|     else
 | |
|         color $COLOR_REGVAL
 | |
|     end
 | |
|     printf " 0x%016lX  ", $rsi
 | |
|     # RDX
 | |
|     color $COLOR_REGNAME
 | |
|    	printf "RDX:"
 | |
|     if ($rdx != $oldrdx && $SHOWREGCHANGES == 1)
 | |
|         color $COLOR_REGVAL_MODIFIED
 | |
|     else
 | |
|         color $COLOR_REGVAL
 | |
|     end
 | |
|     printf " 0x%016lX  ", $rdx
 | |
|     # RCX
 | |
|     color $COLOR_REGNAME
 | |
|    	printf "RCX:"
 | |
|     if ($rcx != $oldrcx && $SHOWREGCHANGES == 1)
 | |
|         color $COLOR_REGVAL_MODIFIED
 | |
|     else
 | |
|         color $COLOR_REGVAL
 | |
|     end
 | |
|     printf " 0x%016lX  ", $rcx
 | |
|     # RIP
 | |
|     color $COLOR_REGNAME
 | |
|     printf "RIP:"
 | |
|     color $COLOR_REGVAL_MODIFIED
 | |
|     printf " 0x%016lX\n  ", $rip
 | |
|     # R8
 | |
|     color $COLOR_REGNAME
 | |
|    	printf "R8 :"
 | |
|     if ($r8 != $oldr8 && $SHOWREGCHANGES == 1)
 | |
|         color $COLOR_REGVAL_MODIFIED
 | |
|     else
 | |
|     color $COLOR_REGVAL
 | |
|     end
 | |
|     printf " 0x%016lX  ", $r8
 | |
|     # R9
 | |
|     color $COLOR_REGNAME
 | |
|    	printf "R9 :"
 | |
|     if ($r9 != $oldr9 && $SHOWREGCHANGES == 1)
 | |
|         color $COLOR_REGVAL_MODIFIED
 | |
|     else
 | |
|         color $COLOR_REGVAL
 | |
|     end
 | |
|     printf " 0x%016lX  ", $r9
 | |
|     # R10
 | |
|     color $COLOR_REGNAME
 | |
|    	printf "R10:"
 | |
|     if ($r10 != $oldr10 && $SHOWREGCHANGES == 1)
 | |
|         color $COLOR_REGVAL_MODIFIED
 | |
|     else
 | |
|         color $COLOR_REGVAL
 | |
|     end
 | |
|     printf " 0x%016lX  ", $r10
 | |
|     # R11
 | |
|    	color $COLOR_REGNAME
 | |
|     printf "R11:"
 | |
|     if ($r11 != $oldr11 && $SHOWREGCHANGES == 1)
 | |
|         color $COLOR_REGVAL_MODIFIED
 | |
|     else
 | |
|         color $COLOR_REGVAL
 | |
|     end
 | |
|     printf " 0x%016lX  ", $r11
 | |
|     # R12
 | |
|     color $COLOR_REGNAME
 | |
|     printf "R12:"
 | |
|     if ($r12 != $oldr12 && $SHOWREGCHANGES == 1)
 | |
|         color $COLOR_REGVAL_MODIFIED
 | |
|     else
 | |
|         color $COLOR_REGVAL
 | |
|     end
 | |
|     printf " 0x%016lX\n  ", $r12
 | |
|     # R13
 | |
|     color $COLOR_REGNAME
 | |
|    	printf "R13:"
 | |
|     if ($r13 != $oldr13 && $SHOWREGCHANGES == 1)
 | |
|         color $COLOR_REGVAL_MODIFIED
 | |
|     else
 | |
|         color $COLOR_REGVAL
 | |
|     end
 | |
|     printf " 0x%016lX  ", $r13
 | |
|     # R14
 | |
|     color $COLOR_REGNAME
 | |
|     printf "R14:"
 | |
|     if ($r14 != $oldr14 && $SHOWREGCHANGES == 1)
 | |
|         color $COLOR_REGVAL_MODIFIED
 | |
|     else
 | |
|         color $COLOR_REGVAL
 | |
|     end
 | |
|     printf " 0x%016lX  ", $r14
 | |
|     # R15
 | |
|     color $COLOR_REGNAME
 | |
|     printf "R15:"
 | |
|     if ($r15 != $oldr15 && $SHOWREGCHANGES == 1)
 | |
|         color $COLOR_REGVAL_MODIFIED
 | |
|     else
 | |
|         color $COLOR_REGVAL
 | |
|     end
 | |
|     printf " 0x%016lX\n  ", $r15
 | |
|     color $COLOR_REGNAME
 | |
|     printf "CS:"
 | |
|     color $COLOR_REGVAL
 | |
|     printf " %04X  ", $cs
 | |
|     color $COLOR_REGNAME
 | |
|     printf "DS:"
 | |
|     color $COLOR_REGVAL
 | |
|     printf " %04X  ", $ds
 | |
|     color $COLOR_REGNAME
 | |
|     printf "ES:"
 | |
|     color $COLOR_REGVAL
 | |
|     printf " %04X  ", $es
 | |
|     color $COLOR_REGNAME
 | |
|     printf "FS:"
 | |
|     color $COLOR_REGVAL
 | |
|     printf " %04X  ", $fs
 | |
|     color $COLOR_REGNAME
 | |
|     printf "GS:"
 | |
|     color $COLOR_REGVAL
 | |
|     printf " %04X  ", $gs
 | |
|     color $COLOR_REGNAME
 | |
|     printf "SS:"
 | |
|     color $COLOR_REGVAL
 | |
|     printf " %04X", $ss
 | |
|     color_reset
 | |
| end
 | |
| document regx64
 | |
| Syntax: regx64
 | |
| | Auxiliary function to display X86_64 registers.
 | |
| end
 | |
| 
 | |
| 
 | |
| define regx86
 | |
|     printf "  "
 | |
|     # EAX
 | |
|     color $COLOR_REGNAME
 | |
|     printf "EAX:"
 | |
|     if ($eax != $oldeax && $SHOWREGCHANGES == 1)
 | |
|         color $COLOR_REGVAL_MODIFIED
 | |
|     else
 | |
|         color $COLOR_REGVAL
 | |
|     end
 | |
|     printf " 0x%08X  ", $eax
 | |
|     # EBX
 | |
|     color $COLOR_REGNAME
 | |
|     printf "EBX:"
 | |
|     if ($ebx != $oldebx && $SHOWREGCHANGES == 1) 
 | |
|         color $COLOR_REGVAL_MODIFIED		
 | |
|     else
 | |
|         color $COLOR_REGVAL
 | |
|     end
 | |
|     printf " 0x%08X  ", $ebx
 | |
|     # ECX
 | |
|     color $COLOR_REGNAME
 | |
|     printf "ECX:"
 | |
|     if ($ecx != $oldecx && $SHOWREGCHANGES == 1)
 | |
|         color $COLOR_REGVAL_MODIFIED
 | |
|     else
 | |
|         color $COLOR_REGVAL
 | |
|     end
 | |
|     printf " 0x%08X  ", $ecx
 | |
|     # EDX
 | |
|     color $COLOR_REGNAME
 | |
|     printf "EDX:"
 | |
|     if ($edx != $oldedx && $SHOWREGCHANGES == 1)
 | |
|         color $COLOR_REGVAL_MODIFIED
 | |
|     else
 | |
|         color $COLOR_REGVAL
 | |
|     end
 | |
|         printf " 0x%08X  ", $edx
 | |
|     color_bold
 | |
|     color_underline
 | |
|     color $COLOR_CPUFLAGS
 | |
|     flags
 | |
|     color_reset
 | |
|     printf "  "
 | |
|     # ESI
 | |
|     color $COLOR_REGNAME
 | |
|     printf "ESI:"
 | |
|     if ($esi != $oldesi && $SHOWREGCHANGES == 1)
 | |
|         color $COLOR_REGVAL_MODIFIED
 | |
|     else
 | |
|         color $COLOR_REGVAL
 | |
|     end
 | |
|     printf " 0x%08X  ", $esi
 | |
|     # EDI
 | |
|     color $COLOR_REGNAME
 | |
|     printf "EDI:"
 | |
|     if ($edi != $oldedi && $SHOWREGCHANGES == 1)
 | |
|         color $COLOR_REGVAL_MODIFIED
 | |
|     else
 | |
|         color $COLOR_REGVAL
 | |
|     end
 | |
|     printf " 0x%08X  ", $edi
 | |
|     # EBP
 | |
|     color $COLOR_REGNAME
 | |
|     printf "EBP:"
 | |
|     if ($ebp != $oldebp && $SHOWREGCHANGES == 1)
 | |
|         color $COLOR_REGVAL_MODIFIED
 | |
|     else
 | |
|         color $COLOR_REGVAL
 | |
|     end
 | |
|     printf " 0x%08X  ", $ebp
 | |
|     # ESP
 | |
|     color $COLOR_REGNAME
 | |
|     printf "ESP:"
 | |
|     if ($esp != $oldesp && $SHOWREGCHANGES == 1)
 | |
|         color $COLOR_REGVAL_MODIFIED
 | |
|     else
 | |
|         color $COLOR_REGVAL
 | |
|     end
 | |
|     printf " 0x%08X  ", $esp
 | |
|     # EIP
 | |
|     color $COLOR_REGNAME
 | |
|     printf "EIP:"
 | |
|     color $COLOR_REGVAL_MODIFIED
 | |
|     printf " 0x%08X\n  ", $eip
 | |
|     color $COLOR_REGNAME
 | |
|     printf "CS:"
 | |
|     color $COLOR_REGVAL
 | |
|     printf " %04X  ", $cs
 | |
|     color $COLOR_REGNAME
 | |
|     printf "DS:"
 | |
|     color $COLOR_REGVAL
 | |
|     printf " %04X  ", $ds
 | |
|     color $COLOR_REGNAME
 | |
|     printf "ES:"
 | |
|     color $COLOR_REGVAL
 | |
|     printf " %04X  ", $es
 | |
|     color $COLOR_REGNAME
 | |
|     printf "FS:"
 | |
|     color $COLOR_REGVAL
 | |
|     printf " %04X  ", $fs
 | |
|     color $COLOR_REGNAME
 | |
|     printf "GS:"
 | |
|     color $COLOR_REGVAL
 | |
|     printf " %04X  ", $gs
 | |
|     color $COLOR_REGNAME
 | |
|     printf "SS:"
 | |
|     color $COLOR_REGVAL
 | |
|     printf " %04X", $ss
 | |
|     color_reset
 | |
| end
 | |
| document regx86
 | |
| Syntax: regx86
 | |
| | Auxiliary function to display X86 registers.
 | |
| end
 | |
| 
 | |
| 
 | |
| define reg
 | |
|     if $ARM == 1
 | |
|         regarm
 | |
|         if ($SHOWREGCHANGES == 1)
 | |
|             set $oldr0  = $r0
 | |
|             set $oldr1  = $r1
 | |
|             set $oldr2  = $r2
 | |
|             set $oldr3  = $r3
 | |
|             set $oldr4  = $r4
 | |
|             set $oldr5  = $r5
 | |
|             set $oldr6  = $r6
 | |
|             set $oldr7  = $r7
 | |
|             set $oldr8  = $r8
 | |
|             set $oldr9  = $r9
 | |
|             set $oldr10 = $r10
 | |
|             set $oldr11 = $r11
 | |
|             set $oldr12 = $r12
 | |
|             set $oldsp  = $sp
 | |
|             set $oldlr  = $lr
 | |
|         end
 | |
|     else
 | |
|         if ($64BITS == 1)
 | |
|             regx64
 | |
|         else
 | |
|             regx86
 | |
|         end
 | |
|         # call smallregisters
 | |
|         smallregisters
 | |
|         # display conditional jump routine
 | |
|         if ($64BITS == 1)
 | |
|             printf "\t\t\t\t"
 | |
|         end
 | |
|         dumpjump
 | |
|         printf "\n"
 | |
|         if ($SHOWREGCHANGES == 1)
 | |
|             if ($64BITS == 1)
 | |
|                 set $oldrax = $rax
 | |
|                 set $oldrbx = $rbx
 | |
|                 set $oldrcx = $rcx
 | |
|                 set $oldrdx = $rdx
 | |
|                 set $oldrsi = $rsi
 | |
|                 set $oldrdi = $rdi
 | |
|                 set $oldrbp = $rbp
 | |
|                 set $oldrsp = $rsp
 | |
|                 set $oldr8  = $r8
 | |
|                 set $oldr9  = $r9
 | |
|                 set $oldr10 = $r10
 | |
|                 set $oldr11 = $r11
 | |
|                 set $oldr12 = $r12
 | |
|                 set $oldr13 = $r13
 | |
|                 set $oldr14 = $r14
 | |
|                 set $oldr15 = $r15
 | |
|             else
 | |
|                 set $oldeax = $eax
 | |
|                 set $oldebx = $ebx
 | |
|                 set $oldecx = $ecx
 | |
|                 set $oldedx = $edx
 | |
|                 set $oldesi = $esi
 | |
|                 set $oldedi = $edi
 | |
|                 set $oldebp = $ebp
 | |
|                 set $oldesp = $esp
 | |
|             end
 | |
|         end
 | |
|     end
 | |
| end
 | |
| document reg
 | |
| Syntax: reg
 | |
| | Print CPU registers.
 | |
| end
 | |
| 
 | |
| 
 | |
| define smallregisters
 | |
|     if ($64BITS == 1)
 | |
|         # from rax
 | |
|         set $eax = $rax & 0xffffffff
 | |
|         set $ax  = $rax & 0xffff
 | |
|         set $al  = $ax & 0xff
 | |
|         set $ah  = $ax >> 8
 | |
|         # from rbx
 | |
|         set $ebx = $rbx & 0xffffffff
 | |
|         set $bx  = $rbx & 0xffff
 | |
|         set $bl  = $bx & 0xff
 | |
|         set $bh  = $bx >> 8
 | |
|         # from rcx
 | |
|         set $ecx = $rcx & 0xffffffff
 | |
|         set $cx  = $rcx & 0xffff
 | |
|         set $cl  = $cx & 0xff
 | |
|         set $ch  = $cx >> 8
 | |
|         # from rdx
 | |
|         set $edx = $rdx & 0xffffffff
 | |
|         set $dx  = $rdx & 0xffff
 | |
|         set $dl  = $dx & 0xff
 | |
|         set $dh  = $dx >> 8
 | |
|         # from rsi
 | |
|         set $esi = $rsi & 0xffffffff
 | |
|         set $si  = $rsi & 0xffff
 | |
|         # from rdi
 | |
|         set $edi = $rdi & 0xffffffff
 | |
|         set $di  = $rdi & 0xffff		
 | |
|     #32 bits stuff
 | |
|     else
 | |
|         # from eax
 | |
|         set $ax = $eax & 0xffff
 | |
|         set $al = $ax & 0xff
 | |
|         set $ah = $ax >> 8
 | |
|         # from ebx
 | |
|         set $bx = $ebx & 0xffff
 | |
|         set $bl = $bx & 0xff
 | |
|         set $bh = $bx >> 8
 | |
|         # from ecx
 | |
|         set $cx = $ecx & 0xffff
 | |
|         set $cl = $cx & 0xff
 | |
|         set $ch = $cx >> 8
 | |
|         # from edx
 | |
|         set $dx = $edx & 0xffff
 | |
|         set $dl = $dx & 0xff
 | |
|         set $dh = $dx >> 8
 | |
|         # from esi
 | |
|         set $si = $esi & 0xffff
 | |
|         # from edi
 | |
|         set $di = $edi & 0xffff		
 | |
|      end
 | |
| end
 | |
| document smallregisters
 | |
| Syntax: smallregisters
 | |
| | Create the 16 and 8 bit cpu registers (gdb doesn't have them by default).
 | |
| | And 32bits if we are dealing with 64bits binaries.
 | |
| end
 | |
| 
 | |
| 
 | |
| define func
 | |
|     if $argc == 0
 | |
|         info functions
 | |
|     end
 | |
|     if $argc == 1
 | |
|         info functions $arg0
 | |
|     end
 | |
|     if $argc > 1
 | |
|         help func
 | |
|     end
 | |
| end
 | |
| document func
 | |
| Syntax: func <REGEXP>
 | |
| | Print all function names in target, or those matching REGEXP.
 | |
| end
 | |
| 
 | |
| 
 | |
| define var
 | |
|     if $argc == 0
 | |
|         info variables
 | |
|     end
 | |
|     if $argc == 1
 | |
|         info variables $arg0
 | |
|     end
 | |
|     if $argc > 1
 | |
|         help var
 | |
|     end
 | |
| end
 | |
| document var
 | |
| Syntax: var <REGEXP>
 | |
| | Print all global and static variable names (symbols), or those matching REGEXP.
 | |
| end
 | |
| 
 | |
| 
 | |
| define lib
 | |
|     info sharedlibrary
 | |
| end
 | |
| document lib
 | |
| Syntax: lib
 | |
| | Print shared libraries linked to target.
 | |
| end
 | |
| 
 | |
| 
 | |
| define sig
 | |
|     if $argc == 0
 | |
|         info signals
 | |
|     end
 | |
|     if $argc == 1
 | |
|         info signals $arg0
 | |
|     end
 | |
|     if $argc > 1
 | |
|         help sig
 | |
|     end
 | |
| end
 | |
| document sig
 | |
| Syntax: sig <SIGNAL>
 | |
| | Print what debugger does when program gets various signals.
 | |
| | Specify a SIGNAL as argument to print info on that signal only.
 | |
| end
 | |
| 
 | |
| 
 | |
| define threads
 | |
|     info threads
 | |
| end
 | |
| document threads
 | |
| Syntax: threads
 | |
| | Print threads in target.
 | |
| end
 | |
| 
 | |
| 
 | |
| define dis
 | |
|     if $argc == 0
 | |
|         disassemble
 | |
|     end
 | |
|     if $argc == 1
 | |
|         disassemble $arg0
 | |
|     end
 | |
|     if $argc == 2
 | |
|         disassemble $arg0 $arg1
 | |
|     end 
 | |
|     if $argc > 2
 | |
|         help dis
 | |
|     end
 | |
| end
 | |
| document dis
 | |
| Syntax: dis <ADDR1> <ADDR2>
 | |
| | Disassemble a specified section of memory.
 | |
| | Default is to disassemble the function surrounding the PC (program counter) of selected frame. 
 | |
| | With one argument, ADDR1, the function surrounding this address is dumped.
 | |
| | Two arguments are taken as a range of memory to dump.
 | |
| end
 | |
| 
 | |
| 
 | |
| # __________hex/ascii dump an address_________
 | |
| define ascii_char
 | |
|     if $argc != 1
 | |
|         help ascii_char
 | |
|     else
 | |
|         # thanks elaine :)
 | |
|         set $_c = *(unsigned char *)($arg0)
 | |
|         if ($_c < 0x20 || $_c > 0x7E)
 | |
|             printf "."
 | |
|         else
 | |
|             printf "%c", $_c
 | |
|         end
 | |
|     end
 | |
| end
 | |
| document ascii_char
 | |
| Syntax: ascii_char ADDR
 | |
| | Print ASCII value of byte at address ADDR.
 | |
| | Print "." if the value is unprintable.
 | |
| end
 | |
| 
 | |
| 
 | |
| define hex_quad
 | |
|     if $argc != 1
 | |
|         help hex_quad
 | |
|     else
 | |
|         printf "%02X %02X %02X %02X %02X %02X %02X %02X", \
 | |
|                *(unsigned char*)($arg0), *(unsigned char*)($arg0 + 1),     \
 | |
|                *(unsigned char*)($arg0 + 2), *(unsigned char*)($arg0 + 3), \
 | |
|                *(unsigned char*)($arg0 + 4), *(unsigned char*)($arg0 + 5), \
 | |
|                *(unsigned char*)($arg0 + 6), *(unsigned char*)($arg0 + 7)
 | |
|     end
 | |
| end
 | |
| document hex_quad
 | |
| Syntax: hex_quad ADDR
 | |
| | Print eight hexadecimal bytes starting at address ADDR.
 | |
| end
 | |
| 
 | |
| 
 | |
| define hexdump
 | |
|     if $argc == 1
 | |
|         hexdump_aux $arg0
 | |
|     else
 | |
|         if $argc == 2
 | |
|             set $_count = 0
 | |
|             while ($_count < $arg1)
 | |
|                 set $_i = ($_count * 0x10)
 | |
|                 hexdump_aux $arg0+$_i
 | |
|                 set $_count++
 | |
|             end
 | |
|         else
 | |
|             help hexdump
 | |
|         end
 | |
|     end
 | |
| end
 | |
| document hexdump
 | |
| Syntax: hexdump ADDR <NR_LINES>
 | |
| | Display a 16-byte hex/ASCII dump of memory starting at address ADDR.
 | |
| | Optional parameter is the number of lines to display if you want more than one. 
 | |
| end
 | |
| 
 | |
| 
 | |
| define hexdump_aux
 | |
|     if $argc != 1
 | |
|         help hexdump_aux
 | |
|     else
 | |
|         color_bold
 | |
|         if ($64BITS == 1)
 | |
|             printf "0x%016lX : ", $arg0
 | |
|         else
 | |
|             printf "0x%08X : ", $arg0
 | |
|         end
 | |
|         color_reset
 | |
|         hex_quad $arg0
 | |
|         color_bold
 | |
|         printf " - "
 | |
|         color_reset
 | |
|         hex_quad $arg0+8
 | |
|         printf " "
 | |
|         color_bold
 | |
|         ascii_char $arg0+0x0
 | |
|         ascii_char $arg0+0x1
 | |
|         ascii_char $arg0+0x2
 | |
|         ascii_char $arg0+0x3
 | |
|         ascii_char $arg0+0x4
 | |
|         ascii_char $arg0+0x5
 | |
|         ascii_char $arg0+0x6
 | |
|         ascii_char $arg0+0x7
 | |
|         ascii_char $arg0+0x8
 | |
|         ascii_char $arg0+0x9
 | |
|         ascii_char $arg0+0xA
 | |
|         ascii_char $arg0+0xB
 | |
|         ascii_char $arg0+0xC
 | |
|         ascii_char $arg0+0xD
 | |
|         ascii_char $arg0+0xE
 | |
|         ascii_char $arg0+0xF
 | |
|         color_reset
 | |
|         printf "\n"
 | |
|     end
 | |
| end
 | |
| document hexdump_aux
 | |
| Syntax: hexdump_aux ADDR
 | |
| | Display a 16-byte hex/ASCII dump of memory at address ADDR.
 | |
| end
 | |
| 
 | |
| 
 | |
| # _______________data window__________________
 | |
| define ddump
 | |
|     if $argc != 1
 | |
|         help ddump
 | |
|     else
 | |
|         color $COLOR_SEPARATOR
 | |
|         if $ARM == 1
 | |
|             printf "[0x%08X]", $data_addr
 | |
|         else
 | |
|             if ($64BITS == 1)
 | |
|                 printf "[0x%04X:0x%016lX]", $ds, $data_addr
 | |
|             else
 | |
|                 printf "[0x%04X:0x%08X]", $ds, $data_addr
 | |
|             end
 | |
|         end
 | |
| 
 | |
|         color $COLOR_SEPARATOR
 | |
|         printf "------------------------"
 | |
|         printf "-------------------------------"
 | |
|         if ($64BITS == 1)
 | |
|             printf "-------------------------------------"
 | |
|         end
 | |
|         color_bold
 | |
|         color $COLOR_SEPARATOR
 | |
|         printf "[data]\n"
 | |
|         color_reset
 | |
|         set $_count = 0
 | |
|         while ($_count < $arg0)
 | |
|             set $_i = ($_count * 0x10)
 | |
|             hexdump $data_addr+$_i
 | |
|             set $_count++
 | |
|         end
 | |
|     end
 | |
| end
 | |
| document ddump
 | |
| Syntax: ddump NUM
 | |
| | Display NUM lines of hexdump for address in $data_addr global variable.
 | |
| end
 | |
| 
 | |
| 
 | |
| define dd
 | |
|     if $argc != 1
 | |
|         help dd
 | |
|     else
 | |
|         set $data_addr = $arg0
 | |
|         ddump 0x10
 | |
|     end
 | |
| end
 | |
| document dd
 | |
| Syntax: dd ADDR
 | |
| | Display 16 lines of a hex dump of address starting at ADDR.
 | |
| end
 | |
| 
 | |
| 
 | |
| define datawin
 | |
|     if $ARM == 1
 | |
|         if ((($r0 >> 0x18) == 0x40) || (($r0 >> 0x18) == 0x08) || (($r0 >> 0x18) == 0xBF))
 | |
|             set $data_addr = $r0
 | |
|         else
 | |
|             if ((($r1 >> 0x18) == 0x40) || (($r1 >> 0x18) == 0x08) || (($r1 >> 0x18) == 0xBF))
 | |
|                 set $data_addr = $r1
 | |
|             else
 | |
|                 if ((($r2 >> 0x18) == 0x40) || (($r2 >> 0x18) == 0x08) || (($r2 >> 0x18) == 0xBF))
 | |
|                     set $data_addr = $r2
 | |
|                 else
 | |
|                     set $data_addr = $sp
 | |
|                 end
 | |
|             end
 | |
|         end
 | |
| ################################# X86
 | |
|     else
 | |
|         if ($64BITS == 1)
 | |
|             if ((($rsi >> 0x18) == 0x40) || (($rsi >> 0x18) == 0x08) || (($rsi >> 0x18) == 0xBF))
 | |
|                 set $data_addr = $rsi
 | |
|             else
 | |
|                 if ((($rdi >> 0x18) == 0x40) || (($rdi >> 0x18) == 0x08) || (($rdi >> 0x18) == 0xBF))
 | |
|                     set $data_addr = $rdi
 | |
|                 else
 | |
|                     if ((($rax >> 0x18) == 0x40) || (($rax >> 0x18) == 0x08) || (($rax >> 0x18) == 0xBF))
 | |
|                         set $data_addr = $rax
 | |
|                     else
 | |
|                         set $data_addr = $rsp
 | |
|                     end
 | |
|                 end
 | |
|             end
 | |
|         else
 | |
|             if ((($esi >> 0x18) == 0x40) || (($esi >> 0x18) == 0x08) || (($esi >> 0x18) == 0xBF))
 | |
|                 set $data_addr = $esi
 | |
|             else
 | |
|                 if ((($edi >> 0x18) == 0x40) || (($edi >> 0x18) == 0x08) || (($edi >> 0x18) == 0xBF))
 | |
|                     set $data_addr = $edi
 | |
|                 else
 | |
|                     if ((($eax >> 0x18) == 0x40) || (($eax >> 0x18) == 0x08) || (($eax >> 0x18) == 0xBF))
 | |
|                         set $data_addr = $eax
 | |
|                     else
 | |
|                         set $data_addr = $esp
 | |
|                     end
 | |
|                 end
 | |
|             end
 | |
|         end
 | |
|     end
 | |
|     ddump $CONTEXTSIZE_DATA
 | |
| end
 | |
| document datawin
 | |
| Syntax: datawin
 | |
| | Display valid address from one register in data window.
 | |
| | Registers to choose are: esi, edi, eax, or esp.
 | |
| end
 | |
| 
 | |
| 
 | |
| ################################
 | |
| ##### ALERT ALERT ALERT ########
 | |
| ################################
 | |
| # Huge mess going here :) HAHA #
 | |
| ################################
 | |
| define dumpjump
 | |
|     if $ARM == 1
 | |
|         ## Most ARM and Thumb instructions are conditional!
 | |
|         # each instruction is 32 bits long
 | |
|         # 4 bits are for condition codes (16 in total) (bits 31:28 in ARM contain the condition or 1111 if instruction is unconditional)
 | |
|         # 2x4 bits for destination and first operand registers
 | |
|         # one for the set-status flag
 | |
|         # an assorted number for other stuff
 | |
|         # 12 bits for any immediate value
 | |
|         # $_t_flag == 0 => ARM mode
 | |
|         # $_t_flag == 1 => Thumb or ThumbEE
 | |
|         # State bit (T), bit 5
 | |
|         if (($cpsr >> 5) & 1)
 | |
|             set $_t_flag = 1
 | |
|         else
 | |
|             set $_t_flag = 0
 | |
|         end
 | |
| 
 | |
|         if $_t_flag == 0
 | |
|             set $_lastbyte = *(unsigned char *)($pc+3)
 | |
|             #set $_bit31 = ($_lastbyte >> 7) & 1
 | |
|             #set $_bit30 = ($_lastbyte >> 6) & 1
 | |
|             #set $_bit29 = ($_lastbyte >> 5) & 1
 | |
|             #set $_bit28 = ($_lastbyte >> 4) & 1
 | |
|             set $_conditional = $_lastbyte >> 4
 | |
|             dumpjumphelper
 | |
|         else
 | |
|             # if bits 15-12 (opcode in Thumb instructions) are equal to 1 1 0 1 (0xD) then we have a conditional branch
 | |
|             # bits 11-8 for the conditional execution code (check ARMv7 manual A8.3)
 | |
|             if ( (*(unsigned char *)($pc+1) >> 4) == 0xD )
 | |
|                 set $_conditional = *(unsigned char *)($pc+1) ^ 0xD0
 | |
|                 dumpjumphelper
 | |
|             end
 | |
|         end 
 | |
| ##################### X86
 | |
|     else
 | |
|         ## grab the first two bytes from the instruction so we can determine the jump instruction
 | |
|         set $_byte1 = *(unsigned char *)$pc
 | |
|         set $_byte2 = *(unsigned char *)($pc+1)
 | |
|         ## and now check what kind of jump we have (in case it's a jump instruction)
 | |
|         ## 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")
 | |
| 
 | |
|         ## opcode 0x77: JA, JNBE (jump if CF=0 and ZF=0)
 | |
|         ## opcode 0x0F87: JNBE, JA
 | |
|         if ( ($_byte1 == 0x77) || ($_byte1 == 0x0F && $_byte2 == 0x87) )
 | |
|             # cf=0 and zf=0
 | |
|             if ($_cf_flag == 0 && $_zf_flag == 0)
 | |
|                 color $RED
 | |
|                 printf "  Jump is taken (c=0 and z=0)"
 | |
|             else
 | |
|                 # cf != 0 or zf != 0
 | |
|                 color $RED
 | |
|                 printf "  Jump is NOT taken (c!=0 or z!=0)"
 | |
|             end 
 | |
|         end
 | |
|         ## opcode 0x73: JAE, JNB, JNC (jump if CF=0)
 | |
|         ## opcode 0x0F83: JNC, JNB, JAE (jump if CF=0)
 | |
|         if ( ($_byte1 == 0x73) || ($_byte1 == 0x0F && $_byte2 == 0x83) )
 | |
|             # cf=0
 | |
|             if ($_cf_flag == 0)
 | |
|                 color $RED
 | |
|                 printf "  Jump is taken (c=0)"
 | |
|             else
 | |
|                 # cf != 0
 | |
|                 color $RED
 | |
|                 printf "  Jump is NOT taken (c!=0)"
 | |
|             end 
 | |
|         end
 | |
|         ## opcode 0x72: JB, JC, JNAE (jump if CF=1)
 | |
|         ## opcode 0x0F82: JNAE, JB, JC
 | |
|         if ( ($_byte1 == 0x72) || ($_byte1 == 0x0F && $_byte2 == 0x82) )
 | |
|             # cf=1
 | |
|             if ($_cf_flag == 1)
 | |
|                 color $RED
 | |
|                 printf "  Jump is taken (c=1)"
 | |
|             else
 | |
|                 # cf != 1
 | |
|                 color $RED
 | |
|                 printf "  Jump is NOT taken (c!=1)"
 | |
|             end 
 | |
|         end
 | |
|         ## opcode 0x76: JBE, JNA (jump if CF=1 or ZF=1)
 | |
|         ## opcode 0x0F86: JBE, JNA
 | |
|         if ( ($_byte1 == 0x76) || ($_byte1 == 0x0F && $_byte2 == 0x86) )
 | |
|             # cf=1 or zf=1
 | |
|             if (($_cf_flag == 1) || ($_zf_flag == 1))
 | |
|                 color $RED
 | |
|                 printf "  Jump is taken (c=1 or z=1)"
 | |
|             else
 | |
|                 # cf != 1 or zf != 1
 | |
|                 color $RED
 | |
|                 printf "  Jump is NOT taken (c!=1 or z!=1)"
 | |
|             end 
 | |
|         end
 | |
|         ## opcode 0xE3: JCXZ, JECXZ, JRCXZ (jump if CX=0 or ECX=0 or RCX=0)
 | |
|         if ($_byte1 == 0xE3)
 | |
|             # cx=0 or ecx=0
 | |
|             if (($ecx == 0) || ($cx == 0))
 | |
|                 color $RED
 | |
|                 printf "  Jump is taken (cx=0 or ecx=0)"
 | |
|             else
 | |
|                 color $RED
 | |
|                 printf "  Jump is NOT taken (cx!=0 or ecx!=0)"
 | |
|             end 
 | |
|         end
 | |
|         ## opcode 0x74: JE, JZ (jump if ZF=1)
 | |
|         ## opcode 0x0F84: JZ, JE, JZ (jump if ZF=1)
 | |
|         if ( ($_byte1 == 0x74) || ($_byte1 == 0x0F && $_byte2 == 0x84) )
 | |
|             # ZF = 1
 | |
|             if ($_zf_flag == 1)
 | |
|                 color $RED
 | |
|                 printf "  Jump is taken (z=1)"
 | |
|             else
 | |
|                 # ZF = 0
 | |
|                 color $RED
 | |
|                 printf "  Jump is NOT taken (z!=1)"
 | |
|             end 
 | |
|         end
 | |
|         ## opcode 0x7F: JG, JNLE (jump if ZF=0 and SF=OF)
 | |
|         ## opcode 0x0F8F: JNLE, JG (jump if ZF=0 and SF=OF)
 | |
|         if ( ($_byte1 == 0x7F) || ($_byte1 == 0x0F && $_byte2 == 0x8F) )
 | |
|             # zf = 0 and sf = of
 | |
|             if (($_zf_flag == 0) && ($_sf_flag == $_of_flag))
 | |
|                 color $RED
 | |
|                 printf "  Jump is taken (z=0 and s=o)"
 | |
|             else
 | |
|                 color $RED
 | |
|                 printf "  Jump is NOT taken (z!=0 or s!=o)"
 | |
|             end 
 | |
|         end
 | |
|         ## opcode 0x7D: JGE, JNL (jump if SF=OF)
 | |
|         ## opcode 0x0F8D: JNL, JGE (jump if SF=OF)
 | |
|         if ( ($_byte1 == 0x7D) || ($_byte1 == 0x0F && $_byte2 == 0x8D) )
 | |
|             # sf = of
 | |
|             if ($_sf_flag == $_of_flag)
 | |
|                 color $RED
 | |
|                 printf "  Jump is taken (s=o)"
 | |
|             else
 | |
|                 color $RED
 | |
|                 printf "  Jump is NOT taken (s!=o)"
 | |
|             end 
 | |
|         end
 | |
|         ## opcode: 0x7C: JL, JNGE (jump if SF != OF)
 | |
|         ## opcode: 0x0F8C: JNGE, JL (jump if SF != OF)
 | |
|         if ( ($_byte1 == 0x7C) || ($_byte1 == 0x0F && $_byte2 == 0x8C) )
 | |
|             # sf != of
 | |
|             if ($_sf_flag != $_of_flag)
 | |
|                 color $RED
 | |
|                 printf "  Jump is taken (s!=o)"
 | |
|             else
 | |
|                 color $RED
 | |
|                 printf "  Jump is NOT taken (s=o)"
 | |
|             end 
 | |
|         end
 | |
|         ## opcode 0x7E: JLE, JNG (jump if ZF = 1 or SF != OF)
 | |
|         ## opcode 0x0F8E: JNG, JLE (jump if ZF = 1 or SF != OF)
 | |
|         if ( ($_byte1 == 0x7E) || ($_byte1 == 0x0F && $_byte2 == 0x8E) )
 | |
|             # zf = 1 or sf != of
 | |
|             if (($_zf_flag == 1) || ($_sf_flag != $_of_flag))
 | |
|                 color $RED
 | |
|                 printf "  Jump is taken (zf=1 or sf!=of)"
 | |
|             else
 | |
|                 color $RED
 | |
|                 printf "  Jump is NOT taken (zf!=1 or sf=of)"
 | |
|             end 
 | |
|         end
 | |
|         ## opcode 0x75: JNE, JNZ (jump if ZF = 0)
 | |
|         ## opcode 0x0F85: JNE, JNZ (jump if ZF = 0)
 | |
|         if ( ($_byte1 == 0x75) || ($_byte1 == 0x0F && $_byte2 == 0x85) )
 | |
|             # ZF = 0
 | |
|             if ($_zf_flag == 0)
 | |
|                 color $RED
 | |
|                 printf "  Jump is taken (z=0)"
 | |
|             else
 | |
|                 # ZF = 1
 | |
|                 color $RED
 | |
|                 printf "  Jump is NOT taken (z!=0)"
 | |
|             end 
 | |
|         end
 | |
|         ## opcode 0x71: JNO (OF = 0)
 | |
|         ## opcode 0x0F81: JNO (OF = 0)
 | |
|         if ( ($_byte1 == 0x71) || ($_byte1 == 0x0F && $_byte2 == 0x81) )
 | |
|             # OF = 0
 | |
|             if ($_of_flag == 0)
 | |
|                 color $RED
 | |
|                 printf "  Jump is taken (o=0)"
 | |
|             else
 | |
|                 # OF != 0
 | |
|                 color $RED
 | |
|                 printf "  Jump is NOT taken (o!=0)"
 | |
|             end 
 | |
|         end
 | |
|         ## opcode 0x7B: JNP, JPO (jump if PF = 0)
 | |
|         ## opcode 0x0F8B: JPO (jump if PF = 0)
 | |
|         if ( ($_byte1 == 0x7B) || ($_byte1 == 0x0F && $_byte2 == 0x8B) )
 | |
|             # PF = 0
 | |
|             if ($_pf_flag == 0)
 | |
|                 color $RED
 | |
|                 printf "  Jump is NOT taken (p=0)"
 | |
|             else
 | |
|                 # PF != 0
 | |
|                 color $RED
 | |
|                 printf "  Jump is taken (p!=0)"
 | |
|             end 
 | |
|         end
 | |
|         ## opcode 0x79: JNS (jump if SF = 0)
 | |
|         ## opcode 0x0F89: JNS (jump if SF = 0)
 | |
|         if ( ($_byte1 == 0x79) || ($_byte1 == 0x0F && $_byte2 == 0x89) )
 | |
|             # SF = 0
 | |
|             if ($_sf_flag == 0)
 | |
|                 color $RED
 | |
|                 printf "  Jump is taken (s=0)"
 | |
|             else
 | |
|                 # SF != 0
 | |
|                 color $RED
 | |
|                 printf "  Jump is NOT taken (s!=0)"
 | |
|             end 
 | |
|         end
 | |
|         ## opcode 0x70: JO (jump if OF=1)
 | |
|         ## opcode 0x0F80: JO (jump if OF=1)
 | |
|         if ( ($_byte1 == 0x70) || ($_byte1 == 0x0F && $_byte2 == 0x80) )
 | |
|             # OF = 1
 | |
|             if ($_of_flag == 1)
 | |
|                 color $RED
 | |
|                 printf "  Jump is taken (o=1)"
 | |
|             else
 | |
|                 # OF != 1
 | |
|                 color $RED
 | |
|                 printf "  Jump is NOT taken (o!=1)"
 | |
|             end 
 | |
|         end
 | |
|         ## opcode 0x7A: JP, JPE (jump if PF=1)
 | |
|         ## opcode 0x0F8A: JP, JPE (jump if PF=1)
 | |
|         if ( ($_byte1 == 0x7A) || ($_byte1 == 0x0F && $_byte2 == 0x8A) )
 | |
|             # PF = 1
 | |
|             if ($_pf_flag == 1)
 | |
|                 color $RED
 | |
|                 printf "  Jump is taken (p=1)"
 | |
|             else
 | |
|                 # PF = 0
 | |
|                 color $RED
 | |
|                 printf "  Jump is NOT taken (p!=1)"
 | |
|             end 
 | |
|         end
 | |
|         ## opcode 0x78: JS (jump if SF=1)
 | |
|         ## opcode 0x0F88: JS (jump if SF=1)
 | |
|         if ( ($_byte1 == 0x78) || ($_byte1 == 0x0F && $_byte2 == 0x88) )
 | |
|             # SF = 1
 | |
|             if ($_sf_flag == 1)
 | |
|                 color $RED
 | |
|                 printf "  Jump is taken (s=1)"
 | |
|             else
 | |
|                 # SF != 1
 | |
|                 color $RED
 | |
|                 printf "  Jump is NOT taken (s!=1)"
 | |
|             end 
 | |
|         end
 | |
|     end
 | |
| end
 | |
| document dumpjump
 | |
| Syntax: dumpjump
 | |
| | Display if conditional jump will be taken or not.
 | |
| end
 | |
| 
 | |
| define dumpjumphelper
 | |
|     # 0000 - EQ: Z == 1
 | |
|     if ($_conditional == 0x0)
 | |
|         if ($_z_flag == 1)
 | |
|             color $RED
 | |
|             printf " Jump is taken (z==1)"
 | |
|         else
 | |
|             color $RED
 | |
|             printf " Jump is NOT taken (z!=1)"
 | |
|         end
 | |
|     end
 | |
|     # 0001 - NE: Z == 0
 | |
|     if ($_conditional == 0x1)
 | |
|         if ($_z_flag == 0)
 | |
|             color $RED
 | |
|             printf " Jump is taken (z==0)"
 | |
|         else
 | |
|             color $RED
 | |
|             printf " Jump is NOT taken (z!=0)"
 | |
|         end
 | |
|     end
 | |
|     # 0010 - CS: C == 1
 | |
|     if ($_conditional == 0x2)
 | |
|         if ($_c_flag == 1)
 | |
|             color $RED
 | |
|             printf " Jump is taken (c==1)"
 | |
|         else
 | |
|             color $RED
 | |
|             printf " Jump is NOT taken (c!=1)"
 | |
|         end
 | |
|     end
 | |
|     # 0011 - CC: C == 0
 | |
|     if ($_conditional == 0x3)
 | |
|         if ($_c_flag == 0)
 | |
|             color $RED
 | |
|             printf " Jump is taken (c==0)"
 | |
|         else
 | |
|             color $RED
 | |
|             printf " Jump is NOT taken (c!=0)"
 | |
|         end
 | |
|     end
 | |
|     # 0100 - MI: N == 1
 | |
|     if ($_conditional == 0x4)
 | |
|         if ($_n_flag == 1)
 | |
|             color $RED
 | |
|             printf " Jump is taken (n==1)"
 | |
|         else
 | |
|             color $RED
 | |
|             printf " Jump is NOT taken (n!=1)"
 | |
|         end
 | |
|     end
 | |
|     # 0101 - PL: N == 0
 | |
|     if ($_conditional == 0x5)
 | |
|         if ($_n_flag == 0)
 | |
|             color $RED
 | |
|             printf " Jump is taken (n==0)"
 | |
|         else
 | |
|             color $RED
 | |
|             printf " Jump is NOT taken (n!=0)"
 | |
|         end
 | |
|     end
 | |
|     # 0110 - VS: V == 1
 | |
|     if ($_conditional == 0x6)
 | |
|         if ($_v_flag == 1)
 | |
|             color $RED
 | |
|             printf " Jump is taken (v==1)"
 | |
|         else
 | |
|             color $RED
 | |
|             printf " Jump is NOT taken (v!=1)"
 | |
|         end
 | |
|     end
 | |
|     # 0111 - VC: V == 0
 | |
|     if ($_conditional == 0x7)
 | |
|         if ($_v_flag == 0)
 | |
|             color $RED
 | |
|             printf " Jump is taken (v==0)"
 | |
|         else
 | |
|             color $RED
 | |
|             printf " Jump is NOT taken (v!=0)"
 | |
|         end
 | |
|     end
 | |
|     # 1000 - HI: C == 1 and Z == 0
 | |
|     if ($_conditional == 0x8)
 | |
|         if ($_c_flag == 1 && $_z_flag == 0)
 | |
|             color $RED
 | |
|             printf " Jump is taken (c==1 and z==0)"
 | |
|         else
 | |
|             color $RED
 | |
|             printf " Jump is NOT taken (c!=1 or z!=0)"
 | |
|         end
 | |
|     end
 | |
|     # 1001 - LS: C == 0 or Z == 1
 | |
|     if ($_conditional == 0x9)
 | |
|         if ($_c_flag == 0 || $_z_flag == 1)
 | |
|             color $RED
 | |
|             printf " Jump is taken (c==0 or z==1)"
 | |
|         else
 | |
|             color $RED
 | |
|             printf " Jump is NOT taken (c!=0 or z!=1)"
 | |
|         end
 | |
|     end
 | |
|     # 1010 - GE: N == V
 | |
|     if ($_conditional == 0xA)
 | |
|         if ($_n_flag == $_v_flag)
 | |
|             color $RED
 | |
|             printf " Jump is taken (n==v)"
 | |
|         else
 | |
|             color $RED
 | |
|             printf " Jump is NOT taken (n!=v)"
 | |
|         end
 | |
|     end
 | |
|     # 1011 - LT: N != V
 | |
|     if ($_conditional == 0xB)
 | |
|         if ($_n_flag != $_v_flag)
 | |
|             color $RED
 | |
|             printf " Jump is taken (n!=v)"
 | |
|         else
 | |
|             color $RED
 | |
|             printf " Jump is NOT taken (n==v)"
 | |
|         end
 | |
|     end
 | |
|     # 1100 - GT: Z == 0 and N == V
 | |
|     if ($_conditional == 0xC)
 | |
|         if ($_z_flag == 0 && $_n_flag == $_v_flag)
 | |
|             color $RED
 | |
|             printf " Jump is taken (z==0 and n==v)"
 | |
|         else
 | |
|             color $RED
 | |
|             printf " Jump is NOT taken (z!=0 or n!=v)"
 | |
|         end
 | |
|     end
 | |
|     # 1101 - LE: Z == 1 or N != V
 | |
|     if ($_conditional == 0xD)
 | |
|         if ($_z_flag == 1 || $_n_flag != $_v_flag)
 | |
|             color $RED
 | |
|             printf " Jump is taken (z==1 or n!=v)"
 | |
|         else
 | |
|             color $RED
 | |
|             printf " Jump is NOT taken (z!=1 or n==v)"
 | |
|         end
 | |
|     end
 | |
| end
 | |
| document dumpjumphelper
 | |
| Syntax: dumpjumphelper
 | |
| | Helper function to decide if conditional jump will be taken or not, for ARM and Thumb.
 | |
| end
 | |
| 
 | |
| 
 | |
| # _______________process context______________
 | |
| # initialize variable
 | |
| set $displayobjectivec = 0
 | |
| 
 | |
| define context 
 | |
|     color $COLOR_SEPARATOR
 | |
|     if $SHOWCPUREGISTERS == 1
 | |
|         printf "----------------------------------------"
 | |
|         printf "----------------------------------"
 | |
|         if ($64BITS == 1)
 | |
|             printf "---------------------------------------------"
 | |
|         end
 | |
|         color $COLOR_SEPARATOR
 | |
|         color_bold
 | |
|         printf "[regs]\n"
 | |
|         color_reset
 | |
|         reg
 | |
|         color $CYAN
 | |
|     end
 | |
|     if $SHOWSTACK == 1
 | |
|         color $COLOR_SEPARATOR
 | |
|         if $ARM == 1
 | |
|             printf "[0x%08X]", $sp
 | |
|         else
 | |
|         if ($64BITS == 1)
 | |
|             printf "[0x%04X:0x%016lX]", $ss, $rsp
 | |
|         else
 | |
|             printf "[0x%04X:0x%08X]", $ss, $esp
 | |
|         end
 | |
|     end
 | |
|         color $COLOR_SEPARATOR
 | |
|         printf "-------------------------"
 | |
|         printf "-----------------------------"
 | |
|         if ($64BITS == 1)
 | |
|             printf "-------------------------------------"
 | |
|         end
 | |
|         color $COLOR_SEPARATOR
 | |
|         color_bold
 | |
|         printf "[stack]\n"
 | |
|         color_reset
 | |
|         set $context_i = $CONTEXTSIZE_STACK
 | |
|         while ($context_i > 0)
 | |
|             set $context_t = $sp + 0x10 * ($context_i - 1)
 | |
|             hexdump $context_t
 | |
|             set $context_i--
 | |
|         end
 | |
|     end
 | |
|     # show the objective C message being passed to msgSend
 | |
|     if $SHOWOBJECTIVEC == 1
 | |
|         #FIXME: X64 and ARM
 | |
|         # What a piece of crap that's going on here :)
 | |
|         # detect if it's the correct opcode we are searching for
 | |
|         if $ARM == 0
 | |
|             set $__byte1 = *(unsigned char *)$pc
 | |
|             set $__byte = *(int *)$pc
 | |
|             if ($__byte == 0x4244489)
 | |
|                 set $objectivec = $eax
 | |
|                 set $displayobjectivec = 1
 | |
|             end
 | |
| 
 | |
|             if ($__byte == 0x4245489)
 | |
|                 set $objectivec = $edx
 | |
|                 set $displayobjectivec = 1
 | |
|             end
 | |
| 
 | |
|             if ($__byte == 0x4244c89)
 | |
|                 set $objectivec = $ecx
 | |
|                 set $displayobjectivec = 1
 | |
|             end
 | |
|         else
 | |
|             set $__byte1 = 0
 | |
|         end
 | |
|         # and now display it or not (we have no interest in having the info displayed after the call)
 | |
|         if $__byte1 == 0xE8
 | |
|             if $displayobjectivec == 1
 | |
|                 color $COLOR_SEPARATOR
 | |
|                 printf "--------------------------------------------------------------------"
 | |
|                 if ($64BITS == 1)
 | |
|                     printf "---------------------------------------------"
 | |
|                 end
 | |
|                 color $COLOR_SEPARATOR
 | |
|                 color_bold
 | |
|                 printf "[ObjectiveC]\n"
 | |
|                 color_reset
 | |
|                 color $BLACK
 | |
|                 x/s $objectivec
 | |
|             end   
 | |
|             set $displayobjectivec = 0     
 | |
|         end
 | |
|         if $displayobjectivec == 1
 | |
|             color $COLOR_SEPARATOR
 | |
|             printf "--------------------------------------------------------------------"
 | |
|             if ($64BITS == 1)
 | |
|                 printf "---------------------------------------------"
 | |
|             end
 | |
|             color $COLOR_SEPARATOR
 | |
|             color_bold
 | |
|             printf "[ObjectiveC]\n"
 | |
|             color_reset
 | |
|             color $BLACK
 | |
|             x/s $objectivec 
 | |
|         end   
 | |
|     end
 | |
|     color_reset
 | |
| # and this is the end of this little crap
 | |
| 
 | |
|     if $SHOWDATAWIN == 1
 | |
|         datawin
 | |
|     end
 | |
|     if $SHOWDISASM == 1
 | |
|         color $COLOR_SEPARATOR
 | |
|         printf "--------------------------------------------------------------------------"
 | |
|         if ($64BITS == 1)
 | |
|             printf "---------------------------------------------"
 | |
|         end
 | |
|         color $COLOR_SEPARATOR
 | |
|         color_bold
 | |
|         printf "[code]\n"
 | |
|         color_reset
 | |
|         set $context_i = $CONTEXTSIZE_CODE
 | |
|         if ($context_i > 0)
 | |
|             if ($SETCOLOR1STLINE == 1)	
 | |
|                 color $GREEN
 | |
|                 if ($ARM == 1)
 | |
|                     #       | $cpsr.t (Thumb flag)
 | |
|                     x/i (unsigned int)$pc | (($cpsr >> 5) & 1)
 | |
|                 else
 | |
|                     x/i $pc
 | |
|                 end
 | |
|                 color_reset
 | |
|             else
 | |
|                 if ($ARM == 1)
 | |
|                     # | $cpsr.t (Thumb flag)
 | |
|                     x/i (unsigned int)$pc | (($cpsr >> 5) & 1)
 | |
|                 else
 | |
|                     x/i $pc
 | |
|                 end
 | |
|             end
 | |
|             set $context_i--
 | |
|         end
 | |
|         while ($context_i > 0)
 | |
|             x /i
 | |
|             set $context_i--
 | |
|         end
 | |
|     end
 | |
|     color $COLOR_SEPARATOR
 | |
|     printf "----------------------------------------"
 | |
|     printf "----------------------------------------"
 | |
|     if ($64BITS == 1)
 | |
|         printf "---------------------------------------------\n"
 | |
|     else
 | |
|         printf "\n"
 | |
|     end
 | |
|     color_reset
 | |
| end
 | |
| document context
 | |
| Syntax: context
 | |
| | Print context window, i.e. regs, stack, ds:esi and disassemble cs:eip.
 | |
| end
 | |
| 
 | |
| 
 | |
| define context-on
 | |
|     set $SHOW_CONTEXT = 1
 | |
|     printf "Displaying of context is now ON\n"
 | |
| end
 | |
| document context-on
 | |
| Syntax: context-on
 | |
| | Enable display of context on every program break.
 | |
| end
 | |
| 
 | |
| 
 | |
| define context-off
 | |
|     set $SHOW_CONTEXT = 0
 | |
|     printf "Displaying of context is now OFF\n"
 | |
| end
 | |
| document context-off
 | |
| Syntax: context-off
 | |
| | Disable display of context on every program break.
 | |
| end
 | |
| 
 | |
| 
 | |
| # _______________process control______________
 | |
| define n
 | |
|     if $argc == 0
 | |
|         nexti
 | |
|     end
 | |
|     if $argc == 1
 | |
|         nexti $arg0
 | |
|     end
 | |
|     if $argc > 1
 | |
|         help n
 | |
|     end
 | |
| end
 | |
| document n
 | |
| Syntax: n <NUM>
 | |
| | Step one instruction, but proceed through subroutine calls.
 | |
| | If NUM is given, then repeat it NUM times or till program stops.
 | |
| | This is alias for nexti.
 | |
| end
 | |
| 
 | |
| 
 | |
| define go
 | |
|     if $argc == 0
 | |
|         stepi
 | |
|     end
 | |
|     if $argc == 1
 | |
|         stepi $arg0
 | |
|     end
 | |
|     if $argc > 1
 | |
|         help go
 | |
|     end
 | |
| end
 | |
| document go
 | |
| Syntax: go <NUM>
 | |
| | Step one instruction exactly.
 | |
| | If NUM is given, then repeat it NUM times or till program stops.
 | |
| | This is alias for stepi.
 | |
| end
 | |
| 
 | |
| 
 | |
| define pret
 | |
|     finish
 | |
| end
 | |
| document pret
 | |
| Syntax: pret
 | |
| | Execute until selected stack frame returns (step out of current call).
 | |
| | Upon return, the value returned is printed and put in the value history.
 | |
| end
 | |
| 
 | |
| 
 | |
| define init
 | |
|     set $SHOW_NEST_INSN = 0
 | |
|     tbreak _init
 | |
|     r
 | |
| end
 | |
| document init
 | |
| Syntax: init
 | |
| | Run program and break on _init().
 | |
| end
 | |
| 
 | |
| 
 | |
| define start
 | |
|     set $SHOW_NEST_INSN = 0
 | |
|     tbreak _start
 | |
|     r
 | |
| end
 | |
| document start
 | |
| Syntax: start
 | |
| | Run program and break on _start().
 | |
| end
 | |
| 
 | |
| 
 | |
| define sstart
 | |
|     set $SHOW_NEST_INSN = 0
 | |
|     tbreak __libc_start_main
 | |
|     r
 | |
| end
 | |
| document sstart
 | |
| Syntax: sstart
 | |
| | Run program and break on __libc_start_main().
 | |
| | Useful for stripped executables.
 | |
| end
 | |
| 
 | |
| 
 | |
| define main
 | |
|     set $SHOW_NEST_INSN = 0
 | |
|     tbreak main
 | |
|     r
 | |
| end
 | |
| document main
 | |
| Syntax: main
 | |
| | Run program and break on main().
 | |
| end
 | |
| 
 | |
| 
 | |
| # FIXME64
 | |
| #### WARNING ! WARNING !!
 | |
| #### More more messy stuff starting !!!
 | |
| #### I was thinking about how to do this and then it ocurred me that it could be as simple as this ! :)
 | |
| define stepoframework
 | |
|     if $ARM == 1
 | |
|         # bl and bx opcodes
 | |
|         # 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
 | |
|         # 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
 | |
|         # bl # => ARM bits 27-24: 1 0 1 1 ; Thumb bits: 15-11: 1 1 1 1 0 
 | |
|         # blx # => ARM bits 31-25: 1 1 1 1 1 0 1 ; Thumb bits: 15-11: 1 1 1 1 0 
 | |
|         set $_nextaddress = 0
 | |
| 
 | |
|         # ARM Mode
 | |
|         if ($_t_flag == 0)
 | |
|             set $_branchesint = *(unsigned int*)$pc
 | |
|             set $_bit31 = ($_branchesint >> 0x1F) & 1
 | |
|             set $_bit30 = ($_branchesint >> 0x1E) & 1
 | |
|             set $_bit29 = ($_branchesint >> 0x1D) & 1
 | |
|             set $_bit28 = ($_branchesint >> 0x1C) & 1
 | |
|             set $_bit27 = ($_branchesint >> 0x1B) & 1
 | |
|             set $_bit26 = ($_branchesint >> 0x1A) & 1
 | |
|             set $_bit25 = ($_branchesint >> 0x19) & 1
 | |
|             set $_bit24 = ($_branchesint >> 0x18) & 1
 | |
|             set $_bit23 = ($_branchesint >> 0x17) & 1
 | |
|             set $_bit22 = ($_branchesint >> 0x16) & 1
 | |
|             set $_bit21 = ($_branchesint >> 0x15) & 1
 | |
|             set $_bit20 = ($_branchesint >> 0x14) & 1
 | |
|             set $_bit7 = ($_branchesint >> 0x7) & 1
 | |
|             set $_bit6 = ($_branchesint >> 0x6) & 1
 | |
|             set $_bit5 = ($_branchesint >> 0x5) & 1
 | |
|             set $_bit4 = ($_branchesint >> 0x4) & 1
 | |
| 
 | |
|             #	set $_lastbyte = *(unsigned char *)($pc+3)
 | |
|             #	set $_bits2724 = $_lastbyte & 0x1
 | |
|             #	set $_bits3128 = $_lastbyte >> 4
 | |
|             #	if ($_bits3128 == 0xF)
 | |
|             #		set $_bits2724 = $_lastbyte & 0xA
 | |
|             #		set $_bits2724 = $_bits2724 >> 1
 | |
|             #	end
 | |
|             #	set $_previousbyte = *(unsigned char *)($pc+2)
 | |
|             #	set $_bits2320 = $_previousbyte >> 4
 | |
|             #	printf "bits2724: %x bits2320: %x\n", $_bits2724, $_bits2320
 | |
| 	
 | |
|             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)
 | |
|                 printf "Found a bx Rn\n"
 | |
|                 set $_nextaddress = $pc+0x4
 | |
|             end
 | |
|             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)
 | |
|                 printf "Found a blx Rn\n"
 | |
|                 set $_nextaddress = $pc+0x4
 | |
|             end
 | |
|             if ($_bit27 == 1 && $_bit26 == 0 && $_bit25 == 1 && $_bit24 == 1)
 | |
|                 printf "Found a bl #\n"
 | |
|                 set $_nextaddress = $pc+0x4
 | |
|             end
 | |
|             if ($_bit31 == 1 && $_bit30 == 1 && $_bit29 == 1 && $_bit28 == 1 && $_bit27 == 1 && $_bit26 == 0 && $_bit25 == 1)
 | |
|                 printf "Found a blx #\n"
 | |
|                 set $_nextaddress = $pc+0x4
 | |
|             end
 | |
|         # Thumb Mode
 | |
|         else
 | |
|             # 32 bits instructions in Thumb are divided into two half words
 | |
|             set $_hw1 = *(unsigned short*)($pc)
 | |
|             set $_hw2 = *(unsigned short*)($pc+2)
 | |
| 
 | |
|             # bl/blx (immediate)
 | |
|             # hw1: bits 15-11: 1 1 1 1 0
 | |
|             # hw2: bits 15-14: 1 1 ; BL bit 12: 1 ; BLX bit 12: 0
 | |
|             if ( ($_hw1 >> 0xC) == 0xF && (($_hw1 >> 0xB) & 1) == 0)
 | |
|                 if ( ((($_hw2 >> 0xF) & 1) == 1) && ((($_hw2 >> 0xE) & 1) == 1) )
 | |
|                     set $_nextaddress = $pc+0x4
 | |
|                 end
 | |
|             end
 | |
|         end
 | |
|         # if we have found a call to bypass we set a temporary breakpoint on next instruction and continue 
 | |
|         if ($_nextaddress != 0)
 | |
|             tbreak *$_nextaddress
 | |
|             continue
 | |
|             printf "[StepO] Next address will be %x\n", $_nextaddress
 | |
|         # else we just single step
 | |
|         else
 | |
|             nexti
 | |
|         end
 | |
| ###################################### X86
 | |
|     else
 | |
|         ## we know that an opcode starting by 0xE8 has a fixed length
 | |
|         ## for the 0xFF opcodes, we can enumerate what is possible to have
 | |
|         # first we grab the first 3 bytes from the current program counter
 | |
|         set $_byte1 = *(unsigned char *)$pc
 | |
|         set $_byte2 = *(unsigned char *)($pc+1)
 | |
|         set $_byte3 = *(unsigned char *)($pc+2)
 | |
|         # and start the fun
 | |
|         # if it's a 0xE8 opcode, the total instruction size will be 5 bytes
 | |
|         # so we can simply calculate the next address and use a temporary breakpoint ! Voila :)
 | |
|         set $_nextaddress = 0
 | |
|         # this one is the must useful for us !!!
 | |
|         if ($_byte1 == 0xE8)
 | |
|             set $_nextaddress = $pc + 0x5
 | |
|         else
 | |
|             # just other cases we might be interested in... maybe this should be removed since the 0xE8 opcode is the one we will use more
 | |
|             # this is a big fucking mess and can be improved for sure :) I don't like the way it is ehehehe
 | |
|             if ($_byte1 == 0xFF)
 | |
|                 # call *%eax (0xFFD0) || call *%edx (0xFFD2) || call *(%ecx) (0xFFD1) || call (%eax) (0xFF10) || call *%esi (0xFFD6) || call *%ebx (0xFFD3) || call   DWORD PTR [edx] (0xFF12)
 | |
|                 if ($_byte2 == 0xD0 || $_byte2 == 0xD1 || $_byte2 == 0xD2 || $_byte2 == 0xD3 || $_byte2 == 0xD6 || $_byte2 == 0x10 || $_byte2 == 0x11 || $_byte2 == 0xD7 || $_byte2 == 0x12)
 | |
|                     set $_nextaddress = $pc + 0x2
 | |
|                 end
 | |
|                 # call *0x??(%ebp) (0xFF55??) || call *0x??(%esi) (0xFF56??) || call *0x??(%edi) (0xFF5F??) || call *0x??(%ebx)
 | |
|                 # call *0x??(%edx) (0xFF52??) || call *0x??(%ecx) (0xFF51??) || call *0x??(%edi) (0xFF57??) || call *0x??(%eax) (0xFF50??)
 | |
|                 if ($_byte2 == 0x55 || $_byte2 == 0x56 || $_byte2 == 0x5F || $_byte2 == 0x53 || $_byte2 == 0x52 || $_byte2 == 0x51 || $_byte2 == 0x57 || $_byte2 == 0x50) 
 | |
|                     set $_nextaddress = $pc + 0x3
 | |
|                 end
 | |
|                 # call *0x????????(%ebx) (0xFF93????????) || 
 | |
|                 if ($_byte2 == 0x93 || $_byte2 == 0x94 || $_byte2 == 0x90 || $_byte2 == 0x92 || $_byte2 == 0x95 || $_byte2 == 0x15)
 | |
|                     set $_nextaddress = $pc + 6
 | |
|                 end
 | |
|                 # call *0x????????(%ebx,%eax,4) (0xFF94??????????)
 | |
|                 if ($_byte2 == 0x94)
 | |
|                     set $_nextaddress = $pc + 7
 | |
|                 end
 | |
|             end
 | |
|             # FIXME: still missing a few?
 | |
|             if ($_byte1 == 0x41 || $_byte1 == 0x40)
 | |
|                if ($_byte2 == 0xFF)
 | |
|                     if ($_byte3 == 0xD0 || $_byte3 == 0xD1 || $_byte3 == 0xD2 || $_byte3 == 0xD3 || $_byte3 == 0xD4 || $_byte3 == 0xD5 ||  $_byte3 == 0xD6 || $_byte3 == 0xD7)
 | |
|                         set $_nextaddress = $pc + 0x3
 | |
|                     end
 | |
|                end
 | |
|             end
 | |
|         end
 | |
|         # if we have found a call to bypass we set a temporary breakpoint on next instruction and continue 
 | |
|         if ($_nextaddress != 0)
 | |
|             if ($arg0 == 1)
 | |
|                 thbreak *$_nextaddress
 | |
|             else
 | |
|                 tbreak *$_nextaddress
 | |
|             end
 | |
|             continue
 | |
|             # else we just single step
 | |
|          else
 | |
|             nexti
 | |
|          end
 | |
|     end
 | |
| end
 | |
| document stepoframework
 | |
| Syntax: stepoframework
 | |
| | Auxiliary function to stepo command.
 | |
| end
 | |
| 
 | |
| define stepo
 | |
|     stepoframework 0
 | |
| end
 | |
| document stepo
 | |
| Syntax: stepo
 | |
| | Step over calls (interesting to bypass the ones to msgSend).
 | |
| | This function will set a temporary breakpoint on next instruction after the call so the call will be bypassed.
 | |
| | 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).
 | |
| end
 | |
| 
 | |
| 
 | |
| define stepoh
 | |
|     stepoframework 1
 | |
| end
 | |
| document stepoh
 | |
| Syntax: stepoh
 | |
| | Same as stepo command but uses temporary hardware breakpoints.
 | |
| end
 | |
| 
 | |
| 
 | |
| # FIXME: ARM
 | |
| define skip
 | |
|     x/2i $pc
 | |
|     set $instruction_size = (int)($_ - $pc)
 | |
|     set $pc = $pc + $instruction_size
 | |
|     if ($SKIPEXECUTE == 1)
 | |
|         if ($SKIPSTEP == 1)
 | |
|             stepo
 | |
|         else
 | |
|             stepi
 | |
|         end
 | |
|     else
 | |
|         context
 | |
|     end
 | |
| end
 | |
| document skip
 | |
| Syntax: skip
 | |
| | Skip over the instruction located at EIP/RIP. By default, the instruction will not be executed!
 | |
| | Some configurable options are available on top of gdbinit to override this.
 | |
| end
 | |
| 
 | |
| 
 | |
| # _______________eflags commands______________
 | |
| # conditional flags are
 | |
| # negative/less than (N), bit 31 of CPSR
 | |
| # zero (Z), bit 30
 | |
| # Carry/Borrow/Extend (C), bit 29
 | |
| # Overflow (V), bit 28
 | |
| 
 | |
| # negative/less than (N), bit 31 of CPSR
 | |
| define cfn
 | |
|     if $ARM == 1
 | |
|         set $tempflag = $cpsr->n
 | |
|         if ($tempflag & 1)
 | |
|             set $cpsr->n = $tempflag&~0x1
 | |
|         else
 | |
|             set $cpsr->n = $tempflag|0x1
 | |
|         end
 | |
|     end
 | |
| end
 | |
| document cfn
 | |
| Syntax: cfn
 | |
| | Change Negative/Less Than Flag.
 | |
| end
 | |
| 
 | |
| 
 | |
| define cfc
 | |
| # Carry/Borrow/Extend (C), bit 29
 | |
|     if $ARM == 1
 | |
|         set $tempflag = $cpsr->c
 | |
|         if ($tempflag & 1)
 | |
|             set $cpsr->c = $tempflag&~0x1
 | |
|         else
 | |
|             set $cpsr->c = $tempflag|0x1
 | |
|         end
 | |
|      else
 | |
|         if ((unsigned int)$eflags & 1)
 | |
|             set $eflags = (unsigned int)$eflags&~0x1
 | |
|         else
 | |
|             set $eflags = (unsigned int)$eflags|0x1
 | |
|         end
 | |
|      end
 | |
| end
 | |
| document cfc
 | |
| Syntax: cfc
 | |
| | Change Carry Flag.
 | |
| end
 | |
| 
 | |
| 
 | |
| define cfp
 | |
|     if (((unsigned int)$eflags >> 2) & 1)
 | |
|         set $eflags = (unsigned int)$eflags&~0x4
 | |
|     else
 | |
|         set $eflags = (unsigned int)$eflags|0x4
 | |
|     end
 | |
| end
 | |
| document cfp
 | |
| Syntax: cfp
 | |
| | Change Parity Flag.
 | |
| end
 | |
| 
 | |
| 
 | |
| define cfa
 | |
|     if (((unsigned int)$eflags >> 4) & 1)
 | |
|         set $eflags = (unsigned int)$eflags&~0x10
 | |
|     else
 | |
|         set $eflags = (unsigned int)$eflags|0x10
 | |
|     end
 | |
| end
 | |
| document cfa
 | |
| Syntax: cfa
 | |
| | Change Auxiliary Carry Flag.
 | |
| end
 | |
| 
 | |
| 
 | |
| define cfz
 | |
| # zero (Z), bit 30
 | |
|     if $ARM == 1
 | |
|         set $tempflag = $cpsr->z
 | |
|         if ($tempflag & 1)
 | |
|             set $cpsr->z = $tempflag&~0x1
 | |
|         else
 | |
|             set $cpsr->z = $tempflag|0x1
 | |
|         end
 | |
|      else
 | |
|         if (((unsigned int)$eflags >> 6) & 1)
 | |
|             set $eflags = (unsigned int)$eflags&~0x40
 | |
|         else
 | |
|             set $eflags = (unsigned int)$eflags|0x40
 | |
|         end
 | |
|      end
 | |
| end
 | |
| document cfz
 | |
| Syntax: cfz
 | |
| | Change Zero Flag.
 | |
| end
 | |
| 
 | |
| 
 | |
| define cfs
 | |
|     if (((unsigned int)$eflags >> 7) & 1)
 | |
|         set $eflags = (unsigned int)$eflags&~0x80
 | |
|     else
 | |
|         set $eflags = (unsigned int)$eflags|0x80
 | |
|     end
 | |
| end
 | |
| document cfs
 | |
| Syntax: cfs
 | |
| | Change Sign Flag.
 | |
| end
 | |
| 
 | |
| 
 | |
| define cft
 | |
|     if (((unsigned int)$eflags >>8) & 1)
 | |
|         set $eflags = (unsigned int)$eflags&~0x100
 | |
|     else
 | |
|         set $eflags = (unsigned int)$eflags|0x100
 | |
|     end
 | |
| end
 | |
| document cft
 | |
| Syntax: cft
 | |
| | Change Trap Flag.
 | |
| end
 | |
| 
 | |
| 
 | |
| define cfi
 | |
|     if (((unsigned int)$eflags >> 9) & 1)
 | |
|         set $eflags = (unsigned int)$eflags&~0x200
 | |
|     else
 | |
|         set $eflags = (unsigned int)$eflags|0x200
 | |
|     end
 | |
| end
 | |
| document cfi
 | |
| Syntax: cfi
 | |
| | Change Interrupt Flag.
 | |
| | Only privileged applications (usually the OS kernel) may modify IF.
 | |
| | This only applies to protected mode (real mode code may always modify IF).
 | |
| end
 | |
| 
 | |
| 
 | |
| define cfd
 | |
|     if (((unsigned int)$eflags >>0xA) & 1)
 | |
|         set $eflags = (unsigned int)$eflags&~0x400
 | |
|     else
 | |
|         set $eflags = (unsigned int)$eflags|0x400
 | |
|     end
 | |
| end
 | |
| document cfd
 | |
| Syntax: cfd
 | |
| | Change Direction Flag.
 | |
| end
 | |
| 
 | |
| 
 | |
| define cfo
 | |
|     if (((unsigned int)$eflags >> 0xB) & 1)
 | |
|         set $eflags = (unsigned int)$eflags&~0x800
 | |
|     else
 | |
|         set $eflags = (unsigned int)$eflags|0x800
 | |
|     end
 | |
| end
 | |
| document cfo
 | |
| Syntax: cfo
 | |
| | Change Overflow Flag.
 | |
| end
 | |
| 
 | |
| 
 | |
| # Overflow (V), bit 28
 | |
| define cfv
 | |
|     if $ARM == 1
 | |
|     	set $tempflag = $cpsr->v
 | |
|         if ($tempflag & 1)
 | |
|             set $cpsr->v = $tempflag&~0x1
 | |
|         else
 | |
|             set $cpsr->v = $tempflag|0x1
 | |
|         end
 | |
|     end
 | |
| end
 | |
| document cfv
 | |
| Syntax: cfv
 | |
| | Change Overflow Flag.
 | |
| end
 | |
| 
 | |
| 
 | |
| # ____________________patch___________________
 | |
| # the usual nops are mov r0,r0 for arm (0xe1a00000)
 | |
| # and mov r8,r8 in Thumb (0x46c0)
 | |
| # armv7 has other nops
 | |
| # FIXME: make sure that the interval fits the 32bits address for arm and 16bits for thumb
 | |
| # status: works, fixme
 | |
| define nop
 | |
|     if ($argc > 2 || $argc == 0)
 | |
|         help nop
 | |
|     end
 | |
| 
 | |
|     if $ARM == 1
 | |
|         if ($argc == 1)
 | |
|             if ($cpsr->t &1)
 | |
|                 # thumb
 | |
|                 set *(short *)$arg0 = 0x46c0
 | |
|             else
 | |
|                 # arm
 | |
|                 set *(int *)$arg0 = 0xe1a00000
 | |
|             end
 | |
|         else
 | |
|             set $addr = $arg0
 | |
|             if ($cpsr->t & 1)
 | |
|                 # thumb
 | |
|                 while ($addr < $arg1)
 | |
|                     set *(short *)$addr = 0x46c0
 | |
|                     set $addr = $addr + 2
 | |
|                 end
 | |
|             else
 | |
|                 # arm
 | |
|                 while ($addr < $arg1)
 | |
|                     set *(int *)$addr = 0xe1a00000
 | |
|                     set $addr = $addr + 4
 | |
|                 end
 | |
|             end
 | |
|         end 
 | |
|     else
 | |
|         if ($argc == 1)
 | |
|             set *(unsigned char *)$arg0 = 0x90
 | |
|         else
 | |
|             set $addr = $arg0
 | |
|             while ($addr < $arg1)
 | |
|                 set *(unsigned char *)$addr = 0x90
 | |
|                 set $addr = $addr + 1
 | |
|             end
 | |
|         end
 | |
|     end
 | |
| end
 | |
| document nop
 | |
| Syntax: nop ADDR1 [ADDR2]
 | |
| | Patch a single byte at address ADDR1, or a series of bytes between ADDR1 and ADDR2 to a NOP (0x90) instruction.
 | |
| | ARM or Thumb code will be patched accordingly.
 | |
| end
 | |
| 
 | |
| 
 | |
| define null
 | |
|     if ( $argc >2 || $argc == 0)
 | |
|         help null
 | |
|     end
 | |
| 
 | |
|     if ($argc == 1)
 | |
|         set *(unsigned char *)$arg0 = 0
 | |
|     else
 | |
|         set $addr = $arg0
 | |
|         while ($addr < $arg1)
 | |
|             set *(unsigned char *)$addr = 0
 | |
|             set $addr = $addr +1
 | |
|         end
 | |
|     end
 | |
| end
 | |
| document null
 | |
| Syntax: null ADDR1 [ADDR2]
 | |
| | Patch a single byte at address ADDR1 to NULL (0x00), or a series of bytes between ADDR1 and ADDR2.
 | |
| end
 | |
| 
 | |
| # FIXME: thumb breakpoint ?
 | |
| define int3
 | |
|     if $argc != 1
 | |
|         help int3
 | |
|     else
 | |
|         if $ARM == 1
 | |
|             set $ORIGINAL_INT3 = *(unsigned int *)$arg0
 | |
|             set $ORIGINAL_INT3ADDRESS = $arg0
 | |
|             set *(unsigned int*)$arg0 = 0xe7ffdefe
 | |
|         else
 | |
|             # save original bytes and address
 | |
|             set $ORIGINAL_INT3 = *(unsigned char *)$arg0
 | |
|             set $ORIGINAL_INT3ADDRESS = $arg0
 | |
|             # patch
 | |
|             set *(unsigned char *)$arg0 = 0xCC
 | |
|         end
 | |
|     end
 | |
| end
 | |
| document int3
 | |
| Syntax int3 ADDR
 | |
| | Patch byte at address ADDR to an INT3 (0xCC) instruction or the equivalent software breakpoint for ARM.
 | |
| end
 | |
| 
 | |
| 
 | |
| define rint3
 | |
|     if $ARM == 1
 | |
|       	set *(unsigned int *)$ORIGINAL_INT3ADDRESS = $ORIGINAL_INT3
 | |
|         set $pc = $ORIGINAL_INT3ADDRESS
 | |
|     else
 | |
|         set *(unsigned char *)$ORIGINAL_INT3ADDRESS = $ORIGINAL_INT3
 | |
|         if ($64BITS == 1)
 | |
|             set $rip = $ORIGINAL_INT3ADDRESS
 | |
|         else
 | |
|             set $eip = $ORIGINAL_INT3ADDRESS
 | |
|         end
 | |
|     end
 | |
| end
 | |
| document rint3
 | |
| Syntax: rint3
 | |
| | Restore the original byte previous to int3 patch issued with "int3" command.
 | |
| end
 | |
| 
 | |
| define patch
 | |
|     if $argc != 3
 | |
|         help patch
 | |
|     end
 | |
|     set $patchaddr = $arg0
 | |
|     set $patchbytes = $arg1
 | |
|     set $patchsize = $arg2
 | |
| 
 | |
|     if ($patchsize == 1)
 | |
|         set *(unsigned char*)$patchaddr = $patchbytes
 | |
|     end
 | |
|     if ($patchsize == 2)
 | |
|         set $lendianbytes = (unsigned short)(($patchbytes << 8) | ($patchbytes >> 8))
 | |
|         set *(unsigned short*)$patchaddr = $lendianbytes
 | |
|     end
 | |
|     if ($patchsize == 4)
 | |
|         set $lendianbytes = (unsigned int)( (($patchbytes << 8) & 0xFF00FF00 ) | (($patchbytes >> 8) & 0xFF00FF ))
 | |
|         set $lendianbytes = (unsigned int)($lendianbytes << 0x10 | $lendianbytes >> 0x10)
 | |
|         set *(unsigned int*)$patchaddr = $lendianbytes
 | |
|     end
 | |
|     if ($patchsize == 8)
 | |
|         set $lendianbytes = (unsigned long long)( (($patchbytes << 8) & 0xFF00FF00FF00FF00ULL ) | (($patchbytes >> 8) & 0x00FF00FF00FF00FFULL ) )
 | |
|         set $lendianbytes = (unsigned long long)( (($lendianbytes << 0x10) & 0xFFFF0000FFFF0000ULL ) | (($lendianbytes >> 0x10) & 0x0000FFFF0000FFFFULL ) )
 | |
|         set $lendianbytes = (unsigned long long)( ($lendianbytes << 0x20) | ($lendianbytes >> 0x20) )
 | |
|         set *(unsigned long long*)$patchaddr = $lendianbytes
 | |
|     end
 | |
| end
 | |
| document patch
 | |
| Syntax: patch address bytes size
 | |
| | Patch a given address, converting the bytes to little-endian.
 | |
| | Assumes input bytes are unsigned values and should be in hexadecimal format (0x...).
 | |
| | Size must be 1, 2, 4, 8 bytes.
 | |
| | Main purpose is to be used with the output from the asm commands.
 | |
| end
 | |
| 
 | |
| # ____________________cflow___________________
 | |
| define print_insn_type
 | |
|     if $argc != 1
 | |
|         help print_insn_type
 | |
|     else
 | |
|         if ($arg0 < 0 || $arg0 > 5)
 | |
|             printf "UNDEFINED/WRONG VALUE"
 | |
|         end
 | |
|         if ($arg0 == 0)
 | |
|             printf "UNKNOWN"
 | |
|         end
 | |
|         if ($arg0 == 1)
 | |
|             printf "JMP"
 | |
|         end
 | |
|         if ($arg0 == 2)
 | |
|             printf "JCC"
 | |
|         end
 | |
|         if ($arg0 == 3)
 | |
|             printf "CALL"
 | |
|         end
 | |
|         if ($arg0 == 4)
 | |
|             printf "RET"
 | |
|         end
 | |
|         if ($arg0 == 5)
 | |
|             printf "INT"
 | |
|         end
 | |
|     end
 | |
| end
 | |
| document print_insn_type
 | |
| Syntax: print_insn_type INSN_TYPE_NUMBER
 | |
| | Print human-readable mnemonic for the instruction type (usually $INSN_TYPE).
 | |
| end
 | |
| 
 | |
| 
 | |
| define get_insn_type
 | |
|     if $argc != 1
 | |
|         help get_insn_type
 | |
|     else
 | |
|         set $INSN_TYPE = 0
 | |
|         set $_byte1 = *(unsigned char *)$arg0
 | |
|         if ($_byte1 == 0x9A || $_byte1 == 0xE8)
 | |
|             # "call"
 | |
|             set $INSN_TYPE = 3
 | |
|         end
 | |
|         if ($_byte1 >= 0xE9 && $_byte1 <= 0xEB)
 | |
|             # "jmp"
 | |
|             set $INSN_TYPE = 1
 | |
|         end
 | |
|         if ($_byte1 >= 0x70 && $_byte1 <= 0x7F)
 | |
|             # "jcc"
 | |
|             set $INSN_TYPE = 2
 | |
|         end
 | |
|         if ($_byte1 >= 0xE0 && $_byte1 <= 0xE3 )
 | |
|             # "jcc"
 | |
|             set $INSN_TYPE = 2
 | |
|         end
 | |
|         if ($_byte1 == 0xC2 || $_byte1 == 0xC3 || $_byte1 == 0xCA || \
 | |
|             $_byte1 == 0xCB || $_byte1 == 0xCF)
 | |
|             # "ret"
 | |
|             set $INSN_TYPE = 4
 | |
|         end
 | |
|         if ($_byte1 >= 0xCC && $_byte1 <= 0xCE)
 | |
|             # "int"
 | |
|             set $INSN_TYPE = 5
 | |
|         end
 | |
|         if ($_byte1 == 0x0F )
 | |
|             # two-byte opcode
 | |
|             set $_byte2 = *(unsigned char *)($arg0 + 1)
 | |
|             if ($_byte2 >= 0x80 && $_byte2 <= 0x8F)
 | |
|                 # "jcc"
 | |
|                 set $INSN_TYPE = 2
 | |
|             end
 | |
|         end
 | |
|         if ($_byte1 == 0xFF)        
 | |
|             # opcode extension
 | |
|             set $_byte2 = *(unsigned char *)($arg0 + 1)
 | |
|             set $_opext = ($_byte2 & 0x38)
 | |
|             if ($_opext == 0x10 || $_opext == 0x18) 
 | |
|                 # "call"
 | |
|                 set $INSN_TYPE = 3
 | |
|             end
 | |
|             if ($_opext == 0x20 || $_opext == 0x28)
 | |
|                 # "jmp"
 | |
|                 set $INSN_TYPE = 1
 | |
|             end
 | |
|         end
 | |
|     end
 | |
| end
 | |
| document get_insn_type
 | |
| Syntax: get_insn_type ADDR
 | |
| | Recognize instruction type at address ADDR.
 | |
| | Take address ADDR and set the global $INSN_TYPE variable to
 | |
| | 0, 1, 2, 3, 4, 5 if the instruction at that address is
 | |
| | unknown, a jump, a conditional jump, a call, a return, or an interrupt.
 | |
| end
 | |
| 
 | |
| 
 | |
| define step_to_call
 | |
|     set $_saved_ctx = $SHOW_CONTEXT
 | |
|     set $SHOW_CONTEXT = 0
 | |
|     set $SHOW_NEST_INSN = 0
 | |
| 
 | |
|     set logging file /dev/null
 | |
|     set logging redirect on
 | |
|     set logging enabled on
 | |
| 
 | |
|     set $_cont = 1
 | |
|     while ($_cont > 0)
 | |
|         stepi
 | |
|         get_insn_type $pc
 | |
|         if ($INSN_TYPE == 3)
 | |
|             set $_cont = 0
 | |
|         end
 | |
|     end
 | |
| 
 | |
|     set logging enabled off
 | |
| 
 | |
|     if ($_saved_ctx > 0)
 | |
|         context
 | |
|     end
 | |
| 
 | |
|     set $SHOW_CONTEXT = $_saved_ctx
 | |
|     set $SHOW_NEST_INSN = 0
 | |
| 
 | |
|     set logging file ~/gdb.txt
 | |
|     set logging redirect off
 | |
|     set logging enabled on
 | |
| 
 | |
|     printf "step_to_call command stopped at:\n  "
 | |
|     x/i $pc
 | |
|     printf "\n"
 | |
|     set logging enabled off
 | |
| 
 | |
| end
 | |
| document step_to_call
 | |
| Syntax: step_to_call
 | |
| | Single step until a call instruction is found.
 | |
| | Stop before the call is taken.
 | |
| | Log is written into the file ~/gdb.txt.
 | |
| end
 | |
| 
 | |
| 
 | |
| define trace_calls
 | |
| 
 | |
|     printf "Tracing...please wait...\n"
 | |
| 
 | |
|     set $_saved_ctx = $SHOW_CONTEXT
 | |
|     set $SHOW_CONTEXT = 0
 | |
|     set $SHOW_NEST_INSN = 0
 | |
|     set $_nest = 1
 | |
|     set listsize 0
 | |
|   
 | |
|     set logging overwrite on
 | |
|     set logging file ~/gdb_trace_calls.txt
 | |
|     set logging enabled on
 | |
|     set logging enabled off
 | |
|     set logging overwrite off
 | |
| 
 | |
|     while ($_nest > 0)
 | |
|         get_insn_type $pc
 | |
|         # handle nesting
 | |
|         if ($INSN_TYPE == 3)
 | |
|             set $_nest = $_nest + 1
 | |
|         else
 | |
|             if ($INSN_TYPE == 4)
 | |
|                 set $_nest = $_nest - 1
 | |
|             end
 | |
|         end
 | |
|         # if a call, print it
 | |
|         if ($INSN_TYPE == 3)
 | |
|             set logging file ~/gdb_trace_calls.txt
 | |
|             set logging redirect off
 | |
|             set logging enabled on
 | |
| 
 | |
|             set $x = $_nest - 2
 | |
|             while ($x > 0)
 | |
|                 printf "\t"
 | |
|                 set $x = $x - 1
 | |
|             end
 | |
|             x/i $pc
 | |
|         end
 | |
| 
 | |
|         set logging enabled off
 | |
|         set logging file /dev/null
 | |
|         set logging redirect on
 | |
|         set logging enabled on
 | |
|         stepi
 | |
|         set logging redirect off
 | |
|         set logging enabled off
 | |
|     end
 | |
| 
 | |
|     set $SHOW_CONTEXT = $_saved_ctx
 | |
|     set $SHOW_NEST_INSN = 0
 | |
|  
 | |
|     printf "Done, check ~/gdb_trace_calls.txt\n"
 | |
| end
 | |
| document trace_calls
 | |
| Syntax: trace_calls
 | |
| | Create a runtime trace of the calls made by target.
 | |
| | Log overwrites(!) the file ~/gdb_trace_calls.txt.
 | |
| end
 | |
| 
 | |
| 
 | |
| define trace_run
 | |
|  
 | |
|     printf "Tracing...please wait...\n"
 | |
| 
 | |
|     set $_saved_ctx = $SHOW_CONTEXT
 | |
|     set $SHOW_CONTEXT = 0
 | |
|     set $SHOW_NEST_INSN = 1
 | |
|     set logging overwrite on
 | |
|     set logging file ~/gdb_trace_run.txt
 | |
|     set logging redirect on
 | |
|     set logging enabled on
 | |
|     set $_nest = 1
 | |
| 
 | |
|     while ( $_nest > 0 )
 | |
| 
 | |
|         get_insn_type $pc
 | |
|         # jmp, jcc, or cll
 | |
|         if ($INSN_TYPE == 3)
 | |
|             set $_nest = $_nest + 1
 | |
|         else
 | |
|             # ret
 | |
|             if ($INSN_TYPE == 4)
 | |
|                 set $_nest = $_nest - 1
 | |
|             end
 | |
|         end
 | |
|         stepi
 | |
|     end
 | |
| 
 | |
|     printf "\n"
 | |
| 
 | |
|     set $SHOW_CONTEXT = $_saved_ctx
 | |
|     set $SHOW_NEST_INSN = 0
 | |
|     set logging redirect off
 | |
|     set logging enabled off
 | |
| 
 | |
|     # clean up trace file
 | |
|     shell  grep -v ' at ' ~/gdb_trace_run.txt > ~/gdb_trace_run.1
 | |
|     shell  grep -v ' in ' ~/gdb_trace_run.1 > ~/gdb_trace_run.txt
 | |
|     shell  rm -f ~/gdb_trace_run.1
 | |
|     printf "Done, check ~/gdb_trace_run.txt\n"
 | |
| end
 | |
| document trace_run
 | |
| Syntax: trace_run
 | |
| | Create a runtime trace of target.
 | |
| | Log overwrites(!) the file ~/gdb_trace_run.txt.
 | |
| end
 | |
| 
 | |
| define entry_point
 | |
|     set logging redirect on
 | |
|     set logging file /tmp/gdb-entry_point
 | |
|     set logging enabled on
 | |
|     info files
 | |
|     set logging enabled off
 | |
|     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
 | |
|     source /tmp/gdb-entry_point
 | |
|     shell /bin/rm -f /tmp/gdb-entry_point
 | |
| end
 | |
| document entry_point
 | |
| Syntax: entry_point
 | |
| | Prints the entry point address of the target and stores it in the variable entry_point.
 | |
| end
 | |
| 
 | |
| define break_entrypoint
 | |
|     entry_point
 | |
|     break *$entry_point_address
 | |
| end
 | |
| document break_entrypoint
 | |
| Syntax: break_entrypoint
 | |
| | Sets a breakpoint on the entry point of the target.
 | |
| end
 | |
| 
 | |
| define objc_symbols
 | |
|     set logging redirect on
 | |
|     set logging file /tmp/gdb-objc_symbols
 | |
|     set logging enabled on
 | |
|     info target
 | |
|     set logging enabled off
 | |
|     # XXX: define paths for objc-symbols and SymTabCreator
 | |
|     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
 | |
|     set logging enabled on
 | |
|     add-symbol-file /tmp/gdb-symtab
 | |
|     set logging enabled off
 | |
|     shell /bin/rm -f /tmp/gdb-objc_symbols
 | |
| end
 | |
| document objc_symbols
 | |
| Syntax: objc_symbols
 | |
| | Loads stripped objc symbols into gdb using objc-symbols and SymTabCreator
 | |
| | See http://stackoverflow.com/questions/17554070/import-class-dump-info-into-gdb
 | |
| | and https://github.com/0xced/class-dump/tree/objc-symbols (for the required utils)
 | |
| end
 | |
| 
 | |
| #define ptraceme
 | |
| #    catch syscall ptrace
 | |
| #    commands
 | |
| #        if ($64BITS == 0)
 | |
| #            if ($ebx == 0)
 | |
| #               set $eax = 0
 | |
| #               continue
 | |
| #            end
 | |
| #        else
 | |
| #            if ($rdi == 0)
 | |
| #                set $rax = 0
 | |
| #                continue
 | |
| #            end
 | |
| #        end
 | |
| #    end
 | |
| #    set $ptrace_bpnum = $bpnum
 | |
| #end
 | |
| #document ptraceme
 | |
| #Syntax: ptraceme
 | |
| #| Hook ptrace to bypass PTRACE_TRACEME anti debugging technique
 | |
| #end
 | |
| 
 | |
| define rptraceme
 | |
|     if ($ptrace_bpnum != 0)
 | |
|         delete $ptrace_bpnum
 | |
|         set $ptrace_bpnum = 0
 | |
|     end
 | |
| end
 | |
| document rptraceme
 | |
| Syntax: rptraceme
 | |
| | Remove ptrace hook.
 | |
| end
 | |
| 
 | |
| 
 | |
| # ____________________misc____________________
 | |
| define hook-stop
 | |
|     if (sizeof(void*) == 8)
 | |
|         set $64BITS = 1
 | |
|     else
 | |
|         set $64BITS = 0
 | |
|     end
 | |
| 
 | |
|     if ($KDP64BITS != -1)
 | |
|         if ($KDP64BITS == 0)
 | |
|             set $64BITS = 0
 | |
|         else
 | |
|             set $64BITS = 1
 | |
|         end
 | |
|     end
 | |
| 
 | |
|     # Display instructions formats
 | |
|     if $ARM == 1
 | |
|         if $ARMOPCODES == 1
 | |
|             set arm show-opcode-bytes 1
 | |
|         end
 | |
|     else
 | |
|         if $X86FLAVOR == 0
 | |
|             set disassembly-flavor intel
 | |
|         else
 | |
|             set disassembly-flavor att
 | |
|         end
 | |
|     end
 | |
| 
 | |
|     # this makes 'context' be called at every BP/step
 | |
|     if ($SHOW_CONTEXT > 0)
 | |
|         context
 | |
|     end
 | |
|     if ($SHOW_NEST_INSN > 0)
 | |
|         set $x = $_nest
 | |
|         while ($x > 0)
 | |
|             printf "\t"
 | |
|             set $x = $x - 1
 | |
|         end
 | |
|     end
 | |
| end
 | |
| document hook-stop
 | |
| Syntax: hook-stop
 | |
| | !!! FOR INTERNAL USE ONLY - DO NOT CALL !!!
 | |
| end
 | |
| 
 | |
| 
 | |
| # original by Tavis Ormandy (http://my.opera.com/taviso/blog/index.dml/tag/gdb) (great fix!)
 | |
| # modified to work with Mac OS X by fG!
 | |
| # seems nasm shipping with Mac OS X has problems accepting input from stdin or heredoc
 | |
| # input is read into a variable and sent to a temporary file which nasm can read
 | |
| define assemble
 | |
|     # dont enter routine again if user hits enter
 | |
|     dont-repeat
 | |
|     if ($argc)
 | |
|         if (*$arg0 = *$arg0)
 | |
|         # check if we have a valid address by dereferencing it,
 | |
|         # if we havnt, this will cause the routine to exit.
 | |
|         end
 | |
|         printf "Instructions will be written to %#x.\n", $arg0
 | |
|     else
 | |
|         printf "Instructions will be written to stdout.\n"
 | |
|     end
 | |
|     printf "Type instructions, one per line."
 | |
|     color_bold
 | |
|     printf " Do not forget to use NASM assembler syntax!\n"
 | |
|     color_reset
 | |
|     printf "End with a line saying just \"end\".\n"
 | |
|     
 | |
|     if ($argc)
 | |
|         if ($64BITS == 1)
 | |
|             # argument specified, assemble instructions into memory at address specified.
 | |
|             shell ASMOPCODE="$(while read -ep '>' r && test "$r" != end ; do echo -E "$r"; done)" ; GDBASMFILENAME=$RANDOM; \
 | |
|             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
 | |
|             source /tmp/gdbassemble
 | |
|             # all done. clean the temporary file
 | |
|             shell /bin/rm -f /tmp/gdbassemble
 | |
|         else
 | |
|             # argument specified, assemble instructions into memory at address specified.
 | |
|             shell ASMOPCODE="$(while read -ep '>' r && test "$r" != end ; do echo -E "$r"; done)" ; GDBASMFILENAME=$RANDOM; \
 | |
|             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
 | |
|             source /tmp/gdbassemble
 | |
|             # all done. clean the temporary file
 | |
|             shell /bin/rm -f /tmp/gdbassemble
 | |
|         end
 | |
|     else
 | |
|         if ($64BITS == 1)
 | |
|             # no argument, assemble instructions to stdout
 | |
|             shell ASMOPCODE="$(while read -ep '>' r && test "$r" != end ; do echo -E "$r"; done)" ; GDBASMFILENAME=$RANDOM; \
 | |
|             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 ; \
 | |
|             /bin/rm -f /tmp/$GDBASMFILENAME
 | |
|     	else
 | |
|             # no argument, assemble instructions to stdout
 | |
|             shell ASMOPCODE="$(while read -ep '>' r && test "$r" != end ; do echo -E "$r"; done)" ; GDBASMFILENAME=$RANDOM; \
 | |
|             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 ; \
 | |
|             /bin/rm -f /tmp/$GDBASMFILENAME
 | |
|         end
 | |
|     end
 | |
| end
 | |
| document assemble
 | |
| Syntax: assemble <ADDR>
 | |
| | Assemble instructions using nasm.
 | |
| | Type a line containing "end" to indicate the end.
 | |
| | If an address is specified, insert/modify instructions at that address.
 | |
| | If no address is specified, assembled instructions are printed to stdout.
 | |
| | Use the pseudo instruction "org ADDR" to set the base address.
 | |
| end
 | |
| 
 | |
| define assemble32
 | |
|     # dont enter routine again if user hits enter
 | |
|     dont-repeat
 | |
|     if ($argc)
 | |
|         if (*$arg0 = *$arg0)
 | |
|         # check if we have a valid address by dereferencing it,
 | |
|         # if we havnt, this will cause the routine to exit.
 | |
|         end
 | |
|         printf "Instructions will be written to %#x.\n", $arg0
 | |
|     else
 | |
|         printf "Instructions will be written to stdout.\n"
 | |
|     end
 | |
|     printf "Type instructions, one per line."
 | |
|     color_bold
 | |
|     printf " Do not forget to use NASM assembler syntax!\n"
 | |
|     color_reset
 | |
|     printf "End with a line saying just \"end\".\n"
 | |
|     
 | |
|     if ($argc)
 | |
|         # argument specified, assemble instructions into memory at address specified.
 | |
|         shell ASMOPCODE="$(while read -ep '>' r && test "$r" != end ; do echo -E "$r"; done)" ; GDBASMFILENAME=$RANDOM; \
 | |
|         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
 | |
|         source /tmp/gdbassemble
 | |
|         # all done. clean the temporary file
 | |
|         shell /bin/rm -f /tmp/gdbassemble
 | |
|     else
 | |
|         # no argument, assemble instructions to stdout
 | |
|         shell ASMOPCODE="$(while read -ep '>' r && test "$r" != end ; do echo -E "$r"; done)" ; GDBASMFILENAME=$RANDOM; \
 | |
|         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 ; \
 | |
|         /bin/rm -f /tmp/$GDBASMFILENAME
 | |
|     end
 | |
| end
 | |
| document assemble32
 | |
| Syntax: assemble32 <ADDR>
 | |
| | Assemble 32 bits instructions using nasm.
 | |
| | Type a line containing "end" to indicate the end.
 | |
| | If an address is specified, insert/modify instructions at that address.
 | |
| | If no address is specified, assembled instructions are printed to stdout.
 | |
| | Use the pseudo instruction "org ADDR" to set the base address.
 | |
| end
 | |
| 
 | |
| define assemble64
 | |
|     # dont enter routine again if user hits enter
 | |
|     dont-repeat
 | |
|     if ($argc)
 | |
|         if (*$arg0 = *$arg0)
 | |
|         # check if we have a valid address by dereferencing it,
 | |
|         # if we havnt, this will cause the routine to exit.
 | |
|         end
 | |
|         printf "Instructions will be written to %#x.\n", $arg0
 | |
|     else
 | |
|         printf "Instructions will be written to stdout.\n"
 | |
|     end
 | |
|     printf "Type instructions, one per line."
 | |
|     color_bold
 | |
|     printf " Do not forget to use NASM assembler syntax!\n"
 | |
|     color_reset
 | |
|     printf "End with a line saying just \"end\".\n"
 | |
|     
 | |
|     if ($argc)
 | |
|         # argument specified, assemble instructions into memory at address specified.
 | |
|         shell ASMOPCODE="$(while read -ep '>' r && test "$r" != end ; do echo -E "$r"; done)" ; GDBASMFILENAME=$RANDOM; \
 | |
|         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
 | |
|         source /tmp/gdbassemble
 | |
|         # all done. clean the temporary file
 | |
|         shell /bin/rm -f /tmp/gdbassemble
 | |
|     else
 | |
|         # no argument, assemble instructions to stdout
 | |
|         shell ASMOPCODE="$(while read -ep '>' r && test "$r" != end ; do echo -E "$r"; done)" ; GDBASMFILENAME=$RANDOM; \
 | |
|         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 ; \
 | |
|         /bin/rm -f /tmp/$GDBASMFILENAME
 | |
|     end
 | |
| end
 | |
| document assemble64
 | |
| Syntax: assemble64 <ADDR>
 | |
| | Assemble 64 bits instructions using nasm.
 | |
| | Type a line containing "end" to indicate the end.
 | |
| | If an address is specified, insert/modify instructions at that address.
 | |
| | If no address is specified, assembled instructions are printed to stdout.
 | |
| | Use the pseudo instruction "org ADDR" to set the base address.
 | |
| end
 | |
| 
 | |
| define asm
 | |
|     if $argc == 1
 | |
|         assemble $arg0
 | |
|     else
 | |
|         assemble
 | |
|     end
 | |
| end
 | |
| document asm
 | |
| Syntax: asm <ADDR>
 | |
| | Shortcut to the asssemble command.
 | |
| end
 | |
| 
 | |
| define asm32
 | |
|     if $argc == 1
 | |
|         assemble32 $arg0
 | |
|     else
 | |
|         assemble32
 | |
|     end
 | |
| end
 | |
| document asm32
 | |
| Syntax: asm32 <ADDR>
 | |
| | Shortcut to the assemble32 command.
 | |
| end
 | |
| 
 | |
| define asm64
 | |
|     if $argc == 1
 | |
|         assemble64 $arg0
 | |
|     else
 | |
|         assemble64
 | |
|     end
 | |
| end
 | |
| document asm64
 | |
| Syntax: asm64 <ADDR>
 | |
| | Shortcut to the assemble64 command.
 | |
| end
 | |
| 
 | |
| define assemble_gas
 | |
|     printf "\nType code to assemble and hit Ctrl-D when finished.\n"
 | |
|     printf "You must use GNU assembler (AT&T) syntax.\n"
 | |
| 
 | |
|     shell filename=$(mktemp); \
 | |
|           binfilename=$(mktemp); \
 | |
|           echo -e "Writing into: ${filename}\n"; \
 | |
|           cat > $filename; echo ""; \
 | |
|           as -o $binfilename < $filename; \
 | |
|           objdump -d -j .text $binfilename; \
 | |
|           rm -f $binfilename; \
 | |
|           rm -f $filename; \
 | |
|           echo -e "temporaly files deleted.\n"
 | |
| end
 | |
| document assemble_gas
 | |
| Syntax: assemble_gas
 | |
| | Assemble instructions to binary opcodes. Uses GNU as and objdump.
 | |
| end
 | |
| 
 | |
| 
 | |
| define dump_hexfile
 | |
|     dump ihex memory $arg0 $arg1 $arg2
 | |
| end
 | |
| document dump_hexfile
 | |
| Syntax: dump_hexfile FILENAME ADDR1 ADDR2
 | |
| | Write a range of memory to a file in Intel ihex (hexdump) format.
 | |
| | The range is specified by ADDR1 and ADDR2 addresses.
 | |
| end
 | |
| 
 | |
| 
 | |
| define dump_binfile
 | |
|     dump memory $arg0 $arg1 $arg2
 | |
| end
 | |
| document dump_binfile
 | |
| Syntax: dump_binfile FILENAME ADDR1 ADDR2
 | |
| | Write a range of memory to a binary file.
 | |
| | The range is specified by ADDR1 and ADDR2 addresses.
 | |
| end
 | |
| 
 | |
| 
 | |
| define dumpmacho
 | |
|     if $argc != 2
 | |
|         help dumpmacho
 | |
|     end
 | |
|     set $headermagic = *$arg0
 | |
|     # the || operator isn't working as it should, wtf!!!
 | |
|     if $headermagic != 0xfeedface
 | |
|         if $headermagic != 0xfeedfacf
 | |
|             printf "[Error] Target address doesn't contain a valid Mach-O binary!\n"
 | |
|             help dumpmacho
 | |
|         end
 | |
|     end
 | |
|     set $headerdumpsize = *($arg0+0x14)
 | |
|     if $headermagic == 0xfeedface
 | |
|         dump memory $arg1 $arg0 ($arg0+0x1c+$headerdumpsize)
 | |
|     end
 | |
|     if $headermagic == 0xfeedfacf
 | |
|         dump memory $arg1 $arg0 ($arg0+0x20+$headerdumpsize)
 | |
|     end
 | |
| end
 | |
| document dumpmacho
 | |
| Syntax: dumpmacho STARTADDRESS FILENAME
 | |
| | Dump the Mach-O header to a file.
 | |
| | You need to input the start address (use info shared command to find it).
 | |
| end
 | |
| 
 | |
| 
 | |
| define cls
 | |
|     shell clear
 | |
| end
 | |
| document cls
 | |
| Syntax: cls
 | |
| | Clear screen.
 | |
| end
 | |
| 
 | |
| 
 | |
| define search
 | |
|     set $start = (char *) $arg0
 | |
|     set $end = (char *) $arg1
 | |
|     set $pattern = (short) $arg2
 | |
|     set $p = $start
 | |
|     while $p < $end
 | |
|         if (*(short *) $p) == $pattern
 | |
|             printf "pattern 0x%hx found at 0x%x\n", $pattern, $p
 | |
|         end
 | |
|         set $p++
 | |
|     end
 | |
| end
 | |
| document search
 | |
| Syntax: search <START> <END> <PATTERN>
 | |
| | Search for the given pattern beetween $start and $end address.
 | |
| end
 | |
| 
 | |
| 
 | |
| # _________________user tips_________________
 | |
| # The 'tips' command is used to provide tutorial-like info to the user
 | |
| define tips
 | |
|     printf "Tip Topic Commands:\n"
 | |
|     printf "\ttip_display : Automatically display values on each break\n"
 | |
|     printf "\ttip_patch   : Patching binaries\n"
 | |
|     printf "\ttip_strip   : Dealing with stripped binaries\n"
 | |
|     printf "\ttip_syntax  : AT&T vs Intel syntax\n"
 | |
| end
 | |
| document tips
 | |
| Syntax: tips
 | |
| | Provide a list of tips from users on various topics.
 | |
| end
 | |
| 
 | |
| 
 | |
| define tip_patch
 | |
|     printf "\n"
 | |
|     printf "                   PATCHING MEMORY\n"
 | |
|     printf "Any address can be patched using the 'set' command:\n"
 | |
|     printf "\t`set ADDR = VALUE` \te.g. `set *0x8049D6E = 0x90`\n"
 | |
|     printf "\n"
 | |
|     printf "                 PATCHING BINARY FILES\n"
 | |
|     printf "Use `set write` in order to patch the target executable\n"
 | |
|     printf "directly, instead of just patching memory\n"
 | |
|     printf "\t`set write on` \t`set write off`\n"
 | |
|     printf "Note that this means any patches to the code or data segments\n"
 | |
|     printf "will be written to the executable file\n"
 | |
|     printf "When either of these commands has been issued,\n"
 | |
|     printf "the file must be reloaded.\n"
 | |
|     printf "\n"
 | |
| end
 | |
| document tip_patch
 | |
| Syntax: tip_patch
 | |
| | Tips on patching memory and binary files.
 | |
| end
 | |
| 
 | |
| 
 | |
| define tip_strip
 | |
|     printf "\n"
 | |
|     printf "             STOPPING BINARIES AT ENTRY POINT\n"
 | |
|     printf "Stripped binaries have no symbols, and are therefore tough to\n"
 | |
|     printf "start automatically. To debug a stripped binary, use\n"
 | |
|     printf "\tinfo file\n"
 | |
|     printf "to get the entry point of the file\n"
 | |
|     printf "The first few lines of output will look like this:\n"
 | |
|     printf "\tSymbols from '/tmp/a.out'\n"
 | |
|     printf "\tLocal exec file:\n"
 | |
|     printf "\t        `/tmp/a.out', file type elf32-i386.\n"
 | |
|     printf "\t        Entry point: 0x80482e0\n"
 | |
|     printf "Use this entry point to set an entry point:\n"
 | |
|     printf "\t`tbreak *0x80482e0`\n"
 | |
|     printf "The breakpoint will delete itself after the program stops as\n"
 | |
|     printf "the entry point\n"
 | |
|     printf "\n"
 | |
| end
 | |
| document tip_strip
 | |
| Syntax: tip_strip
 | |
| | Tips on dealing with stripped binaries.
 | |
| end
 | |
| 
 | |
| 
 | |
| define tip_syntax
 | |
|     printf "\n"
 | |
|     printf "\t    INTEL SYNTAX                        AT&T SYNTAX\n"
 | |
|     printf "\tmnemonic dest, src, imm            mnemonic src, dest, imm\n" 
 | |
|     printf "\t[base+index*scale+disp]            disp(base, index, scale)\n"
 | |
|     printf "\tregister:      eax                 register:      %%eax\n"
 | |
|     printf "\timmediate:     0xFF                immediate:     $0xFF\n"
 | |
|     printf "\tdereference:   [addr]              dereference:   addr(,1)\n"
 | |
|     printf "\tabsolute addr: addr                absolute addr: *addr\n"
 | |
|     printf "\tbyte insn:     mov byte ptr        byte insn:     movb\n"
 | |
|     printf "\tword insn:     mov word ptr        word insn:     movw\n"
 | |
|     printf "\tdword insn:    mov dword ptr       dword insn:    movd\n"
 | |
|     printf "\tfar call:      call far            far call:      lcall\n"
 | |
|     printf "\tfar jump:      jmp far             far jump:      ljmp\n"
 | |
|     printf "\n"
 | |
|     printf "Note that order of operands in reversed, and that AT&T syntax\n"
 | |
|     printf "requires that all instructions referencing memory operands \n"
 | |
|     printf "use an operand size suffix (b, w, d, q)\n"
 | |
|     printf "\n"
 | |
| end
 | |
| document tip_syntax
 | |
| Syntax: tip_syntax
 | |
| | Summary of Intel and AT&T syntax differences.
 | |
| end
 | |
| 
 | |
| 
 | |
| define tip_display
 | |
|     printf "\n"
 | |
|     printf "Any expression can be set to automatically be displayed every time\n"
 | |
|     printf "the target stops. The commands for this are:\n"
 | |
|     printf "\t`display expr'     : automatically display expression 'expr'\n"
 | |
|     printf "\t`display'          : show all displayed expressions\n"
 | |
|     printf "\t`undisplay num'    : turn off autodisplay for expression # 'num'\n"
 | |
|     printf "Examples:\n"
 | |
|     printf "\t`display/x *(int *)$esp`      : print top of stack\n"
 | |
|     printf "\t`display/x *(int *)($ebp+8)`  : print first parameter\n"
 | |
|     printf "\t`display (char *)$esi`        : print source string\n"
 | |
|     printf "\t`display (char *)$edi`        : print destination string\n"
 | |
|     printf "\n"
 | |
| end
 | |
| document tip_display
 | |
| Syntax: tip_display
 | |
| | Tips on automatically displaying values when a program stops.
 | |
| end
 | |
| 
 | |
| # bunch of semi-useless commands
 | |
| 
 | |
| # enable and disable shortcuts for stop-on-solib-events fantastic trick!
 | |
| define enablesolib
 | |
|     set stop-on-solib-events 1
 | |
|     printf "Stop-on-solib-events is enabled!\n"
 | |
| end
 | |
| document enablesolib
 | |
| Syntax: enablesolib
 | |
| | Shortcut to enable stop-on-solib-events trick.
 | |
| end
 | |
| 
 | |
| 
 | |
| define disablesolib
 | |
|     set stop-on-solib-events 0
 | |
|     printf "Stop-on-solib-events is disabled!\n"
 | |
| end
 | |
| document disablesolib
 | |
| Syntax: disablesolib
 | |
| | Shortcut to disable stop-on-solib-events trick.
 | |
| end
 | |
| 
 | |
| 
 | |
| # enable commands for different displays
 | |
| define enabledisasm
 | |
|     set $SHOWDISASM = 1
 | |
| end
 | |
| document enabledisasm
 | |
| Syntax: enabledisasm
 | |
| | Enable disassembly display.
 | |
| end
 | |
| 
 | |
| define enableobjectivec
 | |
|     set $SHOWOBJECTIVEC = 1
 | |
| end
 | |
| document enableobjectivec
 | |
| Syntax: enableobjectivec
 | |
| | Enable display of objective-c information in the context window.
 | |
| end
 | |
| 
 | |
| 
 | |
| define enablecpuregisters
 | |
|     set $SHOWCPUREGISTERS = 1
 | |
| end
 | |
| document enablecpuregisters
 | |
| Syntax: enablecpuregisters
 | |
| | Enable display of cpu registers in the context window.
 | |
| end
 | |
| 
 | |
| 
 | |
| define enablestack
 | |
|     set $SHOWSTACK = 1
 | |
| end
 | |
| document enablestack
 | |
| Syntax: enablestack
 | |
| | Enable display of stack in the context window.
 | |
| end
 | |
| 
 | |
| 
 | |
| define enabledatawin
 | |
|     set $SHOWDATAWIN = 1
 | |
| end
 | |
| document enabledatawin
 | |
| Syntax: enabledatawin
 | |
| | Enable display of data window in the context window.
 | |
| end
 | |
| 
 | |
| 
 | |
| # disable commands for different displays
 | |
| define disabledisasm
 | |
|     set $SHOWDISASM = 0
 | |
| end
 | |
| document disabledisasm
 | |
| Syntax: disabledisasm
 | |
| | Disable disassembly display.
 | |
| end
 | |
| 
 | |
| define disableobjectivec
 | |
|     set $SHOWOBJECTIVEC = 0
 | |
| end
 | |
| document disableobjectivec
 | |
| Syntax: disableobjectivec
 | |
| | Disable display of objective-c information in the context window.
 | |
| end
 | |
| 
 | |
| 
 | |
| define disablecpuregisters
 | |
|     set $SHOWCPUREGISTERS = 0
 | |
| end
 | |
| document disablecpuregisters
 | |
| Syntax: disablecpuregisters
 | |
| | Disable display of cpu registers in the context window.
 | |
| end
 | |
| 
 | |
| 
 | |
| define disablestack
 | |
|     set $SHOWSTACK = 0
 | |
| end
 | |
| document disablestack
 | |
| Syntax: disablestack
 | |
| | Disable display of stack information in the context window.
 | |
| end
 | |
| 
 | |
| 
 | |
| define disabledatawin
 | |
|     set $SHOWDATAWIN = 0
 | |
| end
 | |
| document disabledatawin
 | |
| Syntax: disabledatawin
 | |
| | Disable display of data window in the context window.
 | |
| end
 | |
| 
 | |
| 
 | |
| define arm
 | |
|     if $ARMOPCODES == 1
 | |
|         set arm show-opcode-bytes 1
 | |
|     end
 | |
|     set $ARM = 1
 | |
| end
 | |
| document arm
 | |
| Syntax: arm
 | |
| | Set gdb to work with ARM binaries.
 | |
| end
 | |
| 
 | |
| define ioskdp
 | |
|     set $SHOW_CONTEXT = 0
 | |
|     set $SHOW_NEST_INSN = 0
 | |
| end
 | |
| document ioskdp
 | |
| Syntax: ioskdp
 | |
| | Disable dumping context information for iOS KDP debugging
 | |
| end
 | |
| 
 | |
| define intelsyntax
 | |
|     if $ARM == 0
 | |
|         set disassembly-flavor intel
 | |
|         set $X86FLAVOR = 0
 | |
|     end
 | |
| end
 | |
| document intelsyntax
 | |
| Syntax: intelsyntax
 | |
| | Change disassembly syntax to intel flavor.
 | |
| end
 | |
| 
 | |
| 
 | |
| define attsyntax
 | |
|     if $ARM == 0
 | |
|         set disassembly-flavor att
 | |
|         set $X86FLAVOR = 1
 | |
|     end
 | |
| end
 | |
| document attsyntax
 | |
| Syntax: attsyntax
 | |
| | Change disassembly syntax to at&t flavor.
 | |
| end
 | |
| 
 | |
| define kernel32
 | |
|     if $argc != 0
 | |
|         # try to load kgmacros files
 | |
|         # failure is silent if non-existent...
 | |
|         source $arg0
 | |
|         set architecture i386
 | |
|         if $argc == 2
 | |
|             target remote localhost:$arg1
 | |
|         else
 | |
|             target remote localhost:8832
 | |
|         end
 | |
|     else
 | |
|         help kernel32
 | |
|     end
 | |
| end
 | |
| document kernel32
 | |
| Syntax: kernel32 PATH_TO_KGMACROS <PORT>
 | |
| | Attach to VMware gdb stub for 32 bits kernel.
 | |
| | The path to kgmacros must be supplied as first parameter.
 | |
| | If you don't want to load kgmacros just put something as the first parameter.
 | |
| | Optional parameter is the port to connect to, in case you are not using the default 8832
 | |
| | or want to kernel debug more than one active virtual machine.
 | |
| | By supplying a bogus kgmacros this command should be compatible with any OS.
 | |
| end
 | |
| 
 | |
| define kernel64
 | |
|     if $argc != 0
 | |
|         # try to load kgmacros files
 | |
|         # failure is silent if non-existent...
 | |
|         source $arg0
 | |
|         set architecture i386:x86-64
 | |
|         if $argc == 2
 | |
|             target remote localhost:$arg1
 | |
|         else
 | |
|             target remote localhost:8864
 | |
|         end
 | |
|     else
 | |
|         help kernel64
 | |
|     end
 | |
| end
 | |
| document kernel64
 | |
| Syntax: kernel64 PATH_TO_KGMACROS <PORT>
 | |
| | Attach to VMware gdb stub for 64 bits kernel.
 | |
| | The path to kgmacros must be supplied as first parameter.
 | |
| | If you don't want to load kgmacros just put something as the first parameter.
 | |
| | Optional parameter is the port to connect to, in case you are not using the default 8864
 | |
| | or want to kernel debug more than one active virtual machine.
 | |
| | By supplying a bogus kgmacros this command should be compatible with any OS.
 | |
| end
 | |
| 
 | |
| define 32bits
 | |
|     set $KDP64BITS = 0
 | |
|     set $64BITS = 0
 | |
| end
 | |
| 
 | |
| define 64bits
 | |
|     set $KDP64BITS = 1
 | |
|     set $64BITS = 1
 | |
| end
 | |
| 
 | |
| define resetkdp
 | |
|     set $KDP64BITS = -1
 | |
| end
 | |
| 
 | |
| define header
 | |
|     if $argc != 1
 | |
|         help header
 | |
|     else
 | |
|         dump memory /tmp/gdbinit_header_dump $arg0 $arg0 + 4096
 | |
|         shell /usr/bin/otool -h /tmp/gdbinit_header_dump
 | |
|         shell /bin/rm -f /tmp/gdbinit_header_dump
 | |
|     end
 | |
| end
 | |
| document header
 | |
| Syntax: header MACHO_HEADER_START_ADDRESS
 | |
| | Dump the Mach-O header located at given address
 | |
| end
 | |
| 
 | |
| define loadcmds
 | |
|     if $argc != 1
 | |
|         help loadcmds
 | |
|     else
 | |
|         # this size should be good enough for most binaries
 | |
|         dump memory /tmp/gdbinit_header_dump $arg0 $arg0 + 4096 * 10
 | |
|         shell /usr/bin/otool -l /tmp/gdbinit_header_dump
 | |
|         shell /bin/rm -f /tmp/gdbinit_header_dump
 | |
|     end
 | |
| end
 | |
| document loadcmds
 | |
| Syntax: loadcmds MACHO_HEADER_START_ADDRESS
 | |
| | Dump the Mach-O load commands
 | |
| end
 | |
| 
 | |
| # defining it here doesn't get the space #$#$%"#!
 | |
| define disablecolorprompt
 | |
|     set prompt gdb$
 | |
| end
 | |
| document disablecolorprompt
 | |
| | Remove color from prompt
 | |
| end
 | |
| 
 | |
| define enablecolorprompt
 | |
|     set prompt \033[31mgdb$ \033[0m
 | |
| end
 | |
| document enablecolorprompt
 | |
| | Enable color prompt
 | |
| end
 | |
| 
 | |
| #EOF
 |