Assembly 机器代码中的sizeof()等价物是什么?
我目前正在对一个游戏进行反向工程,遇到了一个问题,我需要调用Assembly 机器代码中的sizeof()等价物是什么?,assembly,x86-64,machine-code,Assembly,X86 64,Machine Code,我目前正在对一个游戏进行反向工程,遇到了一个问题,我需要调用GetRawInputData,它需要pcbSize作为其参数之一 通常在C语言中,我只需编写sizeof(pData),但我不知道如何在机器代码中实现这一点。sizeof纯粹是C类型系统的构造,在编译时完全解析为一个普通数字;机器代码中没有这样的东西,您可能只会在push或mov中找到对应于pData大小的立即值 例如,在我们的一个程序中,序列 RAWINPUT raw; UINT dwSize = sizeof(raw); GetR
GetRawInputData
,它需要pcbSize
作为其参数之一
通常在C语言中,我只需编写
sizeof(pData)
,但我不知道如何在机器代码中实现这一点。sizeof
纯粹是C类型系统的构造,在编译时完全解析为一个普通数字;机器代码中没有这样的东西,您可能只会在push
或mov
中找到对应于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
0x005f351d:leaeax[ebp-0x48]//eax=&dwSize
0x005f3520:mov DWORD PTR[esp+0xc],eax//pcbSize=eax=&dwSize
0x005f3524:lea-eax[ebp-0x38]//eax=&raw
0x005f3527:mov DWORD PTR[ebp-0x48],0x28//dwSize=sizeof(原始)即38
0x005f352e:mov DWORD PTR[esp+0x10],0x10//cbSizeHeader=sizeof(RAWINPUTHEADER)即16
0x005f3536:mov DWORD PTR[esp+0x8],eax//pdata=eax=&raw
0x005f353a:mov DWORD PTR[esp+0x4],0x10000003//uiCommand=RID\U输入
0x005f3542:mov DWORD PTR[esp],ecx//hRawInput=lparam
0x005f3545:调用DWORD PTR ds:0x20967fc//调用GetRawInputData
sizeof
纯粹是C类型系统的构造,在编译时完全解析为一个纯数字;机器代码中没有这样的东西,您可能只会在push
或mov
中找到对应于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
0x005f351d:leaeax[ebp-0x48]//eax=&dwSize
0x005f3520:mov DWORD PTR[esp+0xc],eax//pcbSize=eax=&dwSize
0x005f3524:lea-eax[ebp-0x38]//eax=&raw
0x005f3527:mov DWORD PTR[ebp-0x48],0x28//dwSize=sizeof(原始)即38
0x005f352e:mov DWORD PTR[esp+0x10],0x10//cbSizeHeader=sizeof(RAWINPUTHEADER)即16
0x005f3536:mov DWORD PTR[esp+0x8],eax//pdata=eax=&raw
0x005f353a:mov DWORD PTR[esp+0x4],0x10000003//uiCommand=RID\U输入
0x005f3542:mov DWORD PTR[esp],ecx//hRawInput=lparam
0x005f3545:调用DWORD PTR ds:0x20967fc//调用GetRawInputData
没有任何等价物。sizeof是编译时构造,它被转换为汇编中的一个数字。即sizeof(pcbSize)大约为48或1024左右。如果需要,您必须手动计算大小,或者在反汇编代码中找到它。没有任何等价物。sizeof是编译时构造,它被转换为汇编中的一个数字。即sizeof(pcbSize)大约为48或1024左右。如果需要,您必须手动计算大小或在反汇编代码中找到它。在汇编源代码中,您可以让汇编程序计算汇编时间常数,如
msg: db "hello world", 10 ; 10 = ASCII newline
msglen equ $-msg
然后,当您写入mov-edx,msglen
时,它将汇编为mov-edx,imm32
,并在中替换常量。有关一些示例,请参见
但是在最终的机器代码中,汇编时间常数都变成了立即数或数据常数。(例如,ptr_和_长度:dq msg,msglen
在数据或rodata部分汇编成一个地址和一个qword整数,它就在对象文件中,在运行时不会从任何东西计算出来。)
(汇编时间常数也可用作宏或其他指令中的重复计数。(例如
乘以功率imul eax,ecx
组合成一个由那么多imul
指令组成的块。
power
是一个整数常量,由等式或NASM定义%rep n
/…/%endrep
)
或者在汇编时间表达式中使用,因此大小本身并没有出现在对象文件中,只是基于它的一些计算的结果。(例如,mov-edx,msglen+2
或mov-ecx,arrbytes/4
,后者可能是按DWORD而不是字节计数的循环的边界).在汇编源代码中,您可以让汇编程序计算汇编时间常数,如
msg: db "hello world", 10 ; 10 = ASCII newline
msglen equ $-msg
然后,当您编写mov edx,msglen
时,它将汇编为mov edx,imm32
,并替换为常量。有关一些示例,请参阅
但是在最终的机器代码中,汇编时间常数都变成了立即数或数据常数。(例如,ptr_和_长度:dq msg,msglen
在数据或rodata部分汇编成一个地址和一个qword整数,它就在对象文件中,在运行时不会从任何东西计算出来。)
(汇编时间常数也可用作宏或其他指令中的重复计数。(例如
乘以功率imul eax,ecx
组合成一个由那么多imul
指令组成的块。
power
是一个整数常量,由等式或NASM定义%rep n
/…/%endrep
)
或者在汇编时间表达式中使用,因此大小本身并没有出现在对象文件中,只是基于它的一些计算的结果。(例如,
mov-edx,msglen+2
或mov-ecx,arrbytes/4
,后者可能是按DWORD而不是字节计数的循环的边界).如果这是真的,那么sizeof如何返回在运行时可能会更改大小的数据的大小?如果是常规C数组,则在运行时不会更改。如果是VLA,则情况完全不同。那么pdata的大小将始终为13?我在调用GetRawInputData时发现了这一点,但MSDN文档