各位大佬好,我在做实验的额时候,书中第四版第四章讲到调用约定时(134-135页)中提到64位下前4个参数传参是:
RCX,RDX,R8,R9
我使用的实验代码(OSX/NASM/GCC)如下:
#include <iostream>
class Demo {
private:
int x;
int y;
int z;
public:
int a;
int b;
int c;
int getX() { return this->x; }
int getY() { return this->y; }
int getZ() { return this->z; }
};
extern "C" Demo* InitMe(Demo*,int,int,int,int,int,int);
int main(int argc, const char * argv[]) {
Demo* demo = new Demo();
demo = InitMe(demo,1,2,3,4,5,6);
std::cout << "X=" << demo->getX() << ",";
std::cout << "Y=" << demo->getY() << ",";
std::cout << "Z=" << demo->getZ() << ",";
std::cout << "A=" << demo->a << ",";
std::cout << "B=" << demo->b << ",";
std::cout << "C=" << demo->c << std::endl;
return 0;
}
InitMe的汇编代码如下:
BITS 64
GLOBAL _InitMe
_InitMe:
PUSH RBP
MOV RBP,RSP
MOV RAX,RDI
XOR RCX,RCX
MOV RCX,0x1
MOV [RAX], RCX
INC RCX
MOV [RAX+0x4], RCX
INC RCX
MOV [RAX+0x8], RCX
INC RCX
MOV [RAX+0xc], RCX
INC RCX
MOV [RAX+0x10],RCX
INC RCX
MOV [RAX+0x14],RCX
POP RBP
RET
通过Ghidra反汇编主函数得到如下反汇编结果:
this = (void *)__Znwm(0x18);
_memset(this,0,0x18);
this = (void *)_InitMe(this,1,2,3,4,5,6);
...
100000e3d 48 89 45 e0 MOV qword ptr [RBP + local_28],RAX
100000e41 e8 86 0f CALL __stubs::_memset void * _memset(void * param_1, i
00 00
100000e46 48 8b 45 e0 MOV RAX,qword ptr [RBP + local_28]
100000e4a 48 89 45 e8 MOV qword ptr [RBP + local_20],RAX
100000e4e 48 8b 7d e8 MOV RDI,qword ptr [RBP + local_20] ; 这个是Demo*
100000e52 be 01 00 MOV ESI,0x1 ; 第一个参数
00 00
100000e57 ba 02 00 MOV EDX,0x2
00 00
100000e5c b9 03 00 MOV ECX,0x3
00 00
100000e61 41 b8 04 MOV R8D,0x4
00 00 00
100000e67 41 b9 05 MOV R9D,0x5
00 00 00
100000e6d c7 04 24 MOV dword ptr [RSP]=>local_78,0x6
06 00 00 00
100000e74 e8 80 0e CALL _InitMe undefined _InitMe()
00 00
编译用命令如下:
# NASM version 2.14.02 compiled on Sep 28 2019
# Apple clang version 11.0.3 (clang-1103.0.32.62)
# Target: x86_64-apple-darwin19.5.0
nasm -fmacho64 InitMe.asm
g++ -v -O0 -ggdb main.cpp InitMe.o
可以看到和书中描述的传参方式不完全一致,特别是Demo*的传递有点特别。我的问题是:这个是编译器的问题呢,还是C++的黑魔法?还是我实验用的代码写得有问题?
谢谢指导!
[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)