I need to be able to change a thread’s starting address in certain situations. I have a callback setup with PsSetCreateThreadNotifyRoutine. In the callback routine, I am able to read the thread’s starting address, but not change it. Windows always returns STATUS_INVALID_PARAMETER, which makes me think that the starting address is R/O at this point.
Am I missing something? If I can’t change the starting address in this callback, any ideas where I could do it?
Thanks in advance!
VOID CreateThreadNotifyCallback(__in HANDLE ProcessId, __in HANDLE ThreadId, __in BOOLEAN Create)
{
if ( (ProcessId == g_hProcess) && Create)
{
NTSTATUS rc;
PETHREAD peThread;
rc = PsLookupThreadByThreadId(ThreadId, &peThread);
auto_handle hThreadRef;
rc = ObOpenObjectByPointer(peThread, OBJ_KERNEL_HANDLE, NULL, THREAD_ALL_ACCESS, *PsThreadType, KernelMode, &hThreadRef);
THREAD_BASIC_INFORMATION ThreadInfo;
ULONG res;
// returns STATUS_SUCCESS
rc = ZwQueryInformationThread(hThreadRef, ThreadBasicInformation, &ThreadInfo, sizeof(ThreadInfo), &res);
PVOID pStartAddress;
// returns STATUS_SUCCESS, fills pStartAddress with the thread starting address
rc = ZwQueryInformationThread(hThreadRef, ThreadQuerySetWin32StartAddress, &pStartAddress, sizeof(pStartAddress), &res);
// always returns STATUS_INVALID_PARAMETER no matter what I try
rc = ZwSetInformationThread(hThreadRef, ThreadQuerySetWin32StartAddress, &pStartAddress, sizeof(pStartAddress));
DbgPrint(“PID %d, TID %d, start addr %I64x\n”, ProcessId, ThreadId, pStartAddress);
}
}