机器代码中的sizeof()等价于什么?

时间:2018-09-13 08:39:41

标签: assembly x86-64 machine-code

我目前正在对游戏进行逆向工程,遇到一个需要调用subprocess.Popen(cmd, shell=True, executable='/bin/bash') 的问题,该问题期望GetRawInputData作为其争论之一。

通常在C语言中,我只会写pcbSize,但我不知道如何在机器代码中进行此操作。

2 个答案:

答案 0 :(得分:3)

sizeof纯粹是C类型系统的构造,并在编译时完全解析为纯数字;机器代码中没有这样的东西,您可能只会在pushmov中找到与pData的大小相对应的立即值。

例如,在我们的程序中,序列

RAWINPUT raw;
UINT dwSize = sizeof(raw);
GetRawInputData((HRAWINPUT)lparam, RID_INPUT, &raw, &dwSize, sizeof(RAWINPUTHEADER));

被gcc 4.8翻译为

0x005f351d <+125>:   lea    eax,[ebp-0x48]                   // eax = &dwSize
0x005f3520 <+128>:   mov    DWORD PTR [esp+0xc],eax          // pcbSize = eax = &dwSize
0x005f3524 <+132>:   lea    eax,[ebp-0x38]                   // eax = &raw
0x005f3527 <+135>:   mov    DWORD PTR [ebp-0x48],0x28        // dwSize = sizeof(raw) i.e. 38
0x005f352e <+142>:   mov    DWORD PTR [esp+0x10],0x10        // cbSizeHeader = sizeof(RAWINPUTHEADER) i.e. 16
0x005f3536 <+150>:   mov    DWORD PTR [esp+0x8],eax          // pdata = eax = &raw
0x005f353a <+154>:   mov    DWORD PTR [esp+0x4],0x10000003   // uiCommand = RID_INPUT
0x005f3542 <+162>:   mov    DWORD PTR [esp],ecx              // hRawInput = lparam
0x005f3545 <+165>:   call   DWORD PTR ds:0x20967fc           // call GetRawInputData

答案 1 :(得分:0)

assembly 源代码中,您可以让汇编器计算

之类的汇编时间常数。
msg: db "hello world", 10            ; 10 = ASCII newline
msglen equ $-msg

然后,当您编写mov edx, msglen时,它会被替换为mov edx, imm32并用常量替换。有关某些示例,请参见How does $ work in NASM, exactly?

但是在最终的机器代码中,汇编时常数都变成了立即数或数据常数。(例如data或rodata部分中的ptr_and_length: dq msg, msglen会汇编为地址和qword目标文件中存在的整数,运行时不会根据任何内容计算得出。)


(汇编时间常数也可以在宏或其他指令中用作重复计数。(例如
times power imul eax, ecx汇编成许多imul指令的块。  power是用EQU定义的整数常量。或NASM %rep n / ... / %endrep

或在汇编时表达式中使用,因此大小本身实际上不存在于目标文件中,而只是基于该大小进行计算的结果。 (例如mov edx, msglen+2mov ecx, arrbytes/4,后者可能是一个以dword而不是字节为单位的循环的边界。)