我有一些将在程序中的某个点执行的代码的汇编代码。我不知道内存中代码的地址。
当前指令与输入指令匹配时是否可以使 gdb 中断?
例如,每当 gdb 到达此指令时,我希望 gdb 中断:
leaq 0x000008eb(%rip),%rax
我有一些将在程序中的某个点执行的代码的汇编代码。我不知道内存中代码的地址。
当前指令与输入指令匹配时是否可以使 gdb 中断?
例如,每当 gdb 到达此指令时,我希望 gdb 中断:
leaq 0x000008eb(%rip),%rax
正如其他人所说,由于没有硬件支持,因此可能无法有效地做到这一点。
但是如果你真的想这样做,这个 Python 命令可以作为一个起点。程序单步执行,直到给出具有给定操作码的函数。由于每条指令的执行都返回到 python,如果目标指令距离太多指令,这将非常缓慢。但是对于或多或少的附近呼叫,它应该可以正常工作。
class ContinueI(gdb.Command):
"""
Continue until instruction with given opcode.
ci OPCODE
Example:
ci callq
ci mov
"""
def __init__(self):
super().__init__(
'ci',
gdb.COMMAND_BREAKPOINTS,
gdb.COMPLETE_NONE,
False
)
def invoke(self, arg, from_tty):
if arg == '':
gdb.write('Argument missing.\n')
else:
thread = gdb.inferiors()[0].threads()[0]
while thread.is_valid():
gdb.execute('si', to_string=True)
frame = gdb.selected_frame()
arch = frame.architecture()
pc = gdb.selected_frame().pc()
instruction = arch.disassemble(pc)[0]['asm']
if instruction.startswith(arg + ' '):
gdb.write(instruction + '\n')
break
ContinueI()
只需通过以下方式获取它:
source gdb.py
并将命令用作:
ci mov
ci callq
并且您将被留在使用给定操作码执行的第一条指令上。
TODO:这将忽略您的其他断点。
对于特殊的常见情况syscall
,您可以使用catch syscall
:https ://reverseengineering.stackexchange.com/questions/6835/setting-a-breakpoint-at-system-call
我不知道内存中代码的地址。
是什么阻止您找到该地址?运行objdump -d
,找到感兴趣的指令,记下它的地址。问题解决了?(这也可以简单地扩展到共享库。)
不,这是不可能的,而且实施起来也非常低效。
调试器通常支持两种断点:
int 3
/ )替换断点地址处的操作码。0xcc
匹配当前指令的操作码要么需要 CPU 支持来插入硬件断点,要么调试器需要知道地址才能使用软件断点。
理论上,调试器可以在整个内存中搜索指令的字节序列,但由于字节序列也可能出现在指令中间或数据中,因此可能会出现误报。
由于汇编指令是可变长度的,控制可以跳转到任意地址或代码可以修改自身,反汇编整个内存区域以找到某些特定指令也并非易事。
所以基本上,在任意汇编代码中可靠地找到指令的唯一方法是在指令级别上单步执行。这将是非常昂贵的,即使是一个微不足道的库调用,printf()
如果你单步执行每条指令,在今天的硬件上可能需要几分钟。