汇编指针和基址

时间:2013-10-30 10:56:12

标签: assembly

由于我是汇编语言的初学者和学习目的,我正在尝试在游戏中扫描内存地址和指针。我对指针和地址感到困惑。

我通过youtube上的教程找到了指针,但我想深入了解这个指针和偏移量。

enter image description here

enter image description here 我不明白这些偏移量和地址是如何相加的,并给出一个存储值为1000的最终地址。

据我所知,00F8EBE0是基地址,“22,20,10,C,20”是五个偏移量。

00F8EBE0 - > 11DA0924 = 1000这是怎么发生的? 我怎么能用C ++读取00F8EBE0值?我是否需要这些偏移来帮助我获得最终值?

2 个答案:

答案 0 :(得分:1)

如果将指针和偏移量转换为C / C ++,那么最好用数组来思考。对于数组,通常有一个基指针,它是数组指针。如果要访问特定值,请添加索引,该索引将转换为偏移量。 最简单的情况是char数组,因为这里索引和偏移量之间的关系为1:1。

 char p[100];
 p[10] = 32;

10是你的偏移量并且假设'p'的值为0x1000,那么赋值45的地址将是0x100A。

 mov eax, 1000h
 mov [eax+0ah], 20

现在下一个案例是一个整数数组,其中int的大小为四个字节。这里索引必须乘以编译器为你做的。

 int p[100];
 p[10] = 32;

这将转化为:

 mov eax, 1000h
 mov edx, 0ah
 mov [eax+edx*4], 20

因此目标地址将是1000h + 10 * 4 = 40(28h) - > 1028h

在C ++中,通常有类。从汇编程序的角度来看,这与结构相同,因此您有一个basepointer,它是类的地址,偏移量表示该特定类/结构中的每个单独成员。但是你应该记住,当你在C / C ++中创建一个strcut /类时,编译器可以在成员之间添加填充字节,这实际上意味着在读取时你认为它不是必需的。 C / C ++代码。

 struct { char a; int b; } myStruct;

在这种情况下,b的偏移很可能是myStruct + 2(或4)而不是myStruct + 1,因为编译器可能会添加一个aligment以使其成为偶数地址或DWORD对齐的地址。

答案 1 :(得分:1)

在进程的虚拟内存空间中,加载了映像文件(“something.exe”)。如果您将0x00F8EBE0添加到该地址并阅读该位置,则会获得0x127B5450。将箭头读作“指向”,将方括号中的值读作“地址加偏移量”。您可以以编程方式获取图像库using the ToolHelp32 API

这里有一个指向对象结构的指针链,每个偏移量都为您提供结构/对象中下一个指针的位置。

要使用其他程序中的此信息,您可以使用ReadProcessMemory。从第一个偏移量(图像库)开始,调用ReadProcessMemory然后向其添加相关偏移量,然后重复。一般过程如下:

//assuming you've calculated the image base of the target
//and acquired a handle to the process:

LPVOID base = ImageBase + 0x00F8EBE0; //note: EntryPoint needs obtaining properly
LPVOID value;
ReadProcessMemory(hnd,base,(LPVOID) &value,sizeof value, NULL);
base = value + 0x20;
ReadProcessMemory(hnd,base,(LPVOID) &value,sizeof value, NULL);
base = value + 0xc;
ReadProcessMemory(hnd,base,(LPVOID) &value,sizeof value, NULL);
base = value + 0x10;
ReadProcessMemory(hnd,base,(LPVOID) &value,sizeof value, NULL);
base = value + 0x20;
ReadProcessMemory(hnd,base,(LPVOID) &value,sizeof value, NULL);
base = value + 0x44;
ReadProcessMemory(hnd,base,buf,sizeof value, NULL);
//value will now contain the number 1000.

请注意,没有任何保证进程的地址空间每次运行时看起来都一样;如果它分配任何内存,第一个偏移量到入口点(0x00F8EBE0)将不相同。