我正在尝试实现已知的方法“动态分叉的Win32 EXE",这是众所周知的RunPE。我的问题是,我无法得到“基本地址”的正确结果,正如它在http://www.security.org.sg/code/loadexe.html第三点中提到的那样
这是我的密码:
DWORD* peb;
DWORD* baseAddress;
...snip...
GetThreadContext(hTarget, &contx)
peb = (DWORD *) contx.Ebx;
baseAddress = (DWORD *) contx.Ebx+8;
_tprintf(_T("The EBX [PEB] is: 0x%08X\nThe base address is: 0x%08X\nThe Entry Point is: 0x%08X\n"), peb, baseAddress, contx.Eax);输出值为follwos:
EBX PEB为: 0x7FFD4000 基本地址是: 0x7FFD4020 入口点是: 0x00401000
我认为我的问题在于实现我的baseAddress指针,但我不知道具体问题是什么。或者我没有正确理解上面的文章,baseAddress不是ImageBase,如果是的话,baseAddress是什么?
我试着在Win 7 64b和Win-XP下运行它,在这两种情况下,我都得到了相同的错误结果。
发布于 2012-10-09 22:05:20
注意,说明书上写着"at EBX+8“。括号是指该地址位置的值。有几个问题
baseAddress = (DWORD *) contx.Ebx+8;首先,编译器不注意间距,只注意括号大小,所以这意味着
baseAddress = ((DWORD *)contx.Ebx) + 8;这是错误的,因为8是在计算DWORD,而不是字节。你想要的
baseAddress = (DWORD *)(contx.Ebx + 8);但是这只会得到存储baseAddress的地址,而不是baseAddress的值。为此你需要
baseAddress = *(DWORD *)(contx.Ebx + 8);但是,只有当contx.Ebx引用进程中的地址,但每个进程都有自己的地址空间,并且您需要访问挂起的进程的地址空间时,这才有效;为此,您需要使用ReadProcessMemory ( http://msdn.microsoft.com/en-us/library/windows/desktop/ms680553%28v=vs.85%29.aspx ):
ok = ReadProcessMemory(hTarget, (LPCVOID)(contx.Ebx + 8), (LPVOID)&baseAddress, sizeof baseAddress, NULL);发布于 2012-10-09 21:27:54
您只是在做指针运算,实际上并不是在取消内存,在这一行中:
baseAddress = (DWORD *) contx.Ebx+8;您只是将8*sizeof(DWORD) = 32添加到contx.Ebx的值中。您真正想要做的是在新进程的地址空间中读取位于contx.Ebx+8地址的数据。为了做到这一点,您需要使用ReadProcessMemory,而不必费心地进行转换--您希望使用原始偏移量,而不是偏移乘以sizeof(DWORD),这就是使用DWORD*值进行指针算法时所发生的情况。
但是,我强烈警告您不要深入了解像这样的实现细节,因为这种实现可能而且确实会在不同版本的Windows之间发生变化。记住,你所链接的那篇文章是2004年写的,它只是一个概念的证明,所以在Vista、Windows 7、Windows 8和未来版本中可能会有很多隐藏的问题和意想不到的问题。
Windows没有像Unix的fork(2)函数那样的函数,因此,您应该尽量避免使用CreateProcess而不是fork+exec等。fork是丑陋而缓慢的,由于DLL内存映射问题,它可能会意外失败。
发布于 2012-10-09 23:42:35
除了其他人所说的,还有一种更简单的方法来提取流程的PEB结构的基址。使用NtQueryInformationProcess(),将其ProcessInformationClass参数设置为ProcessBasicInformation。输出将是一个PROCESS_BASIC_INFORMATION结构:
typedef struct _PROCESS_BASIC_INFORMATION {
PVOID Reserved1;
PPEB PebBaseAddress;
PVOID Reserved2[2];
ULONG_PTR UniqueProcessId;
PVOID Reserved3;
} PROCESS_BASIC_INFORMATION;第二个成员是你要找的。
https://stackoverflow.com/questions/12808516
复制相似问题