Reputation: 2488
Using WinDBG's python extension I want to print only call instructions in console. [A kind of one step debugging ]
My Code:
from pykd import *
pid = raw_input ('pid >>> ')
id=attachProcess(int(pid))
print id
while 1:
trace()
r_o = dbgCommand('r')
line = r_o.split('\n')[-2]
sp_line = line.split()
addr = int(sp_line[0],16)
ins = sp_line[2]
if ins == "call":
print line
I tried above code and got below result.
Output :
C:\Program Files (x86)\Debugging Tools for Windows (x86)\winext>db.py
[+] Starting...
pid >>> 3516
0
76ec000d c3 ret
76f4f926 eb07 jmp ntdll!DbgUiRemoteBreakin+0x45 (76f4f92f)
76f4f92f c745fcfeffffff mov dword ptr [ebp-4],0FFFFFFFEh ss:002b:0029ff84=00000000
76f4f936 6a00 push 0
76f4f938 e8df86fbff call ntdll!RtlExitUserThread (76f0801c)
76ed0096 83c404 add esp,4
Here the problem seems to be, after the debugger breaks into the process, the debug thread gets initiated and the debug thread is getting terminated after sometime, because its the current thread [We can see last call is made to ntdll!RtlExitUserThread]. Hence even if the debugee app runs I don't see any thing in command line.
I've seen a script which uses winappdbg and does the similar operation. Here is the script :
https://github.com/MarioVilas/winappdbg/blob/master/tools/ptrace.py
And I want to build something similar.
Upvotes: 0
Views: 3466
Reputation: 9007
not a pykd answer but windbgs inbuilt pc/tc (step / trace to next call) will print out all the calls
0:000> .printf "%y\n" , @eip
multithread!wmain (00411430)
0:000> $ iam at start of winmain and i have disabled all output except disassembly via .prompt_allow
0:000> $ i have set a breakpoint on winmains exit
0:000> $ code for demo is exact copy paste of msdn sample code for createthread documentation
0:000> $lets roll and log all call instructions
0:000> tc 1000000
0041147c ff1530824100 call dword ptr [multithread!_imp__GetProcessHeap (00418230)]
00411484 e8e9fcffff call multithread!ILT+365(__RTC_CheckEsp) (00411172)
0041148a ff152c824100 call dword ptr [multithread!_imp__HeapAlloc (0041822c)]
7c955264 e827ffffff call ntdll!LdrpTagAllocateHeap (7c955190)
7c9551b0 e80faffbff call ntdll!RtlAllocateHeap (7c9100c4)
7c9100ce e8f8e7ffff call ntdll!_SEH_prolog (7c90e8cb)
removed =====================
7c923b25 e80b000000 call ntdll!LdrShutdownProcess+0x1e0 (7c923b35)
7c923b3a e8a1d5fdff call ntdll!RtlLeaveCriticalSection (7c9010e0)
7c923b2a e8d7adfeff call ntdll!_SEH_epilog (7c90e906)
7c81cac3 ff153410807c call dword ptr [kernel32!_imp__CsrClientCallServer (7c801034)]
7c912de3 e8f6acffff call ntdll!NtRequestWaitReplyPort (7c90dade)
7c90dae8 ff12 call dword ptr [edx]
7c90e512 0f34 sysenter
7c81cacc ffd6 call esi
7c90de78 ff12 call dword ptr [edx]
7c90e512 0f34 sysenter
7c90e514 c3 ret
if you are following the code in the msdn sample and would want to trace the thread calls a breakpoint ( hack but will work in most situations) can be used
.prompt_allow
to disable everything except dis-assembly
set a conditional break-point
on CreateThread
condition being setting another break point on poi(@esp+c)
LpThreadStartRoutine
and continuing
the next three pc 1000000
are step until next calls and one quit
we know we have three threads
in the sample so we automated pc 10000000
three times if you don't know
how many threads prior to execution manually enter pc 1000000 manually on each thread exit
.
:cdb -c ".prompt_allow -src -reg -sym -ea ;g wmain;bp kernel32!CreateThread \"ba e1 poi( @esp+c) \\"? $tid ;pc 100000 \\";gc\";pc 100000;pc 1000000;pc 1000000 ;pc 1000000;pc 10000000;pc 1000000; pc 10000000;q" multithread.exe | grep -iE "W rite|Eval"
Evaluate expression: 2148 = 00000864
004011c6 ff1520204000 call dword ptr [multithread!_imp__WriteConsoleW (004
02020)]
Evaluate expression: 2780 = 00000adc
004011c6 ff1520204000 call dword ptr [multithread!_imp__WriteConsoleW (004
02020)]
Evaluate expression: 3440 = 00000d70
004011c6 ff1520204000 call dword ptr [multithread!_imp__WriteConsoleW (004
02020)]
Upvotes: 3
Reputation: 59513
trace()
probably works the same way as t
in WinDbg. That means, it follows one thread only, while the other threads are frozen (frozen is similar to suspended, but visible for the debugger only, so even a thread is resumed it will still not execute if frozen).
When you trace the debugger thread, WinDbg will give you the warning
WARNING: Step/trace thread exited
if the thread exits. If you used Enter to repeat the t
command, it will stop working at that time. If you enter t
again, it behaves like g
(go, without tracing).
Since pykd uses the WinDbg API, I guess it will just do the same.
To trace a different thread in WinDbg, you would use ~5t
, where 5 is the thread number. I don't know a way in WinDbg to trace multiple threads simultaneously.
See also: Similar topic, answered by pykd team
Upvotes: 1