PsSetCreateThreadNotifyRoutine

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);
}
}

Why do you think that you need to change the thread’s start address?

  • S (Msft)

-----Original Message-----
From: xxxxx@lists.osr.com [mailto:xxxxx@lists.osr.com] On Behalf Of xxxxx@earthlink.net
Sent: Tuesday, January 24, 2012 8:22 AM
To: Windows System Software Devs Interest List
Subject: [ntdev] PsSetCreateThreadNotifyRoutine

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);
}
}


NTDEV is sponsored by OSR

For our schedule of WDF, WDM, debugging and other seminars visit:
http://www.osr.com/seminars

To unsubscribe, visit the List Server section of OSR Online at http://www.osronline.com/page.cfm?name=ListServer

Similar situation to this:

https://groups.google.com/group/comp.os.ms-windows.programmer.nt.kernel-mode/browse_thread/thread/ad40259691758361/ec3fec656e889b4e?lnk=gst&q=ThreadQuerySetWin32StartAddress#ec3fec656e889b4e

If I terminate a process that was created by explorer.exe (i.e. the shell), it puts up a message box with an error description. I want to put up my own dialog box.

xxxxx@earthlink.net wrote:

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.

VOID CreateThreadNotifyCallback(__in HANDLE ProcessId, __in HANDLE ThreadId, __in BOOLEAN Create)
{

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));

You have an extra & in there. You should pass pStartAddress, not
&pStartAddress.

ZwQuery needs the & because it is an output parameter. For ZwSet, it is
an input prameter.


Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc.

Looks like appendectomy through an ear.

If you want to intercept process failures, you need to use Windows Error Reporting interfaces. You can register your own handler.

@Tim, I already tried passing pStartAddress and &pStartAddress – both return STATUS_INVALID_PARAMETER

@Alex, I am not intercepting process failures, I am terminating process creation myself. The shell puts up a simple MessageBox in this case. It has nothing to do with WER.

Which process you want to terminate? What bigger problem you’re trying to solve?

There is some serious confusion here. For example, what is the antecedent
of “it”? Certainly, the process cannot put up a message box; that
process is dead, dead, dead and can’t do anything. There is a message
that comes up if you use task manager, which says in effect “terminating a
process this way is not safe for children and other living beings” but
that is task manager. What message are you talking about? If you mean
the kind of message box that happens when some internal error occurs in
the process, most of those messages come from the runtime library, most
commonly the C or C++ runtimes, but there are msny other error messages
that come from errors detected by the CLR, or are VB- or C#-specific.

The shell can also set up to receive notificstions on process termination
of any processes it launches, and can inspect to see if the termination
was abnormal, and if so, it can issue an error message. Did you use spy++
or some other tool to see what process owns this message box?

If you want to report a process has failed, you can build that into the
process; read sbout exception handling in user-level processes (not C++
exception handling, but the __try/__except form) and study the ways of
adding your own interceptor.
joe

Similar situation to this:

https://groups.google.com/group/comp.os.ms-windows.programmer.nt.kernel-mode/browse_thread/thread/ad40259691758361/ec3fec656e889b4e?lnk=gst&q=ThreadQuerySetWin32StartAddress#ec3fec656e889b4e

If I terminate a process that was created by explorer.exe (i.e. the
shell), it puts up a message box with an error description. I want to put
up my own dialog box.


NTDEV is sponsored by OSR

For our schedule of WDF, WDM, debugging and other seminars visit:
http://www.osr.com/seminars

To unsubscribe, visit the List Server section of OSR Online at
http://www.osronline.com/page.cfm?name=ListServer

It’s not the case that anything which can be queried can also be set, so it
might not be the buffer that which is invalid.

You could set a break and step through assembler to see which is the
offending parameter.

On Tue, Jan 24, 2012 at 1:57 PM, wrote:

> @Tim, I already tried passing pStartAddress and &pStartAddress – both
> return STATUS_INVALID_PARAMETER
>
> @Alex, I am not intercepting process failures, I am terminating process
> creation myself. The shell puts up a simple MessageBox in this case. It
> has nothing to do with WER.
>
>
> —
> NTDEV is sponsored by OSR
>
> For our schedu le of WDF, WDM, debugging and other seminars visit:
> http://www.osr.com/seminars
>
> To unsubscribe, visit the List Server section of OSR Online at
> http://www.osronline.com/page.cfm?name=ListServer
>