控制函数参数使cmp edx, 4Dh比较成立的取值及相关地址疑问
分析汇编代码中参数控制的条件满足问题
先把你给出的汇编代码贴出来方便拆解分析:
arg_4 = dword ptr 0Ch push ebp mov ebp, esp mov eax, [ebp+arg_4] mov ecx, [eax+0Ch] movsx edx, byte ptr [ecx+2] cmp edx, 4Dh
一步步理清执行逻辑
我来帮你拆解每一行的作用,以及你需要满足的核心条件:
mov eax, [ebp+arg_4]:这一步直接把你能控制的arg_4参数值加载到eax寄存器里。这里要注意,接下来eax会被当作内存地址来使用——因为下一行是从eax+0xC的内存位置读取数据。mov ecx, [eax+0Ch]:从内存地址eax + 0x0C处读取一个4字节的双字值,存入ecx。用C语言风格的指针逻辑描述,就是ecx = *(arg_4 + 0x0C)。movsx edx, byte ptr [ecx+2]:从内存地址ecx + 0x02处读取1个字节,通过符号扩展把这个8位字节转换成32位的edx。因为0x4D是正数(二进制最高位为0),所以扩展后edx的值就是0x0000004D。cmp edx, 4Dh:比较edx和0x4D(对应ASCII字符'M'),要让这个比较成立,核心就是让edx等于0x4D。
满足比较成立的arg_4取值逻辑
要让cmp edx, 4Dh的条件成立,你需要满足最终的核心要求:
byte ptr [ *(arg_4 + 0x0C) + 0x02 ] == 0x4D
翻译成更直白的步骤:
- 你设置的
arg_4值,加上0x0C后得到内存地址A; - 地址A处的4字节值是内存地址B;
- 地址B加上0x02后得到的地址C,其存储的字节必须是0x4D。
举个实际的例子:
假设你能控制内存地址0x10000000处的4字节值为0x20000000,同时内存地址0x20000002处的字节是0x4D。那你可以设置arg_4 = 0x10000000 - 0x0C = 0x0FFFFFF4,这样:
eax = 0x0FFFFFF4,eax+0xC = 0x10000000,读取到ecx = 0x20000000;ecx+0x2 = 0x20000002,读取字节0x4D,符号扩展后edx = 0x0000004D;- 最终
cmp指令的条件就成立了。
解答你的困惑
你提到“控制arg_4就能任意设置eax的值,这该如何理解”——这里的关键是,eax被当作指针来使用,而不是普通的数值。你确实可以任意设置eax的值,但这个值必须是一个合法的内存地址(否则程序会直接崩溃),并且该地址+0xC处的内容,要能引导到最终存储0x4D字节的位置。
这种场景在漏洞利用中很常见:比如如果arg_4是一个可控的结构体指针,eax+0xC就是结构体里的某个指针成员,你可以通过构造这个结构体,让成员指针指向的内存+2处是目标字节,从而满足比较条件。
内容的提问来源于stack exchange,提问作者ineedahero
相关产品推荐
相关产品推荐

