Strace for NT is a debugging/investigation utility for examining the
NT system calls made by a process. It is meant to be used like the
strace (or truss) on linux and other unix OSes.
How do I use it?
Take the strace.exe and strace.sys from the distribution (or build
them from the sources yourself), and put them together in some
directory on your local hard disk. Then, just run, e.g.,
[c:\strace] strace notepad
and you should see something like:
1 133 139 NtOpenKey (0x80000000, {24, 0, 0x40, 0, 0, "\Registry\Machine [...]
2 133 139 NtCreateEvent (0x100003, 0x0, 1, 0, ... 8, ) == 0x0
3 133 139 NtAllocateVirtualMemory (-1, 1243984, 0, 1244028, 8192, 4, ... ) == 0x0
4 133 139 NtAllocateVirtualMemory (-1, 1243980, 0, 1244032, 4096, 4, ... ) == 0x0
5 133 139 NtAllocateVirtualMemory (-1, 1243584, 0, 1243644, 4096, 4, ... ) == 0x0
6 133 139 NtOpenDirectoryObject (0x3, {24, 0, 0x40, 0, 0, "\KnownDlls"}, ... 12, ) == 0x0
7 133 139 NtOpenSymbolicLinkObject (0x1, {24, 12, 0x40, 0, 0, "KnownDllPath"}, ... 16, ) == 0x0
8 133 139 NtQuerySymbolicLinkObject (16, ... "C:\WINNT\system32", 0x0, ) == 0x0
9 133 139 NtClose (16, ... ) == 0x0
.
.
.
The first column is an identity, which lets you match up calls that
don't complete immediately (and are broken onto two lines). The
second and third columns are the process and thread ids of the thread
making the call. Next is the name of the system call, the input
parameters, three dots (...), then output parameters, and the return
code.
You can also choose to strace a currently running process by
specifying its pid, e.g., if you want to see what winlogon.exe does
when you hit Ctrl-Alt-Del, find its pid with taskmgr, and then
[c:\strace] strace -p 34
1 34 33 NtUserPeekMessage (1244272, 0, 0, 0, 1, 1244192, ... ) == 0x1
2 34 33 NtUserLockWindowStation (68, ... ) == 0x1
3 34 33 NtUserOpenInputDesktop (0, 0, 33554432, ... ) == 0xd8
4 34 33 NtUserGetObjectInformation (216, 2, 0, 0, 1244100, ... ) == 0x0
5 34 33 NtUserGetObjectInformation (216, 2, 1294320, 16, 1244100, ... ) == 0x1
6 34 33 NtUserSwitchDesktop (84, ...
7 34 33 NtOpenKey (0x20019, {24, 0, 0x40, 0, 0, "\Registry\Machine\Hardware\DeviceMap\Video"}, ... 244, ) == 0x0
8 34 33 NtQueryValueKey (244, "\Device\Video0", 1, -203229988, 512, -203229476, ... ) == 0x0
9 34 33 NtOpenKey (0x20019, {24, 0, 0x40, 0, 0, "\Registry\Machine\System\CurrentControlSet [...]
10 34 33 NtClose (244, ... ) == 0x0
.
.
.
You can choose to strace all processes, by specifying a pid of
0. Be sure to read the shortcomings section below before doing this.
How does it work?
It uses the same system call hooking technique described by
Undocumented Windows NT, and used by NTRegMon and other utilities. What
make strace different is that is hooks every system call
instead of just selected ones.
The hooking is done by a device driver which also collects data.
There is a user space application which loads the driver, tells it
what to trace, and then pulls the data and prints it out.
Since NT doesn't provide a good means of putting proper security
descriptors on devices (see sysinternals), and
the workaround presented there is apparently still vulnerable to
races, the strace device instead checks for the SeDebugPrivilege
before allowing the user space application to open it. This means
that by default, only administrators can run strace successfully. If
non-admins are granted the SeDebugPrivilege, they'll be able to run
strace as well, but the SeDebugPrivilege gives users multiple avenues
of promoting themselves to admin, anyway.
Check out the source for all the gory details, although be warned that
you need to be pretty up on the C preprocessor to understand it.
What versions of NT does it support?
NT4 SP4, SP5, and SP6; Windows 2000 GA. Support for earlier NT4
service packs could be added without much trouble, if people want
it.
Shortcomings
- It doesn't pass the ntcrash test, so don't run it on a production
box or you may be in for a nasty surprise (BSOD). There's code which
is meant to prevent this, but it's not effective. I'm not sure why at
this point.
- Naturally, there are lots of NT system calls that aren't documented
anywhere. Argument types for many calls need to be figured out before
they can be decoded.
- For technical reasons, once loaded the driver will not let you
unload it. So, if you want to get rid of it completely, you'll need
to reboot. The reason for this is that because it hooks every system
call there will be outstanding calls with return addresses in strace's
driver. If the driver is unloaded, the system will blue screen when
it eventually tries to return to that address.
- When doing "strace -p 0" (trace all processes), you see tons of
writes and ioctls. That's actually strace itself. I'm planning to
filter that out.
- You can only be doing one strace at a time. Actually, that's a
limitation in the driver, so if you run two strace apps, you'll
probably end up with both of them outputing the trace of whichever one
started last.
- Beware stracing csrss without redirecting to a file. All writes
to a console apparently go through csrss, so you can get some really
bad feedback going on.
Warnings
This is the first public release, and should be considered
ALPHA quality. As mentioned above, it's possible that you may
get blue screens as a result of using it. Be sure to read all of the
Shortcomings above.
Is there source?
Yes. Full source code is provided, under the terms of BindView's
Open Source license (included in the distribution). There's quite
a lot that can be added, including the parameter types of tons
of system calls, so if you know of any that aren't included, please
send me mail at tsabin@bos.bindview.com. Also, feel free to contribute
actual code, subject to the license.
Download
Strace-0.1.zip