Skip to content

Instantly share code, notes, and snippets.

@vixfwis
Last active May 23, 2024 10:00
Show Gist options
  • Save vixfwis/873d5d969e4fb5df44b0d9011a623b0b to your computer and use it in GitHub Desktop.
Save vixfwis/873d5d969e4fb5df44b0d9011a623b0b to your computer and use it in GitHub Desktop.
Rust
# __________________gdb options_________________
set $64BITS = 1
set print pretty on
set language rust
set listsize 16
set verbose off
# These make gdb never pause in its output
set height 0
set width 0
# Display instructions in Intel format
set disassembly-flavor intel
set $SHOW_CONTEXT = 1
set $SHOW_NEST_INSN = 0
set $CONTEXTSIZE_STACK = 6
set $CONTEXTSIZE_DATA = 8
set $CONTEXTSIZE_CODE = 8
# 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
# __________________end gdb options_________________
# ______________window size control___________
define contextsize-stack
if $argc != 1
help contextsize-stack
else
set $CONTEXTSIZE_STACK = $arg0
end
end
document contextsize-stack
Set stack dump window size to NUM lines.
Usage: contextsize-stack NUM
end
define contextsize-data
if $argc != 1
help contextsize-data
else
set $CONTEXTSIZE_DATA = $arg0
end
end
document contextsize-data
Set data dump window size to NUM lines.
Usage: contextsize-data NUM
end
define contextsize-code
if $argc != 1
help contextsize-code
else
set $CONTEXTSIZE_CODE = $arg0
end
end
document contextsize-code
Set code window size to NUM lines.
Usage: contextsize-code NUM
end
# _____________breakpoint aliases_____________
define bpl
info breakpoints
end
document bpl
List all breakpoints.
end
define bp
if $argc != 1
help bp
else
break $arg0
end
end
document bp
Set breakpoint.
Usage: bp LOCATION
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
Clear breakpoint.
Usage: bpc LOCATION
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
Enable breakpoint with number NUM.
Usage: bpe NUM
end
define bpd
if $argc != 1
help bpd
else
disable $arg0
end
end
document bpd
Disable breakpoint with number NUM.
Usage: bpd NUM
end
define bpt
if $argc != 1
help bpt
else
tbreak $arg0
end
end
document bpt
Set a temporary breakpoint.
Will be deleted when hit!
Usage: bpt LOCATION
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
Set a read/write breakpoint on EXPRESSION, e.g. *address.
Usage: bpm EXPRESSION
end
define bhb
if $argc != 1
help bhb
else
hb $arg0
end
end
document bhb
Set hardware assisted breakpoint.
Usage: bhb LOCATION
LOCATION may be a line number, function name, or "*" and an address.
end
# ______________process information____________
define argv
show args
end
document 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
Print backtrace of the call stack, or innermost COUNT frames.
Usage: stack <COUNT>
end
define frame
info frame
info args
info locals
end
document frame
Print stack frame.
end
define reg
if ($64BITS == 1)
# 64bits stuff
printf " "
echo \033[32m
printf "RAX:"
echo \033[0m
printf " 0x%016lX ", $rax
echo \033[32m
printf "RBX:"
echo \033[0m
printf " 0x%016lX ", $rbx
echo \033[32m
printf "RCX:"
echo \033[0m
printf " 0x%016lX ", $rcx
echo \033[32m
printf "RDX:"
echo \033[0m
printf " 0x%016lX ", $rdx
echo \033[1m\033[4m\033[31m
output $eflags
printf "\n"
echo \033[0m
printf " "
echo \033[32m
printf "RSI:"
echo \033[0m
printf " 0x%016lX ", $rsi
echo \033[32m
printf "RDI:"
echo \033[0m
printf " 0x%016lX ", $rdi
echo \033[32m
printf "RBP:"
echo \033[0m
printf " 0x%016lX ", $rbp
echo \033[32m
printf "RSP:"
echo \033[0m
printf " 0x%016lX ", $rsp
echo \033[32m
printf "RIP:"
echo \033[0m
printf " 0x%016lX\n ", $rip
echo \033[32m
printf "R8 :"
echo \033[0m
printf " 0x%016lX ", $r8
echo \033[32m
printf "R9 :"
echo \033[0m
printf " 0x%016lX ", $r9
echo \033[32m
printf "R10:"
echo \033[0m
printf " 0x%016lX ", $r10
echo \033[32m
printf "R11:"
echo \033[0m
printf " 0x%016lX ", $r11
echo \033[32m
printf "R12:"
echo \033[0m
printf " 0x%016lX\n ", $r12
echo \033[32m
printf "R13:"
echo \033[0m
printf " 0x%016lX ", $r13
echo \033[32m
printf "R14:"
echo \033[0m
printf " 0x%016lX ", $r14
echo \033[32m
printf "R15:"
echo \033[0m
printf " 0x%016lX\n ", $r15
echo \033[32m
printf "CS:"
echo \033[0m
printf " %04X ", $cs
echo \033[32m
printf "DS:"
echo \033[0m
printf " %04X ", $ds
echo \033[32m
printf "ES:"
echo \033[0m
printf " %04X ", $es
echo \033[32m
printf "FS:"
echo \033[0m
printf " %04X ", $fs
echo \033[32m
printf "GS:"
echo \033[0m
printf " %04X ", $gs
echo \033[32m
printf "SS:"
echo \033[0m
printf " %04X", $ss
echo \033[0m
# 32bits stuff
else
printf " "
echo \033[32m
printf "EAX:"
echo \033[0m
printf " 0x%08X ", $eax
echo \033[32m
printf "EBX:"
echo \033[0m
printf " 0x%08X ", $ebx
echo \033[32m
printf "ECX:"
echo \033[0m
printf " 0x%08X ", $ecx
echo \033[32m
printf "EDX:"
echo \033[0m
printf " 0x%08X ", $edx
echo \033[1m\033[4m\033[31m
output $eflags
printf "\n"
echo \033[0m
printf " "
echo \033[32m
printf "ESI:"
echo \033[0m
printf " 0x%08X ", $esi
echo \033[32m
printf "EDI:"
echo \033[0m
printf " 0x%08X ", $edi
echo \033[32m
printf "EBP:"
echo \033[0m
printf " 0x%08X ", $ebp
echo \033[32m
printf "ESP:"
echo \033[0m
printf " 0x%08X ", $esp
echo \033[32m
printf "EIP:"
echo \033[0m
printf " 0x%08X\n ", $eip
echo \033[32m
printf "CS:"
echo \033[0m
printf " %04X ", $cs
echo \033[32m
printf "DS:"
echo \033[0m
printf " %04X ", $ds
echo \033[32m
printf "ES:"
echo \033[0m
printf " %04X ", $es
echo \033[32m
printf "FS:"
echo \033[0m
printf " %04X ", $fs
echo \033[32m
printf "GS:"
echo \033[0m
printf " %04X ", $gs
echo \033[32m
printf "SS:"
echo \033[0m
printf " %04X", $ss
echo \033[0m
end
# call smallregisters
smallregisters
# display conditional jump routine
if ($64BITS == 1)
printf "\t\t\t\t"
end
printf "\n"
end
document reg
Print CPU registers.
end
define smallregisters
if ($64BITS == 1)
#64bits stuff
# from rax
set $eax = $rax & 0xffffffff
set $ax = $rax & 0xffff
set $al = $ax & 0xff
set $ah = $ax >> 8
# from rbx
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
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
Print all function names in target, or those matching REGEXP.
Usage: func <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
Print all global and static variable names (symbols), or those matching REGEXP.
Usage: var <REGEXP>
end
define lib
info sharedlibrary
end
document 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
Print what debugger does when program gets various signals.
Specify a SIGNAL as argument to print info on that signal only.
Usage: sig <SIGNAL>
end
define threads
info threads
end
document 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
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.
Usage: dis <ADDR1> <ADDR2>
end
# __________hex/ascii dump an address_________
define ascii_char
if $argc != 1
help ascii_char
else
set $_c = *(($arg0) as *mut u8)
if ($_c < 0x20 || $_c > 0x7E)
printf "."
else
printf "%c", $_c
end
end
end
document ascii_char
Print ASCII value of byte at address ADDR.
Print "." if the value is unprintable.
Usage: ascii_char ADDR
end
define hex_quad
if $argc != 1
help hex_quad
else
printf "%02X ", *(($arg0 + 0) as *mut u8)
printf "%02X ", *(($arg0 + 1) as *mut u8)
printf "%02X ", *(($arg0 + 2) as *mut u8)
printf "%02X ", *(($arg0 + 3) as *mut u8)
printf "%02X ", *(($arg0 + 4) as *mut u8)
printf "%02X ", *(($arg0 + 5) as *mut u8)
printf "%02X ", *(($arg0 + 6) as *mut u8)
printf "%02X" , *(($arg0 + 7) as *mut u8)
end
end
document hex_quad
Print eight hexadecimal bytes starting at address ADDR.
Usage: hex_quad ADDR
end
define hexdump
if $argc != 1
help hexdump
else
echo \033[1m
if ($64BITS == 1)
printf "0x%016lX : ", $arg0
else
printf "0x%08X : ", $arg0
end
echo \033[0m
hex_quad $arg0
echo \033[1m
printf " - "
echo \033[0m
hex_quad $arg0+8
printf " "
echo \033[1m
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
echo \033[0m
printf "\n"
end
end
document hexdump
Display a 16-byte hex/ASCII dump of memory at address ADDR.
Usage: hexdump ADDR
end
# _______________data window__________________
define ddump
if $argc != 1
help ddump
else
echo \033[34m
if ($64BITS == 1)
printf "[0x%04X:0x%016lX]", $ds, $data_addr
else
printf "[0x%04X:0x%08X]", $ds, $data_addr
end
echo \033[34m
printf "------------------------"
printf "-------------------------------"
if ($64BITS == 1)
printf "-------------------------------------"
end
echo \033[1;34m
printf "[data]\n"
echo \033[0m
set $_count = 0
while ($_count < $arg0)
set $_i = ($_count * 0x10)
hexdump $data_addr+$_i
set $_count = $_count + 1
end
end
end
document ddump
Display NUM lines of hexdump for address in $data_addr global variable.
Usage: ddump NUM
end
define dd
if $argc != 1
help dd
else
set $data_addr = $arg0
ddump 0x10
end
end
document dd
Display 16 lines of a hex dump of address starting at ADDR.
Usage: dd ADDR
end
define datawin
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
ddump $CONTEXTSIZE_DATA
end
document datawin
Display valid address from one register in data window.
Registers to choose are: esi, edi, eax, or esp.
end
# _______________process context______________
# initialize variable
set $displayobjectivec = 0
define context
echo \033[34m
if $SHOWCPUREGISTERS == 1
printf "----------------------------------------"
printf "----------------------------------"
if ($64BITS == 1)
printf "---------------------------------------------"
end
echo \033[34m\033[1m
printf "[regs]\n"
echo \033[0m
reg
echo \033[36m
end
if $SHOWSTACK == 1
echo \033[34m
if ($64BITS == 1)
printf "[0x%04X:0x%016lX]", $ss, $rsp
else
printf "[0x%04X:0x%08X]", $ss, $esp
end
echo \033[34m
printf "-------------------------"
printf "-----------------------------"
if ($64BITS == 1)
printf "-------------------------------------"
end
echo \033[34m\033[1m
printf "[stack]\n"
echo \033[0m
set $context_i = $CONTEXTSIZE_STACK
while ($context_i > 0)
set $context_t = $sp + 0x10 * ($context_i - 1)
hexdump $context_t
set $context_i = $context_i - 1
end
end
if $SHOWDATAWIN == 1
datawin
end
echo \033[34m
printf "--------------------------------------------------------------------------"
if ($64BITS == 1)
printf "---------------------------------------------"
end
echo \033[34m\033[1m
printf "[code]\n"
echo \033[0m
set $context_i = $CONTEXTSIZE_CODE
if($context_i > 0)
x /i $pc
set $context_i = $context_i - 1
end
while ($context_i > 0)
x /i
set $context_i = $context_i - 1
end
echo \033[34m
printf "----------------------------------------"
printf "----------------------------------------"
if ($64BITS == 1)
printf "---------------------------------------------\n"
else
printf "\n"
end
echo \033[0m
end
document 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
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
Disable display of context on every program break.
end
# _______________process control______________
define n
if $argc == 0
next
end
if $argc == 1
next $arg0
end
if $argc > 1
help n
end
end
document n
Step one line, but proceed through subroutine calls.
If NUM is given, then repeat it NUM times or till program stops.
This is alias for next
Usage: n <NUM>
end
define ni
if $argc == 0
nexti
end
if $argc == 1
nexti $arg0
end
if $argc > 1
help ni
end
end
document ni
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
Usage: ni <NUM>
end
define go
if $argc == 0
stepi
end
if $argc == 1
stepi $arg0
end
if $argc > 1
help go
end
end
document go
Step one instruction exactly.
If NUM is given, then repeat it NUM times or till program stops.
This is alias for stepi.
Usage: go <NUM>
end
define pret
finish
end
document 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
Run program and break on _init().
end
define start
set $SHOW_NEST_INSN = 0
tbreak _start
r
end
document start
Run program and break on _start().
end
define sstart
set $SHOW_NEST_INSN = 0
tbreak __libc_start_main
r
end
document 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
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 stepo
## 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 = *($pc as *mut u8)
set $_byte2 = *(($pc+1) as *mut u8)
set $_byte3 = *(($pc+2) as *mut u8)
# 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)
if ($_byte2 == 0xD0 || $_byte2 == 0xD1 || $_byte2 == 0xD2 || $_byte2 == 0xD3 || $_byte2 == 0xD6 || $_byte2 == 0x10 )
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)
set $_nextaddress = $pc + 6
end
# call *0x????????(%ebx,%eax,4) (0xFF94??????????)
if ($_byte2 == 0x94)
set $_nextaddress = $pc + 7
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
# else we just single step
else
nexti
end
# end of stepo function
end
document 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
# _______________eflags commands______________
define cfc
if ($eflags & 1)
set $eflags = $eflags&~0x1
else
set $eflags = $eflags|0x1
end
end
document cfc
Change Carry Flag.
end
define cfp
if (($eflags >> 2) & 1)
set $eflags = $eflags&~0x4
else
set $eflags = $eflags|0x4
end
end
document cfp
Change Parity Flag.
end
define cfa
if (($eflags >> 4) & 1)
set $eflags = $eflags&~0x10
else
set $eflags = $eflags|0x10
end
end
document cfa
Change Auxiliary Carry Flag.
end
define cfz
if (($eflags >> 6) & 1)
set $eflags = $eflags&~0x40
else
set $eflags = $eflags|0x40
end
end
document cfz
Change Zero Flag.
end
define cfs
if (($eflags >> 7) & 1)
set $eflags = $eflags&~0x80
else
set $eflags = $eflags|0x80
end
end
document cfs
Change Sign Flag.
end
define cft
if (($eflags >>8) & 1)
set $eflags = $eflags&~0x100
else
set $eflags = $eflags|0x100
end
end
document cft
Change Trap Flag.
end
define cfi
if (($eflags >> 9) & 1)
set $eflags = $eflags&~0x200
else
set $eflags = $eflags|0x200
end
end
document 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 (($eflags >>0xA) & 1)
set $eflags = $eflags&~0x400
else
set $eflags = $eflags|0x400
end
end
document cfd
Change Direction Flag.
end
define cfo
if (($eflags >> 0xB) & 1)
set $eflags = $eflags&~0x800
else
set $eflags = $eflags|0x800
end
end
document cfo
Change Overflow Flag.
end
# ____________________patch___________________
define nop
if ($argc > 2 || $argc == 0)
help nop
end
if ($argc == 1)
set *($arg0 as *mut u8) = 0x90
else
set $addr = $arg0
while ($addr < $arg1)
set *($addr as *mut u8) = 0x90
set $addr = $addr + 1
end
end
end
document nop
Usage: nop ADDR1 [ADDR2]
Patch a single byte at address ADDR1, or a series of bytes between ADDR1 and ADDR2 to a NOP (0x90) instruction.
end
define null
if ( $argc >2 || $argc == 0)
help null
end
if ($argc == 1)
set *($arg0 as *mut u8) = 0
else
set $addr = $arg0
while ($addr < $arg1)
set *($addr as *mut u8) = 0
set $addr = $addr +1
end
end
end
document null
Usage: null ADDR1 [ADDR2]
Patch a single byte at address ADDR1 to NULL (0x00), or a series of bytes between ADDR1 and ADDR2.
end
define int3
if $argc != 1
help int3
else
set *($arg0 as *mut u8) = 0xCC
end
end
document int3
Patch byte at address ADDR to an INT3 (0xCC) instruction.
Usage: int3 ADDR
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
Print human-readable mnemonic for the instruction type (usually $INSN_TYPE).
Usage: print_insn_type INSN_TYPE_NUMBER
end
define get_insn_type
if $argc != 1
help get_insn_type
else
set $INSN_TYPE = 0
set $_byte1 = *($arg0 as *mut u8)
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 = *(($arg0 + 1) as *mut u8)
if ($_byte2 >= 0x80 && $_byte2 <= 0x8F)
# "jcc"
set $INSN_TYPE = 2
end
end
if ($_byte1 == 0xFF)
# opcode extension
set $_byte2 = *(($arg0 + 1) as *mut u8)
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
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.
Usage: get_insn_type ADDR
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 on
set $_cont = 1
while ($_cont > 0)
stepi
get_insn_type $pc
if ($INSN_TYPE == 3)
set $_cont = 0
end
end
set logging 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 on
printf "step_to_call command stopped at:\n "
x/i $pc
printf "\n"
set logging off
end
document 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 on
set logging 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 on
set $x = $_nest - 2
while ($x > 0)
printf "\t"
set $x = $x - 1
end
x/i $pc
end
set logging off
set logging file /dev/null
set logging redirect on
set logging on
stepi
set logging redirect off
set logging off
end
set $SHOW_CONTEXT = $_saved_ctx
set $SHOW_NEST_INSN = 0
printf "Done, check ~/gdb_trace_calls.txt\n"
end
document 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 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 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
Create a runtime trace of target.
Log overwrites(!) the file ~/gdb_trace_run.txt.
end
# ____________________misc____________________
define hook-stop
# 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
!!! 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."
echo \033[1m
printf " Do not forget to use NASM assembler syntax!\n"
echo \033[0m
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)" ; FILENAME=$RANDOM; \
echo -e "BITS 32\n$ASMOPCODE" >/tmp/$FILENAME ; /usr/bin/nasm -f bin -o /dev/stdout /tmp/$FILENAME | /usr/bin/hexdump -ve '1/1 "set *($arg0 + %#2_ax) as *mut u8) = %#02x\n"' >/tmp/gdbassemble ; /bin/rm -f /tmp/$FILENAME
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)" ; FILENAME=$RANDOM; \
echo -e "BITS 32\n$ASMOPCODE" >/tmp/$FILENAME ; /usr/bin/nasm -f bin -o /dev/stdout /tmp/$FILENAME | /usr/bin/ndisasm -i -b32 /dev/stdin ; /bin/rm -f /tmp/$FILENAME
end
end
document assemble
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 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
Assemble instructions to binary opcodes. Uses GNU as and objdump.
Usage: assemble_gas
end
define dump_hexfile
dump ihex memory $arg0 $arg1 $arg2
end
document dump_hexfile
Write a range of memory to a file in Intel ihex (hexdump) format.
The range is specified by ADDR1 and ADDR2 addresses.
Usage: dump_hexfile FILENAME ADDR1 ADDR2
end
define dump_binfile
dump memory $arg0 $arg1 $arg2
end
document dump_binfile
Write a range of memory to a binary file.
The range is specified by ADDR1 and ADDR2 addresses.
Usage: dump_binfile FILENAME ADDR1 ADDR2
end
define cls
shell clear
end
document cls
Clear screen.
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
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
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
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
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
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
end
document enablesolib
Shortcut to enable stop-on-solib-events trick!
end
define disablesolib
set stop-on-solib-events 0
end
document disablesolib
Shortcut to disable stop-on-solib-events trick!
end
# enable commands for different displays
define enableobjectivec
set $SHOWOBJECTIVEC = 1
end
document enableobjectivec
Enable display of objective-c information in the context window
end
define enablecpuregisters
set $SHOWCPUREGISTERS = 1
end
document enablecpuregisters
Enable display of cpu registers in the context window
end
define enablestack
set $SHOWSTACK = 1
end
document enablestack
Enable display of stack in the context window
end
define enabledatawin
set $SHOWDATAWIN = 1
end
document enabledatawin
Enable display of data window in the context window
end
# disable commands for different displays
define disableobjectivec
set $SHOWOBJECTIVEC = 0
end
document disableobjectivec
Disable display of objective-c information in the context window
end
define disablecpuregisters
set $SHOWCPUREGISTERS = 0
end
document disablecpuregisters
Disable display of cpu registers in the context window
end
define disablestack
set $SHOWSTACK = 0
end
document disablestack
Disable display of stack information in the context window
end
define disabledatawin
set $SHOWDATAWIN = 0
end
document disabledatawin
Disable display of data window in the context window
end
define 32bits
set $64BITS = 0
end
document 32bits
Set gdb to work with 32bits binaries
end
define 64bits
set $64BITS = 1
end
document 64bits
Set gdb to work with 64bits binaries
end
#EOF
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment