I am trying to hook to the function NtWriteFile( ) so that I can log
some extra data. When I hooked to ZwWQriteFile things worked, however,
the same doesn’t work for NtWriteFile( ). I read in OSR articles that
ultimately the calls go to th same memory space. I get NULL when I try
fetching the address.
#include <ntddk.h>
extern NTSYSAPI NTSTATUS NTAPI NtWriteFile(
IN HANDLE FileHandle,
IN HANDLE Event OPTIONAL,
IN PIO_APC_ROUTINE ApcRoutine OPTIONAL,
IN PVOID ApcContext OPTIONAL,
OUT PIO_STATUS_BLOCK IoStatusBlock,
IN PVOID Buffer,
IN ULONG Length,
IN PLARGE_INTEGER ByteOffset OPTIONAL,
IN PULONG Key OPTIONAL );
#define DEBUG
typedef unsigned long DWORD, PDWORD;
typedef unsigned char BYTE, PBYTE;
/
* the SDT is recovered
/
#pragma pack(1)
typedef struct ServiceDescriptorEntry {
PDWORD ServiceTable;
PDWORD CounterTableBase;
DWORD ServiceLimit;
PBYTE ArgumentTable;
} SDT;
#pragma pack()
__declspec(dllimport) SDT KeServiceDescriptorTable;
/
* prototype of the API hook
/
typedef NTSYSAPI NTSTATUS (NTWRITEFILE)(
IN HANDLE FileHandle,
IN HANDLE Event OPTIONAL,
IN PIO_APC_ROUTINE ApcRoutine OPTIONAL,
IN PVOID ApcContext OPTIONAL,
OUT PIO_STATUS_BLOCK IoStatusBlock,
IN PVOID Buffer,
IN ULONG Length,
IN PLARGE_INTEGER ByteOffset OPTIONAL,
IN PULONG Key OPTIONAL
);
/
* one makes point OldNtWriteFile towards the function in memory
/
NTWRITEFILE OldNtWriteFile;
extern NTWRITEFILE OldNtWriteFile;
// macro which makes it possible to reach the address of the function
“name” in the SDT
// explanation: the DWORD which follows the first byte of the function
the API one is its callnumber (rip of _ root _)
#define SYSTEMSERVICE(_name)
KeServiceDescriptorTable.ServiceTable[(DWORD ) ((unsigned char
)_name + 1)]
#define INTERRUPT_OFF _asm{cli} // decontaminate the interruptions
systems for step
#define INTERRUPT_ON _asm{sti} // reactivate the interruptions
/
* prototypes of our functions
/
NTSTATUS DriverEntry(PDRIVER_OBJECT, PUNICODE_STRING); // main() of the driver
void unload_driver(IN PDRIVER_OBJECT);
void hook(void);
void unhook();
/
* code
/
NTSTATUS NewNtWriteFile(IN HANDLE FileHandle,
IN HANDLE Event OPTIONAL,
IN PIO_APC_ROUTINE ApcRoutine OPTIONAL,
IN PVOID ApcContext OPTIONAL,
OUT PIO_STATUS_BLOCK IoStatusBlock,
IN PVOID Buffer,
IN ULONG Length,
IN PLARGE_INTEGER ByteOffset OPTIONAL,
IN PULONG Key OPTIONAL
) {
NTSTATUS ntS = (NTSTATUS) NULL;
DbgPrint(“\nNtWriteFile called…”);
if(Buffer)
KdPrint((“\nBuffer = %s”,Buffer));
// the true function is called
ntS = ((NTWRITEFILE)(OldNtWriteFile)) (
FileHandle,Event,ApcRoutine,ApcContext,IoStatusBlock,
Buffer,Length,ByteOffset,Key);
return(ntS);
}
void hook(void) {
INTERRUPT_OFF;
// exchange addresses of the functions in the SDT
if(OldNtWriteFile = (NTWRITEFILE) (SYSTEMSERVICE(NtWriteFile)))
(NTWRITEFILE) (SYSTEMSERVICE(NtWriteFile)) = NewNtWriteFile;
INTERRUPT_ON;
}
void unhook() {
INTERRUPT_OFF;
// one restores the good address of ZeWriteFile in the SDT
if(OldNtWriteFile)
(NTWRITEFILE) (SYSTEMSERVICE(NtWriteFile)) = OldNtWriteFile;
INTERRUPT_ON;
}
void unload_driver(IN PDRIVER_OBJECT DriverObject) {
DbgPrint(“unhooking API …\n”);
unhook();
}
NTSTATUS DriverEntry(PDRIVER_OBJECT driverObject, PUNICODE_STRING
RegistryPath) {
driverObject->DriverUnload = unload_driver;
DbgPrint(“hooking API …\n”);
hook();
return(STATUS_SUCCESS);
}
/
* the end
/
WINDBG analysis
=============
Fatal System Error: 0x0000001e
(0xC0000005,0xEB9DE300,0x00000000,0x7E009704)
Break instruction exception - code 80000003 (first chance)
A fatal system error has occurred.
Debugger entered on first try; Bugcheck callbacks have not been invoked.
A fatal system error has occurred.
The call to LoadLibrary(ext) failed, Win32 error 8
“Not enough storage is available to process this command.”
Please check your debugger configuration and/or network access.
********************************************************************
Bugcheck Analysis
*******************************************************************************
Bugcheck code 0000001E
Arguments c0000005 eb9de300 00000000 7e009704
ChildEBP RetAddr Args to Child
eb837370 8050a068 00000003 804e7808 00000000
nt!PsSetCreateProcessNotifyRoutine+0xa
eb8376f8 8053049c 00000000 c0000005 eb9de300 nt!KeRemoveQueue+0x18
eb837ddc 80543b62 804f6ada 00000001 00000000 nt!PsImpersonateClient+0x50
00000000 00000000 00000000 00000000 00000000 nt!KiTrap0D+0x3e
nt!PsSetCreateProcessNotifyRoutine+0xa:
80530e70 cc int 3
kd> r eax
eax=00000003
kd> u
nt!PsSetCreateProcessNotifyRoutine+0xa:
80530e70 cc int 3
80530e71 c20400 ret 0x4
80530e74 55 push ebp
80530e75 8bec mov ebp,esp
80530e77 6aff push 0xff
80530e79 6870794e80 push 0x804e7970
80530e7e 682cac5380 push 0x8053ac2c
80530e83 64a100000000 mov eax,fs:[00000000]
kd> u eb9de300
rootkit+0x300:
eb9de300 8b1496 mov edx,[esi+edx4]
eb9de303 891520e49deb mov [rootkit+0x420 (eb9de420)],edx
eb9de309 8b4901 mov ecx,[ecx+0x1]
eb9de30c 8b00 mov eax,[eax]
eb9de30e c70488a5e29deb mov dword ptr [eax+ecx4],0xeb9de2a5
eb9de315 fb sti
eb9de316 5e pop esi
eb9de317 c3 ret
kd> d esi+edx4
c0000005 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 …
c0000015 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 …
c0000025 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 …
c0000035 00 00 00 00 00 00 00 00-00 00 00 67 a0 5e 02 67 …g.^.g
c0000045 b0 5e 02 67 c0 5e 02 67-d0 5e 02 67 e0 5e 02 67 .^.g.^.g.^.g.^.g
c0000055 f0 5e 02 67 00 5f 02 67-10 5f 02 67 20 5f 02 67 .^.g..g..g .g
c0000065 30 5f 02 67 40 5f 02 67-50 5f 02 67 60 5f 02 67 xxxxx@.gP_.g`.g
c0000075 70 5f 02 67 80 5f 02 67-90 5f 02 67 a0 5f 02 67 p.g..g..g._.g
kd> r edx
edx=00000000
kd> r eax
eax=00000003
kd> .reload /f rootkit.sys
kd> u eb9de300
rootkit!hook+0x12 [c:\drv\hooker\hooker.c @ 116]:
eb9de300 8b1496 mov edx,[esi+edx4]
eb9de303 891520e49deb mov [rootkit!OldNtWriteFile (eb9de420)],edx
eb9de309 8b4901 mov ecx,[ecx+0x1]
eb9de30c 8b00 mov eax,[eax]
eb9de30e c70488a5e29deb mov dword ptr [eax+ecx4],0xeb9de2a5
eb9de315 fb sti
eb9de316 5e pop esi
eb9de317 c3 ret
kd> u eb9de2a5
rootkit!NewNtWriteFile [c:\drv\hooker\hooker.c @ 99]:
eb9de2a5 55 push ebp
eb9de2a6 8bec mov ebp,esp
eb9de2a8 6880e29deb push 0xeb9de280
eb9de2ad e8dc000000 call rootkit!DbgPrint (eb9de38e)
eb9de2b2 837d1c00 cmp dword ptr [ebp+0x1c],0x0
eb9de2b6 59 pop ecx
eb9de2b7 740f jz rootkit!NewNtWriteFile+0x23 (eb9de2c8)
eb9de2b9 ff751c push dword ptr [ebp+0x1c]
kd> x rootkit!
eb9de3a0 rootkit!_imp__KeServiceDescriptorTable = struct ServiceDescriptorEntry
eb9de420 rootkit!OldNtWriteFile = 0x00000000
eb9de2a5 rootkit!NewNtWriteFile (void *, void *, *, void *,
struct _IO_STATUS_BLOCK *, void , unsigned long, union _LARGE_INTEGER
, unsigned long *)
eb9de347 rootkit!unload_driver (struct _DRIVER_OBJECT *)
eb9de318 rootkit!unhook (void)
eb9de2ee rootkit!hook (void)
eb9de36b rootkit!DriverEntry (struct _DRIVER_OBJECT *, struct _UNICODE_STRING *)
eb9de440 rootkit!_IMPORT_DESCRIPTOR_ntoskrnl =
eb9de38e rootkit!DbgPrint =
eb9de3a4 rootkit!_imp _NtWriteFile =
eb9de3a8 rootkit!imp DbgPrint =
eb9de3ac rootkit!ntoskrnl_NULL_THUNK_DATA =
eb9de454 rootkit!_NULL_IMPORT_DESCRIPTOR =
kd> .reboot
I know I am messing up somewhere. When I try importing the function by
__declspec(dllimport) NTSTATUS NtWriteFile;
it gives a compilation error. I am linking with NTDLL
here is my sources file
TARGETNAME=rootkit
TARGETPATH=obj
TARGETTYPE=DRIVER
TARGETLIBS=$(DDK_LIB_PATH)\ntdll.lib
SOURCES=hooker.c
What is going wrong?
PS:- I know this is not going to work on multi processor systems.
I downloaded this stuff from a site, just to learn.
–
- Developer</ntddk.h>