Skip to content

Instantly share code, notes, and snippets.

@hauleth
Created August 12, 2015 17:00
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save hauleth/fc518b6811eff705c88b to your computer and use it in GitHub Desktop.
Save hauleth/fc518b6811eff705c88b to your computer and use it in GitHub Desktop.
# 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 <COUNT>
| Print backtrace of the call stack, or innermost COUNT frames.
end
define frame
info frame
info args
info locals
end
document frame
Syntax: frame
| Print stack frame.
end
define flagsarm
# conditional flags are
# negative/less than (N), bit 31 of CPSR
# zero (Z), bit 30
# Carry/Borrow/Extend (C), bit 29
# Overflow (V), bit 28
# negative/less than (N), bit 31 of CPSR
if (($cpsr >> 0x1f) & 1)
printf "N "
set $_n_flag = 1
else
printf "n "
set $_n_flag = 0
end
# zero (Z), bit 30
if (($cpsr >> 0x1e) & 1)
printf "Z "
set $_z_flag = 1
else
printf "z "
set $_z_flag = 0
end
# Carry/Borrow/Extend (C), bit 29
if (($cpsr >> 0x1d) & 1)
printf "C "
set $_c_flag = 1
else
printf "c "
set $_c_flag = 0
end
# Overflow (V), bit 28
if (($cpsr >> 0x1c) & 1)
printf "V "
set $_v_flag = 1
else
printf "v "
set $_v_flag = 0
end
# Sticky overflow (Q), bit 27
if (($cpsr >> 0x1b) & 1)
printf "Q "
set $_q_flag = 1
else
printf "q "
set $_q_flag = 0
end
# Java state bit (J), bit 24
# When T=1:
# J = 0 The processor is in Thumb state.
# J = 1 The processor is in ThumbEE state.
if (($cpsr >> 0x18) & 1)
printf "J "
set $_j_flag = 1
else
printf "j "
set $_j_flag = 0
end
# Data endianness bit (E), bit 9
if (($cpsr >> 9) & 1)
printf "E "
set $_e_flag = 1
else
printf "e "
set $_e_flag = 0
end
# Imprecise abort disable bit (A), bit 8
# The A bit is set to 1 automatically. It is used to disable imprecise data aborts.
# It might not be writable in the Nonsecure state if the AW bit in the SCR register is reset.
if (($cpsr >> 8) & 1)
printf "A "
set $_a_flag = 1
else
printf "a "
set $_a_flag = 0
end
# IRQ disable bit (I), bit 7
# When the I bit is set to 1, IRQ interrupts are disabled.
if (($cpsr >> 7) & 1)
printf "I "
set $_i_flag = 1
else
printf "i "
set $_i_flag = 0
end
# FIQ disable bit (F), bit 6
# When the F bit is set to 1, FIQ interrupts are disabled.
# FIQ can be nonmaskable in the Nonsecure state if the FW bit in SCR register is reset.
if (($cpsr >> 6) & 1)
printf "F "
set $_f_flag = 1
else
printf "f "
set $_f_flag = 0
end
# Thumb state bit (F), bit 5
# if 1 then the processor is executing in Thumb state or ThumbEE state depending on the J bit
if (($cpsr >> 5) & 1)
printf "T "
set $_t_flag = 1
else
printf "t "
set $_t_flag = 0
end
# TODO: GE bit ?
end
document flagsarm
Syntax: flagsarm
| Auxiliary function to set ARM cpu flags.
end
define flagsx86
# OF (overflow) flag
if (((unsigned int)$eflags >> 0xB) & 1)
printf "O "
set $_of_flag = 1
else
printf "o "
set $_of_flag = 0
end
# DF (direction) flag
if (((unsigned int)$eflags >> 0xA) & 1)
printf "D "
else
printf "d "
end
# IF (interrupt enable) flag
if (((unsigned int)$eflags >> 9) & 1)
printf "I "
else
printf "i "
end
# TF (trap) flag
if (((unsigned int)$eflags >> 8) & 1)
printf "T "
else
printf "t "
end
# SF (sign) flag
if (((unsigned int)$eflags >> 7) & 1)
printf "S "
set $_sf_flag = 1
else
printf "s "
set $_sf_flag = 0
end
# ZF (zero) flag
if (((unsigned int)$eflags >> 6) & 1)
printf "Z "
set $_zf_flag = 1
else
printf "z "
set $_zf_flag = 0
end
# AF (adjust) flag
if (((unsigned int)$eflags >> 4) & 1)
printf "A "
else
printf "a "
end
# PF (parity) flag
if (((unsigned int)$eflags >> 2) & 1)
printf "P "
set $_pf_flag = 1
else
printf "p "
set $_pf_flag = 0
end
# CF (carry) flag
if ((unsigned int)$eflags & 1)
printf "C "
set $_cf_flag = 1
else
printf "c "
set $_cf_flag = 0
end
printf "\n"
end
document flagsx86
Syntax: flagsx86
| Auxiliary function to set X86/X64 cpu flags.
end
define flags
# call the auxiliary functions based on target cpu
if $ARM == 1
flagsarm
else
flagsx86
end
end
document flags
Syntax: flags
| Print flags register.
end
define eflags
if $ARM == 1
# http://www.heyrick.co.uk/armwiki/The_Status_register
printf " N <%d> Z <%d> C <%d> V <%d>",\
(($cpsr >> 0x1f) & 1), (($cpsr >> 0x1e) & 1), \
(($cpsr >> 0x1d) & 1), (($cpsr >> 0x1c) & 1)
printf " Q <%d> J <%d> GE <%d> E <%d> A <%d>",\
(($cpsr >> 0x1b) & 1), (($cpsr >> 0x18) & 1),\
(($cpsr >> 0x10) & 7), (($cpsr >> 9) & 1), (($cpsr >> 8) & 1)
printf " I <%d> F <%d> T <%d> \n",\
(($cpsr >> 7) & 1), (($cpsr >> 6) & 1), \
(($cpsr >> 5) & 1)
else
printf " OF <%d> DF <%d> IF <%d> TF <%d>",\
(((unsigned int)$eflags >> 0xB) & 1), (((unsigned int)$eflags >> 0xA) & 1), \
(((unsigned int)$eflags >> 9) & 1), (((unsigned int)$eflags >> 8) & 1)
printf " SF <%d> ZF <%d> AF <%d> PF <%d> CF <%d>\n",\
(((unsigned int)$eflags >> 7) & 1), (((unsigned int)$eflags >> 6) & 1),\
(((unsigned int)$eflags >> 4) & 1), (((unsigned int)$eflags >> 2) & 1), ((unsigned int)$eflags & 1)
printf " ID <%d> VIP <%d> VIF <%d> AC <%d>",\
(((unsigned int)$eflags >> 0x15) & 1), (((unsigned int)$eflags >> 0x14) & 1), \
(((unsigned int)$eflags >> 0x13) & 1), (((unsigned int)$eflags >> 0x12) & 1)
printf " VM <%d> RF <%d> NT <%d> IOPL <%d>\n",\
(((unsigned int)$eflags >> 0x11) & 1), (((unsigned int)$eflags >> 0x10) & 1),\
(((unsigned int)$eflags >> 0xE) & 1), (((unsigned int)$eflags >> 0xC) & 3)
end
end
document eflags
Syntax: eflags
| Print eflags register.
end
define cpsr
eflags
end
document cpsr
Syntax: cpsr
| Print cpsr register.
end
define regarm
printf " "
# R0
color $COLOR_REGNAME
printf "R0:"
if ($r0 != $oldr0 && $SHOWREGCHANGES == 1)
color $COLOR_REGVAL_MODIFIED
else
color $COLOR_REGVAL
end
printf " 0x%08X ", $r0
# R1
color $COLOR_REGNAME
printf "R1:"
if ($r1 != $oldr1 && $SHOWREGCHANGES == 1)
color $COLOR_REGVAL_MODIFIED
else
color $COLOR_REGVAL
end
printf " 0x%08X ", $r1
# R2
color $COLOR_REGNAME
printf "R2:"
if ($r2 != $oldr2 && $SHOWREGCHANGES == 1)
color $COLOR_REGVAL_MODIFIED
else
color $COLOR_REGVAL
end
printf " 0x%08X ", $r2
# R3
color $COLOR_REGNAME
printf "R3:"
if ($r3 != $oldr3 && $SHOWREGCHANGES == 1)
color $COLOR_REGVAL_MODIFIED
else
color $COLOR_REGVAL
end
printf " 0x%08X\n", $r3
printf " "
# R4
color $COLOR_REGNAME
printf "R4:"
if ($r4 != $oldr4 && $SHOWREGCHANGES == 1)
color $COLOR_REGVAL_MODIFIED
else
color $COLOR_REGVAL
end
printf " 0x%08X ", $r4
# R5
color $COLOR_REGNAME
printf "R5:"
if ($r5 != $oldr5 && $SHOWREGCHANGES == 1)
color $COLOR_REGVAL_MODIFIED
else
color $COLOR_REGVAL
end
printf " 0x%08X ", $r5
# R6
color $COLOR_REGNAME
printf "R6:"
if ($r6 != $oldr6 && $SHOWREGCHANGES == 1)
color $COLOR_REGVAL_MODIFIED
else
color $COLOR_REGVAL
end
printf " 0x%08X ", $r6
# R7
color $COLOR_REGNAME
printf "R7:"
if ($r7 != $oldr7 && $SHOWREGCHANGES == 1)
color $COLOR_REGVAL_MODIFIED
else
color $COLOR_REGVAL
end
printf " 0x%08X\n", $r7
printf " "
# R8
color $COLOR_REGNAME
printf "R8:"
if ($r8 != $oldr8 && $SHOWREGCHANGES == 1)
color $COLOR_REGVAL_MODIFIED
else
color $COLOR_REGVAL
end
printf " 0x%08X ", $r8
# R9
color $COLOR_REGNAME
printf "R9:"
if ($r9 != $oldr9 && $SHOWREGCHANGES == 1)
color $COLOR_REGVAL_MODIFIED
else
color $COLOR_REGVAL
end
printf " 0x%08X ", $r9
# R10
color $COLOR_REGNAME
printf "R10:"
if ($r10 != $oldr10 && $SHOWREGCHANGES == 1)
color $COLOR_REGVAL_MODIFIED
else
color $COLOR_REGVAL
end
printf " 0x%08X ", $r10
# R11
color $COLOR_REGNAME
printf "R11:"
if ($r11 != $oldr11 && $SHOWREGCHANGES == 1)
color $COLOR_REGVAL_MODIFIED
else
color $COLOR_REGVAL
end
printf " 0x%08X ", $r11
dumpjump
printf "\n"
# R12
color $COLOR_REGNAME
printf " R12:"
if ($r12 != $oldr12 && $SHOWREGCHANGES == 1)
color $COLOR_REGVAL_MODIFIED
else
color $COLOR_REGVAL
end
printf " 0x%08X", $r12
printf " "
# SP
color $COLOR_REGNAME
printf "SP:"
if ($sp != $oldsp && $SHOWREGCHANGES == 1)
color $COLOR_REGVAL_MODIFIED
else
color $COLOR_REGVAL
end
printf " 0x%08X ", $sp
# LR
color $COLOR_REGNAME
printf "LR:"
if ($lr != $oldlr && $SHOWREGCHANGES == 1)
color $COLOR_REGVAL_MODIFIED
else
color $COLOR_REGVAL
end
printf " 0x%08X ", $lr
# PC
color $COLOR_REGNAME
printf "PC:"
color $COLOR_REGVAL_MODIFIED
printf " 0x%08X ", $pc
color_bold
color_underline
color $COLOR_CPUFLAGS
flags
color_reset
printf "\n"
end
document regarm
Syntax: regarm
| Auxiliary function to display ARM registers.
end
define regx64
# 64bits stuff
printf " "
# RAX
color $COLOR_REGNAME
printf "RAX:"
if ($rax != $oldrax && $SHOWREGCHANGES == 1)
color $COLOR_REGVAL_MODIFIED
else
color $COLOR_REGVAL
end
printf " 0x%016lX ", $rax
# RBX
color $COLOR_REGNAME
printf "RBX:"
if ($rbx != $oldrbx && $SHOWREGCHANGES == 1)
color $COLOR_REGVAL_MODIFIED
else
color $COLOR_REGVAL
end
printf " 0x%016lX ", $rbx
# RBP
color $COLOR_REGNAME
printf "RBP:"
if ($rbp != $oldrbp && $SHOWREGCHANGES == 1)
color $COLOR_REGVAL_MODIFIED
else
color $COLOR_REGVAL
end
printf " 0x%016lX ", $rbp
# RSP
color $COLOR_REGNAME
printf "RSP:"
if ($rsp != $oldrsp && $SHOWREGCHANGES == 1)
color $COLOR_REGVAL_MODIFIED
else
color $COLOR_REGVAL
end
printf " 0x%016lX ", $rsp
color_bold
color_underline
color $COLOR_CPUFLAGS
flags
color_reset
printf " "
# RDI
color $COLOR_REGNAME
printf "RDI:"
if ($rdi != $oldrdi && $SHOWREGCHANGES == 1)
color $COLOR_REGVAL_MODIFIED
else
color $COLOR_REGVAL
end
printf " 0x%016lX ", $rdi
# RSI
color $COLOR_REGNAME
printf "RSI:"
if ($rsi != $oldrsi && $SHOWREGCHANGES == 1)
color $COLOR_REGVAL_MODIFIED
else
color $COLOR_REGVAL
end
printf " 0x%016lX ", $rsi
# RDX
color $COLOR_REGNAME
printf "RDX:"
if ($rdx != $oldrdx && $SHOWREGCHANGES == 1)
color $COLOR_REGVAL_MODIFIED
else
color $COLOR_REGVAL
end
printf " 0x%016lX ", $rdx
# RCX
color $COLOR_REGNAME
printf "RCX:"
if ($rcx != $oldrcx && $SHOWREGCHANGES == 1)
color $COLOR_REGVAL_MODIFIED
else
color $COLOR_REGVAL
end
printf " 0x%016lX ", $rcx
# RIP
color $COLOR_REGNAME
printf "RIP:"
color $COLOR_REGVAL_MODIFIED
printf " 0x%016lX\n ", $rip
# R8
color $COLOR_REGNAME
printf "R8 :"
if ($r8 != $oldr8 && $SHOWREGCHANGES == 1)
color $COLOR_REGVAL_MODIFIED
else
color $COLOR_REGVAL
end
printf " 0x%016lX ", $r8
# R9
color $COLOR_REGNAME
printf "R9 :"
if ($r9 != $oldr9 && $SHOWREGCHANGES == 1)
color $COLOR_REGVAL_MODIFIED
else
color $COLOR_REGVAL
end
printf " 0x%016lX ", $r9
# R10
color $COLOR_REGNAME
printf "R10:"
if ($r10 != $oldr10 && $SHOWREGCHANGES == 1)
color $COLOR_REGVAL_MODIFIED
else
color $COLOR_REGVAL
end
printf " 0x%016lX ", $r10
# R11
color $COLOR_REGNAME
printf "R11:"
if ($r11 != $oldr11 && $SHOWREGCHANGES == 1)
color $COLOR_REGVAL_MODIFIED
else
color $COLOR_REGVAL
end
printf " 0x%016lX ", $r11
# R12
color $COLOR_REGNAME
printf "R12:"
if ($r12 != $oldr12 && $SHOWREGCHANGES == 1)
color $COLOR_REGVAL_MODIFIED
else
color $COLOR_REGVAL
end
printf " 0x%016lX\n ", $r12
# R13
color $COLOR_REGNAME
printf "R13:"
if ($r13 != $oldr13 && $SHOWREGCHANGES == 1)
color $COLOR_REGVAL_MODIFIED
else
color $COLOR_REGVAL
end
printf " 0x%016lX ", $r13
# R14
color $COLOR_REGNAME
printf "R14:"
if ($r14 != $oldr14 && $SHOWREGCHANGES == 1)
color $COLOR_REGVAL_MODIFIED
else
color $COLOR_REGVAL
end
printf " 0x%016lX ", $r14
# R15
color $COLOR_REGNAME
printf "R15:"
if ($r15 != $oldr15 && $SHOWREGCHANGES == 1)
color $COLOR_REGVAL_MODIFIED
else
color $COLOR_REGVAL
end
printf " 0x%016lX\n ", $r15
color $COLOR_REGNAME
printf "CS:"
color $COLOR_REGVAL
printf " %04X ", $cs
color $COLOR_REGNAME
printf "DS:"
color $COLOR_REGVAL
printf " %04X ", $ds
color $COLOR_REGNAME
printf "ES:"
color $COLOR_REGVAL
printf " %04X ", $es
color $COLOR_REGNAME
printf "FS:"
color $COLOR_REGVAL
printf " %04X ", $fs
color $COLOR_REGNAME
printf "GS:"
color $COLOR_REGVAL
printf " %04X ", $gs
color $COLOR_REGNAME
printf "SS:"
color $COLOR_REGVAL
printf " %04X", $ss
color_reset
end
document regx64
Syntax: regx64
| Auxiliary function to display X86_64 registers.
end
define regx86
printf " "
# EAX
color $COLOR_REGNAME
printf "EAX:"
if ($eax != $oldeax && $SHOWREGCHANGES == 1)
color $COLOR_REGVAL_MODIFIED
else
color $COLOR_REGVAL
end
printf " 0x%08X ", $eax
# EBX
color $COLOR_REGNAME
printf "EBX:"
if ($ebx != $oldebx && $SHOWREGCHANGES == 1)
color $COLOR_REGVAL_MODIFIED
else
color $COLOR_REGVAL
end
printf " 0x%08X ", $ebx
# ECX
color $COLOR_REGNAME
printf "ECX:"
if ($ecx != $oldecx && $SHOWREGCHANGES == 1)
color $COLOR_REGVAL_MODIFIED
else
color $COLOR_REGVAL
end
printf " 0x%08X ", $ecx
# EDX
color $COLOR_REGNAME
printf "EDX:"
if ($edx != $oldedx && $SHOWREGCHANGES == 1)
color $COLOR_REGVAL_MODIFIED
else
color $COLOR_REGVAL
end
printf " 0x%08X ", $edx
color_bold
color_underline
color $COLOR_CPUFLAGS
flags
color_reset
printf " "
# ESI
color $COLOR_REGNAME
printf "ESI:"
if ($esi != $oldesi && $SHOWREGCHANGES == 1)
color $COLOR_REGVAL_MODIFIED
else
color $COLOR_REGVAL
end
printf " 0x%08X ", $esi
# EDI
color $COLOR_REGNAME
printf "EDI:"
if ($edi != $oldedi && $SHOWREGCHANGES == 1)
color $COLOR_REGVAL_MODIFIED
else
color $COLOR_REGVAL
end
printf " 0x%08X ", $edi
# EBP
color $COLOR_REGNAME
printf "EBP:"
if ($ebp != $oldebp && $SHOWREGCHANGES == 1)
color $COLOR_REGVAL_MODIFIED
else
color $COLOR_REGVAL
end
printf " 0x%08X ", $ebp
# ESP
color $COLOR_REGNAME
printf "ESP:"
if ($esp != $oldesp && $SHOWREGCHANGES == 1)
color $COLOR_REGVAL_MODIFIED
else
color $COLOR_REGVAL
end
printf " 0x%08X ", $esp
# EIP
color $COLOR_REGNAME
printf "EIP:"
color $COLOR_REGVAL_MODIFIED
printf " 0x%08X\n ", $eip
color $COLOR_REGNAME
printf "CS:"
color $COLOR_REGVAL
printf " %04X ", $cs
color $COLOR_REGNAME
printf "DS:"
color $COLOR_REGVAL
printf " %04X ", $ds
color $COLOR_REGNAME
printf "ES:"
color $COLOR_REGVAL
printf " %04X ", $es
color $COLOR_REGNAME
printf "FS:"
color $COLOR_REGVAL
printf " %04X ", $fs
color $COLOR_REGNAME
printf "GS:"
color $COLOR_REGVAL
printf " %04X ", $gs
color $COLOR_REGNAME
printf "SS:"
color $COLOR_REGVAL
printf " %04X", $ss
color_reset
end
document regx86
Syntax: regx86
| Auxiliary function to display X86 registers.
end
define reg
if $ARM == 1
regarm
if ($SHOWREGCHANGES == 1)
set $oldr0 = $r0
set $oldr1 = $r1
set $oldr2 = $r2
set $oldr3 = $r3
set $oldr4 = $r4
set $oldr5 = $r5
set $oldr6 = $r6
set $oldr7 = $r7
set $oldr8 = $r8
set $oldr9 = $r9
set $oldr10 = $r10
set $oldr11 = $r11
set $oldr12 = $r12
set $oldsp = $sp
set $oldlr = $lr
end
else
if ($64BITS == 1)
regx64
else
regx86
end
# call smallregisters
smallregisters
# display conditional jump routine
if ($64BITS == 1)
printf "\t\t\t\t"
end
dumpjump
printf "\n"
if ($SHOWREGCHANGES == 1)
if ($64BITS == 1)
set $oldrax = $rax
set $oldrbx = $rbx
set $oldrcx = $rcx
set $oldrdx = $rdx
set $oldrsi = $rsi
set $oldrdi = $rdi
set $oldrbp = $rbp
set $oldrsp = $rsp
set $oldr8 = $r8
set $oldr9 = $r9
set $oldr10 = $r10
set $oldr11 = $r11
set $oldr12 = $r12
set $oldr13 = $r13
set $oldr14 = $r14
set $oldr15 = $r15
else
set $oldeax = $eax
set $oldebx = $ebx
set $oldecx = $ecx
set $oldedx = $edx
set $oldesi = $esi
set $oldedi = $edi
set $oldebp = $ebp
set $oldesp = $esp
end
end
end
end
document reg
Syntax: reg
| Print CPU registers.
end
define smallregisters
if ($64BITS == 1)
#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 <REGEXP>
| Print all function names in target, or those matching REGEXP.
end
define var
if $argc == 0
info variables
end
if $argc == 1
info variables $arg0
end
if $argc > 1
help var
end
end
document var
Syntax: var <REGEXP>
| Print all global and static variable names (symbols), or those matching REGEXP.
end
define lib
info sharedlibrary
end
document lib
Syntax: lib
| Print shared libraries linked to target.
end
define sig
if $argc == 0
info signals
end
if $argc == 1
info signals $arg0
end
if $argc > 1
help sig
end
end
document sig
Syntax: sig <SIGNAL>
| Print what debugger does when program gets various signals.
| Specify a SIGNAL as argument to print info on that signal only.
end
define threads
info threads
end
document threads
Syntax: threads
| Print threads in target.
end
define dis
if $argc == 0
disassemble
end
if $argc == 1
disassemble $arg0
end
if $argc == 2
disassemble $arg0 $arg1
end
if $argc > 2
help dis
end
end
document dis
Syntax: dis <ADDR1> <ADDR2>
| Disassemble a specified section of memory.
| Default is to disassemble the function surrounding the PC (program counter) of selected frame.
| With one argument, ADDR1, the function surrounding this address is dumped.
| Two arguments are taken as a range of memory to dump.
end
# __________hex/ascii dump an address_________
define ascii_char
if $argc != 1
help ascii_char
else
# thanks elaine :)
set $_c = *(unsigned char *)($arg0)
if ($_c < 0x20 || $_c > 0x7E)
printf "."
else
printf "%c", $_c
end
end
end
document ascii_char
Syntax: ascii_char ADDR
| Print ASCII value of byte at address ADDR.
| Print "." if the value is unprintable.
end
define hex_quad
if $argc != 1
help hex_quad
else
printf "%02X %02X %02X %02X %02X %02X %02X %02X", \
*(unsigned char*)($arg0), *(unsigned char*)($arg0 + 1), \
*(unsigned char*)($arg0 + 2), *(unsigned char*)($arg0 + 3), \
*(unsigned char*)($arg0 + 4), *(unsigned char*)($arg0 + 5), \
*(unsigned char*)($arg0 + 6), *(unsigned char*)($arg0 + 7)
end
end
document hex_quad
Syntax: hex_quad ADDR
| Print eight hexadecimal bytes starting at address ADDR.
end
define hexdump
if $argc == 1
hexdump_aux $arg0
else
if $argc == 2
set $_count = 0
while ($_count < $arg1)
set $_i = ($_count * 0x10)
hexdump_aux $arg0+$_i
set $_count++
end
else
help hexdump
end
end
end
document hexdump
Syntax: hexdump ADDR <NR_LINES>
| Display a 16-byte hex/ASCII dump of memory starting at address ADDR.
| Optional parameter is the number of lines to display if you want more than one.
end
define hexdump_aux
if $argc != 1
help hexdump_aux
else
color_bold
if ($64BITS == 1)
printf "0x%016lX : ", $arg0
else
printf "0x%08X : ", $arg0
end
color_reset
hex_quad $arg0
color_bold
printf " - "
color_reset
hex_quad $arg0+8
printf " "
color_bold
ascii_char $arg0+0x0
ascii_char $arg0+0x1
ascii_char $arg0+0x2
ascii_char $arg0+0x3
ascii_char $arg0+0x4
ascii_char $arg0+0x5
ascii_char $arg0+0x6
ascii_char $arg0+0x7
ascii_char $arg0+0x8
ascii_char $arg0+0x9
ascii_char $arg0+0xA
ascii_char $arg0+0xB
ascii_char $arg0+0xC
ascii_char $arg0+0xD
ascii_char $arg0+0xE
ascii_char $arg0+0xF
color_reset
printf "\n"
end
end
document hexdump_aux
Syntax: hexdump_aux ADDR
| Display a 16-byte hex/ASCII dump of memory at address ADDR.
end
# _______________data window__________________
define ddump
if $argc != 1
help ddump
else
color $COLOR_SEPARATOR
if $ARM == 1
printf "[0x%08X]", $data_addr
else
if ($64BITS == 1)
printf "[0x%04X:0x%016lX]", $ds, $data_addr
else
printf "[0x%04X:0x%08X]", $ds, $data_addr
end
end
color $COLOR_SEPARATOR
printf "------------------------"
printf "-------------------------------"
if ($64BITS == 1)
printf "-------------------------------------"
end
color_bold
color $COLOR_SEPARATOR
printf "[data]\n"
color_reset
set $_count = 0
while ($_count < $arg0)
set $_i = ($_count * 0x10)
hexdump $data_addr+$_i
set $_count++
end
end
end
document ddump
Syntax: ddump NUM
| Display NUM lines of hexdump for address in $data_addr global variable.
end
define dd
if $argc != 1
help dd
else
set $data_addr = $arg0
ddump 0x10
end
end
document dd
Syntax: dd ADDR
| Display 16 lines of a hex dump of address starting at ADDR.
end
define datawin
if $ARM == 1
if ((($r0 >> 0x18) == 0x40) || (($r0 >> 0x18) == 0x08) || (($r0 >> 0x18) == 0xBF))
set $data_addr = $r0
else
if ((($r1 >> 0x18) == 0x40) || (($r1 >> 0x18) == 0x08) || (($r1 >> 0x18) == 0xBF))
set $data_addr = $r1
else
if ((($r2 >> 0x18) == 0x40) || (($r2 >> 0x18) == 0x08) || (($r2 >> 0x18) == 0xBF))
set $data_addr = $r2
else
set $data_addr = $sp
end
end
end
################################# X86
else
if ($64BITS == 1)
if ((($rsi >> 0x18) == 0x40) || (($rsi >> 0x18) == 0x08) || (($rsi >> 0x18) == 0xBF))
set $data_addr = $rsi
else
if ((($rdi >> 0x18) == 0x40) || (($rdi >> 0x18) == 0x08) || (($rdi >> 0x18) == 0xBF))
set $data_addr = $rdi
else
if ((($rax >> 0x18) == 0x40) || (($rax >> 0x18) == 0x08) || (($rax >> 0x18) == 0xBF))
set $data_addr = $rax
else
set $data_addr = $rsp
end
end
end
else
if ((($esi >> 0x18) == 0x40) || (($esi >> 0x18) == 0x08) || (($esi >> 0x18) == 0xBF))
set $data_addr = $esi
else
if ((($edi >> 0x18) == 0x40) || (($edi >> 0x18) == 0x08) || (($edi >> 0x18) == 0xBF))
set $data_addr = $edi
else
if ((($eax >> 0x18) == 0x40) || (($eax >> 0x18) == 0x08) || (($eax >> 0x18) == 0xBF))
set $data_addr = $eax
else
set $data_addr = $esp
end
end
end
end
end
ddump $CONTEXTSIZE_DATA
end
document datawin
Syntax: datawin
| Display valid address from one register in data window.
| Registers to choose are: esi, edi, eax, or esp.
end
################################
##### ALERT ALERT ALERT ########
################################
# Huge mess going here :) HAHA #
################################
define dumpjump
if $ARM == 1
## Most ARM and Thumb instructions are conditional!
# each instruction is 32 bits long
# 4 bits are for condition codes (16 in total) (bits 31:28 in ARM contain the condition or 1111 if instruction is unconditional)
# 2x4 bits for destination and first operand registers
# one for the set-status flag
# an assorted number for other stuff
# 12 bits for any immediate value
# $_t_flag == 0 => ARM mode
# $_t_flag == 1 => Thumb or ThumbEE
# State bit (T), bit 5
if (($cpsr >> 5) & 1)
set $_t_flag = 1
else
set $_t_flag = 0
end
if $_t_flag == 0
set $_lastbyte = *(unsigned char *)($pc+3)
#set $_bit31 = ($_lastbyte >> 7) & 1
#set $_bit30 = ($_lastbyte >> 6) & 1
#set $_bit29 = ($_lastbyte >> 5) & 1
#set $_bit28 = ($_lastbyte >> 4) & 1
set $_conditional = $_lastbyte >> 4
dumpjumphelper
else
# if bits 15-12 (opcode in Thumb instructions) are equal to 1 1 0 1 (0xD) then we have a conditional branch
# bits 11-8 for the conditional execution code (check ARMv7 manual A8.3)
if ( (*(unsigned char *)($pc+1) >> 4) == 0xD )
set $_conditional = *(unsigned char *)($pc+1) ^ 0xD0
dumpjumphelper
end
end
##################### X86
else
## grab the first two bytes from the instruction so we can determine the jump instruction
set $_byte1 = *(unsigned char *)$pc
set $_byte2 = *(unsigned char *)($pc+1)
## and now check what kind of jump we have (in case it's a jump instruction)
## I changed the flags routine to save the flag into a variable, so we don't need to repeat the process :) (search for "define flags")
## opcode 0x77: JA, JNBE (jump if CF=0 and ZF=0)
## opcode 0x0F87: JNBE, JA
if ( ($_byte1 == 0x77) || ($_byte1 == 0x0F && $_byte2 == 0x87) )
# cf=0 and zf=0
if ($_cf_flag == 0 && $_zf_flag == 0)
color $RED
printf " Jump is taken (c=0 and z=0)"
else
# cf != 0 or zf != 0
color $RED
printf " Jump is NOT taken (c!=0 or z!=0)"
end
end
## opcode 0x73: JAE, JNB, JNC (jump if CF=0)
## opcode 0x0F83: JNC, JNB, JAE (jump if CF=0)
if ( ($_byte1 == 0x73) || ($_byte1 == 0x0F && $_byte2 == 0x83) )
# cf=0
if ($_cf_flag == 0)
color $RED
printf " Jump is taken (c=0)"
else
# cf != 0
color $RED
printf " Jump is NOT taken (c!=0)"
end
end
## opcode 0x72: JB, JC, JNAE (jump if CF=1)
## opcode 0x0F82: JNAE, JB, JC
if ( ($_byte1 == 0x72) || ($_byte1 == 0x0F && $_byte2 == 0x82) )
# cf=1
if ($_cf_flag == 1)
color $RED
printf " Jump is taken (c=1)"
else
# cf != 1
color $RED
printf " Jump is NOT taken (c!=1)"
end
end
## opcode 0x76: JBE, JNA (jump if CF=1 or ZF=1)
## opcode 0x0F86: JBE, JNA
if ( ($_byte1 == 0x76) || ($_byte1 == 0x0F && $_byte2 == 0x86) )
# cf=1 or zf=1
if (($_cf_flag == 1) || ($_zf_flag == 1))
color $RED
printf " Jump is taken (c=1 or z=1)"
else
# cf != 1 or zf != 1
color $RED
printf " Jump is NOT taken (c!=1 or z!=1)"
end
end
## opcode 0xE3: JCXZ, JECXZ, JRCXZ (jump if CX=0 or ECX=0 or RCX=0)
if ($_byte1 == 0xE3)
# cx=0 or ecx=0
if (($ecx == 0) || ($cx == 0))
color $RED
printf " Jump is taken (cx=0 or ecx=0)"
else
color $RED
printf " Jump is NOT taken (cx!=0 or ecx!=0)"
end
end
## opcode 0x74: JE, JZ (jump if ZF=1)
## opcode 0x0F84: JZ, JE, JZ (jump if ZF=1)
if ( ($_byte1 == 0x74) || ($_byte1 == 0x0F && $_byte2 == 0x84) )
# ZF = 1
if ($_zf_flag == 1)
color $RED
printf " Jump is taken (z=1)"
else
# ZF = 0
color $RED
printf " Jump is NOT taken (z!=1)"
end
end
## opcode 0x7F: JG, JNLE (jump if ZF=0 and SF=OF)
## opcode 0x0F8F: JNLE, JG (jump if ZF=0 and SF=OF)
if ( ($_byte1 == 0x7F) || ($_byte1 == 0x0F && $_byte2 == 0x8F) )
# zf = 0 and sf = of
if (($_zf_flag == 0) && ($_sf_flag == $_of_flag))
color $RED
printf " Jump is taken (z=0 and s=o)"
else
color $RED
printf " Jump is NOT taken (z!=0 or s!=o)"
end
end
## opcode 0x7D: JGE, JNL (jump if SF=OF)
## opcode 0x0F8D: JNL, JGE (jump if SF=OF)
if ( ($_byte1 == 0x7D) || ($_byte1 == 0x0F && $_byte2 == 0x8D) )
# sf = of
if ($_sf_flag == $_of_flag)
color $RED
printf " Jump is taken (s=o)"
else
color $RED
printf " Jump is NOT taken (s!=o)"
end
end
## opcode: 0x7C: JL, JNGE (jump if SF != OF)
## opcode: 0x0F8C: JNGE, JL (jump if SF != OF)
if ( ($_byte1 == 0x7C) || ($_byte1 == 0x0F && $_byte2 == 0x8C) )
# sf != of
if ($_sf_flag != $_of_flag)
color $RED
printf " Jump is taken (s!=o)"
else
color $RED
printf " Jump is NOT taken (s=o)"
end
end
## opcode 0x7E: JLE, JNG (jump if ZF = 1 or SF != OF)
## opcode 0x0F8E: JNG, JLE (jump if ZF = 1 or SF != OF)
if ( ($_byte1 == 0x7E) || ($_byte1 == 0x0F && $_byte2 == 0x8E) )
# zf = 1 or sf != of
if (($_zf_flag == 1) || ($_sf_flag != $_of_flag))
color $RED
printf " Jump is taken (zf=1 or sf!=of)"
else
color $RED
printf " Jump is NOT taken (zf!=1 or sf=of)"
end
end
## opcode 0x75: JNE, JNZ (jump if ZF = 0)
## opcode 0x0F85: JNE, JNZ (jump if ZF = 0)
if ( ($_byte1 == 0x75) || ($_byte1 == 0x0F && $_byte2 == 0x85) )
# ZF = 0
if ($_zf_flag == 0)
color $RED
printf " Jump is taken (z=0)"
else
# ZF = 1
color $RED
printf " Jump is NOT taken (z!=0)"
end
end
## opcode 0x71: JNO (OF = 0)
## opcode 0x0F81: JNO (OF = 0)
if ( ($_byte1 == 0x71) || ($_byte1 == 0x0F && $_byte2 == 0x81) )
# OF = 0
if ($_of_flag == 0)
color $RED
printf " Jump is taken (o=0)"
else
# OF != 0
color $RED
printf " Jump is NOT taken (o!=0)"
end
end
## opcode 0x7B: JNP, JPO (jump if PF = 0)
## opcode 0x0F8B: JPO (jump if PF = 0)
if ( ($_byte1 == 0x7B) || ($_byte1 == 0x0F && $_byte2 == 0x8B) )
# PF = 0
if ($_pf_flag == 0)
color $RED
printf " Jump is NOT taken (p=0)"
else
# PF != 0
color $RED
printf " Jump is taken (p!=0)"
end
end
## opcode 0x79: JNS (jump if SF = 0)
## opcode 0x0F89: JNS (jump if SF = 0)
if ( ($_byte1 == 0x79) || ($_byte1 == 0x0F && $_byte2 == 0x89) )
# SF = 0
if ($_sf_flag == 0)
color $RED
printf " Jump is taken (s=0)"
else
# SF != 0
color $RED
printf " Jump is NOT taken (s!=0)"
end
end
## opcode 0x70: JO (jump if OF=1)
## opcode 0x0F80: JO (jump if OF=1)
if ( ($_byte1 == 0x70) || ($_byte1 == 0x0F && $_byte2 == 0x80) )
# OF = 1
if ($_of_flag == 1)
color $RED
printf " Jump is taken (o=1)"
else
# OF != 1
color $RED
printf " Jump is NOT taken (o!=1)"
end
end
## opcode 0x7A: JP, JPE (jump if PF=1)
## opcode 0x0F8A: JP, JPE (jump if PF=1)
if ( ($_byte1 == 0x7A) || ($_byte1 == 0x0F && $_byte2 == 0x8A) )
# PF = 1
if ($_pf_flag == 1)
color $RED
printf " Jump is taken (p=1)"
else
# PF = 0
color $RED
printf " Jump is NOT taken (p!=1)"
end
end
## opcode 0x78: JS (jump if SF=1)
## opcode 0x0F88: JS (jump if SF=1)
if ( ($_byte1 == 0x78) || ($_byte1 == 0x0F && $_byte2 == 0x88) )
# SF = 1
if ($_sf_flag == 1)
color $RED
printf " Jump is taken (s=1)"
else
# SF != 1
color $RED
printf " Jump is NOT taken (s!=1)"
end
end
end
end
document dumpjump
Syntax: dumpjump
| Display if conditional jump will be taken or not.
end
define dumpjumphelper
# 0000 - EQ: Z == 1
if ($_conditional == 0x0)
if ($_z_flag == 1)
color $RED
printf " Jump is taken (z==1)"
else
color $RED
printf " Jump is NOT taken (z!=1)"
end
end
# 0001 - NE: Z == 0
if ($_conditional == 0x1)
if ($_z_flag == 0)
color $RED
printf " Jump is taken (z==0)"
else
color $RED
printf " Jump is NOT taken (z!=0)"
end
end
# 0010 - CS: C == 1
if ($_conditional == 0x2)
if ($_c_flag == 1)
color $RED
printf " Jump is taken (c==1)"
else
color $RED
printf " Jump is NOT taken (c!=1)"
end
end
# 0011 - CC: C == 0
if ($_conditional == 0x3)
if ($_c_flag == 0)
color $RED
printf " Jump is taken (c==0)"
else
color $RED
printf " Jump is NOT taken (c!=0)"
end
end
# 0100 - MI: N == 1
if ($_conditional == 0x4)
if ($_n_flag == 1)
color $RED
printf " Jump is taken (n==1)"
else
color $RED
printf " Jump is NOT taken (n!=1)"
end
end
# 0101 - PL: N == 0
if ($_conditional == 0x5)
if ($_n_flag == 0)
color $RED
printf " Jump is taken (n==0)"
else
color $RED
printf " Jump is NOT taken (n!=0)"
end
end
# 0110 - VS: V == 1
if ($_conditional == 0x6)
if ($_v_flag == 1)
color $RED
printf " Jump is taken (v==1)"
else
color $RED
printf " Jump is NOT taken (v!=1)"
end
end
# 0111 - VC: V == 0
if ($_conditional == 0x7)
if ($_v_flag == 0)
color $RED
printf " Jump is taken (v==0)"
else
color $RED
printf " Jump is NOT taken (v!=0)"
end
end
# 1000 - HI: C == 1 and Z == 0
if ($_conditional == 0x8)
if ($_c_flag == 1 && $_z_flag == 0)
color $RED
printf " Jump is taken (c==1 and z==0)"
else
color $RED
printf " Jump is NOT taken (c!=1 or z!=0)"
end
end
# 1001 - LS: C == 0 or Z == 1
if ($_conditional == 0x9)
if ($_c_flag == 0 || $_z_flag == 1)
color $RED
printf " Jump is taken (c==0 or z==1)"
else
color $RED
printf " Jump is NOT taken (c!=0 or z!=1)"
end
end
# 1010 - GE: N == V
if ($_conditional == 0xA)
if ($_n_flag == $_v_flag)
color $RED
printf " Jump is taken (n==v)"
else
color $RED
printf " Jump is NOT taken (n!=v)"
end
end
# 1011 - LT: N != V
if ($_conditional == 0xB)
if ($_n_flag != $_v_flag)
color $RED
printf " Jump is taken (n!=v)"
else
color $RED
printf " Jump is NOT taken (n==v)"
end
end
# 1100 - GT: Z == 0 and N == V
if ($_conditional == 0xC)
if ($_z_flag == 0 && $_n_flag == $_v_flag)
color $RED
printf " Jump is taken (z==0 and n==v)"
else
color $RED
printf " Jump is NOT taken (z!=0 or n!=v)"
end
end
# 1101 - LE: Z == 1 or N != V
if ($_conditional == 0xD)
if ($_z_flag == 1 || $_n_flag != $_v_flag)
color $RED
printf " Jump is taken (z==1 or n!=v)"
else
color $RED
printf " Jump is NOT taken (z!=1 or n==v)"
end
end
end
document dumpjumphelper
Syntax: dumpjumphelper
| Helper function to decide if conditional jump will be taken or not, for ARM and Thumb.
end
# _______________process context______________
# initialize variable
set $displayobjectivec = 0
define context
color $COLOR_SEPARATOR
if $SHOWCPUREGISTERS == 1
printf "----------------------------------------"
printf "----------------------------------"
if ($64BITS == 1)
printf "---------------------------------------------"
end
color $COLOR_SEPARATOR
color_bold
printf "[regs]\n"
color_reset
reg
color $CYAN
end
if $SHOWSTACK == 1
color $COLOR_SEPARATOR
if $ARM == 1
printf "[0x%08X]", $sp
else
if ($64BITS == 1)
printf "[0x%04X:0x%016lX]", $ss, $rsp
else
printf "[0x%04X:0x%08X]", $ss, $esp
end
end
color $COLOR_SEPARATOR
printf "-------------------------"
printf "-----------------------------"
if ($64BITS == 1)
printf "-------------------------------------"
end
color $COLOR_SEPARATOR
color_bold
printf "[stack]\n"
color_reset
set $context_i = $CONTEXTSIZE_STACK
while ($context_i > 0)
set $context_t = $sp + 0x10 * ($context_i - 1)
hexdump $context_t
set $context_i--
end
end
# show the objective C message being passed to msgSend
if $SHOWOBJECTIVEC == 1
#FIXME: X64 and ARM
# What a piece of crap that's going on here :)
# detect if it's the correct opcode we are searching for
if $ARM == 0
set $__byte1 = *(unsigned char *)$pc
set $__byte = *(int *)$pc
if ($__byte == 0x4244489)
set $objectivec = $eax
set $displayobjectivec = 1
end
if ($__byte == 0x4245489)
set $objectivec = $edx
set $displayobjectivec = 1
end
if ($__byte == 0x4244c89)
set $objectivec = $ecx
set $displayobjectivec = 1
end
else
set $__byte1 = 0
end
# and now display it or not (we have no interest in having the info displayed after the call)
if $__byte1 == 0xE8
if $displayobjectivec == 1
color $COLOR_SEPARATOR
printf "--------------------------------------------------------------------"
if ($64BITS == 1)
printf "---------------------------------------------"
end
color $COLOR_SEPARATOR
color_bold
printf "[ObjectiveC]\n"
color_reset
color $BLACK
x/s $objectivec
end
set $displayobjectivec = 0
end
if $displayobjectivec == 1
color $COLOR_SEPARATOR
printf "--------------------------------------------------------------------"
if ($64BITS == 1)
printf "---------------------------------------------"
end
color $COLOR_SEPARATOR
color_bold
printf "[ObjectiveC]\n"
color_reset
color $BLACK
x/s $objectivec
end
end
color_reset
# and this is the end of this little crap
if $SHOWDATAWIN == 1
datawin
end
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 <NUM>
| Step one instruction, but proceed through subroutine calls.
| If NUM is given, then repeat it NUM times or till program stops.
| This is alias for nexti.
end
define go
if $argc == 0
stepi
end
if $argc == 1
stepi $arg0
end
if $argc > 1
help go
end
end
document go
Syntax: go <NUM>
| Step one instruction exactly.
| If NUM is given, then repeat it NUM times or till program stops.
| This is alias for stepi.
end
define pret
finish
end
document pret
Syntax: pret
| Execute until selected stack frame returns (step out of current call).
| Upon return, the value returned is printed and put in the value history.
end
define init
set $SHOW_NEST_INSN = 0
tbreak _init
r
end
document init
Syntax: init
| Run program and break on _init().
end
define start
set $SHOW_NEST_INSN = 0
tbreak _start
r
end
document start
Syntax: start
| Run program and break on _start().
end
define sstart
set $SHOW_NEST_INSN = 0
tbreak __libc_start_main
r
end
document sstart
Syntax: sstart
| Run program and break on __libc_start_main().
| Useful for stripped executables.
end
define main
set $SHOW_NEST_INSN = 0
tbreak main
r
end
document main
Syntax: main
| Run program and break on main().
end
# FIXME64
#### WARNING ! WARNING !!
#### More more messy stuff starting !!!
#### I was thinking about how to do this and then it ocurred me that it could be as simple as this ! :)
define stepoframework
if $ARM == 1
# bl and bx opcodes
# bx Rn => ARM bits 27-20: 0 0 0 1 0 0 1 0 , bits 7-4: 0 0 0 1 ; Thumb bits: 15-7: 0 1 0 0 0 1 1 1 0
# blx Rn => ARM bits 27-20: 0 0 0 1 0 0 1 0 , bits 7-4: 0 0 1 1 ; Thumb bits: 15-7: 0 1 0 0 0 1 1 1 1
# bl # => ARM bits 27-24: 1 0 1 1 ; Thumb bits: 15-11: 1 1 1 1 0
# blx # => ARM bits 31-25: 1 1 1 1 1 0 1 ; Thumb bits: 15-11: 1 1 1 1 0
set $_nextaddress = 0
# ARM Mode
if ($_t_flag == 0)
set $_branchesint = *(unsigned int*)$pc
set $_bit31 = ($_branchesint >> 0x1F) & 1
set $_bit30 = ($_branchesint >> 0x1E) & 1
set $_bit29 = ($_branchesint >> 0x1D) & 1
set $_bit28 = ($_branchesint >> 0x1C) & 1
set $_bit27 = ($_branchesint >> 0x1B) & 1
set $_bit26 = ($_branchesint >> 0x1A) & 1
set $_bit25 = ($_branchesint >> 0x19) & 1
set $_bit24 = ($_branchesint >> 0x18) & 1
set $_bit23 = ($_branchesint >> 0x17) & 1
set $_bit22 = ($_branchesint >> 0x16) & 1
set $_bit21 = ($_branchesint >> 0x15) & 1
set $_bit20 = ($_branchesint >> 0x14) & 1
set $_bit7 = ($_branchesint >> 0x7) & 1
set $_bit6 = ($_branchesint >> 0x6) & 1
set $_bit5 = ($_branchesint >> 0x5) & 1
set $_bit4 = ($_branchesint >> 0x4) & 1
# set $_lastbyte = *(unsigned char *)($pc+3)
# set $_bits2724 = $_lastbyte & 0x1
# set $_bits3128 = $_lastbyte >> 4
# if ($_bits3128 == 0xF)
# set $_bits2724 = $_lastbyte & 0xA
# set $_bits2724 = $_bits2724 >> 1
# end
# set $_previousbyte = *(unsigned char *)($pc+2)
# set $_bits2320 = $_previousbyte >> 4
# printf "bits2724: %x bits2320: %x\n", $_bits2724, $_bits2320
if ($_bit27 == 0 && $_bit26 == 0 && $_bit25 == 0 && $_bit24 == 1 && $_bit23 == 0 && $_bit22 == 0 && $_bit21 == 1 && $_bit20 == 0 && $_bit7 == 0 && $_bit6 == 0 && $_bit5 == 0 && $_bit4 == 1)
printf "Found a bx Rn\n"
set $_nextaddress = $pc+0x4
end
if ($_bit27 == 0 && $_bit26 == 0 && $_bit25 == 0 && $_bit24 == 1 && $_bit23 == 0 && $_bit22 == 0 && $_bit21 == 1 && $_bit20 == 0 && $_bit7 == 0 && $_bit6 == 0 && $_bit5 == 1 && $_bit4 == 1)
printf "Found a blx Rn\n"
set $_nextaddress = $pc+0x4
end
if ($_bit27 == 1 && $_bit26 == 0 && $_bit25 == 1 && $_bit24 == 1)
printf "Found a bl #\n"
set $_nextaddress = $pc+0x4
end
if ($_bit31 == 1 && $_bit30 == 1 && $_bit29 == 1 && $_bit28 == 1 && $_bit27 == 1 && $_bit26 == 0 && $_bit25 == 1)
printf "Found a blx #\n"
set $_nextaddress = $pc+0x4
end
# Thumb Mode
else
# 32 bits instructions in Thumb are divided into two half words
set $_hw1 = *(unsigned short*)($pc)
set $_hw2 = *(unsigned short*)($pc+2)
# bl/blx (immediate)
# hw1: bits 15-11: 1 1 1 1 0
# hw2: bits 15-14: 1 1 ; BL bit 12: 1 ; BLX bit 12: 0
if ( ($_hw1 >> 0xC) == 0xF && (($_hw1 >> 0xB) & 1) == 0)
if ( ((($_hw2 >> 0xF) & 1) == 1) && ((($_hw2 >> 0xE) & 1) == 1) )
set $_nextaddress = $pc+0x4
end
end
end
# if we have found a call to bypass we set a temporary breakpoint on next instruction and continue
if ($_nextaddress != 0)
tbreak *$_nextaddress
continue
printf "[StepO] Next address will be %x\n", $_nextaddress
# else we just single step
else
nexti
end
###################################### X86
else
## we know that an opcode starting by 0xE8 has a fixed length
## for the 0xFF opcodes, we can enumerate what is possible to have
# first we grab the first 3 bytes from the current program counter
set $_byte1 = *(unsigned char *)$pc
set $_byte2 = *(unsigned char *)($pc+1)
set $_byte3 = *(unsigned char *)($pc+2)
# and start the fun
# if it's a 0xE8 opcode, the total instruction size will be 5 bytes
# so we can simply calculate the next address and use a temporary breakpoint ! Voila :)
set $_nextaddress = 0
# this one is the must useful for us !!!
if ($_byte1 == 0xE8)
set $_nextaddress = $pc + 0x5
else
# just other cases we might be interested in... maybe this should be removed since the 0xE8 opcode is the one we will use more
# this is a big fucking mess and can be improved for sure :) I don't like the way it is ehehehe
if ($_byte1 == 0xFF)
# call *%eax (0xFFD0) || call *%edx (0xFFD2) || call *(%ecx) (0xFFD1) || call (%eax) (0xFF10) || call *%esi (0xFFD6) || call *%ebx (0xFFD3) || call DWORD PTR [edx] (0xFF12)
if ($_byte2 == 0xD0 || $_byte2 == 0xD1 || $_byte2 == 0xD2 || $_byte2 == 0xD3 || $_byte2 == 0xD6 || $_byte2 == 0x10 || $_byte2 == 0x11 || $_byte2 == 0xD7 || $_byte2 == 0x12)
set $_nextaddress = $pc + 0x2
end
# call *0x??(%ebp) (0xFF55??) || call *0x??(%esi) (0xFF56??) || call *0x??(%edi) (0xFF5F??) || call *0x??(%ebx)
# call *0x??(%edx) (0xFF52??) || call *0x??(%ecx) (0xFF51??) || call *0x??(%edi) (0xFF57??) || call *0x??(%eax) (0xFF50??)
if ($_byte2 == 0x55 || $_byte2 == 0x56 || $_byte2 == 0x5F || $_byte2 == 0x53 || $_byte2 == 0x52 || $_byte2 == 0x51 || $_byte2 == 0x57 || $_byte2 == 0x50)
set $_nextaddress = $pc + 0x3
end
# call *0x????????(%ebx) (0xFF93????????) ||
if ($_byte2 == 0x93 || $_byte2 == 0x94 || $_byte2 == 0x90 || $_byte2 == 0x92 || $_byte2 == 0x95 || $_byte2 == 0x15)
set $_nextaddress = $pc + 6
end
# call *0x????????(%ebx,%eax,4) (0xFF94??????????)
if ($_byte2 == 0x94)
set $_nextaddress = $pc + 7
end
end
# FIXME: still missing a few?
if ($_byte1 == 0x41 || $_byte1 == 0x40)
if ($_byte2 == 0xFF)
if ($_byte3 == 0xD0 || $_byte3 == 0xD1 || $_byte3 == 0xD2 || $_byte3 == 0xD3 || $_byte3 == 0xD4 || $_byte3 == 0xD5 || $_byte3 == 0xD6 || $_byte3 == 0xD7)
set $_nextaddress = $pc + 0x3
end
end
end
end
# if we have found a call to bypass we set a temporary breakpoint on next instruction and continue
if ($_nextaddress != 0)
if ($arg0 == 1)
thbreak *$_nextaddress
else
tbreak *$_nextaddress
end
continue
# else we just single step
else
nexti
end
end
end
document stepoframework
Syntax: stepoframework
| Auxiliary function to stepo command.
end
define stepo
stepoframework 0
end
document stepo
Syntax: stepo
| Step over calls (interesting to bypass the ones to msgSend).
| This function will set a temporary breakpoint on next instruction after the call so the call will be bypassed.
| You can safely use it instead nexti or n since it will single step code if it's not a call instruction (unless you want to go into the call function).
end
define stepoh
stepoframework 1
end
document stepoh
Syntax: stepoh
| Same as stepo command but uses temporary hardware breakpoints.
end
# FIXME: ARM
define skip
x/2i $pc
set $instruction_size = (int)($_ - $pc)
set $pc = $pc + $instruction_size
if ($SKIPEXECUTE == 1)
if ($SKIPSTEP == 1)
stepo
else
stepi
end
else
context
end
end
document skip
Syntax: skip
| Skip over the instruction located at EIP/RIP. By default, the instruction will not be executed!
| Some configurable options are available on top of gdbinit to override this.
end
# _______________eflags commands______________
# conditional flags are
# negative/less than (N), bit 31 of CPSR
# zero (Z), bit 30
# Carry/Borrow/Extend (C), bit 29
# Overflow (V), bit 28
# negative/less than (N), bit 31 of CPSR
define cfn
if $ARM == 1
set $tempflag = $cpsr->n
if ($tempflag & 1)
set $cpsr->n = $tempflag&~0x1
else
set $cpsr->n = $tempflag|0x1
end
end
end
document cfn
Syntax: cfn
| Change Negative/Less Than Flag.
end
define cfc
# Carry/Borrow/Extend (C), bit 29
if $ARM == 1
set $tempflag = $cpsr->c
if ($tempflag & 1)
set $cpsr->c = $tempflag&~0x1
else
set $cpsr->c = $tempflag|0x1
end
else
if ((unsigned int)$eflags & 1)
set $eflags = (unsigned int)$eflags&~0x1
else
set $eflags = (unsigned int)$eflags|0x1
end
end
end
document cfc
Syntax: cfc
| Change Carry Flag.
end
define cfp
if (((unsigned int)$eflags >> 2) & 1)
set $eflags = (unsigned int)$eflags&~0x4
else
set $eflags = (unsigned int)$eflags|0x4
end
end
document cfp
Syntax: cfp
| Change Parity Flag.
end
define cfa
if (((unsigned int)$eflags >> 4) & 1)
set $eflags = (unsigned int)$eflags&~0x10
else
set $eflags = (unsigned int)$eflags|0x10
end
end
document cfa
Syntax: cfa
| Change Auxiliary Carry Flag.
end
define cfz
# zero (Z), bit 30
if $ARM == 1
set $tempflag = $cpsr->z
if ($tempflag & 1)
set $cpsr->z = $tempflag&~0x1
else
set $cpsr->z = $tempflag|0x1
end
else
if (((unsigned int)$eflags >> 6) & 1)
set $eflags = (unsigned int)$eflags&~0x40
else
set $eflags = (unsigned int)$eflags|0x40
end
end
end
document cfz
Syntax: cfz
| Change Zero Flag.
end
define cfs
if (((unsigned int)$eflags >> 7) & 1)
set $eflags = (unsigned int)$eflags&~0x80
else
set $eflags = (unsigned int)$eflags|0x80
end
end
document cfs
Syntax: cfs
| Change Sign Flag.
end
define cft
if (((unsigned int)$eflags >>8) & 1)
set $eflags = (unsigned int)$eflags&~0x100
else
set $eflags = (unsigned int)$eflags|0x100
end
end
document cft
Syntax: cft
| Change Trap Flag.
end
define cfi
if (((unsigned int)$eflags >> 9) & 1)
set $eflags = (unsigned int)$eflags&~0x200
else
set $eflags = (unsigned int)$eflags|0x200
end
end
document cfi
Syntax: cfi
| Change Interrupt Flag.
| Only privileged applications (usually the OS kernel) may modify IF.
| This only applies to protected mode (real mode code may always modify IF).
end
define cfd
if (((unsigned int)$eflags >>0xA) & 1)
set $eflags = (unsigned int)$eflags&~0x400
else
set $eflags = (unsigned int)$eflags|0x400
end
end
document cfd
Syntax: cfd
| Change Direction Flag.
end
define cfo
if (((unsigned int)$eflags >> 0xB) & 1)
set $eflags = (unsigned int)$eflags&~0x800
else
set $eflags = (unsigned int)$eflags|0x800
end
end
document cfo
Syntax: cfo
| Change Overflow Flag.
end
# Overflow (V), bit 28
define cfv
if $ARM == 1
set $tempflag = $cpsr->v
if ($tempflag & 1)
set $cpsr->v = $tempflag&~0x1
else
set $cpsr->v = $tempflag|0x1
end
end
end
document cfv
Syntax: cfv
| Change Overflow Flag.
end
# ____________________patch___________________
# the usual nops are mov r0,r0 for arm (0xe1a00000)
# and mov r8,r8 in Thumb (0x46c0)
# armv7 has other nops
# FIXME: make sure that the interval fits the 32bits address for arm and 16bits for thumb
# status: works, fixme
define nop
if ($argc > 2 || $argc == 0)
help nop
end
if $ARM == 1
if ($argc == 1)
if ($cpsr->t &1)
# thumb
set *(short *)$arg0 = 0x46c0
else
# arm
set *(int *)$arg0 = 0xe1a00000
end
else
set $addr = $arg0
if ($cpsr->t & 1)
# thumb
while ($addr < $arg1)
set *(short *)$addr = 0x46c0
set $addr = $addr + 2
end
else
# arm
while ($addr < $arg1)
set *(int *)$addr = 0xe1a00000
set $addr = $addr + 4
end
end
end
else
if ($argc == 1)
set *(unsigned char *)$arg0 = 0x90
else
set $addr = $arg0
while ($addr < $arg1)
set *(unsigned char *)$addr = 0x90
set $addr = $addr + 1
end
end
end
end
document nop
Syntax: nop ADDR1 [ADDR2]
| Patch a single byte at address ADDR1, or a series of bytes between ADDR1 and ADDR2 to a NOP (0x90) instruction.
| ARM or Thumb code will be patched accordingly.
end
define null
if ( $argc >2 || $argc == 0)
help null
end
if ($argc == 1)
set *(unsigned char *)$arg0 = 0
else
set $addr = $arg0
while ($addr < $arg1)
set *(unsigned char *)$addr = 0
set $addr = $addr +1
end
end
end
document null
Syntax: null ADDR1 [ADDR2]
| Patch a single byte at address ADDR1 to NULL (0x00), or a series of bytes between ADDR1 and ADDR2.
end
# FIXME: thumb breakpoint ?
define int3
if $argc != 1
help int3
else
if $ARM == 1
set $ORIGINAL_INT3 = *(unsigned int *)$arg0
set $ORIGINAL_INT3ADDRESS = $arg0
set *(unsigned int*)$arg0 = 0xe7ffdefe
else
# save original bytes and address
set $ORIGINAL_INT3 = *(unsigned char *)$arg0
set $ORIGINAL_INT3ADDRESS = $arg0
# patch
set *(unsigned char *)$arg0 = 0xCC
end
end
end
document int3
Syntax int3 ADDR
| Patch byte at address ADDR to an INT3 (0xCC) instruction or the equivalent software breakpoint for ARM.
end
define rint3
if $ARM == 1
set *(unsigned int *)$ORIGINAL_INT3ADDRESS = $ORIGINAL_INT3
set $pc = $ORIGINAL_INT3ADDRESS
else
set *(unsigned char *)$ORIGINAL_INT3ADDRESS = $ORIGINAL_INT3
if ($64BITS == 1)
set $rip = $ORIGINAL_INT3ADDRESS
else
set $eip = $ORIGINAL_INT3ADDRESS
end
end
end
document rint3
Syntax: rint3
| Restore the original byte previous to int3 patch issued with "int3" command.
end
define patch
if $argc != 3
help patch
end
set $patchaddr = $arg0
set $patchbytes = $arg1
set $patchsize = $arg2
if ($patchsize == 1)
set *(unsigned char*)$patchaddr = $patchbytes
end
if ($patchsize == 2)
set $lendianbytes = (unsigned short)(($patchbytes << 8) | ($patchbytes >> 8))
set *(unsigned short*)$patchaddr = $lendianbytes
end
if ($patchsize == 4)
set $lendianbytes = (unsigned int)( (($patchbytes << 8) & 0xFF00FF00 ) | (($patchbytes >> 8) & 0xFF00FF ))
set $lendianbytes = (unsigned int)($lendianbytes << 0x10 | $lendianbytes >> 0x10)
set *(unsigned int*)$patchaddr = $lendianbytes
end
if ($patchsize == 8)
set $lendianbytes = (unsigned long long)( (($patchbytes << 8) & 0xFF00FF00FF00FF00ULL ) | (($patchbytes >> 8) & 0x00FF00FF00FF00FFULL ) )
set $lendianbytes = (unsigned long long)( (($lendianbytes << 0x10) & 0xFFFF0000FFFF0000ULL ) | (($lendianbytes >> 0x10) & 0x0000FFFF0000FFFFULL ) )
set $lendianbytes = (unsigned long long)( ($lendianbytes << 0x20) | ($lendianbytes >> 0x20) )
set *(unsigned long long*)$patchaddr = $lendianbytes
end
end
document patch
Syntax: patch address bytes size
| Patch a given address, converting the bytes to little-endian.
| Assumes input bytes are unsigned values and should be in hexadecimal format (0x...).
| Size must be 1, 2, 4, 8 bytes.
| Main purpose is to be used with the output from the asm commands.
end
# ____________________cflow___________________
define print_insn_type
if $argc != 1
help print_insn_type
else
if ($arg0 < 0 || $arg0 > 5)
printf "UNDEFINED/WRONG VALUE"
end
if ($arg0 == 0)
printf "UNKNOWN"
end
if ($arg0 == 1)
printf "JMP"
end
if ($arg0 == 2)
printf "JCC"
end
if ($arg0 == 3)
printf "CALL"
end
if ($arg0 == 4)
printf "RET"
end
if ($arg0 == 5)
printf "INT"
end
end
end
document print_insn_type
Syntax: print_insn_type INSN_TYPE_NUMBER
| Print human-readable mnemonic for the instruction type (usually $INSN_TYPE).
end
define get_insn_type
if $argc != 1
help get_insn_type
else
set $INSN_TYPE = 0
set $_byte1 = *(unsigned char *)$arg0
if ($_byte1 == 0x9A || $_byte1 == 0xE8)
# "call"
set $INSN_TYPE = 3
end
if ($_byte1 >= 0xE9 && $_byte1 <= 0xEB)
# "jmp"
set $INSN_TYPE = 1
end
if ($_byte1 >= 0x70 && $_byte1 <= 0x7F)
# "jcc"
set $INSN_TYPE = 2
end
if ($_byte1 >= 0xE0 && $_byte1 <= 0xE3 )
# "jcc"
set $INSN_TYPE = 2
end
if ($_byte1 == 0xC2 || $_byte1 == 0xC3 || $_byte1 == 0xCA || \
$_byte1 == 0xCB || $_byte1 == 0xCF)
# "ret"
set $INSN_TYPE = 4
end
if ($_byte1 >= 0xCC && $_byte1 <= 0xCE)
# "int"
set $INSN_TYPE = 5
end
if ($_byte1 == 0x0F )
# two-byte opcode
set $_byte2 = *(unsigned char *)($arg0 + 1)
if ($_byte2 >= 0x80 && $_byte2 <= 0x8F)
# "jcc"
set $INSN_TYPE = 2
end
end
if ($_byte1 == 0xFF)
# opcode extension
set $_byte2 = *(unsigned char *)($arg0 + 1)
set $_opext = ($_byte2 & 0x38)
if ($_opext == 0x10 || $_opext == 0x18)
# "call"
set $INSN_TYPE = 3
end
if ($_opext == 0x20 || $_opext == 0x28)
# "jmp"
set $INSN_TYPE = 1
end
end
end
end
document get_insn_type
Syntax: get_insn_type ADDR
| Recognize instruction type at address ADDR.
| Take address ADDR and set the global $INSN_TYPE variable to
| 0, 1, 2, 3, 4, 5 if the instruction at that address is
| unknown, a jump, a conditional jump, a call, a return, or an interrupt.
end
define step_to_call
set $_saved_ctx = $SHOW_CONTEXT
set $SHOW_CONTEXT = 0
set $SHOW_NEST_INSN = 0
set logging file /dev/null
set logging redirect on
set logging 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 <ADDR>
| Assemble instructions using nasm.
| Type a line containing "end" to indicate the end.
| If an address is specified, insert/modify instructions at that address.
| If no address is specified, assembled instructions are printed to stdout.
| Use the pseudo instruction "org ADDR" to set the base address.
end
define assemble32
# dont enter routine again if user hits enter
dont-repeat
if ($argc)
if (*$arg0 = *$arg0)
# check if we have a valid address by dereferencing it,
# if we havnt, this will cause the routine to exit.
end
printf "Instructions will be written to %#x.\n", $arg0
else
printf "Instructions will be written to stdout.\n"
end
printf "Type instructions, one per line."
color_bold
printf " Do not forget to use NASM assembler syntax!\n"
color_reset
printf "End with a line saying just \"end\".\n"
if ($argc)
# argument specified, assemble instructions into memory at address specified.
shell ASMOPCODE="$(while read -ep '>' r && test "$r" != end ; do echo -E "$r"; done)" ; GDBASMFILENAME=$RANDOM; \
echo -e "BITS 32\n$ASMOPCODE" >/tmp/$GDBASMFILENAME ; /usr/bin/nasm -f bin -o /dev/stdout /tmp/$GDBASMFILENAME | /usr/bin/hexdump -ve '1/1 "set *((unsigned char *) $arg0 + %#2_ax) = %#02x\n"' >/tmp/gdbassemble ; /bin/rm -f /tmp/$GDBASMFILENAME
source /tmp/gdbassemble
# all done. clean the temporary file
shell /bin/rm -f /tmp/gdbassemble
else
# no argument, assemble instructions to stdout
shell ASMOPCODE="$(while read -ep '>' r && test "$r" != end ; do echo -E "$r"; done)" ; GDBASMFILENAME=$RANDOM; \
echo -e "BITS 32\n$ASMOPCODE" >/tmp/$GDBASMFILENAME ; /usr/bin/nasm -f bin -o /dev/stdout /tmp/$GDBASMFILENAME | /usr/bin/ndisasm -i -b32 /dev/stdin ; \
/bin/rm -f /tmp/$GDBASMFILENAME
end
end
document assemble32
Syntax: assemble32 <ADDR>
| Assemble 32 bits instructions using nasm.
| Type a line containing "end" to indicate the end.
| If an address is specified, insert/modify instructions at that address.
| If no address is specified, assembled instructions are printed to stdout.
| Use the pseudo instruction "org ADDR" to set the base address.
end
define assemble64
# dont enter routine again if user hits enter
dont-repeat
if ($argc)
if (*$arg0 = *$arg0)
# check if we have a valid address by dereferencing it,
# if we havnt, this will cause the routine to exit.
end
printf "Instructions will be written to %#x.\n", $arg0
else
printf "Instructions will be written to stdout.\n"
end
printf "Type instructions, one per line."
color_bold
printf " Do not forget to use NASM assembler syntax!\n"
color_reset
printf "End with a line saying just \"end\".\n"
if ($argc)
# argument specified, assemble instructions into memory at address specified.
shell ASMOPCODE="$(while read -ep '>' r && test "$r" != end ; do echo -E "$r"; done)" ; GDBASMFILENAME=$RANDOM; \
echo -e "BITS 64\n$ASMOPCODE" >/tmp/$GDBASMFILENAME ; /usr/local/bin/nasm -f bin -o /dev/stdout /tmp/$GDBASMFILENAME | /usr/bin/hexdump -ve '1/1 "set *((unsigned char *) $arg0 + %#2_ax) = %#02x\n"' >/tmp/gdbassemble ; /bin/rm -f /tmp/$GDBASMFILENAME
source /tmp/gdbassemble
# all done. clean the temporary file
shell /bin/rm -f /tmp/gdbassemble
else
# no argument, assemble instructions to stdout
shell ASMOPCODE="$(while read -ep '>' r && test "$r" != end ; do echo -E "$r"; done)" ; GDBASMFILENAME=$RANDOM; \
echo -e "BITS 64\n$ASMOPCODE" >/tmp/$GDBASMFILENAME ; /usr/local/bin/nasm -f bin -o /dev/stdout /tmp/$GDBASMFILENAME | /usr/local/bin/ndisasm -i -b64 /dev/stdin ; \
/bin/rm -f /tmp/$GDBASMFILENAME
end
end
document assemble64
Syntax: assemble64 <ADDR>
| Assemble 64 bits instructions using nasm.
| Type a line containing "end" to indicate the end.
| If an address is specified, insert/modify instructions at that address.
| If no address is specified, assembled instructions are printed to stdout.
| Use the pseudo instruction "org ADDR" to set the base address.
end
define asm
if $argc == 1
assemble $arg0
else
assemble
end
end
document asm
Syntax: asm <ADDR>
| Shortcut to the asssemble command.
end
define asm32
if $argc == 1
assemble32 $arg0
else
assemble32
end
end
document asm32
Syntax: asm32 <ADDR>
| Shortcut to the assemble32 command.
end
define asm64
if $argc == 1
assemble64 $arg0
else
assemble64
end
end
document asm64
Syntax: asm64 <ADDR>
| Shortcut to the assemble64 command.
end
define assemble_gas
printf "\nType code to assemble and hit Ctrl-D when finished.\n"
printf "You must use GNU assembler (AT&T) syntax.\n"
shell filename=$(mktemp); \
binfilename=$(mktemp); \
echo -e "Writing into: ${filename}\n"; \
cat > $filename; echo ""; \
as -o $binfilename < $filename; \
objdump -d -j .text $binfilename; \
rm -f $binfilename; \
rm -f $filename; \
echo -e "temporaly files deleted.\n"
end
document assemble_gas
Syntax: assemble_gas
| Assemble instructions to binary opcodes. Uses GNU as and objdump.
end
define dump_hexfile
dump ihex memory $arg0 $arg1 $arg2
end
document dump_hexfile
Syntax: dump_hexfile FILENAME ADDR1 ADDR2
| Write a range of memory to a file in Intel ihex (hexdump) format.
| The range is specified by ADDR1 and ADDR2 addresses.
end
define dump_binfile
dump memory $arg0 $arg1 $arg2
end
document dump_binfile
Syntax: dump_binfile FILENAME ADDR1 ADDR2
| Write a range of memory to a binary file.
| The range is specified by ADDR1 and ADDR2 addresses.
end
define dumpmacho
if $argc != 2
help dumpmacho
end
set $headermagic = *$arg0
# the || operator isn't working as it should, wtf!!!
if $headermagic != 0xfeedface
if $headermagic != 0xfeedfacf
printf "[Error] Target address doesn't contain a valid Mach-O binary!\n"
help dumpmacho
end
end
set $headerdumpsize = *($arg0+0x14)
if $headermagic == 0xfeedface
dump memory $arg1 $arg0 ($arg0+0x1c+$headerdumpsize)
end
if $headermagic == 0xfeedfacf
dump memory $arg1 $arg0 ($arg0+0x20+$headerdumpsize)
end
end
document dumpmacho
Syntax: dumpmacho STARTADDRESS FILENAME
| Dump the Mach-O header to a file.
| You need to input the start address (use info shared command to find it).
end
define cls
shell clear
end
document cls
Syntax: cls
| Clear screen.
end
define search
set $start = (char *) $arg0
set $end = (char *) $arg1
set $pattern = (short) $arg2
set $p = $start
while $p < $end
if (*(short *) $p) == $pattern
printf "pattern 0x%hx found at 0x%x\n", $pattern, $p
end
set $p++
end
end
document search
Syntax: search <START> <END> <PATTERN>
| Search for the given pattern beetween $start and $end address.
end
# _________________user tips_________________
# The 'tips' command is used to provide tutorial-like info to the user
define tips
printf "Tip Topic Commands:\n"
printf "\ttip_display : Automatically display values on each break\n"
printf "\ttip_patch : Patching binaries\n"
printf "\ttip_strip : Dealing with stripped binaries\n"
printf "\ttip_syntax : AT&T vs Intel syntax\n"
end
document tips
Syntax: tips
| Provide a list of tips from users on various topics.
end
define tip_patch
printf "\n"
printf " PATCHING MEMORY\n"
printf "Any address can be patched using the 'set' command:\n"
printf "\t`set ADDR = VALUE` \te.g. `set *0x8049D6E = 0x90`\n"
printf "\n"
printf " PATCHING BINARY FILES\n"
printf "Use `set write` in order to patch the target executable\n"
printf "directly, instead of just patching memory\n"
printf "\t`set write on` \t`set write off`\n"
printf "Note that this means any patches to the code or data segments\n"
printf "will be written to the executable file\n"
printf "When either of these commands has been issued,\n"
printf "the file must be reloaded.\n"
printf "\n"
end
document tip_patch
Syntax: tip_patch
| Tips on patching memory and binary files.
end
define tip_strip
printf "\n"
printf " STOPPING BINARIES AT ENTRY POINT\n"
printf "Stripped binaries have no symbols, and are therefore tough to\n"
printf "start automatically. To debug a stripped binary, use\n"
printf "\tinfo file\n"
printf "to get the entry point of the file\n"
printf "The first few lines of output will look like this:\n"
printf "\tSymbols from '/tmp/a.out'\n"
printf "\tLocal exec file:\n"
printf "\t `/tmp/a.out', file type elf32-i386.\n"
printf "\t Entry point: 0x80482e0\n"
printf "Use this entry point to set an entry point:\n"
printf "\t`tbreak *0x80482e0`\n"
printf "The breakpoint will delete itself after the program stops as\n"
printf "the entry point\n"
printf "\n"
end
document tip_strip
Syntax: tip_strip
| Tips on dealing with stripped binaries.
end
define tip_syntax
printf "\n"
printf "\t INTEL SYNTAX AT&T SYNTAX\n"
printf "\tmnemonic dest, src, imm mnemonic src, dest, imm\n"
printf "\t[base+index*scale+disp] disp(base, index, scale)\n"
printf "\tregister: eax register: %%eax\n"
printf "\timmediate: 0xFF immediate: $0xFF\n"
printf "\tdereference: [addr] dereference: addr(,1)\n"
printf "\tabsolute addr: addr absolute addr: *addr\n"
printf "\tbyte insn: mov byte ptr byte insn: movb\n"
printf "\tword insn: mov word ptr word insn: movw\n"
printf "\tdword insn: mov dword ptr dword insn: movd\n"
printf "\tfar call: call far far call: lcall\n"
printf "\tfar jump: jmp far far jump: ljmp\n"
printf "\n"
printf "Note that order of operands in reversed, and that AT&T syntax\n"
printf "requires that all instructions referencing memory operands \n"
printf "use an operand size suffix (b, w, d, q)\n"
printf "\n"
end
document tip_syntax
Syntax: tip_syntax
| Summary of Intel and AT&T syntax differences.
end
define tip_display
printf "\n"
printf "Any expression can be set to automatically be displayed every time\n"
printf "the target stops. The commands for this are:\n"
printf "\t`display expr' : automatically display expression 'expr'\n"
printf "\t`display' : show all displayed expressions\n"
printf "\t`undisplay num' : turn off autodisplay for expression # 'num'\n"
printf "Examples:\n"
printf "\t`display/x *(int *)$esp` : print top of stack\n"
printf "\t`display/x *(int *)($ebp+8)` : print first parameter\n"
printf "\t`display (char *)$esi` : print source string\n"
printf "\t`display (char *)$edi` : print destination string\n"
printf "\n"
end
document tip_display
Syntax: tip_display
| Tips on automatically displaying values when a program stops.
end
# bunch of semi-useless commands
# enable and disable shortcuts for stop-on-solib-events fantastic trick!
define enablesolib
set stop-on-solib-events 1
printf "Stop-on-solib-events is enabled!\n"
end
document enablesolib
Syntax: enablesolib
| Shortcut to enable stop-on-solib-events trick.
end
define disablesolib
set stop-on-solib-events 0
printf "Stop-on-solib-events is disabled!\n"
end
document disablesolib
Syntax: disablesolib
| Shortcut to disable stop-on-solib-events trick.
end
# enable commands for different displays
define 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 <PORT>
| Attach to VMware gdb stub for 32 bits kernel.
| The path to kgmacros must be supplied as first parameter.
| If you don't want to load kgmacros just put something as the first parameter.
| Optional parameter is the port to connect to, in case you are not using the default 8832
| or want to kernel debug more than one active virtual machine.
| By supplying a bogus kgmacros this command should be compatible with any OS.
end
define kernel64
if $argc != 0
# try to load kgmacros files
# failure is silent if non-existent...
source $arg0
set architecture i386:x86-64
if $argc == 2
target remote localhost:$arg1
else
target remote localhost:8864
end
else
help kernel64
end
end
document kernel64
Syntax: kernel64 PATH_TO_KGMACROS <PORT>
| Attach to VMware gdb stub for 64 bits kernel.
| The path to kgmacros must be supplied as first parameter.
| If you don't want to load kgmacros just put something as the first parameter.
| Optional parameter is the port to connect to, in case you are not using the default 8864
| or want to kernel debug more than one active virtual machine.
| By supplying a bogus kgmacros this command should be compatible with any OS.
end
define 32bits
set $KDP64BITS = 0
set $64BITS = 0
end
define 64bits
set $KDP64BITS = 1
set $64BITS = 1
end
define resetkdp
set $KDP64BITS = -1
end
define header
if $argc != 1
help header
else
dump memory /tmp/gdbinit_header_dump $arg0 $arg0 + 4096
shell /usr/bin/otool -h /tmp/gdbinit_header_dump
shell /bin/rm -f /tmp/gdbinit_header_dump
end
end
document header
Syntax: header MACHO_HEADER_START_ADDRESS
| Dump the Mach-O header located at given address
end
define loadcmds
if $argc != 1
help loadcmds
else
# this size should be good enough for most binaries
dump memory /tmp/gdbinit_header_dump $arg0 $arg0 + 4096 * 10
shell /usr/bin/otool -l /tmp/gdbinit_header_dump
shell /bin/rm -f /tmp/gdbinit_header_dump
end
end
document loadcmds
Syntax: loadcmds MACHO_HEADER_START_ADDRESS
| Dump the Mach-O load commands
end
# defining it here doesn't get the space #$#$%"#!
define disablecolorprompt
set prompt gdb$
end
document disablecolorprompt
| Remove color from prompt
end
define enablecolorprompt
set prompt \033[31mgdb$ \033[0m
end
document enablecolorprompt
| Enable color prompt
end
#EOF
# 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
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment