Another Windows Strace. Blog Post
There have been a lot of open source atteptms to creating something like strace for Windows. Many have drawbacks or specific/customized setup requirements. This is simply my attempt.
Here are some of the others:
| Name | Method | Link |
|---|---|---|
| NtTrace | Debugger Engine COM Objects - Software Breakpoints | https://github.com/rogerorr/NtTrace |
| stracent | IAT patching. Pressuembly redirecting to some type of logging | https://github.com/ipankajg/stracent |
| STrace | Kernel module and DTrace | https://github.com/mandiant/STrace |
I'm sure there are many others that I've missed.
Some of the requirements I wanted for ease of use:
- No kernel mode (Can't be something like my CallMon concept)
- No admin required
- Can trace win32k system calls
- Fast (ish)
- Use this for learning more about using Rust for Windows
Install RWX shellcode into a process and use it to communicate over a named pipe back to the server process. This method will be much faster than using breakpoints. Each system call stub inside ntdll has just enough instructions thanks to the int 0x2E detection test. This gives enough opcodes for our jump shellcode.
Before:
ntdll!NtCreateFile:
00007ffc`a62c2520 4c8bd1 mov r10,rcx
00007ffc`a62c2523 b855000000 mov eax,55h
00007ffc`a62c2528 f604250803fe7f01 test byte ptr [SharedUserData+0x308 (00000000`7ffe0308)],1
00007ffc`a62c2530 7503 jne ntdll!NtCreateFile+0x15 (00007ffc`a62c2535)
00007ffc`a62c2532 0f05 syscall
00007ffc`a62c2534 c3 ret
After:
ntdll!NtCreateFile:
00007ffc`a62c2520 4c8bd1 mov r10,rcx
00007ffc`a62c2523 b855000000 mov eax,55h
00007ffc`a62c2528 50 push rax
00007ffc`a62c2529 48b800000c0000000000 mov rax,0C0000h
00007ffc`a62c2533 ffe0 jmp rax
00007ffc`a62c2535 cd2e int 2Eh
00007ffc`a62c2537 c3 ret
In this example, obviously 0xC0000 is our remote shellcode. Also note that this shellcode is pre-system-call, so the data is written to the pipe before the actual system call instruction executes.

This method is not a 100% way to detect every system call. Malware or other programs that directly use syscall instruction not be traced.
- No Debugger object attached - Can "strace" and debug at the same time.
- No kernel driver required.
- Doesn't trap all uses of the
syscallinstruction. - Can only safely trace one process at a time.
- Currently not support for tracing an already running process.
- Better named pipe support so multiple processes can be traced at the same time.
- Support attaching to an already running process.
- File like
/etc/ltrace.confwhich provides basic type information so system call arguments can be parsed better and provide more detail. For example displaying the actual string in aUNICODE_STRINGstruct. - Need to hook all
win32u.dll(and maybe others) to get all possible win32k system calls. - Improve argument count, and maybe even get return NTSTATUS return value.
- (Windows System Call Table)[https://github.com/j00ru/windows-syscalls] by j00ru
- Assembler: FASM