当我看到装配线: >
 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:。疯了,但是当你在靠近金属的地方玩时一定要。

评论


是的,可以将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

#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;