debugging an unknown driver

while in user mode for an exe
when the debugger stops on PeHeader->AddrOfEntrypoint
we normally have 0xffffffff that was set there by kernel32!SehProlog
thats called in Kernel32!BaseProcessorStartThunk ->
Kernel32!BaseProcessorStart

like wise what would be the value for a driver when it enters
AdrressOfEntryPoint ?

when is the AddressOf EntryPoint reached in a drivers lifetime ?

ive seen docs stating DriverEntryPoint is mostly an appendage to
satisy Compiler and if a driver is loaded via CreateService the
DriverEntry may never be called at all ? is that statement correct

if a DriverEntry happens to be at peheader->addrof EntryPoint is it
still true ??
will it never be called ?

if a driver is packed and obfuscated is there an easy way to step
through it without having to install it and trace it live (assume it
is a rootkit driver) most likely i would like to know if there is a
single machine non kernel debugger way to analyze it
if possible no vm and kd with pipe too to comport

how good it would be to use windbg -z rootkit.sys to load the sys file
as dump file ?
what can i deduce from loading this sysfile in such a manner ?

is there a document or referance that shows how one could start
debugging or if not possible to debug DISASSEMBLE and deadlist the
driver ?

any pointers comments suggestions are welcome

here is a sample out of the driver im trying to analyze

*** ERROR: Module load completed but symbols could not be loaded for ROOTKIT.SYS
ROOTKIT+0xd300:
0001d300 8b542404 mov edx,dword ptr [esp+4] ss:00000004=???
0:000> lm
start end module name
00010000 0001e000 ROOTKIT (no symbols)
0:000> uf eip
Flow analysis was incomplete, some code may be missing
ROOTKIT+0xd300:
0001d300 8b542404 mov edx,dword ptr [esp+4]
0001d304 8b520c mov edx,dword ptr [edx+0Ch]
0001d307 81c200db0000 add edx,0DB00h
0001d30d b895df0000 mov eax,0DF95h
0001d312 60 pushad
0001d313 b95c040000 mov ecx,45Ch
0001d318 89d6 mov esi,edx
0001d31a 89f7 mov edi,esi

ROOTKIT+0xd31c:
0001d31c ad lods dword ptr [esi]
0001d31d 2d68827324 sub eax,24738268h
0001d322 ab stos dword ptr es:[edi]
0001d323 83e904 sub ecx,4
0001d326 83f900 cmp ecx,0
0001d329 7df1 jge ROOTKIT+0xd31c (0001d31c)

ROOTKIT+0xd32b:
0001d32b 61 popad
0001d32c 83c208 add edx,8
0001d32f ffe2 jmp edx

thanks and regards

raj_r

That’s quite an open-ended question.

First, about DriverEntry. The name doesn’t really matter; I believe a field in the PE/COFF header contains the RVA of the driver entry routine. Traditionally, the entry point for NT drivers is named DriverEntry, but that’s not required. DriverEntry is called for all drivers loaded by NtLoadDriver. This includes “legacy” drivers (created using CreateService), as well as PNP drivers. NtLoadManager is a system service, and the Service Control Manager (SCM, the user-mode services.exe process) uses this function (and NtUnloadDriver) to, well, load and unload drivers. The implementation of NtLoadDriver eventually looks up the entry point of the driver, and calls it. If the entry point registers an unload routine, then that will be called when the driver is unloaded.

If you saw text stating that drivers installed by using CreateService don’t have their DriverEntry entry points called, that’s false.

About reverse-engineering malicious code: It’s going to be difficult, and you’re going to have to learn a fair amount of assembly. There are some good RE tools out there, a lot of people are fond of IDA. However, the author of the malware will probably try to prevent those tools from working, and generally hide what is going on. The only fool-proof solution is to read the code, and understand what it does, line by line, instruction by instruction.

“Windbg -z .sys” is a great tool. It will not run the code; and anyway, the code assumes kernel mode, so it wouldn’t matter if it did run. In this mode, you can disassemble the code, dump memory, etc. Most of the usual read-only commands work, such as “x foo!findme”, “ln”, etc. Other good tools are depends.exe (ships with VC, also available free & legitimately at http://www.dependencywalker.com), “link /dump”, etc.

-----Original Message-----
From: xxxxx@lists.osr.com [mailto:xxxxx@lists.osr.com] On Behalf Of raj_r
Sent: Wednesday, May 23, 2007 12:27 PM
To: Kernel Debugging Interest List
Subject: [windbg] debugging an unknown driver

while in user mode for an exe
when the debugger stops on PeHeader->AddrOfEntrypoint
we normally have 0xffffffff that was set there by kernel32!SehProlog
thats called in Kernel32!BaseProcessorStartThunk ->
Kernel32!BaseProcessorStart

like wise what would be the value for a driver when it enters
AdrressOfEntryPoint ?

when is the AddressOf EntryPoint reached in a drivers lifetime ?

ive seen docs stating DriverEntryPoint is mostly an appendage to
satisy Compiler and if a driver is loaded via CreateService the
DriverEntry may never be called at all ? is that statement correct

if a DriverEntry happens to be at peheader->addrof EntryPoint is it
still true ??
will it never be called ?

if a driver is packed and obfuscated is there an easy way to step
through it without having to install it and trace it live (assume it
is a rootkit driver) most likely i would like to know if there is a
single machine non kernel debugger way to analyze it
if possible no vm and kd with pipe too to comport

how good it would be to use windbg -z rootkit.sys to load the sys file
as dump file ?
what can i deduce from loading this sysfile in such a manner ?

is there a document or referance that shows how one could start
debugging or if not possible to debug DISASSEMBLE and deadlist the
driver ?

any pointers comments suggestions are welcome

here is a sample out of the driver im trying to analyze

*** ERROR: Module load completed but symbols could not be loaded for ROOTKIT.SYS
ROOTKIT+0xd300:
0001d300 8b542404 mov edx,dword ptr [esp+4] ss:00000004=???
0:000> lm
start end module name
00010000 0001e000 ROOTKIT (no symbols)
0:000> uf eip
Flow analysis was incomplete, some code may be missing
ROOTKIT+0xd300:
0001d300 8b542404 mov edx,dword ptr [esp+4]
0001d304 8b520c mov edx,dword ptr [edx+0Ch]
0001d307 81c200db0000 add edx,0DB00h
0001d30d b895df0000 mov eax,0DF95h
0001d312 60 pushad
0001d313 b95c040000 mov ecx,45Ch
0001d318 89d6 mov esi,edx
0001d31a 89f7 mov edi,esi

ROOTKIT+0xd31c:
0001d31c ad lods dword ptr [esi]
0001d31d 2d68827324 sub eax,24738268h
0001d322 ab stos dword ptr es:[edi]
0001d323 83e904 sub ecx,4
0001d326 83f900 cmp ecx,0
0001d329 7df1 jge ROOTKIT+0xd31c (0001d31c)

ROOTKIT+0xd32b:
0001d32b 61 popad
0001d32c 83c208 add edx,8
0001d32f ffe2 jmp edx

thanks and regards

raj_r


You are currently subscribed to windbg as: xxxxx@microsoft.com
To unsubscribe send a blank email to xxxxx@lists.osr.com

I’m missing something here. Where did that WinDbg information come
from: a live system or WinDbg -z, because the load address is damn
strange. I’m not entirely sure what it is you seek. It sounds like you
don’t want to use live kernel mode debugging, and I’m assuming you don’t
have symbols for ROOTKIT.SYS. If those are correct, you are indeed down
some for of static disassembly, which without symbols is a serious
undertaking. If you looking for a way to disassemble it, I would
recommend IDA. It’s a truly tremendous product and totally worth the
price (although getting 64 bit support is a little irritating), but it
is expensive (I think about $500 for 32-bit, and $900 for 32 bit & 64
bit). Failing that, if you’re desperate and you have Visual Studio, you
can use dumpbin; it may come with other products as well, but I don’t
think so. If you go this route and by some remarkable chance you have
symbols for ROOTKIT.SYS, which seems pretty unlikely, if you set the
_NT_SYMBOL_PATH environment variable to point to the location of the
symbols, the dumpbin will use them.

mm

>> xxxxx@gmail.com 2007-05-23 12:26 >>>
while in user mode for an exe
when the debugger stops on PeHeader->AddrOfEntrypoint
we normally have 0xffffffff that was set there by kernel32!SehProlog
thats called in Kernel32!BaseProcessorStartThunk ->
Kernel32!BaseProcessorStart

like wise what would be the value for a driver when it enters
AdrressOfEntryPoint ?

when is the AddressOf EntryPoint reached in a drivers lifetime ?

ive seen docs stating DriverEntryPoint is mostly an appendage to
satisy Compiler and if a driver is loaded via CreateService the
DriverEntry may never be called at all ? is that statement correct

if a DriverEntry happens to be at peheader->addrof EntryPoint is it
still true ??
will it never be called ?

if a driver is packed and obfuscated is there an easy way to step
through it without having to install it and trace it live (assume it
is a rootkit driver) most likely i would like to know if there is a
single machine non kernel debugger way to analyze it
if possible no vm and kd with pipe too to comport

how good it would be to use windbg -z rootkit.sys to load the sys file
as dump file ?
what can i deduce from loading this sysfile in such a manner ?

is there a document or referance that shows how one could start
debugging or if not possible to debug DISASSEMBLE and deadlist the
driver ?

any pointers comments suggestions are welcome

here is a sample out of the driver im trying to analyze

*** ERROR: Module load completed but symbols could not be loaded for
ROOTKIT.SYS
ROOTKIT+0xd300:
0001d300 8b542404 mov edx,dword ptr [esp+4]
ss:00000004=???
0:000> lm
start end module name
00010000 0001e000 ROOTKIT (no symbols)
0:000> uf eip
Flow analysis was incomplete, some code may be missing
ROOTKIT+0xd300:
0001d300 8b542404 mov edx,dword ptr [esp+4]
0001d304 8b520c mov edx,dword ptr [edx+0Ch]
0001d307 81c200db0000 add edx,0DB00h
0001d30d b895df0000 mov eax,0DF95h
0001d312 60 pushad
0001d313 b95c040000 mov ecx,45Ch
0001d318 89d6 mov esi,edx
0001d31a 89f7 mov edi,esi

ROOTKIT+0xd31c:
0001d31c ad lods dword ptr [esi]
0001d31d 2d68827324 sub eax,24738268h
0001d322 ab stos dword ptr es:[edi]
0001d323 83e904 sub ecx,4
0001d326 83f900 cmp ecx,0
0001d329 7df1 jge ROOTKIT+0xd31c (0001d31c)

ROOTKIT+0xd32b:
0001d32b 61 popad
0001d32c 83c208 add edx,8
0001d32f ffe2 jmp edx

thanks and regards

raj_r


You are currently subscribed to windbg as: xxxxx@evitechnology.com
To unsubscribe send a blank email to xxxxx@lists.osr.com

Thanks Arlie for replying back,

i posted this yesterday but it seems lyris list manager rejected this
answer stating some thing about including base 64 blah blah
attachement

i think it dislikes hexdump not sure

  1. Driver Entry not called

i think i saw that statement in tim roberts kernel dll
i may be utterly wrong in interpreting it

quote
Your DLL must include the standard DriverEntry entry point, but the
system won’t actually call that entry point. This requirement is an
artifact of the build system, which adds /ENTRY:DriverEntry to the
linker options for every kernel driver. An EXPORT_DRIVER can also
function as a normal driver, and the build system cannot tell whether
we want to do that or not, so we have to supply this dummy entry point
for an export-only DLL.

http://www.wd-3.com/archive/KernelDlls.htm

i know a fair bit of assembly

i have been looking and if this driver is loaded by ntLoadDriver
then i assume it takes only one param

lkd> .fnent nt!Ntloaddriver
Debugger function entry 00aac8c0 for:
(805505a5) nt!NtLoadDriver | (805506f4) nt!SdbReadWORDTag
Exact matches:
nt!NtLoadDriver =

OffStart: 0007c5a5
ProcSize: 0x192
Prologue: 0xc
Params: 0n1 (0x4 bytes) <—
Locals: 0n26 (0x68 bytes)

so if that is struct driver object (not sure) just guessing

lkd> dt _driver_object
nt!_DRIVER_OBJECT
+0x000 Type : Int2B
+0x002 Size : Int2B
+0x004 DeviceObject : Ptr32 _DEVICE_OBJECT
+0x008 Flags : Uint4B
+0x00c DriverStart : Ptr32 Void <-----
+0x010 DriverSize : Uint4B
+0x014 DriverSection : Ptr32 Void
+0x018 DriverExtension : Ptr32 _DRIVER_EXTENSION
+0x01c DriverName : _UNICODE_STRING
+0x024 HardwareDatabase : Ptr32 _UNICODE_STRING
+0x028 FastIoDispatch : Ptr32 _FAST_IO_DISPATCH
+0x02c DriverInit : Ptr32 long
+0x030 DriverStartIo : Ptr32 void
+0x034 DriverUnload : Ptr32 void
+0x038 MajorFunction : [28] Ptr32 long
lkd>

then in the snippet i posted above
edx will hold driver start ?? am i right so far ? is driverstart ==
MZ header ???
so can i assume it will be 0x10000

if i am right and since raw and virtual address of thi driver is same

can i assume that this decryption rountine decrypts 45c bytes from 1db00

and jumps to 0x1db00 via jump edx

if that is the case can i script a little with
for every dword from 0x1bd00 subtract constant from original and do ed back

ed is write back to memory

or am i far from reality ?

mm

yes thats an output from windbg -z

windbg -z loads the driver at its stated base of image which happens
to be 0x10000
in this case

in reality the address will be somewhere in 0x804##### ++++ till 0xffffffff

also there is a sideeffect of loading this sysfile as dump file

it discards the .reloc section (pages it out otherwise) i cant acces
these bytes from within windbg and the address 0xdb00 resides in
.reloc section

On 5/23/07, Arlie Davis wrote:
> That’s quite an open-ended question.
>
> First, about DriverEntry. The name doesn’t really matter; I believe a field in the PE/COFF header contains the RVA of the driver entry routine. Traditionally, the entry point for NT drivers is named DriverEntry, but that’s not required. DriverEntry is called for all drivers loaded by NtLoadDriver. This includes “legacy” drivers (created using CreateService), as well as PNP drivers. NtLoadManager is a system service, and the Service Control Manager (SCM, the user-mode services.exe process) uses this function (and NtUnloadDriver) to, well, load and unload drivers. The implementation of NtLoadDriver eventually looks up the entry point of the driver, and calls it. If the entry point registers an unload routine, then that will be called when the driver is unloaded.
>
> If you saw text stating that drivers installed by using CreateService don’t have their DriverEntry entry points called, that’s false.
>
> About reverse-engineering malicious code: It’s going to be difficult, and you’re going to have to learn a fair amount of assembly. There are some good RE tools out there, a lot of people are fond of IDA. However, the author of the malware will probably try to prevent those tools from working, and generally hide what is going on. The only fool-proof solution is to read the code, and understand what it does, line by line, instruction by instruction.
>
> “Windbg -z .sys” is a great tool. It will not run the code; and anyway, the code assumes kernel mode, so it wouldn’t matter if it did run. In this mode, you can disassemble the code, dump memory, etc. Most of the usual read-only commands work, such as “x foo!findme”, “ln”, etc. Other good tools are depends.exe (ships with VC, also available free & legitimately at http://www.dependencywalker.com), “link /dump”, etc.
>
>
>
> -----Original Message-----
> From: xxxxx@lists.osr.com [mailto:xxxxx@lists.osr.com] On Behalf Of raj_r
> Sent: Wednesday, May 23, 2007 12:27 PM
> To: Kernel Debugging Interest List
> Subject: [windbg] debugging an unknown driver
>
> while in user mode for an exe
> when the debugger stops on PeHeader->AddrOfEntrypoint
> we normally have 0xffffffff that was set there by kernel32!SehProlog
> thats called in Kernel32!BaseProcessorStartThunk ->
> Kernel32!BaseProcessorStart
>
> like wise what would be the value for a driver when it enters
> AdrressOfEntryPoint ?
>
> when is the AddressOf EntryPoint reached in a drivers lifetime ?
>
> ive seen docs stating DriverEntryPoint is mostly an appendage to
> satisy Compiler and if a driver is loaded via CreateService the
> DriverEntry may never be called at all ? is that statement correct
>
> if a DriverEntry happens to be at peheader->addrof EntryPoint is it
> still true ??
> will it never be called ?
>
> if a driver is packed and obfuscated is there an easy way to step
> through it without having to install it and trace it live (assume it
> is a rootkit driver) most likely i would like to know if there is a
> single machine non kernel debugger way to analyze it
> if possible no vm and kd with pipe too to comport
>
> how good it would be to use windbg -z rootkit.sys to load the sys file
> as dump file ?
> what can i deduce from loading this sysfile in such a manner ?
>
> is there a document or referance that shows how one could start
> debugging or if not possible to debug DISASSEMBLE and deadlist the
> driver ?
>
> any pointers comments suggestions are welcome
>
> here is a sample out of the driver im trying to analyze
>
> *** ERROR: Module load completed but symbols could not be loaded for ROOTKIT.SYS
> ROOTKIT+0xd300:
> 0001d300 8b542404 mov edx,dword ptr [esp+4] ss:00000004=???
> 0:000> lm
> start end module name
> 00010000 0001e000 ROOTKIT (no symbols)
> 0:000> uf eip
> Flow analysis was incomplete, some code may be missing
> ROOTKIT+0xd300:
> 0001d300 8b542404 mov edx,dword ptr [esp+4]
> 0001d304 8b520c mov edx,dword ptr [edx+0Ch]
> 0001d307 81c200db0000 add edx,0DB00h
> 0001d30d b895df0000 mov eax,0DF95h
> 0001d312 60 pushad
> 0001d313 b95c040000 mov ecx,45Ch
> 0001d318 89d6 mov esi,edx
> 0001d31a 89f7 mov edi,esi
>
> ROOTKIT+0xd31c:
> 0001d31c ad lods dword ptr [esi]
> 0001d31d 2d68827324 sub eax,24738268h
> 0001d322 ab stos dword ptr es:[edi]
> 0001d323 83e904 sub ecx,4
> 0001d326 83f900 cmp ecx,0
> 0001d329 7df1 jge ROOTKIT+0xd31c (0001d31c)
>
> ROOTKIT+0xd32b:
> 0001d32b 61 popad
> 0001d32c 83c208 add edx,8
> 0001d32f ffe2 jmp edx
>
> thanks and regards
>
> raj_r
>
> —
> You are currently subscribed to windbg as: xxxxx@microsoft.com
> To unsubscribe send a blank email to xxxxx@lists.osr.com
>
> —
> You are currently subscribed to windbg as: unknown lmsubst tag argument: ‘’
> To unsubscribe send a blank email to xxxxx@lists.osr.com
>

Ahh, I see. There is a distinction between a driver and a kernel library. Drivers are loaded by NtLoadDriver, and what I said about DriverEntry applies to them, but not to libraries. The kernel also reads and resolves PE/COFF symbol imports, so if that driver imports symbols from other modules (such as nt!IoBlahBlah), the kernel will either load that module or add a reference to it if it already loaded. That’s how drivers import all of the usual DDK are imported. In this case, if the loaded module has not already been loaded *as a driver*, then I believe the entry point of the target won’t be called. Which makes sense – it isn’t being used as a driver, it’s being used as a library.

There are lots of kernel-mode libraries: ataport.sys, battc.sys, classpnp.sys, etc. I thought ntfs.sys used to be a mixed-mode module (both a library and a driver), but maybe that has changed, because I don’t see any exported symbols on ntfs.sys any more. Maybe I’m remembering ntfs wrong.


From: xxxxx@lists.osr.com [xxxxx@lists.osr.com] On Behalf Of raj_r [xxxxx@gmail.com]
Sent: Wednesday, May 23, 2007 11:29 PM
To: Kernel Debugging Interest List
Subject: Re: [windbg] debugging an unknown driver

Thanks Arlie for replying back,

i posted this yesterday but it seems lyris list manager rejected this
answer stating some thing about including base 64 blah blah
attachement

i think it dislikes hexdump not sure

  1. Driver Entry not called

i think i saw that statement in tim roberts kernel dll
i may be utterly wrong in interpreting it

quote
Your DLL must include the standard DriverEntry entry point, but the
system won’t actually call that entry point. This requirement is an
artifact of the build system, which adds /ENTRY:DriverEntry to the
linker options for every kernel driver. An EXPORT_DRIVER can also
function as a normal driver, and the build system cannot tell whether
we want to do that or not, so we have to supply this dummy entry point
for an export-only DLL.

http://www.wd-3.com/archive/KernelDlls.htm

i know a fair bit of assembly

i have been looking and if this driver is loaded by ntLoadDriver
then i assume it takes only one param

lkd> .fnent nt!Ntloaddriver
Debugger function entry 00aac8c0 for:
(805505a5) nt!NtLoadDriver | (805506f4) nt!SdbReadWORDTag
Exact matches:
nt!NtLoadDriver =

OffStart: 0007c5a5
ProcSize: 0x192
Prologue: 0xc
Params: 0n1 (0x4 bytes) <—
Locals: 0n26 (0x68 bytes)

so if that is struct driver object (not sure) just guessing

lkd> dt _driver_object
nt!_DRIVER_OBJECT
+0x000 Type : Int2B
+0x002 Size : Int2B
+0x004 DeviceObject : Ptr32 _DEVICE_OBJECT
+0x008 Flags : Uint4B
+0x00c DriverStart : Ptr32 Void <-----
+0x010 DriverSize : Uint4B
+0x014 DriverSection : Ptr32 Void
+0x018 DriverExtension : Ptr32 _DRIVER_EXTENSION
+0x01c DriverName : _UNICODE_STRING
+0x024 HardwareDatabase : Ptr32 _UNICODE_STRING
+0x028 FastIoDispatch : Ptr32 _FAST_IO_DISPATCH
+0x02c DriverInit : Ptr32 long
+0x030 DriverStartIo : Ptr32 void
+0x034 DriverUnload : Ptr32 void
+0x038 MajorFunction : [28] Ptr32 long
lkd>

then in the snippet i posted above
edx will hold driver start ?? am i right so far ? is driverstart ==
MZ header ???
so can i assume it will be 0x10000

if i am right and since raw and virtual address of thi driver is same

can i assume that this decryption rountine decrypts 45c bytes from 1db00

and jumps to 0x1db00 via jump edx

if that is the case can i script a little with
for every dword from 0x1bd00 subtract constant from original and do ed back

ed is write back to memory

or am i far from reality ?

mm

yes thats an output from windbg -z

windbg -z loads the driver at its stated base of image which happens
to be 0x10000
in this case

in reality the address will be somewhere in 0x804##### ++++ till 0xffffffff

also there is a sideeffect of loading this sysfile as dump file

it discards the .reloc section (pages it out otherwise) i cant acces
these bytes from within windbg and the address 0xdb00 resides in
.reloc section

On 5/23/07, Arlie Davis wrote:
> That’s quite an open-ended question.
>
> First, about DriverEntry. The name doesn’t really matter; I believe a field in the PE/COFF header contains the RVA of the driver entry routine. Traditionally, the entry point for NT drivers is named DriverEntry, but that’s not required. DriverEntry is called for all drivers loaded by NtLoadDriver. This includes “legacy” drivers (created using CreateService), as well as PNP drivers. NtLoadManager is a system service, and the Service Control Manager (SCM, the user-mode services.exe process) uses this function (and NtUnloadDriver) to, well, load and unload drivers. The implementation of NtLoadDriver eventually looks up the entry point of the driver, and calls it. If the entry point registers an unload routine, then that will be called when the driver is unloaded.
>
> If you saw text stating that drivers installed by using CreateService don’t have their DriverEntry entry points called, that’s false.
>
> About reverse-engineering malicious code: It’s going to be difficult, and you’re going to have to learn a fair amount of assembly. There are some good RE tools out there, a lot of people are fond of IDA. However, the author of the malware will probably try to prevent those tools from working, and generally hide what is going on. The only fool-proof solution is to read the code, and understand what it does, line by line, instruction by instruction.
>
> “Windbg -z .sys” is a great tool. It will not run the code; and anyway, the code assumes kernel mode, so it wouldn’t matter if it did run. In this mode, you can disassemble the code, dump memory, etc. Most of the usual read-only commands work, such as “x foo!findme”, “ln”, etc. Other good tools are depends.exe (ships with VC, also available free & legitimately at http://www.dependencywalker.com), “link /dump”, etc.
>
>
>
> -----Original Message-----
> From: xxxxx@lists.osr.com [mailto:xxxxx@lists.osr.com] On Behalf Of raj_r
> Sent: Wednesday, May 23, 2007 12:27 PM
> To: Kernel Debugging Interest List
> Subject: [windbg] debugging an unknown driver
>
> while in user mode for an exe
> when the debugger stops on PeHeader->AddrOfEntrypoint
> we normally have 0xffffffff that was set there by kernel32!SehProlog
> thats called in Kernel32!BaseProcessorStartThunk ->
> Kernel32!BaseProcessorStart
>
> like wise what would be the value for a driver when it enters
> AdrressOfEntryPoint ?
>
> when is the AddressOf EntryPoint reached in a drivers lifetime ?
>
> ive seen docs stating DriverEntryPoint is mostly an appendage to
> satisy Compiler and if a driver is loaded via CreateService the
> DriverEntry may never be called at all ? is that statement correct
>
> if a DriverEntry happens to be at peheader->addrof EntryPoint is it
> still true ??
> will it never be called ?
>
> if a driver is packed and obfuscated is there an easy way to step
> through it without having to install it and trace it live (assume it
> is a rootkit driver) most likely i would like to know if there is a
> single machine non kernel debugger way to analyze it
> if possible no vm and kd with pipe too to comport
>
> how good it would be to use windbg -z rootkit.sys to load the sys file
> as dump file ?
> what can i deduce from loading this sysfile in such a manner ?
>
> is there a document or referance that shows how one could start
> debugging or if not possible to debug DISASSEMBLE and deadlist the
> driver ?
>
> any pointers comments suggestions are welcome
>
> here is a sample out of the driver im trying to analyze
>
> *** ERROR: Module load completed but symbols could not be loaded for ROOTKIT.SYS
> ROOTKIT+0xd300:
> 0001d300 8b542404 mov edx,dword ptr [esp+4] ss:00000004=???
> 0:000> lm
> start end module name
> 00010000 0001e000 ROOTKIT (no symbols)
> 0:000> uf eip
> Flow analysis was incomplete, some code may be missing
> ROOTKIT+0xd300:
> 0001d300 8b542404 mov edx,dword ptr [esp+4]
> 0001d304 8b520c mov edx,dword ptr [edx+0Ch]
> 0001d307 81c200db0000 add edx,0DB00h
> 0001d30d b895df0000 mov eax,0DF95h
> 0001d312 60 pushad
> 0001d313 b95c040000 mov ecx,45Ch
> 0001d318 89d6 mov esi,edx
> 0001d31a 89f7 mov edi,esi
>
> ROOTKIT+0xd31c:
> 0001d31c ad lods dword ptr [esi]
> 0001d31d 2d68827324 sub eax,24738268h
> 0001d322 ab stos dword ptr es:[edi]
> 0001d323 83e904 sub ecx,4
> 0001d326 83f900 cmp ecx,0
> 0001d329 7df1 jge ROOTKIT+0xd31c (0001d31c)
>
> ROOTKIT+0xd32b:
> 0001d32b 61 popad
> 0001d32c 83c208 add edx,8
> 0001d32f ffe2 jmp edx
>
> thanks and regards
>
> raj_r
>
> —
> You are currently subscribed to windbg as: xxxxx@microsoft.com
> To unsubscribe send a blank email to xxxxx@lists.osr.com
>
> —
> You are currently subscribed to windbg as: unknown lmsubst tag argument: ‘’
> To unsubscribe send a blank email to xxxxx@lists.osr.com
>


You are currently subscribed to windbg as: xxxxx@microsoft.com
To unsubscribe send a blank email to xxxxx@lists.osr.com

Thanks once again ,

so you mean if a driver is loaded with LoadLibraryAorWorEx()
equivalent kernel api then its Driver entry will not be called

but if it is loaded via nt!NtLoadDriver then its entry point will be called

so all those drivers that have thier entry in hklm\system\controlset##\services
having any type of start (auto,manual) (start type 1 ,2) will be
loaded via NtLoadDriver ??

from google i gather NtLoadDriver is defined thus

NTSYSAPI
NTSTATUS
NTAPI
NtLoadDriver(

IN PUNICODE_STRING DriverServiceName );

the device service name must contain a minimum of two entries a
PUNICODE_STRING structure and start type

a sample inf file DeviceServiceName Section contains these

[Amity2.ServiceInstall.NT]
DisplayName = %A2.DeviceServiceName%
ServiceType = %SERVICE_KERNEL_DRIVER%
StartType = %SERVICE_DEMAND_START%
ErrorControl = %SERVICE_ERROR_NORMAL%
ServiceBinary = %12%\hcwPP2.sys
AddReg = Amity2.ServiceInstall.AddReg
DelReg = WolfsonOverrides.DelReg

so coming to the original query

this disassembly here

ROOTKIT+0xd300:
0001d300 8b542404 mov edx,dword ptr [esp+4]
0001d304 8b520c mov edx,dword ptr [edx+0Ch]
0001d307 81c200db0000 add edx,0DB00h

can i deduce that [esp+4] will contain DeviceServiceName ?

this DeviceServiceName doesnt look like a structure

it has to be structure i think so i think im wrong
becuse this is derefernced again in second line

0001d304 8b520c mov edx,dword ptr [edx+0Ch]

my original assumption that [esp+4] contains a pointer to Driver_Object
looks like more plausible

if it was indeed Driver_Object
then edx will hold Driver_Object->DriverStart (void ptr 32)

+0x00c DriverStart : Ptr32 Void

osronline Ex online Ddd from google states that this DRIVER_OBJECT
structure is opaque and only a few are accessible

one of them is DriverInit Routine

PDRIVER_INITIALIZE DriverInit
The entry point for the DriverEntry routine, which is set up by the
I/O Manager.
http://www.osronline.com/ddkx/kmarch/k112_6jaq.htm

this is at offset 0x2c in the said structure

+0x02c DriverInit : Ptr32 long

so what Does DriverStart normally point to ?

is it mapped images pointer to MZ header ?? or what is usually called
ImageBase in usermode terminology ?

if that assumption is right then i can decrypt 45c bytes starting from
0x1db00 in this case it is a simple subtraction of a constant it seems

0001d31c ad lods dword ptr [esi]
0001d31d 2d68827324 sub eax,24738268h
0001d322 ab stos dword ptr es:[edi]

and after decrypting thus it will jump to 0xdb008

now windbg -z does not map this section :frowning: so to make windbg load this
section too i probably have to spleunk the header and change the
charecteristics from page_disacardable non paged may be or simply make
all the sections into one big section

ill post later what transpires on my endevour

till then any comments are welcome

thanks and regards

raj_r

On 5/24/07, Arlie Davis wrote:
> Ahh, I see. There is a distinction between a driver and a kernel library. Drivers are loaded by NtLoadDriver, and what I said about DriverEntry applies to them, but not to libraries. The kernel also reads and resolves PE/COFF symbol imports, so if that driver imports symbols from other modules (such as nt!IoBlahBlah), the kernel will either load that module or add a reference to it if it already loaded. That’s how drivers import all of the usual DDK are imported. In this case, if the loaded module has not already been loaded as a driver, then I believe the entry point of the target won’t be called. Which makes sense – it isn’t being used as a driver, it’s being used as a library.
>
> There are lots of kernel-mode libraries: ataport.sys, battc.sys, classpnp.sys, etc. I thought ntfs.sys used to be a mixed-mode module (both a library and a driver), but maybe that has changed, because I don’t see any exported symbols on ntfs.sys any more. Maybe I’m remembering ntfs wrong.
>
>
> ________________________________________
> From: xxxxx@lists.osr.com [xxxxx@lists.osr.com] On Behalf Of raj_r [xxxxx@gmail.com]
> Sent: Wednesday, May 23, 2007 11:29 PM
> To: Kernel Debugging Interest List
> Subject: Re: [windbg] debugging an unknown driver
>
> Thanks Arlie for replying back,
>
> i posted this yesterday but it seems lyris list manager rejected this
> answer stating some thing about including base 64 blah blah
> attachement
>
> i think it dislikes hexdump not sure
>
> 1) Driver Entry not called
>
> i think i saw that statement in tim roberts kernel dll
> i may be utterly wrong in interpreting it
>
> quote
> Your DLL must include the standard DriverEntry entry point, but the
> system won’t actually call that entry point. This requirement is an
> artifact of the build system, which adds /ENTRY:DriverEntry to the
> linker options for every kernel driver. An EXPORT_DRIVER can also
> function as a normal driver, and the build system cannot tell whether
> we want to do that or not, so we have to supply this dummy entry point
> for an export-only DLL.
>
> http://www.wd-3.com/archive/KernelDlls.htm
>
> i know a fair bit of assembly
>
> i have been looking and if this driver is loaded by ntLoadDriver
> then i assume it takes only one param
>
> lkd> .fnent nt!Ntloaddriver
> Debugger function entry 00aac8c0 for:
> (805505a5) nt!NtLoadDriver | (805506f4) nt!SdbReadWORDTag
> Exact matches:
> nt!NtLoadDriver =
>
> OffStart: 0007c5a5
> ProcSize: 0x192
> Prologue: 0xc
> Params: 0n1 (0x4 bytes) <—
> Locals: 0n26 (0x68 bytes)
>
> so if that is struct driver object (not sure) just guessing
>
> lkd> dt _driver_object
> nt!_DRIVER_OBJECT
> +0x000 Type : Int2B
> +0x002 Size : Int2B
> +0x004 DeviceObject : Ptr32 _DEVICE_OBJECT
> +0x008 Flags : Uint4B
> +0x00c DriverStart : Ptr32 Void <-----
> +0x010 DriverSize : Uint4B
> +0x014 DriverSection : Ptr32 Void
> +0x018 DriverExtension : Ptr32 _DRIVER_EXTENSION
> +0x01c DriverName : _UNICODE_STRING
> +0x024 HardwareDatabase : Ptr32 _UNICODE_STRING
> +0x028 FastIoDispatch : Ptr32 _FAST_IO_DISPATCH
> +0x02c DriverInit : Ptr32 long
> +0x030 DriverStartIo : Ptr32 void
> +0x034 DriverUnload : Ptr32 void
> +0x038 MajorFunction : [28] Ptr32 long
> lkd>
>
> then in the snippet i posted above
> edx will hold driver start ?? am i right so far ? is driverstart ==
> MZ header ???
> so can i assume it will be 0x10000
>
> if i am right and since raw and virtual address of thi driver is same
>
> can i assume that this decryption rountine decrypts 45c bytes from 1db00
>
> and jumps to 0x1db00 via jump edx
>
> if that is the case can i script a little with
> for every dword from 0x1bd00 subtract constant from original and do ed back
>
> ed is write back to memory
>
> or am i far from reality ?
>
>
> mm
>
> yes thats an output from windbg -z
>
> windbg -z loads the driver at its stated base of image which happens
> to be 0x10000
> in this case
>
> in reality the address will be somewhere in 0x804##### ++++ till 0xffffffff
>
> also there is a sideeffect of loading this sysfile as dump file
>
> it discards the .reloc section (pages it out otherwise) i cant acces
> these bytes from within windbg and the address 0xdb00 resides in
> .reloc section
>
>
>
>
>
>
> On 5/23/07, Arlie Davis wrote:
> > That’s quite an open-ended question.
> >
> > First, about DriverEntry. The name doesn’t really matter; I believe a field in the PE/COFF header contains the RVA of the driver entry routine. Traditionally, the entry point for NT drivers is named DriverEntry, but that’s not required. DriverEntry is called for all drivers loaded by NtLoadDriver. This includes “legacy” drivers (created using CreateService), as well as PNP drivers. NtLoadManager is a system service, and the Service Control Manager (SCM, the user-mode services.exe process) uses this function (and NtUnloadDriver) to, well, load and unload drivers. The implementation of NtLoadDriver eventually looks up the entry point of the driver, and calls it. If the entry point registers an unload routine, then that will be called when the driver is unloaded.
> >
> > If you saw text stating that drivers installed by using CreateService don’t have their DriverEntry entry points called, that’s false.
> >
> > About reverse-engineering malicious code: It’s going to be difficult, and you’re going to have to learn a fair amount of assembly. There are some good RE tools out there, a lot of people are fond of IDA. However, the author of the malware will probably try to prevent those tools from working, and generally hide what is going on. The only fool-proof solution is to read the code, and understand what it does, line by line, instruction by instruction.
> >
> > “Windbg -z .sys” is a great tool. It will not run the code; and anyway, the code assumes kernel mode, so it wouldn’t matter if it did run. In this mode, you can disassemble the code, dump memory, etc. Most of the usual read-only commands work, such as “x foo!findme”, “ln”, etc. Other good tools are depends.exe (ships with VC, also available free & legitimately at http://www.dependencywalker.com), “link /dump”, etc.
> >
> >
> >
> > -----Original Message-----
> > From: xxxxx@lists.osr.com [mailto:xxxxx@lists.osr.com] On Behalf Of raj_r
> > Sent: Wednesday, May 23, 2007 12:27 PM
> > To: Kernel Debugging Interest List
> > Subject: [windbg] debugging an unknown driver
> >
> > while in user mode for an exe
> > when the debugger stops on PeHeader->AddrOfEntrypoint
> > we normally have 0xffffffff that was set there by kernel32!SehProlog
> > thats called in Kernel32!BaseProcessorStartThunk ->
> > Kernel32!BaseProcessorStart
> >
> > like wise what would be the value for a driver when it enters
> > AdrressOfEntryPoint ?
> >
> > when is the AddressOf EntryPoint reached in a drivers lifetime ?
> >
> > ive seen docs stating DriverEntryPoint is mostly an appendage to
> > satisy Compiler and if a driver is loaded via CreateService the
> > DriverEntry may never be called at all ? is that statement correct
> >
> > if a DriverEntry happens to be at peheader->addrof EntryPoint is it
> > still true ??
> > will it never be called ?
> >
> > if a driver is packed and obfuscated is there an easy way to step
> > through it without having to install it and trace it live (assume it
> > is a rootkit driver) most likely i would like to know if there is a
> > single machine non kernel debugger way to analyze it
> > if possible no vm and kd with pipe too to comport
> >
> > how good it would be to use windbg -z rootkit.sys to load the sys file
> > as dump file ?
> > what can i deduce from loading this sysfile in such a manner ?
> >
> > is there a document or referance that shows how one could start
> > debugging or if not possible to debug DISASSEMBLE and deadlist the
> > driver ?
> >
> > any pointers comments suggestions are welcome
> >
> > here is a sample out of the driver im trying to analyze
> >
> > *** ERROR: Module load completed but symbols could not be loaded for ROOTKIT.SYS
> > ROOTKIT+0xd300:
> > 0001d300 8b542404 mov edx,dword ptr [esp+4] ss:00000004=???
> > 0:000> lm
> > start end module name
> > 00010000 0001e000 ROOTKIT (no symbols)
> > 0:000> uf eip
> > Flow analysis was incomplete, some code may be missing
> > ROOTKIT+0xd300:
> > 0001d300 8b542404 mov edx,dword ptr [esp+4]
> > 0001d304 8b520c mov edx,dword ptr [edx+0Ch]
> > 0001d307 81c200db0000 add edx,0DB00h
> > 0001d30d b895df0000 mov eax,0DF95h
> > 0001d312 60 pushad
> > 0001d313 b95c040000 mov ecx,45Ch
> > 0001d318 89d6 mov esi,edx
> > 0001d31a 89f7 mov edi,esi
> >
> > ROOTKIT+0xd31c:
> > 0001d31c ad lods dword ptr [esi]
> > 0001d31d 2d68827324 sub eax,24738268h
> > 0001d322 ab stos dword ptr es:[edi]
> > 0001d323 83e904 sub ecx,4
> > 0001d326 83f900 cmp ecx,0
> > 0001d329 7df1 jge ROOTKIT+0xd31c (0001d31c)
> >
> > ROOTKIT+0xd32b:
> > 0001d32b 61 popad
> > 0001d32c 83c208 add edx,8
> > 0001d32f ffe2 jmp edx
> >
> > thanks and regards
> >
> > raj_r
> >
> > —
> > You are currently subscribed to windbg as: xxxxx@microsoft.com
> > To unsubscribe send a blank email to xxxxx@lists.osr.com
> >
> > —
> > You are currently subscribed to windbg as: unknown lmsubst tag argument: ‘’
> > To unsubscribe send a blank email to xxxxx@lists.osr.com
> >
>
> —
> You are currently subscribed to windbg as: xxxxx@microsoft.com
> To unsubscribe send a blank email to xxxxx@lists.osr.com
>
> —
> You are currently subscribed to windbg as: unknown lmsubst tag argument: ‘’
> To unsubscribe send a blank email to xxxxx@lists.osr.com
>

Driver DLLs are not going to be in the services key, just the binary has
to be present. A Driver DLL can have an initialization function,
DllInitialize, called on load. The name of this function is fixed and
explicit (unlike DriverEntry which is specified by the PE header), the
memory mamager looks for this export name when loading the module.

d

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of raj_r
Sent: Thursday, May 24, 2007 9:43 AM
To: Kernel Debugging Interest List
Subject: Re: [windbg] debugging an unknown driver

Thanks once again ,

so you mean if a driver is loaded with LoadLibraryAorWorEx()
equivalent kernel api then its Driver entry will not be called

but if it is loaded via nt!NtLoadDriver then its entry point will be
called

so all those drivers that have thier entry in
hklm\system\controlset##\services
having any type of start (auto,manual) (start type 1 ,2) will be
loaded via NtLoadDriver ??

from google i gather NtLoadDriver is defined thus

NTSYSAPI
NTSTATUS
NTAPI
NtLoadDriver(

IN PUNICODE_STRING DriverServiceName );

the device service name must contain a minimum of two entries a
PUNICODE_STRING structure and start type

a sample inf file DeviceServiceName Section contains these

[Amity2.ServiceInstall.NT]
DisplayName = %A2.DeviceServiceName%
ServiceType = %SERVICE_KERNEL_DRIVER%
StartType = %SERVICE_DEMAND_START%
ErrorControl = %SERVICE_ERROR_NORMAL%
ServiceBinary = %12%\hcwPP2.sys
AddReg = Amity2.ServiceInstall.AddReg
DelReg = WolfsonOverrides.DelReg

so coming to the original query

this disassembly here

ROOTKIT+0xd300:
0001d300 8b542404 mov edx,dword ptr [esp+4]
0001d304 8b520c mov edx,dword ptr [edx+0Ch]
0001d307 81c200db0000 add edx,0DB00h

can i deduce that [esp+4] will contain DeviceServiceName ?

this DeviceServiceName doesnt look like a structure

it has to be structure i think so i think im wrong
becuse this is derefernced again in second line

0001d304 8b520c mov edx,dword ptr [edx+0Ch]

my original assumption that [esp+4] contains a pointer to Driver_Object
looks like more plausible

if it was indeed Driver_Object
then edx will hold Driver_Object->DriverStart (void ptr 32)

+0x00c DriverStart : Ptr32 Void

osronline Ex online Ddd from google states that this DRIVER_OBJECT
structure is opaque and only a few are accessible

one of them is DriverInit Routine

PDRIVER_INITIALIZE DriverInit
The entry point for the DriverEntry routine, which is set up by the
I/O Manager.
http://www.osronline.com/ddkx/kmarch/k112_6jaq.htm

this is at offset 0x2c in the said structure

+0x02c DriverInit : Ptr32 long

so what Does DriverStart normally point to ?

is it mapped images pointer to MZ header ?? or what is usually called
ImageBase in usermode terminology ?

if that assumption is right then i can decrypt 45c bytes starting from
0x1db00 in this case it is a simple subtraction of a constant it seems

0001d31c ad lods dword ptr [esi]
0001d31d 2d68827324 sub eax,24738268h
0001d322 ab stos dword ptr es:[edi]

and after decrypting thus it will jump to 0xdb008

now windbg -z does not map this section :frowning: so to make windbg load this
section too i probably have to spleunk the header and change the
charecteristics from page_disacardable non paged may be or simply make
all the sections into one big section

ill post later what transpires on my endevour

till then any comments are welcome

thanks and regards

raj_r

On 5/24/07, Arlie Davis wrote:
> Ahh, I see. There is a distinction between a driver and a kernel
library. Drivers are loaded by NtLoadDriver, and what I said about
DriverEntry applies to them, but not to libraries. The kernel also
reads and resolves PE/COFF symbol imports, so if that driver imports
symbols from other modules (such as nt!IoBlahBlah), the kernel will
either load that module or add a reference to it if it already loaded.
That’s how drivers import all of the usual DDK are imported. In this
case, if the loaded module has not already been loaded as a driver,
then I believe the entry point of the target won’t be called. Which
makes sense – it isn’t being used as a driver, it’s being used as a
library.
>
> There are lots of kernel-mode libraries: ataport.sys, battc.sys,
classpnp.sys, etc. I thought ntfs.sys used to be a mixed-mode module
(both a library and a driver), but maybe that has changed, because I
don’t see any exported symbols on ntfs.sys any more. Maybe I’m
remembering ntfs wrong.
>
>
> ________________________________________
> From: xxxxx@lists.osr.com
[xxxxx@lists.osr.com] On Behalf Of raj_r
[xxxxx@gmail.com]
> Sent: Wednesday, May 23, 2007 11:29 PM
> To: Kernel Debugging Interest List
> Subject: Re: [windbg] debugging an unknown driver
>
> Thanks Arlie for replying back,
>
> i posted this yesterday but it seems lyris list manager rejected this
> answer stating some thing about including base 64 blah blah
> attachement
>
> i think it dislikes hexdump not sure
>
> 1) Driver Entry not called
>
> i think i saw that statement in tim roberts kernel dll
> i may be utterly wrong in interpreting it
>
> quote
> Your DLL must include the standard DriverEntry entry point, but the
> system won’t actually call that entry point. This requirement is an
> artifact of the build system, which adds /ENTRY:DriverEntry to the
> linker options for every kernel driver. An EXPORT_DRIVER can also
> function as a normal driver, and the build system cannot tell whether
> we want to do that or not, so we have to supply this dummy entry point
> for an export-only DLL.
>
> http://www.wd-3.com/archive/KernelDlls.htm
>
> i know a fair bit of assembly
>
> i have been looking and if this driver is loaded by ntLoadDriver
> then i assume it takes only one param
>
> lkd> .fnent nt!Ntloaddriver
> Debugger function entry 00aac8c0 for:
> (805505a5) nt!NtLoadDriver | (805506f4) nt!SdbReadWORDTag
> Exact matches:
> nt!NtLoadDriver =
>
> OffStart: 0007c5a5
> ProcSize: 0x192
> Prologue: 0xc
> Params: 0n1 (0x4 bytes) <—
> Locals: 0n26 (0x68 bytes)
>
> so if that is struct driver object (not sure) just guessing
>
> lkd> dt _driver_object
> nt!_DRIVER_OBJECT
> +0x000 Type : Int2B
> +0x002 Size : Int2B
> +0x004 DeviceObject : Ptr32 _DEVICE_OBJECT
> +0x008 Flags : Uint4B
> +0x00c DriverStart : Ptr32 Void <-----
> +0x010 DriverSize : Uint4B
> +0x014 DriverSection : Ptr32 Void
> +0x018 DriverExtension : Ptr32 _DRIVER_EXTENSION
> +0x01c DriverName : _UNICODE_STRING
> +0x024 HardwareDatabase : Ptr32 _UNICODE_STRING
> +0x028 FastIoDispatch : Ptr32 _FAST_IO_DISPATCH
> +0x02c DriverInit : Ptr32 long
> +0x030 DriverStartIo : Ptr32 void
> +0x034 DriverUnload : Ptr32 void
> +0x038 MajorFunction : [28] Ptr32 long
> lkd>
>
> then in the snippet i posted above
> edx will hold driver start ?? am i right so far ? is driverstart ==
> MZ header ???
> so can i assume it will be 0x10000
>
> if i am right and since raw and virtual address of thi driver is same
>
> can i assume that this decryption rountine decrypts 45c bytes from
1db00
>
> and jumps to 0x1db00 via jump edx
>
> if that is the case can i script a little with
> for every dword from 0x1bd00 subtract constant from original and do ed
back
>
> ed is write back to memory
>
> or am i far from reality ?
>
>
> mm
>
> yes thats an output from windbg -z
>
> windbg -z loads the driver at its stated base of image which happens
> to be 0x10000
> in this case
>
> in reality the address will be somewhere in 0x804##### ++++ till
0xffffffff
>
> also there is a sideeffect of loading this sysfile as dump file
>
> it discards the .reloc section (pages it out otherwise) i cant acces
> these bytes from within windbg and the address 0xdb00 resides in
> .reloc section
>
>
>
>
>
>
> On 5/23/07, Arlie Davis wrote:
> > That’s quite an open-ended question.
> >
> > First, about DriverEntry. The name doesn’t really matter; I believe
a field in the PE/COFF header contains the RVA of the driver entry
routine. Traditionally, the entry point for NT drivers is named
DriverEntry, but that’s not required. DriverEntry is called for all
drivers loaded by NtLoadDriver. This includes “legacy” drivers (created
using CreateService), as well as PNP drivers. NtLoadManager is a system
service, and the Service Control Manager (SCM, the user-mode
services.exe process) uses this function (and NtUnloadDriver) to, well,
load and unload drivers. The implementation of NtLoadDriver eventually
looks up the entry point of the driver, and calls it. If the entry
point registers an unload routine, then that will be called when the
driver is unloaded.
> >
> > If you saw text stating that drivers installed by using
CreateService don’t have their DriverEntry entry points called, that’s
false.
> >
> > About reverse-engineering malicious code: It’s going to be
difficult, and you’re going to have to learn a fair amount of assembly.
There are some good RE tools out there, a lot of people are fond of IDA.
However, the author of the malware will probably try to prevent those
tools from working, and generally hide what is going on. The only
fool-proof solution is to read the code, and understand what it does,
line by line, instruction by instruction.
> >
> > “Windbg -z .sys” is a great tool. It will not run the code;
and anyway, the code assumes kernel mode, so it wouldn’t matter if it
did run. In this mode, you can disassemble the code, dump memory, etc.
Most of the usual read-only commands work, such as “x foo!findme”,
“ln”, etc. Other good tools are depends.exe (ships with VC, also
available free & legitimately at http://www.dependencywalker.com), “link
/dump”, etc.
> >
> >
> >
> > -----Original Message-----
> > From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of raj_r
> > Sent: Wednesday, May 23, 2007 12:27 PM
> > To: Kernel Debugging Interest List
> > Subject: [windbg] debugging an unknown driver
> >
> > while in user mode for an exe
> > when the debugger stops on PeHeader->AddrOfEntrypoint
> > we normally have 0xffffffff that was set there by kernel32!SehProlog
> > thats called in Kernel32!BaseProcessorStartThunk ->
> > Kernel32!BaseProcessorStart
> >
> > like wise what would be the value for a driver when it enters
> > AdrressOfEntryPoint ?
> >
> > when is the AddressOf EntryPoint reached in a drivers lifetime ?
> >
> > ive seen docs stating DriverEntryPoint is mostly an appendage to
> > satisy Compiler and if a driver is loaded via CreateService the
> > DriverEntry may never be called at all ? is that statement correct
> >
> > if a DriverEntry happens to be at peheader->addrof EntryPoint is it
> > still true ??
> > will it never be called ?
> >
> > if a driver is packed and obfuscated is there an easy way to step
> > through it without having to install it and trace it live (assume
it
> > is a rootkit driver) most likely i would like to know if there is a
> > single machine non kernel debugger way to analyze it
> > if possible no vm and kd with pipe too to comport
> >
> > how good it would be to use windbg -z rootkit.sys to load the sys
file
> > as dump file ?
> > what can i deduce from loading this sysfile in such a manner ?
> >
> > is there a document or referance that shows how one could start
> > debugging or if not possible to debug DISASSEMBLE and deadlist the
> > driver ?
> >
> > any pointers comments suggestions are welcome
> >
> > here is a sample out of the driver im trying to analyze
> >
> > *** ERROR: Module load completed but symbols could not be loaded for
ROOTKIT.SYS
> > ROOTKIT+0xd300:
> > 0001d300 8b542404 mov edx,dword ptr [esp+4]
ss:00000004=???
> > 0:000> lm
> > start end module name
> > 00010000 0001e000 ROOTKIT (no symbols)
> > 0:000> uf eip
> > Flow analysis was incomplete, some code may be missing
> > ROOTKIT+0xd300:
> > 0001d300 8b542404 mov edx,dword ptr [esp+4]
> > 0001d304 8b520c mov edx,dword ptr [edx+0Ch]
> > 0001d307 81c200db0000 add edx,0DB00h
> > 0001d30d b895df0000 mov eax,0DF95h
> > 0001d312 60 pushad
> > 0001d313 b95c040000 mov ecx,45Ch
> > 0001d318 89d6 mov esi,edx
> > 0001d31a 89f7 mov edi,esi
> >
> > ROOTKIT+0xd31c:
> > 0001d31c ad lods dword ptr [esi]
> > 0001d31d 2d68827324 sub eax,24738268h
> > 0001d322 ab stos dword ptr es:[edi]
> > 0001d323 83e904 sub ecx,4
> > 0001d326 83f900 cmp ecx,0
> > 0001d329 7df1 jge ROOTKIT+0xd31c (0001d31c)
> >
> > ROOTKIT+0xd32b:
> > 0001d32b 61 popad
> > 0001d32c 83c208 add edx,8
> > 0001d32f ffe2 jmp edx
> >
> > thanks and regards
> >
> > raj_r
> >
> > —
> > You are currently subscribed to windbg as: xxxxx@microsoft.com
> > To unsubscribe send a blank email to
xxxxx@lists.osr.com
> >
> > —
> > You are currently subscribed to windbg as: unknown lmsubst tag
argument: ‘’
> > To unsubscribe send a blank email to
xxxxx@lists.osr.com
> >
>
> —
> You are currently subscribed to windbg as: xxxxx@microsoft.com
> To unsubscribe send a blank email to xxxxx@lists.osr.com
>
> —
> You are currently subscribed to windbg as: unknown lmsubst tag
argument: ‘’
> To unsubscribe send a blank email to xxxxx@lists.osr.com
>


You are currently subscribed to windbg as: xxxxx@microsoft.com
To unsubscribe send a blank email to xxxxx@lists.osr.com

raj_r wrote:

so you mean if a driver is loaded with LoadLibraryAorWorEx()
equivalent kernel api then its Driver entry will not be called

(Unless whomever made that call does so manually, this happens for
display drivers on NT4.x and NT5.x)
This is also true if a .sys file A.SYS is only loaded indirectly, e.g.
by loading another B.SYS file which lists A.SYS in its import table.

but if it is loaded via nt!NtLoadDriver then its entry point will be called
Yes. If a driver is loaded directly by nt!NtLoadDriver, DriverEntry
will be called with the 2 parameters specified in the WDK/DDK:

NTSTATUS
DriverEntry(
IN PDRIVER_OBJECT DriverObject,
IN PUNICODE_STRING RegistryPath
);

DriverObject points to a structure which is partially filled and will be
completed by DriverEntry (if this was a normal driver and not a rootkit).

RegistryPath is approximately the same value passed to NtLoadDriver.
Most drivers ignore it, the rest typically make a local copy of the
string and use it to read any driver-specific registry entries.

If DriverEntry returns success, the driver will stay in memory, if it
returns error, the driver will be unloaded and the error returned from
NtLoadDriver.

so all those drivers that have thier entry in
hklm\system\controlset##\services
having any type of start (auto,manual) (start type 1 ,2) will be
loaded via NtLoadDriver ??

from google i gather NtLoadDriver is defined thus

NTSYSAPI
NTSTATUS
NTAPI
NtLoadDriver(

IN PUNICODE_STRING DriverServiceName );

the device service name must contain a minimum of two entries a
PUNICODE_STRING structure and start type

so coming to the original query

this disassembly here

ROOTKIT+0xd300:
0001d300 8b542404 mov edx,dword ptr [esp+4]
0001d304 8b520c mov edx,dword ptr [edx+0Ch]
0001d307 81c200db0000 add edx,0DB00h

can i deduce that [esp+4] will contain DeviceServiceName ?
No [esp+8] is DeviceServiceName
[esp+4] is DriverObject
[edx+c] is the field 0xC bytes into struct _DRIVER_OBJECT
(see ntddk.h in the old DDK or wdm.h in the new WDK)

this DeviceServiceName doesnt look like a structure

it has to be structure i think so i think im wrong
becuse this is derefernced again in second line

0001d304 8b520c mov edx,dword ptr [edx+0Ch]

my original assumption that [esp+4] contains a pointer to Driver_Object
looks like more plausible
It is also correct, see above

if it was indeed Driver_Object
then edx will hold Driver_Object->DriverStart (void ptr 32)

+0x00c DriverStart : Ptr32 Void

osronline Ex online Ddd from google states that this DRIVER_OBJECT
structure is opaque and only a few are accessible

Formally, it is opaque, in reality, all the fields are listed in
ntddk.h/wdm.h, and only a few are undocumented (and could thus in theory
be reused by Microsoft for a completely different purpose).

one of them is DriverInit Routine

PDRIVER_INITIALIZE DriverInit
The entry point for the DriverEntry routine, which is set up by the
I/O Manager.
http://www.osronline.com/ddkx/kmarch/k112_6jaq.htm
Actually: The address of DriverEntry, as found in the PE header of the
.sys file.

this is at offset 0x2c in the said structure

+0x02c DriverInit : Ptr32 long

so what Does DriverStart normally point to ?

is it mapped images pointer to MZ header ?? or what is usually called
ImageBase in usermode terminology ?
That would be my guess too, but formally, this is undocumented.

if that assumption is right then i can decrypt 45c bytes starting from
0x1db00 in this case it is a simple subtraction of a constant it seems

0001d31c ad lods dword ptr [esi]
0001d31d 2d68827324 sub eax,24738268h
0001d322 ab stos dword ptr es:[edi]

and after decrypting thus it will jump to 0xdb008

now windbg -z does not map this section :frowning: so to make windbg load this
section too i probably have to spleunk the header and change the
charecteristics from page_disacardable non paged may be or simply make
all the sections into one big section

ill post later what transpires on my endevour

till then any comments are welcome


Jakob B?hm, M.Sc.Eng. * xxxxx@danware.dk * direct tel:+45-45-90-25-33
Danware Data A/S * Bregnerodvej 127 * DK-3460 Birkerod * DENMARK
http://www.netop.com * tel:+45-45-90-25-25 * fax tel:+45-45-90-25-26
Information in this mail is hasty, not binding and may not be right

Jakob,

is it mapped images pointer to MZ header ?? or what is usually called
ImageBase in usermode terminology ?

That would be my guess too, but formally, this is undocumented.

thanks

i assumed it is Mzheader and went ahead on that ssumption
and kida decryted and has ripped it apart till it reaches the real entry point
though i have to add that i didnt use windbg but used some hexeditor
and ollydbg to do further work

thanks a lot again for taking time to read my whole question and reply
point by point

regards

raj_r