Apperantly, GetThreadId is a Vista API. How can I get a thread's id on pre vista systems?
There are a few options:
When you call CreateThread, you get the handle back.
You can call GetCurrentThreadId to get the current thread's ID.
You can use Thread32First/Thread32Next to enumerate threads.
If you can somehow make the thread in question call GetCurrentThreadId and store it somewhere, you could read the result.
If the thread in question enters an alertable wait state frequently, you could send it an APC with QueueUserAPC; the APC handler can then call GetCurrentThreadId and communicate the result back to the caller using whatever method you like.
You can also do this with undocumented NT functions. Using NtQueryInformationThread() on the ThreadBasicInformation class will give you the thread ID in the returned structure. An example can be found in the wine source. However, I'm not sure what versions of windows this is available on - keep in mind these undocumented functions can change at any time, so it's best to test them on the older versions of windows you're interested in, and simply use GetThreadId() where it's available.
Note that these undocumented functions can only be accessed by LoadLibrary() and GetProcAddress() on NTDLL; they have no import library. According to MSDN, declarations for the data structures can be found in Winternl.h, but if not, just define them yourselves based on the ntinternals links above.
Related
I read here that the inverse is possible, but how does one achieve such a thing? I'd hope there's a simple way, similar to calling from a loaded DLL, but my google research comes up with nothing. My only other thought is that one could pass some predefined constants through WriteFile or DeviceIoControl that the driver parses like a switch statement to execute the relevant function; does a more direct method exist?
The question is why would you want to do it? Generally if you have to rely on some mechanism like this, you need to revisit the design of the application/driver that you are writing.
The correct way to do something in context of your user mode application is exactly what you described. You can do a DeviceIoControl call to your driver and the driver validates all the parameters that you have passed, then carries out the operation on behalf of the user mode call.
If for some reason, you need to call into kernel directly, you will have to resort to undocumented methods. There are ways to hook into kernel dispatch table and overwrite one of the dispatch handler to redirect the call to your function. But I hope you never ever ship anything like this to your customer. This is good for learning how the dispatch table works, etc but introduces several security nightmares. Ultimately your software should not be responsible for someone's machine getting hacked.
I'm working on a way to hook any API call to perform some verification on the function. (I'm creating a SandBox)
The first way that I think about, is with register key, and implement our own dll into MicrosoftNT to be able to redirect any defined syscall. https://www.apriorit.com/dev-blog/160-apihooks .
Problem? only work on 32 bit, and if the binarie is loading User32.dll, so it's abig issue.
The second way is to inject a dll into a process? Simple but impossible, most program is defended from those injection, so it's not possible.
The last way that I think was to modify the SSDT to change the function address by mine and redirect to the original by creating a driver. Or by InlineHook and just modify the first byte of each address that I want.
The Problem, only working on 32 bit, because windows add a PatchGuard on the Kernel, so we can't do that.
We can delete de PatchGuard but, anticheat will notice the technique.
For the Sandbox I think it won't be a problem to delete a PatchGuard.
The main problem is for real time analysis, I have no more idea how I can do to hook every API call that I want, on any windows OS. I mean on 32 and 62 bit.
I'm a beginner in this domain I started this week so I'm open to any suggestion.
You say you want to hook every API call for a sandbox but then reference the SSDT? Those are two very different things. Do you want to hook VirtualQuery(Ex) or do you want to hook NtQueryVirtualMemory? From kernel or user mode? Or maybe you're referring to all loaded module exports as well as kernel system services?
WinApi
Iterate all loaded modules as well as installing an event to hook all future modules loaded. For each one you will iterate all exports and apply a hook of your preference which all jump to some handler. This handler should be raw assembly that preserves the CPU state, calls some method that does the logging and filtering, restores CPU state, before finally jumping to the original.
Syscalls
Disable Patchguard and apply hooks to every method in the service table similar to the WinApi method described above. This is definitely not suitable for production for obvious reasons.
Use an instrumentation callback which uses ZwSetInformationProcess to redirect most syscalls to an arbitrary assembly block. You can extract the syscall id here as well as parameters. Universal support is an issue though as it wasn't introduced until W7 iirc and you have a lot of limitations prior to W10.
Map a wrapper module that has a hook for every syscall into each newly loaded process from kernel. These hooks will apply to ntdll and simply invoke an NtDeviceIoControlFile call with the syscall id and arguments, forwarding it to your kernel driver for processing. This is commonly employed by antivirus software to monitor user mode system calls without disrupting Patchguard.
The most approved method would probably be callbacks. You can register process and thread callbacks in kernel, stripping handle access at your leisure. This will give you full control over process and thread access from external processes, and you can add a file minfilter to similarly restrict access to the file system.
As a part of my project, I get an event notification every time a Service is Started or Stopped using the WMI class Win32_Service through an EventSink.
I want to detect the application which had requested "services.exe" to start a particular service.
Till now, I tried Monitoring ALPC calls between any process and "services.exe" and got a Message_ID every time a process communicates (sends/receives) any information to/from "services.exe" using the ALPC Class. I would like to know what these messages are so that I can decode a StartService() or a StopService() procedure.
Is there any way to detect which application starts/stops a service?
The best way to do this, in my opinion, would be from kernel-mode using the PsSetCreateProcessNotifyRoutine/Ex/Ex2 kernel-mode callback.
If you're going to be using PsSetCreateProcessNotifyRoutine, you will receive less information than if you were using the Extended version of the kernel-mode callback (the Ex one). However, you can still query information such as the image file path of the parent process (or the one being created) by using PsLookupProcessByProcessId to get a pointer to the _EPROCESS structure and then relying on SeLocateProcessImageName (undocumented, however it is accessible in WDK by default).
The SeLocateProcessImageName routine will rely internally on that _EPROCESS structure, since information like the path of the process image on-disk is all tracked by the Windows kernel there.
If you're going to be using the Ex version of the kernel-mode callback, then you eliminate the need to do what is mentioned above. The Ex version of the routine is more recent than the non-Ex version.
The routine prototype for the callback routine will be:
VOID
CreateProcessNotifyRoutineEx(
PEPROCESS Process,
HANDLE ProcessId,
PPS_CREATE_NOTIFY_INFO CreateInfo
)
As seen above, you get a pointer to the _PS_CREATE_NOTIFY_INFO structure. You can then access the ImageFileName and CommandLine fields to filter for services.exe (make sure you filter properly to not catch it for a rogue copy - so ensure full path indicates its the real one) and gain more insight into why it was being invoked (if such information is exposed via the command-line... I cannot remember - nonetheless, you can still detect its creation and be aware of who spawned it).
To determine the parent who was responsible for the process creation operation of services.exe (e.g. if it relied on the Service Manager which in turn resulted in the spawning of it), you can rely on the ParentProcessId field (under the _PS_CREATE_NOTIFY_INFO structure as well). The SeLocateProcessImageName trick will work perfectly here.
SeLocateProcessImageName is undocumented so here is the routine prototype:
NTSTATUS
NTAPI
SeLocateProcessImageName(
PEPROCESS Process,
PUNICODE_STRING *ImageName
);
At-least with the latest Windows 10 WDK, it's already available by default. If you wanted to though, you can use a dynamic import with MmGetSystemRoutineAddress.
Resources:
https://learn.microsoft.com/en-us/windows-hardware/drivers/ddi/content/ntddk/nf-ntddk-pssetcreateprocessnotifyroutine
https://learn.microsoft.com/en-us/windows-hardware/drivers/ddi/content/ntddk/nf-ntddk-pssetcreateprocessnotifyroutineex
https://learn.microsoft.com/en-us/windows-hardware/drivers/ddi/content/ntddk/nf-ntddk-pssetcreateprocessnotifyroutineex2
https://learn.microsoft.com/en-us/windows-hardware/drivers/ddi/content/wdm/nf-wdm-mmgetsystemroutineaddress
https://learn.microsoft.com/en-us/windows-hardware/drivers/ddi/content/ntifs/nf-ntifs-pslookupprocessbyprocessid
https://learn.microsoft.com/en-us/windows-hardware/drivers/ddi/content/ntddk/ns-ntddk-_ps_create_notify_info
I am trying to override the singe instance limit of an application for which I don't have the source. I know that the app is using the good ol' trick of using CreateMutex to determine whether there is another instance running. (If the mutex is created successfully it proceeds, if getlasterror says that the mutex has been created it quits immediately). I found that through sniffing the Win32 api calls.
I thought using Detours would do the trick, but it doesn't quite work out. I am intercepting CreateMutexW, but for some reason, it doesn't catch the first four calls to it. (Again I know what these calls are by sniffing win32 calls and looking at the name of the mutexes). I do get the fifth one intercepted, but the one I actually want to intercept is the first one.
I am using detours through the sample application withdll. I wonder if the problem is that detours is kicking in too late or because of some kind of protection these calls may have. Is detours the best approach? Perhaps using something else may be a better idea?
There might be several reasons for the situation you describe. Here are the most probable of them:
The CreateMutexW call you need to catch occurs within the DllMain
method of one of the DLLs that are imported by the process, and you
are using the DetoursCreateProcessWithDll() function to inject your
code. Detours injects your DLL by placing it at the end of the
process executable import list, and hence all the DLLs that are
imported by the process would be loaded and initialized within the
process prior to yours. In order to overcome this, try using
CreateProcess(CREATE_SUSPENDED) and CreateRemoteThread()-based
injection, although this method raises its own challenges.
The API that is used in the first call is different. Have you tried
overriding CreateMutexExW? Are you sure ANSI methods call Unicode
ones?
Hope this helps.
Is it possible to get current locale of a thread living inside another Windows process? Is there a utility that shows this or maybe a Win32 API call?
The locale is stored in the TEB, so you would have to be able to open the process with PROCESS_VM_READ rights and the thread with THREAD_QUERY_INFORMATION and then call OpenThread()+NtQueryInformationThread(ThreadBasicInformation) and then get the TEB address in THREAD_BASIC_INFORMATION and read it with ReadProcessMemory().
All of this is undocumented and could change at any time, you also need to handle WOW64 etc...
There's no API call for this. Assuming that you can't modify the target app to provide the information on demand, the only solution I can see is a global hook. This allows you to inject your code into the thread in question.