Reputation: 365
I started a new project recently and my objectives is to inject bytecode into another process, and then start a remote thread executing my bytecode, however i have run into a very strange problem.
What it does is that it allocates and write to memory of a arbitrary process, it writes a struct containing pointers to functions in user32.dll and kernel32.dll for the remote process, it also writes a calling operation for the function pointers from the struct, it then creates a remotethread with a lpStartAddress of the "calling operation"
You can find the source code here : http://pastie.org/9298306
GetPrivileges is being called on line 55 (method on line 185), it returns true meaning that OpenProcessToken, LookupPrivilegeValue and AdjustTokenPrivileges returned true.
Soon after that the following will be callled:
param->pMessageBox = (DWORD)GetProcAddress(user32, "MessageBoxA");
param->pSleep = (DWORD)GetProcAddress(kernel32, "Sleep");
Both user32 and kernel32 are valid handles, but param->pMessageBox will be set to NULL, whilst param->pSleep will get the actual pointer for the Sleep.
And the strange thing about this is when i replace the GetPrivileges with this snippet that i copied online it works fine and the param->pMessageBox will be set with the correct pointer address.
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;
}
Continuing on with my debugging take note that the else statement in the copied GetPrivileges will not be called due to OpenProcessToken returning true as expected, and by removing:
TCHAR buffer[256];
wsprintf(buffer, TEXT("0x%x"), GetLastError());
param->pMessageBox will set to NULL, how can that be?
Regards a frustrated ogelami.
Upvotes: 2
Views: 2144
Reputation: 613491
The module handles are in fact not valid. They are module handles for a remote process. Module handles are in fact implement as base addresses and so only have meaning with respect to the virtual address space of the executing process.
It looks like, by chance, the base address of the kernel32 module of the injecting process is the same as the base address of the kernel32 module in the remote process.
Realistically, your goals are going to be hard to achieve if you put so much code in the injecting process. You would be better off if you injected a DLL into the other process. Create a remote thread whose first act is to load this DLL. Then you will have code running in the other process, inside its address space, and so able to call directly functions like GetModuleHandle
, GetProcAddress
etc.
Upvotes: 2