4,6 The Native API

If some of the options in this batch file are foreign to you, don't worry. I'll

discuss Windows debuggers in more detail later on. Now that we've cranked

up our debugger, let's disassemble the Wn'teFile(J function to see where it

leads us.

> uf Wn'tePi 1 e

kernel 32!WriteFi1e+OxlfO

7655dcfa ff75e4

push

dword ptr [ebp-lCh]

7655dcfd e88ae80300

cal 1

kernel 32!BaseSetLastNTError {7659c58c)

7655dd02 33c0

xor

eax,eax

7655dd42 ffl5f8115576

cal 1

dword ptr [kernel32! imp NtWriteFile

(765511f8)]

Looking at this listing (which I've truncated for the sake of brevity), the first

thing you can see is that the WriteFile(} API function has been implennented

in the Kernel32.dl 1. The last line of this listing is also important. It calls a

routine located at an address (0x765511f8) that's stored in a lookup table.

> dps 765511f8 L3

765511f8 77bb9278 ntdl1INtWriteFi 1 e

765511fc 77becc6d ntdl1IZwCancelloFi1eEx

76551200 77b78908 ntdl1IZwReadPi1eScatter

Hence, the WriteFi!e() code in kennel32.dll ends up calling a funcdon that

has been exported by ntdll .dll. Now we're getting somewhere.

> uf ntdl1!NtWriteFi 1 e

ntdl1INtWriteFile:

77bb9278 b863010000

mov

eax,18Ch

77bb927d ba0003fe7f

mov

edx.offset SharedUserData!SystemCal1 Stub

{7ffe0300)

77bb9282 ffl2

cal 1

dword ptr [edx]

77bb9284 c22400

ret

24h

As you can see, this isn't really the implementation of the NtWritePi 1 e() Na¬

tive API call. Instead, it's just a stub routine residing in ntdll .dl1 that ends up

calling the gateway in ntdll .dl1 that executes the SYSENTER instrucdon. Notice

how the system service number for the NtWriteFi 1 e() Native call (i.e., 0xl8C)

is loaded into the EAX register in the stub code, well in advance of the SYSENTER

instruction.

> dps 7ffe0300

7ffe0300 77da0f30 ntdl 1 ! Ki FastSysteinCal 1

7ffe0304 77da0f34 ntdl1!KiFastSystemCal1 Ret

7ffG0308 00000000

> uf ntdl1jKiFastSystemCal 1_

Parti I 167