DynamoRIO / drmemory

Memory Debugger for Windows, Linux, Mac, and Android
Other
2.44k stars 262 forks source link

use kernel driver to identify output parameters written by system calls #468

Open derekbruening opened 9 years ago

derekbruening commented 9 years ago

From bruen...@google.com on June 21, 2011 15:07:08

filing an issue to cover the idea of using a driver that hooks the probe routines called by the kernel to detect output parameters and avoid false positives for unknown syscalls.

expected to be useful for offline analysis regardless. may not be usable in an online fashion for 64-bit kernels due to PatchGuard.

for writes via MDL: good enough to mark as written prior to the completion event (already doing that in drmem for any asynch write)

we have a prototype driver from siggi that hooks ProbeForWrite and MmProbeAndLockPages.

ProbeForRead is apparently not used in ntoskrnl (inlined checks are used instead) so ignoring for now but could help analyze drivers.

TODO for the driver: use PsSetCreateThreadNotifyRoutine for thread termination event

initial results:

-------------------------------- Issue #1 : ProbeForWrite covers user buffer capacity, not actual amount written

Example: The NtUserGetAtomName system call takes in a UNICODE_STRING as an OUT parameter. The syscall calls ProbeForWrite on the capacity of the string (MaximumLength), which in my app is 512 bytes. The syscall then goes and writes the real data, which is 30 bytes. The driver tells Dr. Memory that the kernel wrote 512 bytes when really only the first 30 of those bytes were written.

-------------------------------- Issue #2 : Driver seems to be missing quite a few kernel writes.

E.g., driver didn't detect any writes here: ZwQueryPerformanceCounter( OUT PLARGE_INTEGER PerformanceCount, OUT PLARGE_INTEGER PerformanceFrequency OPTIONAL ); processing post system call #0xa5 NtQueryPerformanceCounter res=0x0 post considering arg 0 8 1 start 0x0012ffa0, size 0x8 marking 0x12ffa0-0x12ffa8 written () post considering arg 1 8 1 start 0x0012ff8c, size 0x8 marking 0x12ff8c-0x12ff94 written () It seems the syscall was successful -- but maybe for some reason nothing was really written. I should print the contents before and after to confirm. But it seems likely that at least the non-optional would be written.

Here are more examples. They all seem to be short OUT params like PVOID or PULONG, except NtQueryValueKey's arg 3 == the OUT name and/or value buffer.

processing post system call #0x11 NtAllocateVirtualMemory res=0x0 marking 0x12ff20-0x12ff24 written () marking 0x12ff4c-0x12ff50 written ()

driver info: syscall #0xb2 write 0: 0x0012fcf8-0x0012fd14 processing post system call #0xb2 NtQueryVirtualMemory res=0x0 marking 0x12fcf8-0x12fd14 written () marking 0x12fcdc-0x12fce0 written ()

processing post system call #0x44 NtDuplicateObject res=0x0 marking 0x2b7c0d4-0x2b7c0d8 written ()

processing post system call #0x77 NtOpenKey res=0x0 marking 0x12fc04-0x12fc08 written ()

processing post system call #0xb1 NtQueryValueKey res=0x0 marking 0x12fab8-0x12fb48 written () marking 0x12faa8-0x12faac written ()

processing post system call #0x23 NtCreateEvent res=0x0 marking 0x12fbd0-0x12fbd4 written ()

processing post system call #0x7b NtOpenProcessToken res=0x0 marking 0x12fc70-0x12fc74 written ()

Original issue: http://code.google.com/p/drmemory/issues/detail?id=468

derekbruening commented 9 years ago

From bruen...@google.com on June 21, 2011 12:15:44

running calc, the driver removes quite a few uninits, but not all, and not as many as analyzing args plus using sentinels. this is calc on xp32sp3:

% bin/drmemory.exe -no_analyze_unknown_syscalls -batch -debug -- calc :::Dr.Memory::: 496 unique, 4353 total uninitialized access(es) % bin/drmemory.exe -syscall_driver -no_analyze_unknown_syscalls -batch -debug -- calc :::Dr.Memory::: 202 unique, 622 total uninitialized access(es)

% bin/drmemory.exe -batch -debug -- calc :::Dr.Memory::: 344 unique, 3281 total uninitialized access(es) % bin/drmemory.exe -syscall_driver -batch -debug -- calc :::Dr.Memory::: 131 unique, 264 total uninitialized access(es)

% bin/drmemory.exe -syscall_sentinels -batch -debug -- calc :::Dr.Memory::: 4 unique, 12 total uninitialized access(es) % bin/drmemory.exe -syscall_driver -syscall_sentinels -batch -debug -- calc :::Dr.Memory::: 2 unique, 3 total uninitialized access(es)

running ./net_unittests.exe --gtest_filter="URLRequestTestHTTP.ProxyTunnelRedirectTest": defaults: :::Dr.Memory::: 186 unique, 1206 total uninitialized access(es) -syscall_driver: :::Dr.Memory::: 92 unique, 100 total uninitialized access(es)

derekbruening commented 9 years ago

From derek.br...@gmail.com on October 28, 2011 07:47:29

This issue was closed by revision r575 .

Status: Fixed

derekbruening commented 9 years ago

From bruen...@google.com on October 28, 2011 07:48:17

typo in commit log

Status: Accepted