From c80890693c55ab66072c9adc4ea4e447c411faa5 Mon Sep 17 00:00:00 2001 From: Valentin Brandl Date: Sat, 11 Feb 2017 20:37:45 +0100 Subject: [PATCH] Add gdb config and install script --- meta/configs/gdb.yaml | 4 + tools/debugger/gdb/gdbinit | 4000 ++++++++++++++++++++++++++++++ tools/debugger/gdb/gdbinit.local | 2 + 3 files changed, 4006 insertions(+) create mode 100644 meta/configs/gdb.yaml create mode 100644 tools/debugger/gdb/gdbinit create mode 100644 tools/debugger/gdb/gdbinit.local diff --git a/meta/configs/gdb.yaml b/meta/configs/gdb.yaml new file mode 100644 index 0000000..e79e7cc --- /dev/null +++ b/meta/configs/gdb.yaml @@ -0,0 +1,4 @@ +- link: + ~/.gdbinit: tools/debugger/gdb/gdbinit + ~/.gdbinit.local: tools/debugger/gdb/gdbinit.local +# vim: set filetype=yaml ts=4 sw=4 tw=0 et : diff --git a/tools/debugger/gdb/gdbinit b/tools/debugger/gdb/gdbinit new file mode 100644 index 0000000..276db00 --- /dev/null +++ b/tools/debugger/gdb/gdbinit @@ -0,0 +1,4000 @@ +# INSTALL INSTRUCTIONS: save as ~/.gdbinit +# +# DESCRIPTION: A user-friendly gdb configuration file, for x86/x86_64 and ARM platforms. +# +# REVISION : 8.0.5 (18/08/2013) +# +# CONTRIBUTORS: mammon_, elaine, pusillus, mong, zhang le, l0kit, +# truthix the cyberpunk, fG!, gln +# +# FEEDBACK: http://reverse.put.as - reverser@put.as +# +# 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 http://reverse.put.as/2008/11/28/apples-gdb-bug/ +# +# UPDATE: This bug can be fixed in gdb source. Refer to http://reverse.put.as/2009/08/10/fix-for-apples-gdb-bug-or-why-apple-forks-are-bad/ +# and http://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 http://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 http://reverse.put.as/2008/11/28/apples-gdb-bug/ +# +# CHANGELOG: (older changes at the end of the file) +# +# Version 8.0.6 (05/09/2013) +# - Add patch command to convert bytes to little-endian and patch memory +# +# Version 8.0.5 (18/08/2013) +# - Add commands header and loadcmds to dump Mach-O header information +# - Other fixes and additions from previous commits +# +# Version 8.0.4 (08/05/2013) +# - Detect automatically 32 or 64 bits archs using sizeof(void*). +# Thanks to Tyilo for the simple but very effective idea! +# - Typo in hexdump command also fixed by vuquangtrong. +# - Add shortcuts to attach to VMware kernel debugging gdb stub (kernel32 and kernel64) +# +# Version 8.0.3 (21/03/2013) +# - Add option to colorize or not output (thanks to argp and skier for the request and ideas!) +# - Convert the escape codes into functions so colors can be easily customized +# - Other enhancements available at git commit logs +# Thanks to Plouj, argp, xristos for their ideas and fixes! +# +# Version 8.0.2 (31/07/2012) +# - Merge pull request from mheistermann to support local modifications in a .gdbinit.local file +# - Add a missing opcode to the stepo command +# +# Version 8.0.1 (23/04/2012) +# - Small bug fix to the attsyntax and intelsyntax commands (changing X86 flavor variable was missing) +# +# Version 8.0 (13/04/2012) +# - Merged x86/x64 and ARM versions +# - Added commands intelsyntax and attsyntax to switch between x86 disassembly flavors +# - Added new configuration variables ARM, ARMOPCODES, and X86FLAVOR +# - Code cleanups and fixes to the indentation +# - Bug fixes to some ARM related code +# - Added the dumpmacho command to memory dump the mach-o header to a file +# +# 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 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 = 1 +# 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 + +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 + end +end + +define color_underline + if $USECOLOR == 1 + echo \033[4m + end +end + +# 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 prompt \033[31mgdb$ \033[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 + break $arg0 + 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 +| 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) + #64bits stuff + # 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 +| 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 +| 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 +| 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 +| 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 +| 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 + + 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 + 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 +| 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 +| 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 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 +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 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 +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 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 +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 on + + info files + + set logging 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 on + + info target + + set logging 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 on + add-symbol-file /tmp/gdb-symtab + set logging 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 +| 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 +| 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 +| 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 +| Shortcut to the asssemble command. +end + +define asm32 + if $argc == 1 + assemble32 $arg0 + else + assemble32 + end +end +document asm32 +Syntax: asm32 +| Shortcut to the assemble32 command. +end + +define asm64 + if $argc == 1 + assemble64 $arg0 + else + assemble64 + end +end +document asm64 +Syntax: asm64 +| 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 +| 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 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 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 +| 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 +| 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 + +# Older change logs: +# +# Version 7.4.4 (02/01/2012) +# - Added the "skip" command. This will jump to the next instruction after EIP/RIP without executing the current one. +# Thanks to @bSr43 for the tip to retrieve the current instruction size. +# +# Version 7.4.3 (04/11/2011) +# - Modified "hexdump" command to support a variable number of lines (optional parameter) +# - Removed restrictions on type of addresses in the "dd" command - Thanks to Plouj for the warning :-) +# I don't know what was the original thinking behind those :-) +# - Modified the assemble command to support 64bits - You will need to recompile nasm since the version shipped with OS X doesn't supports 64bits (www.nasm.us). +# Assumes that the new binary is installed at /usr/local/bin - modify the variable at the top if you need so. +# It will assemble based on the target arch being debugged. If you want to use gdb for a quick asm just use the 32bits or 64bits commands to set your target. +# Thanks to snare for the warning and original patch :-) +# - Added "asm" command - it's a shortcut to the "assemble" command. +# - Added configuration variable for colorized prompt. Plouj reported some issues with Ubuntu's gdb 7.2 if prompt is colorized. +# +# Version 7.4.2 (11/08/2011) +# Small fix to a weird bug happening on FreeBSD 8.2. It doesn't like a "if(" instruction, needs to be "if (". Weird! +# Many thanks to Evan for reporting and sending the patch :-) +# Added the ptraceme/rptraceme commands to bypass PTRACE_TRACME anti-debugging technique. +# Grabbed this from http://falken.tuxfamily.org/?p=171 +# It's commented out due to a gdb problem in OS X (refer to http://reverse.put.as/2011/08/20/another-patch-for-apples-gdb-the-definecommands-problem/ ) +# Just uncomment it if you want to use in ptrace enabled systems. +# +# Version 7.4.1 (21/06/2011) - fG! +# Added patch sent by sbz, more than 1 year ago, which I forgot to add :-/ +# This will allow to search for a given pattern between start and end address. +# On sbz words: "It's usefull to find call, ret or everything like that." :-) +# New command is "search" +# +# Version 7.4 (20/06/2011) - fG! +# When registers change between instructions the color will change to red (like it happens in OllyDBG) +# This is the default behavior, if you don't like it, modify the variable SHOWREGCHANGES +# Added patch sent by Philippe Langlois +# color the first disassembly line - change the setting below on SETCOLOR1STLINE - by default it's disabled +# +# Version 7.3.2 (21/02/2011) - fG! +# Added the command rint3 and modified the int3 command. The new command will restore the byte in previous int3 patch. +# +# Version 7.3.1 (29/06/2010) - fG! +# Added enablelib/disablelib command to quickly set the stop-on-solib-events trick +# Implemented the stepoh command equivalent to the stepo but using hardware breakpoints +# More fixes to stepo +# +# Version 7.3 (16/04/2010) - fG! +# Support for 64bits targets. Default is 32bits, you should modify the variable or use the 32bits or 64bits to choose the mode. +# I couldn't find another way to recognize the type of binary… Testing the register doesn't work that well. +# TODO: fix objectivec messages and stepo for 64bits +# Version 7.2.1 (24/11/2009) - fG! +# Another fix to stepo (0xFF92 missing) +# +# Version 7.2 (11/10/2009) - fG! +# Added the smallregisters function to create 16 and 8 bit versions from the registers EAX, EBX, ECX, EDX +# Revised and fixed all the dumpjump stuff, following Intel manuals. There were some errors (thx to rev who pointed the jle problem). +# Small fix to stepo command (missed a few call types) +# +# Version 7.1.7 - fG! +# Added the possibility to modify what's displayed with the context window. You can change default options at the gdb options part. For example, kernel debugging is much slower if the stack display is enabled... +# New commands enableobjectivec, enablecpuregisters, enablestack, enabledatawin and their disable equivalents (to support realtime change of default options) +# Fixed problem with the assemble command. I was calling /bin/echo which doesn't support the -e option ! DUH ! Should have used bash internal version. +# Small fixes to colors... +# New commands enablesolib and disablesolib . Just shortcuts for the stop-on-solib-events fantastic trick ! Hey... I'm lazy ;) +# Fixed this: Possible removal of "u" command, info udot is missing in gdb 6.8-debian . Doesn't exist on OS X so bye bye !!! +# Displays affected flags in jump decisions +# +# Version 7.1.6 - fG! +# Added modified assemble command from Tavis Ormandy (further modified to work with Mac OS X) (shell commands used use full path name, working for Leopard, modify for others if necessary) +# Renamed thread command to threads because thread is an internal gdb command that allows to move between program threads +# +# Version 7.1.5 (04/01/2009) - fG! +# Fixed crash on Leopard ! There was a If Else condition where the else had no code and that made gdb crash on Leopard (CRAZY!!!!) +# Better code indention +# +# Version 7.1.4 (02/01/2009) - fG! +# Bug in show objective c messages with Leopard ??? +# Nop routine support for single address or range (contribution from gln [ghalen at hack.se]) +# Used the same code from nop to null routine +# +# Version 7.1.3 (31/12/2008) - fG! +# Added a new command 'stepo'. This command will step a temporary breakpoint on next instruction after the call, so you can skip over +# the call. Did this because normal commands not always skip over (mainly with objc_msgSend) +# +# Version 7.1.2 (31/12/2008) - fG! +# Support for the jump decision (will display if a conditional jump will be taken or not) +# +# Version 7.1.1 (29/12/2008) - fG! +# Moved gdb options to the beginning (makes more sense) +# Added support to dump message being sent to msgSend (easier to understand what's going on) +# +# Version 7.1 +# Fixed serious (and old) bug in dd and datawin, causing dereference of +# obviously invalid address. See below: +# gdb$ dd 0xffffffff +# FFFFFFFF : Cannot access memory at address 0xffffffff +# +# Version 7.0 +# Added cls command. +# Improved documentation of many commands. +# Removed bp_alloc, was neither portable nor usefull. +# Checking of passed argument(s) in these commands: +# contextsize-stack, contextsize-data, contextsize-code +# bp, bpc, bpe, bpd, bpt, bpm, bhb,... +# Fixed bp and bhb inconsistencies, look at * signs in Version 6.2 +# Bugfix in bhb command, changed "break" to "hb" command body +# Removed $SHOW_CONTEXT=1 from several commands, this variable +# should only be controlled globally with context-on and context-off +# Improved stack, func, var and sig, dis, n, go,... +# they take optional argument(s) now +# Fixed wrong $SHOW_CONTEXT assignment in context-off +# Fixed serious bug in cft command, forgotten ~ sign +# Fixed these bugs in step_to_call: +# 1) the correct logging sequence is: +# set logging file > set logging redirect > set logging on +# 2) $SHOW_CONTEXT is now correctly restored from $_saved_ctx +# Fixed these bugs in trace_calls: +# 1) the correct logging sequence is: +# set logging file > set logging overwrite > +# set logging redirect > set logging on +# 2) removed the "clean up trace file" part, which is not needed now, +# stepi output is properly redirected to /dev/null +# 3) $SHOW_CONTEXT is now correctly restored from $_saved_ctx +# Fixed bug in trace_run: +# 1) $SHOW_CONTEXT is now correctly restored from $_saved_ctx +# Fixed print_insn_type -- removed invalid semicolons!, wrong value checking, +# Added TODO entry regarding the "u" command +# Changed name from gas_assemble to assemble_gas due to consistency +# Output from assemble and assemble_gas is now similar, because i made +# both of them to use objdump, with respect to output format (AT&T|Intel). +# Whole code was checked and made more consistent, readable/maintainable. +# +# Version 6.2 +# Add global variables to allow user to control stack, data and code window sizes +# Increase readability for registers +# Some corrections (hexdump, ddump, context, cfp, assemble, gas_asm, tips, prompt) +# +# Version 6.1-color-user +# Took the Gentoo route and ran sed s/user/user/g +# +# Version 6.1-color +# Added color fixes from +# http://gnurbs.blogsome.com/2006/12/22/colorizing-mamons-gdbinit/ +# +# Version 6.1 +# Fixed filename in step_to_call so it points to /dev/null +# Changed location of logfiles from /tmp to ~ +# +# Version 6 +# Added print_insn_type, get_insn_type, context-on, context-off commands +# Added trace_calls, trace_run, step_to_call commands +# Changed hook-stop so it checks $SHOW_CONTEXT variable +# +# Version 5 +# Added bpm, dump_bin, dump_hex, bp_alloc commands +# Added 'assemble' by elaine, 'gas_asm' by mong +# Added Tip Topics for aspiring users ;) +# +# Version 4 +# Added eflags-changing insns by pusillus +# Added bp, nop, null, and int3 patch commands, also hook-stop +# +# Version 3 +# Incorporated elaine's if/else goodness into the hex/ascii dump +# +# Version 2 +# Radix bugfix by elaine +source /usr/share/peda/peda.py +/* vim: set filetype=gdb ts=8 sw=4 tw=120 et :*/ diff --git a/tools/debugger/gdb/gdbinit.local b/tools/debugger/gdb/gdbinit.local new file mode 100644 index 0000000..2da6e66 --- /dev/null +++ b/tools/debugger/gdb/gdbinit.local @@ -0,0 +1,2 @@ +source /usr/share/peda/peda.py +/* vim: set filetype=gdb ts=4 sw=4 tw=120 noet :*/