1

I am trying to make a program work with system-calls not dll's (kernel32.dll,ntdll.dll).
I know for example that the 0x2C (44) system call in windows 10 64-bit is the NtTerminateProcess buy that web page. Also when I disassemble the ntdll.dll i found that code:

NtTerminateProcess:
        mov r10, rcx
        mov eax, 44
        test byte [abs 7FFE0308h], 01h  ;also what is in that memory address?
        jnz label
        syscall
        ret    
label:  
        int 46 ;and why the 46 (the 2Eh windows NT interrupt) is here
        ret

My question is how can for example terminate the program with that way?

ARISTOS
  • 336
  • 3
  • 7
  • 1
    That's just a flag indicating whether to use `syscall` or `int`. You can probably just use `syscall` unconditionally. Have you tried it? Did you have any problems? – Jester Jun 23 '17 at 13:28

1 Answers1

6

Doing syscalls directly is not a good idea because this is not a stable ABI. The numbers can in theory change between service packs and even a plain update.

The instruction used on 32-bit Windows is not the same on all systems either!

Windows NT and 2000 always uses int 2e. Windows XP started using SysEnter/SysCall when running on "newer" Intel/AMD CPUs (Pentium II, AMD K7, and later). Because Windows XP also supported older CPUs, it used a little helper function (SystemCallStub) to enter kernel mode. This function (and later, the address of this function) is stored in a memory page accessible by all processes called _KUSER_SHARED_DATA located at 0x7ffe0000.

The original int 2e method is still supported, but I'm not sure why 64-bit Windows bothers checking which method to use, since every CPU it runs on supports SysCall. My Windows 8 machine does not check:

0:000> uf ntdll!NtTerminateProcess
ntdll!ZwTerminateProcess:
000007ff`1ad52ea0 4c8bd1          mov     r10,rcx
000007ff`1ad52ea3 b82a000000      mov     eax,2Ah
000007ff`1ad52ea8 0f05            syscall
000007ff`1ad52eaa c3              ret

These are just implementation details anyway, and they can change at any time. See https://j00ru.vexillium.org/syscalls/nt/64/ for a reverse-engineered table of x64 NT system-call numbers broken down by Windows kernel version. (Do not use in portable code, only for experiments to satisfy your curiosity about how Windows and/or asm works.)

int 2e is probably a little bit slower, so just use SysCall in 64-bit code and int 2e in 32-bit code if you want to stay "portable".

Peter Cordes
  • 328,167
  • 45
  • 605
  • 847
Anders
  • 97,548
  • 12
  • 110
  • 164
  • OK, can you tell me for exemple if I import only `ntdll.dll` and use only the functions with systemcalls (like NtTerminateProcess) how can I make a `hello word` program? – ARISTOS Jun 25 '17 at 07:20
  • 1
    Making a "Hello world" program requires console I/O, and the best way to do that is to use the console library provided by Kernel32.dll (specifically, the `WriteConsole` function). Otherwise, you are *massively* re-inventing the wheel. Probably not something you are up for if you have to ask this question. What would be the point of writing a non-portable console application anyway? @ARISTOS – Cody Gray - on strike Jun 25 '17 at 08:20