我最近开始了一个新项目,我的目标是将字节码注入另一个进程,然后启动一个执行我的字节码的远程线程,但是我遇到了一个非常奇怪的问题。
它的作用是分配并写入任意进程的内存,它为远程进程写入包含指向user32.dll和kernel32.dll中函数的指针的结构,它还为函数指针编写一个调用操作从结构中,然后使用“调用操作”
的lpStartAddress创建一个remotethread您可以在此处找到源代码: http://pastie.org/9298306
在第55行调用GetPrivileges(第185行的方法),返回true表示OpenProcessToken,LookupPrivilegeValue和AdjustTokenPrivileges返回true。
之后不久将调用以下内容:
param->pMessageBox = (DWORD)GetProcAddress(user32, "MessageBoxA");
param->pSleep = (DWORD)GetProcAddress(kernel32, "Sleep");
user32和kernel32都是有效句柄,但param-> pMessageBox将设置为NULL,而param-> pSleep将获得Sleep的实际指针。
关于这一点的奇怪之处在于,当我使用我在线复制的这个片段替换GetPrivileges时,它工作正常,并且param-> pMessageBox将使用正确的指针地址进行设置。
BOOL GetPrivileges()
{
HANDLE tokenHandle;
TOKEN_PRIVILEGES tokenPriv;
if(OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY | TOKEN_ADJUST_PRIVILEGES, &tokenHandle) != 0)
{
LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &tokenPriv.Privileges[0].Luid);
tokenPriv.PrivilegeCount = 1;
tokenPriv.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
AdjustTokenPrivileges(tokenHandle, 0, &tokenPriv, sizeof(tokenPriv), NULL, NULL);
}
else
{
TCHAR buffer[256];
wsprintf(buffer, TEXT("0x%x"), GetLastError());
MessageBox(NULL, buffer, TEXT("OpenProcessTokenError"), MB_ICONERROR);
return FALSE;
}
return true;
}
继续我的调试请注意,由于OpenProcessToken按预期返回true,并且删除了以下内容,因此不会调用复制的GetPrivileges中的else语句:
TCHAR buffer[256];
wsprintf(buffer, TEXT("0x%x"), GetLastError());
param-> pMessageBox将设置为NULL,那怎么可能?
关注沮丧的ogelami。
答案 0 :(得分:1)
模块句柄实际上无效。它们是远程进程的模块句柄。模块句柄实际上是作为基地址实现的,因此只对执行过程的虚拟地址空间有意义。
看起来,一个偶然的机会,注入过程的kernel32模块的基地址与远程进程中kernel32模块的基地址相同。
实际上,如果在注入过程中放入如此多的代码,那么您的目标很难实现。如果你将DLL注入另一个进程,你会更好。创建一个远程线程,其第一步是加载此DLL。然后,您将在其地址空间内的其他进程中运行代码,因此可以直接调用GetModuleHandle
,GetProcAddress
等函数。