This is not DR related but rather in my own code but you guys seem to really know what you're doing so I'm hoping you might be willing to help me out.
I'm struggling to do something that I feel should be very easy.
I've spawned a 32 bit child suspended from a 64 bit parent and am doing some manipulation of it from the parent. It's very early so only the wow64 and nt dlls are present.
I'm hooking all the 64 bit ntdll functions but I also need to do some work in the 32 bit layer so I'm trying to figure out from the parent code what the base address of the childs 32 bit ntdll is.
Windbg and process explorer both show the base load address of all the dlls at this point so clearly the information exists but I'm unable to figure out how to get the address of the 32 bit ntdll.
I feel like this code SHOULD do what I'm attempting. Just POC so not the cleanest but here's what I'm trying.
#define TEB32OFFSET 0x2000
void interceptNtDll32(HANDLE hProcess)
{
THREAD_BASIC_INFORMATION tbi;
NTSTATUS ntrv;
TEB32 teb32;
void *teb32addr;
PEB_LDR_DATA32 ldrData;
PEB32 peb32;
LIST_ENTRY32 *pMark = NULL;
LDR_DATA_TABLE_ENTRY32 ldrDataTblEntry;
size_t bytes_read;
HANDLE hThread = getThreadHandle(hProcess);
/* Used to be able to get 32 bit PEB from PEB64 with 0x1000 offset but
Windows 8 changed that so we do it indirectly from the TEB */
if(!hThread)
return;
/* Get thread basic information to get 64 bit TEB */
ntrv = NtQueryInformationThread(hThread, ThreadBasicInformation, &tbi, sizeof(tbi), NULL);
if(ntrv != 0){
goto out;
}
/* Use magic to find 32 bit TEB */
teb32addr = (char *)tbi.TebBaseAddress + TEB32OFFSET; // Magic...
ntrv = NtReadVirtualMemory(hProcess, teb32addr, &teb32, sizeof(teb32), NULL);
if(ntrv != 0 || teb32.NtTib.Self != (DWORD)teb32addr){ // Verify magic...
goto out;
}
/* TEB32 has address for 32 bit PEB.*/
ntrv = NtReadVirtualMemory(hProcess, (void *)teb32.ProcessEnvironmentBlock, &peb32, sizeof(peb32), NULL);
if(ntrv != 0){
goto out;
}
/* This is where it goes south. The 32 bit PEB LOOKS like it should be okay but Ldr is NULL
so we don't get the 32 bit ldr information. */
ntrv = NtReadVirtualMemory(hProcess, (void *)peb32.Ldr, &ldrData, sizeof(ldrData), &bytes_read);
if(ntrv != 0){
goto out;
}
/* If the above had worked we could now iterate through the ldr data to find ntdll32.dll */
ntrv = NtReadVirtualMemory(hProcess, (VOID *)ldrData.InLoadOrderModuleList.Flink, &ldrDataTblEntry, sizeof(ldrDataTblEntry), NULL);
...
Any suggestions of alternate ways of doing it? Running through the 64 bit ldr data only gives me the wow64 and 64 bit ntdll addresses.
cheers,
Kris