C 使用带寄存器的三参数算术在汇编中使用lea运算符
再一次,我在寻找最基本问题的答案时遇到了问题。这一次,我正在进行一个二元炸弹的第二阶段,以完成一个类分配。我将在下面发布反汇编代码 我很难理解网上发生了什么。据我目前所知,它试图将((4*%edx)+%eax)算术运算中的地址加载到%eax寄存器中。到目前为止,我很可能是错的,这是我的寄存器中的内容,其中x、y、z是scanf调用中输入的三个参数: %eax:y %edx:z 因此,程序试图加载((4*z)+y)的地址?我不知道要将此值存储到%eax中,它会是什么样子 我的问题涉及lea指令在二进制炸弹中的具体应用。我以前在这里读过这篇文章:但我仍然不明白它是如何应用到我的场景中的C 使用带寄存器的三参数算术在汇编中使用lea运算符,c,assembly,x86,reverse-engineering,C,Assembly,X86,Reverse Engineering,再一次,我在寻找最基本问题的答案时遇到了问题。这一次,我正在进行一个二元炸弹的第二阶段,以完成一个类分配。我将在下面发布反汇编代码 我很难理解网上发生了什么。据我目前所知,它试图将((4*%edx)+%eax)算术运算中的地址加载到%eax寄存器中。到目前为止,我很可能是错的,这是我的寄存器中的内容,其中x、y、z是scanf调用中输入的三个参数: %eax:y %edx:z 因此,程序试图加载((4*z)+y)的地址?我不知道要将此值存储到%eax中,它会是什么样子 我的问题涉及lea指令在二
0x08048764 <+0>: sub $0x3c,%esp
0x08048767 <+3>: lea 0x2c(%esp),%eax
0x0804876b <+7>: mov %eax,0x10(%esp)
0x0804876f <+11>: lea 0x28(%esp),%eax
0x08048773 <+15>: mov %eax,0xc(%esp)
0x08048777 <+19>: lea 0x24(%esp),%eax
0x0804877b <+23>: mov %eax,0x8(%esp)
0x0804877f <+27>: movl $0x8048ba7,0x4(%esp)
0x08048787 <+35>: mov 0x804b040,%eax
0x0804878c <+40>: mov %eax,(%esp)
0x0804878f <+43>: call 0x8048480 <__isoc99_fscanf@plt>
0x08048794 <+48>: cmp $0x3,%eax
0x08048797 <+51>: je 0x80487a5 <phase_2_of_5+65>
0x08048799 <+53>: movl $0x2,(%esp)
0x080487a0 <+60>: call 0x80486ef <explode>
0x080487a5 <+65>: mov 0x24(%esp),%edx
0x080487a9 <+69>: cmp $0x4,%edx
0x080487ac <+72>: jg 0x80487ba <phase_2_of_5+86>
0x080487ae <+74>: movl $0x2,(%esp)
0x080487b5 <+81>: call 0x80486ef <explode>
0x080487ba <+86>: mov 0x28(%esp),%eax
0x080487be <+90>: cmp $0xa,%eax
0x080487c1 <+93>: jle 0x80487cf <phase_2_of_5+107>
0x080487c3 <+95>: movl $0x2,(%esp)
0x080487ca <+102>: call 0x80486ef <explode>
0x080487cf <+107>: lea (%eax,%edx,4),%eax
0x080487d2 <+110>: cmp 0x2c(%esp),%eax
0x080487d6 <+114>: je 0x80487e4 <phase_2_of_5+128>
0x080487d8 <+116>: movl $0x2,(%esp)
0x080487df <+123>: call 0x80486ef <explode>
0x080487e4 <+128>: add $0x3c,%esp
0x080487e7 <+131>: ret
0x08048764:sub$0x3c,%esp
0x08048767:lea 0x2c(%esp),%eax
0x0804876b:mov%eax,0x10(%esp)
0x0804876f:lea 0x28(%esp),%eax
0x08048773:mov%eax,0xc(%esp)
0x08048777:lea 0x24(%esp),%eax
0x0804877b:mov%eax,0x8(%esp)
0x0804877f:movl$0x8048ba7,0x4(%esp)
0x08048787:mov 0x804b040,%eax
0x0804878c:mov%eax,(%esp)
0x0804878f:调用0x8048480
0x08048794:cmp$0x3,%eax
0x08048797:je 0x80487a5
0x08048799:movl$0x2,(%esp)
0x080487a0:调用0x80486ef
0x080487a5:mov 0x24(%esp),%edx
0x080487a9:cmp$0x4,%edx
0x080487ac:jg 0x80487ba
0x080487ae:movl$0x2,(%esp)
0x080487b5:调用0x80486ef
0x080487ba:mov 0x28(%esp),%eax
0x080487be:cmp$0xa,%eax
0x080487c1:jle 0x80487cf
0x080487c3:movl$0x2,(%esp)
0x080487ca:调用0x80486ef
0x080487cf:lea(%eax,%edx,4),%eax
0x080487d2:cmp 0x2c(%esp),%eax
0x080487d6:je 0x80487e4
0x080487d8:movl$0x2,(%esp)
0x080487df:调用0x80486ef
0x080487e4:添加$0x3c,%esp
0x080487e7:ret
好的,那么你是在告诉我在操作之后,eax将包含该计算的值而不是地址吗?例如,如果eax包含4,edx包含5,则eax将变为24 值变为24,但EAX中的是该值的地址,而不是值本身。因此,当您进行寄存器转储时,您将在EAX中看到类似0x12345678的值,而不是0x00000018。它本质上是一个指针 这就是说,如果您试图避免在处调用,那么您通过LEA加载到EAX的地址必须等于ESP+2c处的地址,才能满足跳转条件。进行寄存器和堆栈转储以查看ESP在该点的位置。在这一点上,它归结为只是相应地调整您的偏移量
希望这有帮助第107行确实做了
eax=eax+edx*4
-不多也不少。好的,你是说在操作后,eax将包含该计算的值,而不是地址吗?例如,如果eax包含4,edx包含5,那么eax将变为24?我已经尝试了我的理论,但到目前为止还没有成功。很高兴听到你的回音。从我到目前为止的分析来看,除非我在某个地方搞砸了,否则为了避免调用explode(其中x,y,z是来自scanf的输入),z必须大于4,y<10,x==y+z*4。我一定是错了,因为我尝试了z=2,y=12,x=20,但没有用。LEA只是计算了一个有效地址,但没有解引用它。500的评论完全正确。是的,在你的例子中,eax将变成24。有关详细信息,请参阅。很不幸,OP已经接受了这一点,但它是错误的<代码>如果eax包含4,edx包含5,则eax将变为24,这是真的,因此,当您进行寄存器转储时,您将在eax中看到类似0x12345678而不是0x00000018的值完全错误。第二段关于看esp的内容也毫无意义。你根本不需要知道esp的价值。好吧,杰斯特,谢谢你让我觉得自己是废物。我很感激。这不是为了让你有任何感觉。这是关于消除错误信息的。如果你不相信我们,就用调试器试试<代码>mov eax,4;mov-edx,5,lea-eax,[eax+edx*4]
<代码>eax将是24。我感谢X0r的帮助。如果这让你感觉更好的话,你的回答让我信服了,哈哈。