我是一个新手与组装,我明白一些事情,但它仍然是非常复杂和困难的时刻,我。
我想在GDB中查看一个二进制代码,但有一段代码我一辈子都搞不清楚它在做什么。我知道它可能在做什么,但我不确定。
让我不爽的是:
Dump of assembler code for function main:
0x08048647 <+0>: lea 0x4(%esp),%ecx
0x0804864b <+4>: and $0xfffffff0,%esp
0x0804864e <+7>: pushl -0x4(%ecx)
0x08048651 <+10>: push %ebp
0x08048652 <+11>: mov %esp,%ebp
0x08048654 <+13>: push %ebx
0x08048655 <+14>: push %ecx
=> 0x08048656 <+15>: sub $0x10,%esp
0x08048659 <+18>: mov %ecx,%ebx
0x0804865b <+20>: movb $0x0,-0x9(%ebp)
0x0804865f <+24>: sub $0xc,%esp
0x08048662 <+27>: push $0x0
0x08048664 <+29>: call 0x8048400 <time@plt>
0x08048669 <+34>: add $0x10,%esp
0x0804866c <+37>: sub $0xc,%esp
0x0804866f <+40>: push %eax
0x08048670 <+41>: call 0x8048460 <srand@plt>
0x08048675 <+46>: add $0x10,%esp
0x08048678 <+49>: call 0x8048480 <rand@plt>
0x0804867d <+54>: mov %eax,%ecx
0x0804867f <+56>: mov $0x51eb851f,%edx
0x08048684 <+61>: mov %ecx,%eax
0x08048686 <+63>: imul %edx
0x08048688 <+65>: sar $0x5,%edx
0x0804868b <+68>: mov %ecx,%eax
0x0804868d <+70>: sar $0x1f,%eax
0x08048690 <+73>: sub %eax,%edx
0x08048692 <+75>: mov %edx,%eax
0x08048694 <+77>: imul $0x64,%eax,%eax
0x08048697 <+80>: sub %eax,%ecx
0x08048699 <+82>: mov %ecx,%eax
0x0804869b <+84>: mov %al,-0x9(%ebp)
...
...
我认为它是用时间作为随机数生成器的种子,然后生成一个随机数,但还有一个类似$0x51eb851f
的局部变量,看起来也像一个时间,然后在底部,看起来像是通过使用% al将随机数截断为8位。
谁能帮我把这个分解一下吗?
- part 2* -等效的C代码是什么样子的?
1条答案
按热度按时间pinkon5k1#
看来汇编代码为:
当对一段汇编代码进行逆向工程(或询问它)时,总是值得将它拆开并对每一段进行注解。
第一部分应明确:
下一部分有点混乱,除非你已经遇到了this compiler trick。
它是通过定点倒数 * 1/d * 除以 * d *,使用了一个技巧来提高精度(参见this)。
将这个数乘以一个整数将生成一个64位的定点数,点在中间(左边32位,右边32位)。由于我们只对整数部分感兴趣,所以我们只取高32位。
为了提高精度,* 1/d * 的浮点表示中的所有前导零都通过向 * 左 * 移位来移除,然后必须通过向 * 右 * 移位来补偿结果。
最后,如果被除数为负,结果可能会相差1,因此我们可能需要加1。
让我们看看代码:
若要找出除数
0x51eb851f
和5
的移位表示什么,您可以:1.求移位后的除数0x51eb851f/0x100000000(与0.99 = 99/100完全相同),在本例中为0.32,然后将其除以
2^5
,得到:0.32/32 = 0.01 = 1/100。1.取一个大的光滑数(一个有很多小素数除数的数),比如2310000,乘以
0x51eb851f
,然后将结果右移32 + 5位。(2310000 * 0x51eb851f) >> 37 = 23100
,这样你就可以看到结果是被除数的1/100。这里你需要记住整数除法不是单射的。You can always check with godbolt.org。
我们现在可以完成逆向工程: