hasherezade / tiny_tracer

A Pin Tool for tracing API calls etc
1.25k stars 138 forks source link

Unable to trace Nanodump syscalls #29

Closed hxnoyd closed 1 year ago

hxnoyd commented 1 year ago

I'm trying to use tiny trace to trace Nanodump (https://github.com/fortra) syscalls but with no success.

For example, I'm trying to trace NtCreateFile, used to write the dump on disk, using the following in params.txt:

ntdll;NtCreateFile;11
<SYSCALL>;0x55;11

My TinyTracer.ini has TRACE_SYSCALL=True:

ENABLE_SHORT_LOGGING=True
FOLLOW_SHELLCODES=1
;FOLLOW_SHELLCODES:
; 0 : trace only the main target module
; 1 : follow only the first shellcode called from the main module
; 2 : follow also the shellcodes called recursively from the the original shellcode
; 3 : follow any shellcodes
TRACE_RDTSC=False
TRACE_SYSCALL=True
LOG_SECTIONS_TRANSITIONS=True
LOG_SHELLCODES_TRANSITIONS=True
HEXDUMP_SIZE=8
HOOK_SLEEP=False
SLEEP_TIME=10
LOG_INDIRECT_CALLS=False

When running nanodump, the nanodump.x64.exe.tag file does not seem to be tracing the syscall:

54be;kernel32.HeapFree
54a6;kernel32.GetProcessHeap
54be;kernel32.HeapFree
9722;ntdll.[ZwCreateFile+12]*
9779;ntdll.[NtWriteFile+12]*
94b8;ntdll.[NtClose+12]*
13800;msvcrt.strrchr
13a30;msvcrt.__iob_func
13878;msvcrt.fprintf

I'm probably doing something wrong. Could you give me some hints?

Thanks in advance!

hasherezade commented 1 year ago

Hi! I am gonna check it... Few questions: 1) Are you sure that application uses direct syscalls, called from the main module? If it uses them via DLL, they won't be included in the log. 2) Are your sure that the execution path that you deployed uses direct syscalls?

hasherezade commented 1 year ago

ok, I checked it and I see what is the reason. The syscalls are actually called via NTDLL. This is the part of the code responsible for the syscalls implementation:

https://github.com/fortra/nanodump/blob/main/source/syscalls-asm.asm

example:


NtOpenProcess PROC
    mov [rsp +8], rcx
    mov [rsp+16], rdx
    mov [rsp+24], r8
    mov [rsp+32], r9
    mov rcx, 0CD9B2A0Fh
    push rcx
    sub rsp, 028h
    call SW3_GetSyscallAddress
    add rsp, 028h
    pop rcx
    push rax
    sub rsp, 028h
    call SW2_GetSyscallNumber
    add rsp, 028h
    pop r11
    mov rcx, [rsp+8]
    mov rdx, [rsp+16]
    mov r8, [rsp+24]
    mov r9, [rsp+32]
    mov r10, rcx
    jmp r11
NtOpenProcess ENDP

While the syscall is extracted in the main application, yet, it isn't called from the main application. Actually, the jmp r11 redirects the exection to NTDLL.

Step 1 - in the main application:

syscall_step1

Step 2 - in the NTDLL (where the syscall is actually called):

syscall_called2

This is how it looks in the tracelog:

syscall_called

Long story short - it is not a bug in the tracer, because the tracer is supposed to log the syscalls only from the module that is under the observation.