Does anyone have an idea what is the structure of the DriverSection pointer in the x64 bit version of win7. In 32 bit I used the following:
typedef struct _KLDR_DATA_TABLE_ENTRY {
LIST_ENTRY InLoadOrderLinks;
PVOID ExceptionTable;
ULONG ExceptionTableSize;
//ULONG padding1;
PVOID GpValue;
PVOID NonPagedDebugInfo;
PVOID DllBase;
PVOID EntryPoint;
ULONG SizeOfImage;
UNICODE_STRING FullDllName;
UNICODE_STRING BaseDllName;
ULONG Flags;
USHORT LoadCount;
USHORT __Unused5;
PVOID SectionPointer;
ULONG CheckSum;
//ULONG Padding2;
PVOID LoadedImports;
PVOID PatchInformation;
} KLDR_DATA_TABLE_ENTRY, *PKLDR_DATA_TABLE_ENTRY;
And everything was working but on x64 it is crashing when trying to dereference the LIST_ENTRY. Any pointers/tips would be greatly appreciated
And everything was working but on x64 it is crashing when trying to dereference the LIST_ENTRY. Any pointers/tips would be greatly appreciated
If you can hook up a kernel debugger, you can verify whether or not the DriverSection object matches your definition. To do this, pick a driver you wish to debug - I tend to use a simple one I have. Load its symbols by fixing the symbol path to include its pdb, then break into windbg or kd and type:
.reload
To reload the symbols. Then you can load the driver with:
sc start drivername
having created its service assuming it is a legacy driver. Type:
bu drivername!DriverEntry
to set a breakpoint on the DriverEntry for this module. The difference between bp and bu is that bu breakpoints are evaluated and set on module load. Currently, of course, DriverEntry won't be called, but if we reload the driver it will:
sc stop drivername
sc start drivername
Now your breakpoint should be hit and rcx will contain the DRIVER_OBJECT structure, since it is a pointer argument and pointer/integer arguments are passed in rcx,rdx,r8,r9 according to the Windows ABI. So, you can print out the driver object structure with:
dt _DRIVER_OBJECT (address of rcx)
Which will give you a pointer to the driver section. Then, type:
dt _LDR_DATA_TABLE_ENTRY (driver section object pointer)
This should give you your driver section object. _LDR_DATA_TABLE_ENTRY is actually present in the Windows symbols, so this will work.
Using the debugger, you should be able to dereference the LIST_ENTRY pointers (.flink and .blink) successfully (try dpps on the address of the _LDR_DATA_TABLE_ENTRYstructure, for example). If you do it successfully, one of those addresses will resolve tont!PsLoadedModuleList`.
What I'm trying to say is that in a roundabout way, is that:
Either there is a bug in your code somewhere, or
You've hit upon a synchronisation issue. Remember, this structure is supposed to be opaque and we're not supposed to be modifying it in any way. It's also liable to change on us, and we don't know where the lock for synchronising access to it is.
If you are certain 1 is not the case, it is likely 2 is. Luckily, Microsoft actually provided a function to get the information from these structures called AuxKlibQueryModuleInformation(). You do need to add an extra library to your driver, but that's not the end of the world. Include Aux_klib.h. There's also a code sample on the MSDN page showing how to use it - it's pretty straightforward.
Related
I'm trying to invoke ZwCreateThread(). But since it is a undocumented function I don't know how to do it. The 3rd, 5th, 6th and 7th argument of the function?
How to initialize those structures to use them in ZwCreateThread()?
The question is a loaded one
I don't fully agree with the assessment by Basile in the comments that - if something is undocumented - it should not be used. But it requires extra caution for sure.
There is also a relevant bit of information missing from your question: kernel or user mode?!
Resources
I cannot answer regarding fasm, but if you know how to read C function prototypes and make those work for you, you can use one of the following resources to find the prototypes:
undocumented.ntinternals.net
the phnt offspring of the Process Hacker (mind the license!)
ReactOS tries to be a fairly faithful functional clone of Windows (the target version has been adjusted over the years)
The desired information is part of the NDK inside psfuncs.h
The Windows Research Kernel and its documentation have leaked and were available in several shapes and forms all over the web (IIRC this was based on Windows 2003 Server)
Microsoft documents some functions and structs as part of their Windows Driver Kits (WDKs, formerly Device Driver Kits [DDKs])
winternl.h is one of the headers
"Windows NT/2000 Native API Reference" by Gary Nebbett
"Undocumented Windows 2000 Secrets" by Sven B. Schreiber; IIRC the author made this available on his website as several PDFs some years ago
"Undocumented Windows NT" by Prasad Dabak, Sandeep Phadke, and Milind Borate
The syscall tables (j00ru/windows-syscalls) as a reference of sorts for availability of functions from user mode
For structs as found from the PDBs (debugging symbols) made available by Microsoft: Vergilius Project
Yet again for structs, but more useful for user mode: Terminus Project by ReWolf
Windows NT, Secret APIs and the Consequences by Bruce Ediger
To a lesser extent the "Windows Internals" books from Microsoft Press
A code search or GitHub/GitLab/etc search for some of your desired function names or related functions
E.g. in the source code to several debuggers or other very low-level tools, to binary instrumentation frameworks etc ...
Books and resources for related topics such as sandboxes, rootkits, bootkits, malware ...
Useful knowledge
ZwCreateThread and NtCreateThread are identical in user mode (you can even verify this by using dumpbin on ntdll.dll and checking the RVA of the two exports. This is true for most (if not all) Zw* and Nt* functions
This means their prototype is identical!
In kernel mode they differ, one of them does more checking and is supposed to receive calls via the SSDT from user mode, the other is supposed to be called from kernel mode.
The identical prototype notion also holds true here
... let's try to answer it
Up front: if what you are trying to achieve is to create a user mode thread, in all likelihood RtlCreateUserThread() is more likely what you are looking for (for reference phnt)!
The prototype for ZwCreateThread is as follows:
// source: ntzwapi.h from https://github.com/processhacker/phnt
NTSYSCALLAPI
NTSTATUS
NTAPI
ZwCreateThread(
_Out_ PHANDLE ThreadHandle,
_In_ ACCESS_MASK DesiredAccess,
_In_opt_ POBJECT_ATTRIBUTES ObjectAttributes,
_In_ HANDLE ProcessHandle,
_Out_ PCLIENT_ID ClientId,
_In_ PCONTEXT ThreadContext,
_In_ PINITIAL_TEB InitialTeb,
_In_ BOOLEAN CreateSuspended
);
// for reference, Nebbett gives the prototype as:
NTSYSAPI
NTSTATUS
NTAPI
ZwCreateThread(
OUT PHANDLE ThreadHandle,
IN ACCESS_MASK DesiredAccess,
IN POBJECT_ATTRIBUTES ObjectAttributes,
IN HANDLE ProcessHandle,
OUT PCLIENT_ID ClientId,
IN PCONTEXT ThreadContext,
IN PUSER_STACK UserStack,
IN BOOLEAN CreateSuspended
);
You probably noticed the difference in the parameter 7 (starting at 1) immediately: PUSER_STACK vs. PINITIAL_TEB. TEB stands for Thread Environment Block and is the extension of the TIB (IIRC: Thread Information Block). Compare Nebbett's take on the USER_STACK struct:
typedef struct _USER_STACK {
PVOID FixedStackBase;
PVOID FixedStackLimit;
PVOID ExpandableStackBase;
PVOID ExpandableStackLimit;
PVOID ExpandableStackBottom;
} USER_STACK, *PUSER_STACK;
... with the INITIAL_TEB from undocumented.ntinternals.net you will notice they're the same (also for reference phnt). Nebbett took a guess at the name at the time of his writing. But this right there is the reason why Basile cautions not to use undocumented functions. You have to put in your own research and can't blindly rely on others' research. Also you should apply a very defensive coding style when using those functions.
Either way, Nebbett lists CreateThread() and CreateRemoteThread() as related Windows APIs. The latter is obviously a superset of the former and ZwCreateThread() uses ProcessHandle for the target process. It's always worthwhile looking for and looking at related Windows APIs.
3rd parameter: _In_opt_ POBJECT_ATTRIBUTES ObjectAttributes
The _In_opt (see SAL) tells you, that you may pass a NULL pointer here. But if you insist on passing the object attributes and know what to put in them: InitializeObjectAttributes() - a macro - is there to help.
5th parameter: _Out_ PCLIENT_ID ClientId
The _Out_ tells you that you supply the space for this info to be filled. The CLIENT_ID combines process and thread ID into a struct. The struct can be found in the headers of the WDKs/DDKs (e.g. wdm.h or ntddk.h) and looks like this in C:
typedef struct _CLIENT_ID {
HANDLE UniqueProcess;
HANDLE UniqueThread;
} CLIENT_ID;
6th parameter: _In_ PCONTEXT ThreadContext
The CONTEXT is indeed a documented struct and used in official APIs such as SetThreadContext(). Its definition depends on the target architecture, but can be found in official MS headers.
This struct also plays a big role in exception handling, e.g. when resuming execution after an exception.
For ZwCreateThread() this defines the initial state of the thread, especially the initial address of the instruction pointer and the initial CPU register states (which explains why it depends on the target architecture).
7th parameter: _In_ PINITIAL_TEB InitialTeb
By now you should have an idea that you need to supply the space and initial values for this struct as well.
Conclusion
And this complicated "having to know and fill in all details" explains why in all likelihood you want to use:
typedef NTSTATUS (NTAPI *PUSER_THREAD_START_ROUTINE)(
_In_ PVOID ThreadParameter
);
NTSYSAPI
NTSTATUS
NTAPI
RtlCreateUserThread(
_In_ HANDLE Process,
_In_opt_ PSECURITY_DESCRIPTOR ThreadSecurityDescriptor,
_In_ BOOLEAN CreateSuspended,
_In_opt_ ULONG ZeroBits,
_In_opt_ SIZE_T MaximumStackSize,
_In_opt_ SIZE_T CommittedStackSize,
_In_ PUSER_THREAD_START_ROUTINE StartAddress,
_In_opt_ PVOID Parameter,
_Out_opt_ PHANDLE Thread,
_Out_opt_ PCLIENT_ID ClientId
);
// again taken from phnt
This is much closer to CreateRemoteThreadEx and similar APIs. You don't have to care about the initial CONTEXT and don't have to deal with OBJECT_ATTRIBUTES or INITIAL_TEB.
There's a bug in a driver within our company's codebase that's been there for years.
Basically we make calls to the driver via ioctls. The data passed between userspace and driver space is stored in a struct, and the pointer to the data is fed into the ioctl. The driver is responsible to dereference the pointer by using copy_from_user(). But this code hasn't been doing that for years, instead just dereferencing the userspace pointer. And so far (that I know of) it hasn't caused any issues until now.
I'm wondering how this code hasn't caused any problems for so long? In what case will dereferencing a pointer in kernel space straight from userspace not cause a problem?
In userspace
struct InfoToDriver_t data;
data.cmd = DRV_SET_THE_CLOCK;
data.speed = 1000;
ioctl(driverFd, DEVICE_XX_DRIVER_MODIFY, &data);
In the driver
device_xx_driver_ioctl_handler (struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg)
{
struct InfoToDriver_t *user_data;
switch(cmd)
{
case DEVICE_XX_DRIVER_MODIFY:
// what we've been doing for years, BAD
// But somehow never caused a kernel oops until now
user_data = (InfoToDriver_t *)arg;
if (user_data->cmd == DRV_SET_THE_CLOCK)
{ .... }
// what we're supposed to do
copy_from_user(user_data, (void *)arg, sizeof(InfoToDriver_t));
if (user_data->cmd == DRV_SET_THE_CLOCK)
{ ... }
A possible answer is, this depends on the architecture. As you have seen, on a sane architecture (such as x86 or x86-64) simply dereferencing __user pointers just works. But Linux pretends to support every possible architecture, there are architectures where simple dereference does not work. Otherwise copy_to/from_user won't existed.
Another reason for copy_to/from_user is possibility that usermode side modifies its memory simultaneously with the kernel side (in another thread). You cannot assume that the content of usermode memory is frozen while accessing it from kernel. Rougue usermode code can use this to attack the kernel. For example, you can probe the pointer to output data before executing the work, but when you get to copy the result back to usermode, this pointer is already invalid. Oops. The copy_to_user API ensures (should ensure) that the kernel won't crash during the copy, instead the guilty application will be killed.
A safer approach is to copy the whole usermode data structure into kernel (aka 'capture'), check this copy for consistency.
The bottom line... if this driver is proven to work well on certain architecture, and there are no plans to port it, there's no urgency to change it. But check carefully robustness of the kernel code, if capture of the usermode data is needed, or problem may arise during copying from usermode.
After quite a bit of googling and some hints given here, I finally managed to find a layout of the FS segment (used by windows to store TIB data). Of particular interest to me is the ArbitraryUserPointer member provided in the PSDK:
typedef struct _NT_TIB {
struct _EXCEPTION_REGISTRATION_RECORD *ExceptionList;
PVOID StackBase;
PVOID StackLimit;
PVOID SubSystemTib;
union {
PVOID FiberData;
DWORD Version;
};
PVOID ArbitraryUserPointer;
struct _NT_TIB *Self;
} NT_TIB;
How safe exactly is it to use this variable (under Vista and above)? and does it still exist on x64?
Secondary to that is the access of this variable. I'm using MSVC, and as such I
have access to the __readfsdword & __readgsqword intrinsics, however, MSDN for some reason marks these as privileged instructions:
These intrinsics are only available in kernel mode, and the routines are only available as intrinsics.
They are of course not kernel only, but why are they marked as such, just incorrect documentation? (my offline VS 2008 docs don't have this clause).
Finally, is it safe to access ArbitraryUserPointer directly via a single __readfsdword(0x14) or is it preferred to use it via the linear TIB address? (which will still require a read from FS).
ArbitraryUserPointer is an internal field not for general use. The operating system uses it internally, and if you overwrite it, you will corrupt stuff. I concede that it has a very poor name.
In case you're still for an answer, I've had the same problem too and posted my question, similar to yours:
Thread-local storage in kernel mode?
I need a TLS-equivalent in the kernel-mode driver. To be exact, I have a deep function call tree which originates at some point (driver's dispatch routine for instance), and I need to pass the context information.
In my specific case the catch is that I don't need a persistent storage, I just need a thread-specific placeholder for something for a single top-level function call. Hence I decided to use an arbitrary entry in the TLS array for the function call, and after it's done - restore its original value.
You get the TLS array by the following:
DWORD* get_Tls()
{
return (DWORD*) (__readfsdword(0x18) + 0xe10);
}
BTW I have no idea why the TIB is usually accessed by reading the contents of fs:[0x18]. It's just pointed by the fs selector. But this is how all the MS's code accesses it, hence I decided to do this as well.
Next, you choose an arbitrary TLS index, say 0.
const DWORD g_dwMyTlsIndex = 0;
void MyTopLevelFunc()
{
// prolog
DWORD dwOrgVal = get_Tls()[g_dwMyTlsIndex];
get_Tls()[g_dwMyTlsIndex] = dwMyContextValue;
DoSomething();
// epilog
get_Tls()[g_dwMyTlsIndex] = dwOrgVal;
}
void DoSomething()
{
DWORD dwMyContext = get_Tls()[g_dwMyTlsIndex];
}
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
We don’t allow questions seeking recommendations for books, tools, software libraries, and more. You can edit the question so it can be answered with facts and citations.
Closed 8 years ago.
Improve this question
I'd like to try writing my own minimal NT subsystem on Windows 7 for purely educational purposes -- something like a bare-bones equivalent of the posix.exe in Microsoft's Subsystem for Unix-based Applications.
But I can't seem to find any public documentation on this topic. What API does a subsystem need to implement? How does it get registered with Windows? How does the subsystem image need to be built (what flags need to be set in the PE header, etc.)?
I'd most like to find a book or web site with an overview of the entire subject, or even the source code for a "hello world" NT subsystem that someone else has written. But anything at all would be appreciated if you can point me in the right direction here...
Here are the major components of a subsystem:
User-mode server. The server creates a (A)LPC port and listens for and handles client requests.
User-mode client DLL. In the DLL_INIT_ROUTINE, you can connect to the port set up by the server. This DLL will expose your subsystem's API, and some functions will require communication with the server.
Kernel-mode support driver (you might not need this).
You will want to store process or thread state in either your server or driver. If you're storing it in the server, you might need something like NtRegisterThreadTerminatePort to ensure you get to clean up when a process or thread exits. If you're using a driver, you need PsSetCreateProcessNotifyRoutine.
And lastly, if you're on XP and below, you can add new system calls. You can do this by calling KeAddSystemServiceTable. To invoke the system calls from user-mode, you need to create stubs like this (for x86):
; XyzCreateFooBar(__out PHANDLE FooBarHandle, __in ACCESS_MASK DesiredAccess, ...)
mov eax, SYSTEM_CALL_NUMBER
mov edx, 0x7ffe0300
call [edx]
retn 4
On Vista and above you can no longer add new system service tables because there is only room for two: the kernel's system calls and win32k's system calls.
After a bit of Googling I found this: http://winntposix.sourceforge.net/. I think it's very similar to what you're looking for, and uses a lot of the things I have mentioned.
I'm also obsessed with the native API. :)
And I'm glad to say that it's nowhere near as dangerous or as undocumented as some people make it seem. :]
There's no source code for "Hello, world" because the native API doesn't interact so easily with the console, since it's part of the Win32 subsystem and requires client/server communication with ports. If you need to write a console application, you need to communicate directly with CSRSS, whose message formats are undocumented (although some of its format can be found in ReactOS's source -- it would do you many benefits if you get familiar with ReactOS).
I'll post an example here soon that you might find interesting; for now, do be aware that your only option ever is to link with NTDLL.dll, and that, for that, you need the Driver Development Kit (since you need the lib file).
Update: Check this out!
(I have a feeling no one else will post something quite as rebellious as this. Showing GUI with the native API?! I must be crazy!)
#include <Windows.h>
typedef DWORD NTSTATUS;
//These are from ReactOS
typedef enum _HARDERROR_RESPONSE_OPTION
{
OptionAbortRetryIgnore,
OptionOk,
OptionOkCancel,
OptionRetryCancel,
OptionYesNo,
OptionYesNoCancel,
OptionShutdownSystem
} HARDERROR_RESPONSE_OPTION, *PHARDERROR_RESPONSE_OPTION;
typedef enum _HARDERROR_RESPONSE
{
ResponseReturnToCaller,
ResponseNotHandled,
ResponseAbort,
ResponseCancel,
ResponseIgnore,
ResponseNo,
ResponseOk,
ResponseRetry,
ResponseYes,
ResponseTryAgain,
ResponseContinue
} HARDERROR_RESPONSE, *PHARDERROR_RESPONSE;
typedef struct _UNICODE_STRING {
USHORT Length;
USHORT MaximumLength;
PWSTR Buffer;
} UNICODE_STRING, *PUNICODE_STRING;
//You'll need to link to NTDLL.lib
//which you can get from the Windows 2003 DDK or any later WDK
NTSYSAPI VOID NTAPI RtlInitUnicodeString(IN OUT PUNICODE_STRING DestinationString,
IN PCWSTR SourceString);
NTSYSAPI NTSTATUS NTAPI NtRaiseHardError(IN NTSTATUS ErrorStatus,
IN ULONG NumberOfParameters, IN ULONG UnicodeStringParameterMask,
IN PULONG_PTR Parameters,
IN HARDERROR_RESPONSE_OPTION ValidResponseOptions,
OUT PHARDERROR_RESPONSE Response);
#define STATUS_SERVICE_NOTIFICATION_2 0x50000018
int main()
{
HARDERROR_RESPONSE response;
ULONG_PTR items[4] = {0};
UNICODE_STRING text, title;
RtlInitUnicodeString(&text,
L"Hello, NT!\r\nDo you like this?\r\n"
L"This is just about as pretty as the GUI will get.\r\n"
L"This message will self-destruct in 5 seconds...");
RtlInitUnicodeString(&title, L"Native Message Box!");
items[0] = (ULONG_PTR)&text;
items[1] = (ULONG_PTR)&title;
items[2] = (ULONG_PTR)OptionYesNo;
items[3] = (ULONG_PTR)5000;
NtRaiseHardError(STATUS_SERVICE_NOTIFICATION_2, ARRAYSIZE(items),
0x1 | 0x2 /*First two parameters are UNICODE_STRINGs*/, items,
OptionOk /*This is ignored, since we have a custom message box.*/,
&response);
return 0;
}
If you have any questions, feel free to ask! I'm not scared of the native API! :)
Edit 2:
If you're trying to make your own DLL version of Kernel32 and have it load like Kernel32 does with every process (hence a new subsystem), I just wanted to let you know that I don't think it's possible. It's rather similar to this question that I asked a couple of days ago, and it seems that you can't extend the NT PE Loader to know about new subsystems, so I don't think it'll be possible.
Is there a simple way to hook registry access of a process that my code executes? I know about SetWindowsHookEx and friends, but its just too complex... I still have hopes that there is a way as simple as LD_PRELOAD on Unix...
Read up on the theory of DLL Injection here: http://en.wikipedia.org/wiki/DLL_injection
However, I will supply you with a DLL Injection snippet here: http://www.dreamincode.net/code/snippet407.htm
It's pretty easy to do these types of things once you're in the memory of an external application, upon injection, you might as well be a part of the process.
There's something called detouring, which I believe is what you're looking for, it simply hooks a function, and when that process calls it, it executes your own function instead. (To ensure that it doesn't crash, call the function at the end of your function)
So if you were wanting to write your own function over CreateRegKeyEx
(http://msdn.microsoft.com/en-us/library/ms724844%28v=vs.85%29.aspx)
It might look something like this:
LONG WINAPI myRegCreateKeyEx(HKEY hKey, LPCTSTR lpSubKey, DWORD Reserved, LPTSTR lpClass, DWORD dwOptions, REGSAM samDesired, LPSECURITY_ATTRIBUTES lpSecurityAttributes, PHKEY phkResult, LPDWORD lpdwDisposition)
{
//check for suspicious keys being made via the parameters
RegCreateKeyEx(hKey, lpSubKey, Reserved, lpClass, dwOptions, samDesired, lpSecurityAttributes, phkResult, lpdwDisposition);
}
You can get a very well written detour library called DetourXS here: http://www.gamedeception.net/threads/10649-DetourXS
Here is his example code of how to establish a detour using it:
#include <detourxs.h>
typedef DWORD (WINAPI* tGetTickCount)(void);
tGetTickCount oGetTickCount;
DWORD WINAPI hGetTickCount(void)
{
printf("GetTickCount hooked!");
return oGetTickCount();
}
// To create the detour
oGetTickCount = (tGetTickCount) DetourCreate("kernel32.dll", "GetTickCount", hGetTickCount, DETOUR_TYPE_JMP);
// ...Or an address
oGetTickCount = (tGetTickCount) DetourCreate(0x00000000, hGetTickCount, DETOUR_TYPE_JMP);
// ...You can also specify the detour len
oGetTickCount = (tGetTickCount) DetourCreate(0x00000000, hGetTickCount, DETOUR_TYPE_JMP, 5);
// To remove the detour
DetourRemove(oGetTickCount);
And if you can't tell, that snippet is hooking GetTickCount() and whenever the function is called, he writes "GetTickCount hooked!" -- then he executes the function GetTickCount is it was intended.
Sorry for being so scattered with info, but I hope this helps. :)
-- I realize this is an old question. --
Most winapi calls generate symbol table entries for inter modular calls, this makes it pretty simple to hook them, all you need to do is overwrite the IAT addresses. Using something such as MSDetours, it can be done safely in a few lines of code. MSDetours also provides the tools to inject a custom dll into the target process so you can do the hooking
SetWindowsHookEx won't help at all - it provides different functionality.
Check if https://web.archive.org/web/20080212040635/http://www.codeproject.com/KB/system/RegMon.aspx helps. SysInternals' RegMon uses a kernel-mode driver which is very complicated way.
Update: Our company offers CallbackRegistry product, that lets you track registry operations without hassle. And BTW we offer free non-commercial licenses upon request (subject to approval on case by case basis).