我有一些代码的汇编代码将在程序中的某个点执行。 我不知道内存中代码的地址。
当当前指令与输入的指令匹配时,是否可以使gdb中断?
例如,每当gdb到达此指令时,我都希望gdb中断:
leaq 0x000008eb(%rip),%rax
答案 0 :(得分:7)
正如其他人所说,由于没有硬件支持,很可能无法有效地完成它。
但如果你真的想这样做,这个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
并使用命令:
breaki mov
breaki callq
并且您将继续执行使用给定操作码执行的第一条指令。
TODO:这会忽略你的其他断点。
对于syscall
的特定常见情况,您可以使用catch syscall
:https://reverseengineering.stackexchange.com/questions/6835/setting-a-breakpoint-at-system-call
答案 1 :(得分:2)
不,这是不可能的,实施效率也很低。
调试器通常支持两种断点:
int 3
/ 0xcc
)替换断点地址处的操作码。匹配当前指令的操作码要么需要CPU支持来插入硬件断点,要么调试器需要知道使用软件断点的地址。
理论上,调试器只能在整个存储器中搜索指令的字节序列,但由于字节序列也可能出现在指令或数据的中间,因此可能会出现误报。
由于汇编指令是可变长度的,控制可以跳转到任意地址或代码可以修改自身,因此反汇编整个内存区域以找到某些特定指令也是不容易的。
基本上,在任意汇编代码中可靠地查找指令的唯一方法是单步执行指令级。这将是非常昂贵的,如果你单步执行每条指令,即使像printf()
这样的简单库调用也可能需要几分钟才能完成今天的硬件。
答案 2 :(得分:2)
我不知道内存中代码的地址。
什么阻止您找到该地址?运行objdump -d
,找到感兴趣的指令,记下它的地址。问题解决了? (这也简单地扩展到共享库。)