如何调试此反汇编代码?我必须在C ++语言上重写这个函数。但首先我必须了解它是如何运作的。
有什么方法可以调试吗?
0804865a <generate_key>:
804865a: 55 push %ebp
804865b: 89 e5 mov %esp,%ebp
804865d: 57 push %edi
804865e: 56 push %esi
804865f: 53 push %ebx
8048660: 83 ec 18 sub $0x18,%esp
8048663: 8b 7d 0c mov 0xc(%ebp),%edi
8048666: ff 75 08 pushl 0x8(%ebp)
8048669: e8 b2 fe ff ff call 8048520 <atoi@plt>
804866e: 83 c4 10 add $0x10,%esp
8048671: 85 c0 test %eax,%eax
8048673: 89 c3 mov %eax,%ebx
8048675: 75 0f jne 8048686 <generate_key+0x2c>
8048677: e8 d4 fe ff ff call 8048550 <rand@plt>
804867c: b9 40 42 0f 00 mov $0xf4240,%ecx
8048681: 99 cltd
8048682: f7 f9 idiv %ecx
8048684: 89 d3 mov %edx,%ebx
8048686: 31 c9 xor %ecx,%ecx
8048688: be 1b 00 00 00 mov $0x1b,%esi
804868d: eb 13 jmp 80486a2 <generate_key+0x48>
804868f: 8d 04 c9 lea (%ecx,%ecx,8),%eax
8048692: 31 d2 xor %edx,%edx
8048694: 01 d8 add %ebx,%eax
8048696: f7 f6 div %esi
8048698: 8a 82 18 9e 04 08 mov 0x8049e18(%edx),%al
804869e: 88 04 0f mov %al,(%edi,%ecx,1)
80486a1: 41 inc %ecx
80486a2: 3b 4d 10 cmp 0x10(%ebp),%ecx
80486a5: 73 05 jae 80486ac <generate_key+0x52>
答案 0 :(得分:1)
你可以:
A)使用右边的部分(指令助记符)和一些像气体一样的汇编程序(你的列表采用AT&amp; T语法,因此气体是自然选择)来编译它(它可能需要一些语法修复才能编译,并且正确设置代码段和起点等内容。优点是,如果您对某些内容感兴趣(如果您知道Assembly足够好以便在其中编程),您还可以包含自己的帮助程序指令来修改代码。
B)取字节代码值的中间部分,然后将其在hexa编辑器中写入文件...然后将其加载到调试器内存到代码段,在开头设置cs:eip
然后你去。这种方法的优点是您不需要修复任何语法,六进制字节值是六进制字节值。
这两种方法都有一个巨大的缺陷,像call 8048520 <atoi@plt>
之类的东西不能调用所需的代码,因为它不是你的列表的一部分,也不会让它从相同的物理地址开始,因为那个列表是取而代之,所以你必须要了解Assembly以完全理解如何调整该代码中的任何全局指针值,并删除那些calls
,而是通过手动修改该位置中的寄存器/内存来模拟它们的功能调试器(所以你必须完全理解这些调用最初的作用)。
但是通常在给出这些练习时,二进制文件是可用的,所以学生可以自己在调试器中运行它,所以我想知道为什么你只有这个列表(问题看起来它看起来甚至太早了)。
C)明显的选择是在纸上进行调试,它太短了,通过指令参考指南,您可以轻松查找任何指令并在原始行旁边写下注释,您认为正在进行的操作。
A-hybrid)将其作为C ++代码的一部分,因此您可以调用真正的atoi
和rand
函数。这些当然可能与原始版本不同,因此当您没有完整的原始代码时,您仍然不清楚如何获得与原始代码完全相同的结果。
来自彼得的评论:
使用.S
编译gcc
(GCC主要使用的汇编源文件的扩展名)可以让您轻松访问真正的libc atoi
和rand
函数。 GNU as
(gas)甚至不需要EXTERN声明。