MOV ESI, DWORD PTR DS:[EBP+0x8]
或者,我应该使用堆栈地址
[EBP+0x8] = 00000000
还是EBP + 0x8
,并写类似以下内容:是正确的答案,但对此我感到非常困惑。
#1 楼
括号的意思是“内容”,因此更像是:int esi = 0;
-或-
int esi = *(ebp+8); /* assuming ebp is correct */
<我希望
(EBP+0x8)
不会是0x12FF43
,因为堆栈指针应该对齐4或8个字节的地址(4对于32位的cpu,对于8位的,对于64位,虽然通常为16字节,但在64位中对齐)。 DS:
。疯了,但是当你在靠近金属的地方玩时一定要。#2 楼
[EBX+8]
是此堆栈帧的第二个dword
变量。如果将它放在esi
中,则可能是指针操作,因此,如果在声明了memcpy(dest,src,0x100)
后将src
设置为NULL
,则char *src = argument;
将包括该行。通常直接从C访问esi。当然,在我的示例中,当取消引用
memcpy
时,NULL
会出现段错误。评论
stackoverflow.com/questions/1856320/…
–offbyseveral
2014年5月23日下午4:49
#3 楼
我认为这里存在误解。ESI
是一个寄存器,不是变量,因此: > 此外,通常在OllyDbg中,
esi
行也会出现在以下函数的开头: 。因此,要用C语言编写行,您应该编写一个至少带有一个参数的函数。您传递给此函数的第一个参数将是asm {}
的值。#4 楼
MOV ESI, DWORD PTR DS:[EBP+0x8]
将
EBP+0x8
中的4个字节加载到ESI
中。 ESI
到[EBP+0x8]
。在读取汇编程序以将每一行转换为C时很有用,但有时您需要了解其余代码中使用了什么类型才能正确转换。
#5 楼
比方说:EBP = 00100000
然后:
EBP+8 = 00100008
然后代码变为:
MOV ESI, DWORD PTR DS:[00100008]
这意味着将地址
ESI
中的双字复制到寄存器00100008
中,这样您就可以在c中将MOV ESI, DWORD PTR DS:[00100008]
编写为:int esi = *0x00100008;
评论
是的,可以将EBP与DS:一起使用,只是奇怪地看到它在非堆栈设置中使用。它经常用于在函数中设置堆栈框架,有时会忘记它是常规的完整寄存器。
– lornix
2014年5月23日下午4:38
没有帧指针并将EBP用作通用寄存器是很常见的。毕竟,ia32极度缺乏寄存器。无效指针上的Btw指针算术是非法的,因此,上面的(void *)情况将不起作用,并且(char *)情况将仅读取一个char并将其转换为int,因此将是错误的。您需要在读取值之前将其强制转换为(int *),但必须添加至(char *)。可能还有趣的是,如果程序集到C的第二次翻译正确,那么您很可能会看到LEA指令而不是MOV。
–彼得·安德森(Peter Andersson)
2014年5月23日下午4:54