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