2019-07-17 14:09:41 +02:00
|
|
|
# Modified by Nicolas Horde
|
|
|
|
# Special mode for GDB that allows to debug/disassemble FLAT OR UNREAL MODE x86 code
|
2019-07-14 11:26:53 +02:00
|
|
|
#
|
|
|
|
# It has been designed to be used with QEMU or BOCHS gdb-stub
|
|
|
|
#
|
|
|
|
# 08/2011 Hugo Mercier - GPL v3 license
|
|
|
|
#
|
|
|
|
# Freely inspired from "A user-friendly gdb configuration file" widely available
|
|
|
|
# on the Internet
|
|
|
|
|
|
|
|
set confirm off
|
|
|
|
set verbose off
|
|
|
|
set prompt \033[31mreal-mode-gdb$ \033[0m
|
|
|
|
|
|
|
|
set output-radix 0d10
|
|
|
|
set input-radix 0d10
|
|
|
|
|
|
|
|
# These make gdb never pause in its output
|
|
|
|
set height 0
|
|
|
|
set width 0
|
|
|
|
|
|
|
|
# Intel syntax
|
|
|
|
set disassembly-flavor intel
|
|
|
|
# Real mode
|
|
|
|
set architecture i8086
|
|
|
|
|
|
|
|
set $SHOW_CONTEXT = 1
|
|
|
|
|
|
|
|
set $REAL_MODE = 1
|
|
|
|
|
|
|
|
# By default A20 is present
|
|
|
|
set $ADDRESS_MASK = 0x1FFFFF
|
|
|
|
|
|
|
|
# nb of instructions to display
|
|
|
|
set $CODE_SIZE = 20
|
|
|
|
|
|
|
|
define enable-a20
|
|
|
|
set $ADDRESS_MASK = 0x1FFFFF
|
|
|
|
end
|
|
|
|
define disable-a20
|
|
|
|
set $ADDRESS_MASK = 0x0FFFFF
|
|
|
|
end
|
|
|
|
|
|
|
|
# convert segment:offset address to physical address
|
|
|
|
define r2p
|
|
|
|
if $argc < 2
|
|
|
|
printf "Arguments: segment offset\n"
|
|
|
|
else
|
|
|
|
set $ADDR = (((unsigned long)$arg0 & 0xFFFF) << 4) + (((unsigned long)$arg1 & 0xFFFF) & $ADDRESS_MASK)
|
|
|
|
printf "0x%05X\n", $ADDR
|
|
|
|
end
|
|
|
|
end
|
|
|
|
document r2p
|
|
|
|
Convert segment:offset address to physical address
|
|
|
|
Set the global variable $ADDR to the computed one
|
|
|
|
end
|
|
|
|
|
|
|
|
# get address of Interruption
|
|
|
|
define int_addr
|
|
|
|
if $argc < 1
|
|
|
|
printf "Argument: interruption_number\n"
|
|
|
|
else
|
|
|
|
set $offset = (unsigned short)*($arg0 * 4)
|
|
|
|
set $segment = (unsigned short)*($arg0 * 4 + 2)
|
|
|
|
r2p $segment $offset
|
|
|
|
printf "%04X:%04X\n", $segment, $offset
|
|
|
|
end
|
|
|
|
end
|
|
|
|
document int_addr
|
|
|
|
Get address of interruption
|
|
|
|
end
|
|
|
|
|
|
|
|
define compute_regs
|
2019-07-17 14:09:41 +02:00
|
|
|
set $rax = ((unsigned long)$eax & 0xFFFFFFFF)
|
|
|
|
set $rbx = ((unsigned long)$ebx & 0xFFFFFFFF)
|
|
|
|
set $rcx = ((unsigned long)$ecx & 0xFFFFFFFF)
|
|
|
|
set $rdx = ((unsigned long)$edx & 0xFFFFFFFF)
|
|
|
|
set $rsi = ((unsigned long)$esi & 0xFFFFFFFF)
|
|
|
|
set $rdi = ((unsigned long)$edi & 0xFFFFFFFF)
|
|
|
|
set $rbp = ((unsigned long)$ebp & 0xFFFFFFFF)
|
|
|
|
set $rsp = ((unsigned long)$esp & 0xFFFFFFFF)
|
2019-07-14 11:26:53 +02:00
|
|
|
set $rcs = ((unsigned long)$cs & 0xFFFF)
|
|
|
|
set $rds = ((unsigned long)$ds & 0xFFFF)
|
|
|
|
set $res = ((unsigned long)$es & 0xFFFF)
|
|
|
|
set $rss = ((unsigned long)$ss & 0xFFFF)
|
2019-07-17 14:09:41 +02:00
|
|
|
set $rfs = ((unsigned long)$es & 0xFFFF)
|
|
|
|
set $rgs = ((unsigned long)$ss & 0xFFFF)
|
|
|
|
set $rip = ((((unsigned long)$cs & 0xFFFF) << 4) + ((unsigned long)$eip & 0xFFFFFFFF)) & $ADDRESS_MASK
|
|
|
|
set $r_ss_sp = ((((unsigned long)$ss & 0xFFFF) << 4) + ((unsigned long)$esp & 0xFFFFFFFF)) & $ADDRESS_MASK
|
|
|
|
set $r_ss_bp = ((((unsigned long)$ss & 0xFFFF) << 4) + ((unsigned long)$ebp & 0xFFFFFFFF)) & $ADDRESS_MASK
|
2019-07-14 11:26:53 +02:00
|
|
|
end
|
|
|
|
|
|
|
|
define print_regs
|
2019-07-17 14:09:41 +02:00
|
|
|
printf "EAX: %08X EBX: %08X ", $rax, $rbx
|
|
|
|
printf "ECX: %08X EDX: %08X\n", $rcx, $rdx
|
|
|
|
printf "ESI: %08X EDI: %08X ", $rsi, $rdi
|
|
|
|
printf "ESP: %08X EBP: %08X\n", $rsp, $rbp
|
|
|
|
printf " CS: %04X DS: %04X ", $rcs, $rds
|
|
|
|
printf " ES: %04X SS: %04X ", $res, $rss
|
|
|
|
printf " FS: %04X GS: %04X ", $rfs, $rgs
|
2019-07-14 11:26:53 +02:00
|
|
|
printf "\n"
|
2019-07-17 14:09:41 +02:00
|
|
|
printf "CS:IP: %04X:%08X (0x%05X)\n", $rcs, ((unsigned long)$eip), $rip
|
|
|
|
printf "SS:SP: %04X:%08X (0x%05X)\n", $rss, $rsp, $r_ss_sp
|
|
|
|
printf "SS:BP: %04X:%08X (0x%05X)\n", $rss, $rbp, $r_ss_bp
|
2019-07-14 11:26:53 +02:00
|
|
|
end
|
|
|
|
document print_regs
|
|
|
|
Print CPU registers
|
|
|
|
end
|
|
|
|
|
|
|
|
define print_eflags
|
2019-07-17 14:09:41 +02:00
|
|
|
printf "EFLAGS: %08X [",$eflags
|
|
|
|
if ($eflags & 1)
|
|
|
|
printf "C"
|
|
|
|
else
|
|
|
|
printf "-"
|
|
|
|
end
|
|
|
|
printf "-"
|
|
|
|
if (($eflags >> 2) & 1)
|
|
|
|
printf "P"
|
|
|
|
else
|
|
|
|
printf "-"
|
|
|
|
end
|
|
|
|
printf "-"
|
|
|
|
if (($eflags >> 4) & 1)
|
|
|
|
printf "A"
|
|
|
|
else
|
|
|
|
printf "-"
|
|
|
|
end
|
|
|
|
printf "-"
|
|
|
|
if (($eflags >> 6) & 1)
|
|
|
|
printf "Z"
|
|
|
|
else
|
|
|
|
printf "-"
|
|
|
|
end
|
|
|
|
if (($eflags >> 7) & 1)
|
|
|
|
printf "S"
|
|
|
|
else
|
|
|
|
printf "-"
|
|
|
|
end
|
|
|
|
if (($eflags >> 8) & 1)
|
|
|
|
printf "T"
|
|
|
|
else
|
|
|
|
printf "-"
|
|
|
|
if (($eflags >> 9) & 1)
|
|
|
|
printf "I"
|
|
|
|
else
|
|
|
|
printf "-"
|
|
|
|
end
|
|
|
|
if (($eflags >> 0xA) & 1)
|
|
|
|
printf "D"
|
|
|
|
else
|
|
|
|
printf "-"
|
|
|
|
end
|
|
|
|
if (($eflags >> 0xB) & 1)
|
|
|
|
printf "O"
|
|
|
|
else
|
|
|
|
printf "-"
|
|
|
|
end
|
|
|
|
printf "]\n"
|
|
|
|
end
|
2019-07-14 11:26:53 +02:00
|
|
|
end
|
|
|
|
document print_eflags
|
|
|
|
Print eflags register.
|
|
|
|
end
|
|
|
|
|
|
|
|
# dump content of bytes in memory
|
|
|
|
# arg0 : addr
|
|
|
|
# arg1 : nb of bytes
|
|
|
|
define _dump_memb
|
|
|
|
if $argc < 2
|
|
|
|
printf "Arguments: address number_of_bytes\n"
|
|
|
|
else
|
|
|
|
set $_nb = $arg1
|
|
|
|
set $_i = 0
|
|
|
|
set $_addr = $arg0
|
|
|
|
while ($_i < $_nb)
|
|
|
|
printf "%02X ", *((unsigned char*)$_addr + $_i)
|
|
|
|
set $_i++
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
# dump content of memory in words
|
|
|
|
# arg0 : addr
|
|
|
|
# arg1 : nb of words
|
|
|
|
define _dump_memw
|
|
|
|
if $argc < 2
|
|
|
|
printf "Arguments: address number_of_words\n"
|
|
|
|
else
|
|
|
|
set $_nb = $arg1
|
|
|
|
set $_i = 0
|
|
|
|
set $_addr = $arg0
|
|
|
|
while ($_i < $_nb)
|
|
|
|
printf "%04X ", *((unsigned short*)$_addr + $_i)
|
|
|
|
set $_i++
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
# display data at given address
|
|
|
|
define print_data
|
|
|
|
if ($argc > 0)
|
|
|
|
set $seg = $arg0
|
|
|
|
set $off = $arg1
|
|
|
|
set $maddr = ($arg0 << 4) + $arg1
|
|
|
|
|
|
|
|
set $w = 16
|
|
|
|
set $i = (int)0
|
2019-07-17 14:09:41 +02:00
|
|
|
while ($i < 2)
|
|
|
|
printf "%08X: ", ($maddr + $i * $w)
|
2019-07-14 11:26:53 +02:00
|
|
|
set $j = (int)0
|
|
|
|
while ($j < $w)
|
|
|
|
printf "%02X ", *(unsigned char*)($maddr + $i * $w + $j)
|
|
|
|
set $j++
|
|
|
|
end
|
|
|
|
printf " "
|
|
|
|
set $j = (int)0
|
|
|
|
while ($j < $w)
|
|
|
|
set $c = *(unsigned char*)($maddr + $i * $w + $j)
|
|
|
|
if ($c > 32) && ($c < 128)
|
|
|
|
printf "%c", $c
|
|
|
|
else
|
|
|
|
printf "."
|
|
|
|
end
|
|
|
|
set $j++
|
|
|
|
end
|
|
|
|
printf "\n"
|
|
|
|
set $i++
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2019-07-17 14:09:41 +02:00
|
|
|
# affiche les mb
|
|
|
|
define print_mb
|
|
|
|
set $mem=1280
|
|
|
|
set $verif = *(unsigned char*)($mem)
|
|
|
|
set $verif2 = *(unsigned char*)($mem+1)
|
|
|
|
set $stop = 0x01
|
|
|
|
while ($verif == 0x4E && $verif2 == 0x48 && $stop == 0x01)
|
|
|
|
set $stop = *(unsigned char*)($mem+2)
|
|
|
|
set $size = *(unsigned short*)($mem+6)
|
|
|
|
set $name = (unsigned char*)($mem+8)
|
|
|
|
printf "%s:%4X:%4X\n",$name,$mem,$size
|
|
|
|
set $mem=$mem+$size
|
|
|
|
set $verif = *(unsigned char*)($mem)
|
|
|
|
set $verif2 = *(unsigned char*)($mem+1)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2019-07-14 11:26:53 +02:00
|
|
|
define context
|
2019-07-17 14:09:41 +02:00
|
|
|
printf "---------------------------[ STACK ]---------------------------\n"
|
2019-07-14 11:26:53 +02:00
|
|
|
_dump_memw $r_ss_sp 8
|
|
|
|
printf "\n"
|
|
|
|
set $_a = $r_ss_sp + 16
|
|
|
|
_dump_memw $_a 8
|
|
|
|
printf "\n"
|
2019-07-17 14:09:41 +02:00
|
|
|
printf "---------------------------[ DS:ESI ]---------------------------\n"
|
2019-07-14 11:26:53 +02:00
|
|
|
print_data $ds $rsi
|
2019-07-17 14:09:41 +02:00
|
|
|
printf "---------------------------[ ES:EDI ]---------------------------\n"
|
2019-07-14 11:26:53 +02:00
|
|
|
print_data $es $rdi
|
2019-07-17 14:09:41 +02:00
|
|
|
printf "----------------------------[ CPU ]---------------------------\n"
|
2019-07-14 11:26:53 +02:00
|
|
|
print_regs
|
|
|
|
print_eflags
|
2019-07-17 14:09:41 +02:00
|
|
|
printf "----------------------------[ MB ]---------------------------\n"
|
|
|
|
print_mb
|
|
|
|
printf "---------------------------[ CODE ]---------------------------\n"
|
2019-07-14 11:26:53 +02:00
|
|
|
|
|
|
|
set $_code_size = $CODE_SIZE
|
|
|
|
|
|
|
|
# disassemble
|
|
|
|
# first call x/i with an address
|
|
|
|
# subsequent calls to x/i will increment address
|
|
|
|
if ($_code_size > 0)
|
|
|
|
x /i $rip
|
|
|
|
set $_code_size--
|
|
|
|
end
|
|
|
|
while ($_code_size > 0)
|
|
|
|
x /i
|
|
|
|
set $_code_size--
|
|
|
|
end
|
|
|
|
end
|
|
|
|
document context
|
|
|
|
Print context window, i.e. regs, stack, ds:esi and disassemble cs:eip.
|
|
|
|
end
|
|
|
|
|
|
|
|
define hook-stop
|
|
|
|
compute_regs
|
|
|
|
if ($SHOW_CONTEXT > 0)
|
|
|
|
context
|
|
|
|
end
|
|
|
|
end
|
|
|
|
document hook-stop
|
|
|
|
!!! FOR INTERNAL USE ONLY - DO NOT CALL !!!
|
|
|
|
end
|
|
|
|
|
|
|
|
# add a breakpoint on an interrupt
|
|
|
|
define break_int
|
|
|
|
set $offset = (unsigned short)*($arg0 * 4)
|
|
|
|
set $segment = (unsigned short)*($arg0 * 4 + 2)
|
|
|
|
|
|
|
|
break *$offset
|
|
|
|
end
|
|
|
|
|
|
|
|
define break_int_if_ah
|
|
|
|
if ($argc < 2)
|
|
|
|
printf "Arguments: INT_N AH\n"
|
|
|
|
else
|
|
|
|
set $addr = (unsigned short)*($arg0 * 4)
|
|
|
|
set $segment = (unsigned short)*($arg0 * 4 + 2)
|
|
|
|
break *$addr if ((unsigned long)$eax & 0xFF00) == ($arg1 << 8)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
document break_int_if_ah
|
|
|
|
Install a breakpoint on INT N only if AH is equal to the expected value
|
|
|
|
end
|
|
|
|
|
|
|
|
define break_int_if_ax
|
|
|
|
if ($argc < 2)
|
|
|
|
printf "Arguments: INT_N AX\n"
|
|
|
|
else
|
|
|
|
set $addr = (unsigned short)*($arg0 * 4)
|
|
|
|
set $segment = (unsigned short)*($arg0 * 4 + 2)
|
|
|
|
break *$addr if ((unsigned long)$eax & 0xFFFF) == $arg1
|
|
|
|
end
|
|
|
|
end
|
|
|
|
document break_int_if_ax
|
|
|
|
Install a breakpoint on INT N only if AX is equal to the expected value
|
|
|
|
end
|
|
|
|
|
2019-07-17 14:09:41 +02:00
|
|
|
define so
|
2019-07-14 11:26:53 +02:00
|
|
|
## we know that an opcode starting by 0xE8 has a fixed length
|
|
|
|
## for the 0xFF opcodes, we can enumerate what is possible to have
|
|
|
|
|
|
|
|
set $lip = $rip
|
|
|
|
set $offset = 0
|
|
|
|
|
|
|
|
# first, get rid of segment prefixes, if any
|
|
|
|
set $_byte1 = *(unsigned char *)$rip
|
|
|
|
# CALL DS:xx CS:xx, etc.
|
|
|
|
if ($_byte1 == 0x3E || $_byte1 == 0x26 || $_byte1 == 0x2E || $_byte1 == 0x36 || $_byte1 == 0x3E || $_byte1 == 0x64 || $_byte1 == 0x65)
|
|
|
|
set $lip = $rip + 1
|
|
|
|
set $_byte1 = *(unsigned char*)$lip
|
|
|
|
set $offset = 1
|
|
|
|
end
|
|
|
|
set $_byte2 = *(unsigned char *)($lip+1)
|
|
|
|
set $_byte3 = *(unsigned char *)($lip+2)
|
|
|
|
|
|
|
|
set $noffset = 0
|
|
|
|
|
|
|
|
if ($_byte1 == 0xE8)
|
|
|
|
# call near
|
|
|
|
set $noffset = 3
|
|
|
|
else
|
|
|
|
if ($_byte1 == 0xFF)
|
|
|
|
# A "ModR/M" byte follows
|
|
|
|
set $_mod = ($_byte2 & 0xC0) >> 6
|
|
|
|
set $_reg = ($_byte2 & 0x38) >> 3
|
|
|
|
set $_rm = ($_byte2 & 7)
|
|
|
|
#printf "mod: %d reg: %d rm: %d\n", $_mod, $_reg, $_rm
|
|
|
|
|
|
|
|
# only for CALL instructions
|
|
|
|
if ($_reg == 2 || $_reg == 3)
|
|
|
|
|
|
|
|
# default offset
|
|
|
|
set $noffset = 2
|
|
|
|
|
|
|
|
if ($_mod == 0)
|
|
|
|
if ($_rm == 6)
|
|
|
|
# a 16bit address follows
|
|
|
|
set $noffset = 4
|
|
|
|
end
|
|
|
|
else
|
|
|
|
if ($_mod == 1)
|
|
|
|
# a 8bit displacement follows
|
|
|
|
set $noffset = 3
|
|
|
|
else
|
|
|
|
if ($_mod == 2)
|
|
|
|
# 16bit displacement
|
|
|
|
set $noffset = 4
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
end
|
|
|
|
# end of _reg == 2 or _reg == 3
|
|
|
|
|
|
|
|
else
|
|
|
|
# else byte1 != 0xff
|
|
|
|
if ($_byte1 == 0x9A)
|
|
|
|
# call far
|
|
|
|
set $noffset = 5
|
|
|
|
else
|
|
|
|
if ($_byte1 == 0xCD)
|
|
|
|
# INTERRUPT CASE
|
|
|
|
set $noffset = 2
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
end
|
|
|
|
# end of byte1 == 0xff
|
|
|
|
end
|
|
|
|
# else byte1 != 0xe8
|
|
|
|
|
|
|
|
# if we have found a call to bypass we set a temporary breakpoint on next instruction and continue
|
|
|
|
if ($noffset != 0)
|
2019-07-17 14:09:41 +02:00
|
|
|
set $_nextaddress = $eip + $offset + $noffset+$cs*16
|
2019-07-14 11:26:53 +02:00
|
|
|
printf "Setting BP to %04X\n", $_nextaddress
|
2019-07-17 14:09:41 +02:00
|
|
|
break *$_nextaddress
|
2019-07-14 11:26:53 +02:00
|
|
|
continue
|
2019-07-17 14:09:41 +02:00
|
|
|
cl *$_nextaddress
|
2019-07-14 11:26:53 +02:00
|
|
|
# else we just single step
|
|
|
|
else
|
|
|
|
nexti
|
|
|
|
end
|
|
|
|
end
|
2019-07-17 14:09:41 +02:00
|
|
|
document so
|
2019-07-14 11:26:53 +02:00
|
|
|
Step over calls
|
|
|
|
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 since it will single step code if it's not a call instruction (unless you want to go into the call function)
|
|
|
|
end
|
|
|
|
|
|
|
|
define step_until_iret
|
|
|
|
set $SHOW_CONTEXT=0
|
|
|
|
set $_found = 0
|
|
|
|
while (!$_found)
|
|
|
|
if (*(unsigned char*)$rip == 0xCF)
|
|
|
|
set $_found = 1
|
|
|
|
else
|
|
|
|
stepo
|
|
|
|
end
|
|
|
|
end
|
|
|
|
set $SHOW_CONTEXT=1
|
|
|
|
context
|
|
|
|
end
|
|
|
|
|
|
|
|
define step_until_ret
|
|
|
|
set $SHOW_CONTEXT=0
|
|
|
|
set $_found = 0
|
|
|
|
while (!$_found)
|
|
|
|
set $_p = *(unsigned char*)$rip
|
|
|
|
if ($_p == 0xC3 || $_p == 0xCB || $_p == 0xC2 || $_p == 0xCA)
|
|
|
|
set $_found = 1
|
|
|
|
else
|
|
|
|
stepo
|
|
|
|
end
|
|
|
|
end
|
|
|
|
set $SHOW_CONTEXT=1
|
|
|
|
context
|
|
|
|
end
|
|
|
|
|
|
|
|
define step_until_int
|
|
|
|
set $SHOW_CONTEXT = 0
|
|
|
|
|
|
|
|
while (*(unsigned char*)$rip != 0xCD)
|
|
|
|
stepo
|
|
|
|
end
|
|
|
|
set $SHOW_CONTEXT = 1
|
|
|
|
context
|
|
|
|
end
|
|
|
|
|
|
|
|
# Find a pattern in memory
|
|
|
|
# The pattern is given by a string as arg0
|
|
|
|
# If another argument is present it gives the starting address (0 otherwise)
|
|
|
|
define find_in_mem
|
|
|
|
if ($argc >= 2)
|
|
|
|
set $_addr = $arg1
|
|
|
|
else
|
|
|
|
set $_addr = 0
|
|
|
|
end
|
|
|
|
set $_found = 0
|
|
|
|
set $_tofind = $arg0
|
|
|
|
while ($_addr < $ADDRESS_MASK) && (!$_found)
|
|
|
|
if ($_addr % 0x100 == 0)
|
|
|
|
printf "%08X\n", $_addr
|
|
|
|
end
|
|
|
|
set $_i = 0
|
|
|
|
set $_found = 1
|
|
|
|
while ($_tofind[$_i] != 0 && $_found == 1)
|
|
|
|
set $_b = *((char*)$_addr + $_i)
|
|
|
|
set $_t = (char)$_tofind[$_i]
|
|
|
|
if ($_t != $_b)
|
|
|
|
set $_found = 0
|
|
|
|
end
|
|
|
|
set $_i++
|
|
|
|
end
|
|
|
|
if ($_found == 1)
|
|
|
|
printf "Code found at 0x%05X\n", $_addr
|
|
|
|
end
|
|
|
|
set $_addr++
|
|
|
|
end
|
|
|
|
end
|
|
|
|
document find_in_mem
|
|
|
|
Find a pattern in memory
|
|
|
|
The pattern is given by a string as arg0
|
|
|
|
If another argument is present it gives the starting address (0 otherwise)
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
define step_until_code
|
|
|
|
set $_tofind = $arg0
|
|
|
|
set $SHOW_CONTEXT = 0
|
|
|
|
|
|
|
|
set $_found = 0
|
|
|
|
while (!$_found)
|
|
|
|
set $_i = 0
|
|
|
|
set $_found = 1
|
|
|
|
|
|
|
|
while ($_tofind[$_i] != 0 && $_found == 1)
|
|
|
|
set $_b = *((char*)$rip + $_i)
|
|
|
|
set $_t = (char)$_tofind[$_i]
|
|
|
|
if ($_t != $_b)
|
|
|
|
set $_found = 0
|
|
|
|
end
|
|
|
|
set $_i++
|
|
|
|
end
|
|
|
|
|
|
|
|
if ($_found == 0)
|
|
|
|
stepo
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
set $SHOW_CONTEXT = 1
|
|
|
|
context
|
|
|
|
end
|
|
|
|
|