NtWriteFile

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+edx
4]
eb9de303 891520e49deb mov [rootkit+0x420 (eb9de420)],edx
eb9de309 8b4901 mov ecx,[ecx+0x1]
eb9de30c 8b00 mov eax,[eax]
eb9de30e c70488a5e29deb mov dword ptr [eax+ecx
4],0xeb9de2a5
eb9de315 fb sti
eb9de316 5e pop esi
eb9de317 c3 ret
kd> d esi+edx
4
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+edx
4]
eb9de303 891520e49deb mov [rootkit!OldNtWriteFile (eb9de420)],edx
eb9de309 8b4901 mov ecx,[ecx+0x1]
eb9de30c 8b00 mov eax,[eax]
eb9de30e c70488a5e29deb mov dword ptr [eax+ecx
4],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>

Use a file system filter. What you are doing is just going to crash the OS.


Don Burn (MVP, Windows DDK)
Windows 2k/XP/2k3 Filesystem and Driver Consulting
Remove StopSpam from the email to reply

“Developer” wrote in message news:xxxxx@ntdev…
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+edx
4]
eb9de303 891520e49deb mov [rootkit+0x420 (eb9de420)],edx
eb9de309 8b4901 mov ecx,[ecx+0x1]
eb9de30c 8b00 mov eax,[eax]
eb9de30e c70488a5e29deb mov dword ptr [eax+ecx
4],0xeb9de2a5
eb9de315 fb sti
eb9de316 5e pop esi
eb9de317 c3 ret
kd> d esi+edx
4
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+edx
4]
eb9de303 891520e49deb mov [rootkit!OldNtWriteFile (eb9de420)],edx
eb9de309 8b4901 mov ecx,[ecx+0x1]
eb9de30c 8b00 mov eax,[eax]
eb9de30e c70488a5e29deb mov dword ptr [eax+ecx
4],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>

this was just for experimental purpose, i got the code and tested it,
then it was for ZwCreateFile ( ) it worked splendidly and I could
even print the File name from objectattributes. then i tried with
ZwWriteFile and got results, in case of internal functions I dont seem
to get it to work.

This shouldn’t be the case, as ZwWrite* and NtWrite* are in the same
dll, or am i wrong?

On 8/27/05, Don Burn wrote:
> Use a file system filter. What you are doing is just going to crash the OS.
>
>
> –
> Don Burn (MVP, Windows DDK)
> Windows 2k/XP/2k3 Filesystem and Driver Consulting
> Remove StopSpam from the email to reply
>
>
>
> “Developer” wrote in message news:xxxxx@ntdev…
> 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+edx
4]
> eb9de303 891520e49deb mov [rootkit+0x420 (eb9de420)],edx
> eb9de309 8b4901 mov ecx,[ecx+0x1]
> eb9de30c 8b00 mov eax,[eax]
> eb9de30e c70488a5e29deb mov dword ptr [eax+ecx
4],0xeb9de2a5
> eb9de315 fb sti
> eb9de316 5e pop esi
> eb9de317 c3 ret
> kd> d esi+edx
4
> 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+edx
4]
> eb9de303 891520e49deb mov [rootkit!OldNtWriteFile (eb9de420)],edx
> eb9de309 8b4901 mov ecx,[ecx+0x1]
> eb9de30c 8b00 mov eax,[eax]
> eb9de30e c70488a5e29deb mov dword ptr [eax+ecx
4],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
>
>
>
> —
> Questions? First check the Kernel Driver FAQ at http://www.osronline.com/article.cfm?id=256
>
> You are currently subscribed to ntdev as: xxxxx@gmail.com
> To unsubscribe send a blank email to xxxxx@lists.osr.com
>



- Developer</ntddk.h>

No they are not, take a look at
http://www.osronline.com/article.cfm?article=257 to explain the kernel
differences.


Don Burn (MVP, Windows DDK)
Windows 2k/XP/2k3 Filesystem and Driver Consulting
Remove StopSpam from the email to reply

“Developer” wrote in message news:xxxxx@ntdev…
this was just for experimental purpose, i got the code and tested it,
then it was for ZwCreateFile ( ) it worked splendidly and I could
even print the File name from objectattributes. then i tried with
ZwWriteFile and got results, in case of internal functions I dont seem
to get it to work.

This shouldn’t be the case, as ZwWrite* and NtWrite* are in the same
dll, or am i wrong?

On 8/27/05, Don Burn wrote:
> Use a file system filter. What you are doing is just going to crash the
> OS.
>
>
> –
> Don Burn (MVP, Windows DDK)
> Windows 2k/XP/2k3 Filesystem and Driver Consulting
> Remove StopSpam from the email to reply
>
>
>
> “Developer” wrote in message news:xxxxx@ntdev…
> 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+edx
4]
> eb9de303 891520e49deb mov [rootkit+0x420 (eb9de420)],edx
> eb9de309 8b4901 mov ecx,[ecx+0x1]
> eb9de30c 8b00 mov eax,[eax]
> eb9de30e c70488a5e29deb mov dword ptr [eax+ecx
4],0xeb9de2a5
> eb9de315 fb sti
> eb9de316 5e pop esi
> eb9de317 c3 ret
> kd> d esi+edx
4
> 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+edx
4]
> eb9de303 891520e49deb mov [rootkit!OldNtWriteFile (eb9de420)],edx
> eb9de309 8b4901 mov ecx,[ecx+0x1]
> eb9de30c 8b00 mov eax,[eax]
> eb9de30e c70488a5e29deb mov dword ptr [eax+ecx
4],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
>
>
>
> —
> Questions? First check the Kernel Driver FAQ at
> http://www.osronline.com/article.cfm?id=256
>
> You are currently subscribed to ntdev as: xxxxx@gmail.com
> To unsubscribe send a blank email to xxxxx@lists.osr.com
>



- Developer</ntddk.h>

yes don, i have read that atricle, and that is what triggered all
this. If i am not mistaken, ntwritefile is exported by either
nsoskernel or ntdll. also zwwritefile and ntwritefile are exported by
ntdll.dll. does this mean that ntdll just the stub and ntoskernel has
the actual function?

why doesnt it let me import teh function when i try
__declspec(dllimport) NTSTATUS NtWriteFile; (linking with ntdll.dll
ofcourse) it gives a compilation error stating that the prototye
mismatch has occured?

I know i am makng a fundamental mistake somewhere.

On 8/27/05, Don Burn wrote:
> No they are not, take a look at
> http://www.osronline.com/article.cfm?article=257 to explain the kernel
> differences.
>
>
> –
> Don Burn (MVP, Windows DDK)
> Windows 2k/XP/2k3 Filesystem and Driver Consulting
> Remove StopSpam from the email to reply
>
>
>
> “Developer” wrote in message news:xxxxx@ntdev…
> this was just for experimental purpose, i got the code and tested it,
> then it was for ZwCreateFile ( ) it worked splendidly and I could
> even print the File name from objectattributes. then i tried with
> ZwWriteFile and got results, in case of internal functions I dont seem
> to get it to work.
>
> This shouldn’t be the case, as ZwWrite* and NtWrite* are in the same
> dll, or am i wrong?
>
>
>
> On 8/27/05, Don Burn wrote:
> > Use a file system filter. What you are doing is just going to crash the
> > OS.
> >
> >
> > –
> > Don Burn (MVP, Windows DDK)
> > Windows 2k/XP/2k3 Filesystem and Driver Consulting
> > Remove StopSpam from the email to reply
> >
> >
> >
> > “Developer” wrote in message news:xxxxx@ntdev…
> > 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+edx
4]
> > eb9de303 891520e49deb mov [rootkit+0x420 (eb9de420)],edx
> > eb9de309 8b4901 mov ecx,[ecx+0x1]
> > eb9de30c 8b00 mov eax,[eax]
> > eb9de30e c70488a5e29deb mov dword ptr [eax+ecx
4],0xeb9de2a5
> > eb9de315 fb sti
> > eb9de316 5e pop esi
> > eb9de317 c3 ret
> > kd> d esi+edx
4
> > 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+edx
4]
> > eb9de303 891520e49deb mov [rootkit!OldNtWriteFile (eb9de420)],edx
> > eb9de309 8b4901 mov ecx,[ecx+0x1]
> > eb9de30c 8b00 mov eax,[eax]
> > eb9de30e c70488a5e29deb mov dword ptr [eax+ecx
4],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
> >
> >
> >
> > —
> > Questions? First check the Kernel Driver FAQ at
> > http://www.osronline.com/article.cfm?id=256
> >
> > You are currently subscribed to ntdev as: xxxxx@gmail.com
> > To unsubscribe send a blank email to xxxxx@lists.osr.com
> >
>
>
> –
>
> - Developer
>
>
>
> —
> Questions? First check the Kernel Driver FAQ at http://www.osronline.com/article.cfm?id=256
>
> You are currently subscribed to ntdev as: xxxxx@gmail.com
> To unsubscribe send a blank email to xxxxx@lists.osr.com
>



- Developer</ntddk.h>

Well, first it is exported by ntoskrnl.exe, you don’t use ntdll.dll in the
kernel. As far as the import if that is your definition it will not work,
you need to match the arguments.


Don Burn (MVP, Windows DDK)
Windows 2k/XP/2k3 Filesystem and Driver Consulting
Remove StopSpam from the email to reply

“Developer” wrote in message news:xxxxx@ntdev…
yes don, i have read that atricle, and that is what triggered all
this. If i am not mistaken, ntwritefile is exported by either
nsoskernel or ntdll. also zwwritefile and ntwritefile are exported by
ntdll.dll. does this mean that ntdll just the stub and ntoskernel has
the actual function?

why doesnt it let me import teh function when i try
_declspec(dllimport) NTSTATUS NtWriteFile; (linking with ntdll.dll
ofcourse) it gives a compilation error stating that the prototye
mismatch has occured?

I know i am makng a fundamental mistake somewhere.

On 8/27/05, Don Burn wrote:
> No they are not, take a look at
> http://www.osronline.com/article.cfm?article=257 to explain the kernel
> differences.
>
>
> –
> Don Burn (MVP, Windows DDK)
> Windows 2k/XP/2k3 Filesystem and Driver Consulting
> Remove StopSpam from the email to reply
>
>
>
> “Developer” wrote in message news:xxxxx@ntdev…
> this was just for experimental purpose, i got the code and tested it,
> then it was for ZwCreateFile ( ) it worked splendidly and I could
> even print the File name from objectattributes. then i tried with
> ZwWriteFile and got results, in case of internal functions I dont seem
> to get it to work.
>
> This shouldn’t be the case, as ZwWrite* and NtWrite* are in the same
> dll, or am i wrong?
>
>
>
> On 8/27/05, Don Burn wrote:
> > Use a file system filter. What you are doing is just going to crash the
> > OS.
> >
> >
> > –
> > Don Burn (MVP, Windows DDK)
> > Windows 2k/XP/2k3 Filesystem and Driver Consulting
> > Remove StopSpam from the email to reply
> >
> >
> >
> > “Developer” wrote in message news:xxxxx@ntdev…
> > 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+edx
4]
> > eb9de303 891520e49deb mov [rootkit+0x420 (eb9de420)],edx
> > eb9de309 8b4901 mov ecx,[ecx+0x1]
> > eb9de30c 8b00 mov eax,[eax]
> > eb9de30e c70488a5e29deb mov dword ptr [eax+ecx
4],0xeb9de2a5
> > eb9de315 fb sti
> > eb9de316 5e pop esi
> > eb9de317 c3 ret
> > kd> d esi+edx
4
> > 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+ecx
4],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
> >
> >
> >
> > —
> > Questions? First check the Kernel Driver FAQ at
> > http://www.osronline.com/article.cfm?id=256
> >
> > You are currently subscribed to ntdev as: xxxxx@gmail.com
> > To unsubscribe send a blank email to xxxxx@lists.osr.com
> >
>
>
> –
>
> - Developer
>
>
>
> —
> Questions? First check the Kernel Driver FAQ at
> http://www.osronline.com/article.cfm?id=256
>
> You are currently subscribed to ntdev as: xxxxx@gmail.com
> To unsubscribe send a blank email to xxxxx@lists.osr.com
>



- Developer</ntddk.h>

You cannot. Paging writes do not go via ZwWriteFile.

Maxim Shatskih, Windows DDK MVP
StorageCraft Corporation
xxxxx@storagecraft.com
http://www.storagecraft.com

----- Original Message -----
From: “Developer”
To: “Windows System Software Devs Interest List”
Sent: Saturday, August 27, 2005 6:10 PM
Subject: [ntdev] NtWriteFile

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+edx
4]
eb9de303 891520e49deb mov [rootkit+0x420 (eb9de420)],edx
eb9de309 8b4901 mov ecx,[ecx+0x1]
eb9de30c 8b00 mov eax,[eax]
eb9de30e c70488a5e29deb mov dword ptr [eax+ecx
4],0xeb9de2a5
eb9de315 fb sti
eb9de316 5e pop esi
eb9de317 c3 ret
kd> d esi+edx
4
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+edx
4]
eb9de303 891520e49deb mov [rootkit!OldNtWriteFile (eb9de420)],edx
eb9de309 8b4901 mov ecx,[ecx+0x1]
eb9de30c 8b00 mov eax,[eax]
eb9de30e c70488a5e29deb mov dword ptr [eax+ecx
4],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


Questions? First check the Kernel Driver FAQ at
http://www.osronline.com/article.cfm?id=256

You are currently subscribed to ntdev as: unknown lmsubst tag argument: ‘’
To unsubscribe send a blank email to xxxxx@lists.osr.com</ntddk.h>

On 8/27/05, Developer wrote:
> 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 );

where did you get the NtWriteFile prototype, I dont find it anywhere
in the DDK or MSSDK include?</ntddk.h>

Do you ever read these newsgroups or just post? This has been answered many
times. Read some of the recommended books, take a couple of classes from
OSR or one of the others, try to write a couple of drivers that do the same
things as drivers supplied in the DDK without copying them, and then maybe
the questions will be more useful. We don’t read the manuals for those who
won’t do it themselves.

“F Lace” wrote in message news:xxxxx@ntdev…
On 8/27/05, Developer wrote:
> 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 );

where did you get the NtWriteFile prototype, I dont find it anywhere
in the DDK or MSSDK include?</ntddk.h>

>where did you get the NtWriteFile prototype, I dont find it anywhere

in the DDK or MSSDK include?

Use ZwWriteFile instead.

Maxim Shatskih, Windows DDK MVP
StorageCraft Corporation
xxxxx@storagecraft.com
http://www.storagecraft.com