How to do continuous Step Debugging[Step Over/Into] using PyKd

Jan 21, 2015 at 7:25 PM
Hi,

I'm trying to continuous step debugging using pykd using infinite while loop and in each step when the debugger breaks, do some operation.

1-> Do some operation (mainly collect info)
2-> Go one step/instruction forward (Actually Step Over [F10])
3-> Repeat same operation done in step 1 (collect info)

and so on
from pykd import *
while 1:
       #Do stuff
       #Do Stuff
       step()
But always my debugger is getting hanged and sometimes its crashing, Is there any other way to do this ??

Thanks,
Developer
Jan 21, 2015 at 8:35 PM
"But always my debugger is getting hanged"
while 1:
    #Do stuff
It is look like infinite loop. May be the debbuger is not hanged but hard working? Try to added debug output in the loop.

"sometimes its crashing"
can you get a crash dump?

In my experience, scripts like yours work unstable inside windbg. Windbg has special loop for waiting and handling debug events. The normal algorithm for windbg:
1)wait for debug event ( break )
2)handle event
3) wait for user command
4) if command is g, p, t - change execution status of the target and go to point 1)
But when you call pykd routines like step() this algorithm is changed: pykd has own loop for debug events waiting.

Try to move you work outside windbg. Pykd can work within standalone python applicaton. All you need to added some code for starting debugging:
startProcess( "my_target_app  param1 param2" ) #start debugging
setBp( my_func ) #set breakpoint on the investigated code
go() #go until breakpoint is hit

while 1:
       #Do stuff
       #Do Stuff
       step()
You can try to run your script with karmadbg ( https://karmadbg.codeplex.com/)
Type %run script_name in the command line, may be you will more fortunate with karmadbg ( and you will have one benefit with karmadbg: visual script debugging with %rund macro command )
Jan 22, 2015 at 9:20 AM
Thanks for your reply. I guess you were right when I thought its getting hanged because it was actually working hard. So I moved out of windbg and ruunnng the script externally. To test I modified the code in this way.
from pykd import *
from pykd import *

pid = raw_input(' Enter PID >>> ')
d=attachProcess(int(pid))
print d
while 1:
    dprintln('Hello!!')
    r_o = dbgCommand('r')
    dprintln(r_o)
    step()
Here I should continuously get "Hello" and "r" command output in command prompt. I get for few instruction, but after sometime it stopped printing "Hello" and "r" command output. Here is my out put
C:\Program Files (x86)\Debugging Tools for Windows (x86)\winext>python test.py
 Enter PID >>> 6736
0
Hello!!
eax=7ef64000 ebx=00000000 ecx=00000000 edx=777cf8ea esi=00000000 edi=00000000
eip=7774000c esp=0f6dfa94 ebp=0f6dfac0 iopl=0         nv up ei pl zr na pe nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000246
ntdll!DbgBreakPoint:
7774000c cc              int     3

Hello!!
eax=7ef64000 ebx=00000000 ecx=00000000 edx=777cf8ea esi=00000000 edi=00000000
eip=7774000d esp=0f6dfa94 ebp=0f6dfac0 iopl=0         nv up ei pl zr na pe nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000244
ntdll!DbgBreakPoint+0x1:
7774000d c3              ret

Hello!!
eax=7ef64000 ebx=00000000 ecx=00000000 edx=777cf8ea esi=00000000 edi=00000000
eip=777cf926 esp=0f6dfa98 ebp=0f6dfac0 iopl=0         nv up ei pl zr na pe nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000246
ntdll!DbgUiRemoteBreakin+0x3c:
777cf926 eb07            jmp     ntdll!DbgUiRemoteBreakin+0x45 (777cf92f)

Hello!!
eax=7ef64000 ebx=00000000 ecx=00000000 edx=777cf8ea esi=00000000 edi=00000000
eip=777cf92f esp=0f6dfa98 ebp=0f6dfac0 iopl=0         nv up ei pl zr na pe nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000246
ntdll!DbgUiRemoteBreakin+0x45:
777cf92f c745fcfeffffff  mov     dword ptr [ebp-4],0FFFFFFFEh ss:002b:0f6dfabc=00000000

Hello!!
eax=7ef64000 ebx=00000000 ecx=00000000 edx=777cf8ea esi=00000000 edi=00000000
eip=777cf936 esp=0f6dfa98 ebp=0f6dfac0 iopl=0         nv up ei pl zr na pe nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000246
ntdll!DbgUiRemoteBreakin+0x4c:
777cf936 6a00            push    0

Hello!!
eax=7ef64000 ebx=00000000 ecx=00000000 edx=777cf8ea esi=00000000 edi=00000000
eip=777cf938 esp=0f6dfa94 ebp=0f6dfac0 iopl=0         nv up ei pl zr na pe nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000246
ntdll!DbgUiRemoteBreakin+0x4e:
777cf938 e8df86fbff      call    ntdll!RtlExitUserThread (7778801c)

Hello!!
eax=00000000 ebx=00000000 ecx=00000000 edx=00000000 esi=00000000 edi=00000000
eip=77750096 esp=0f6dfa74 ebp=0f6dfa8c iopl=0         nv up ei pl zr na pe nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000246
ntdll!ZwTerminateThread+0x12:
77750096 83c404          add     esp,4


Is there anything extra I need to add to fix this.,
Coordinator
Jan 22, 2015 at 12:02 PM
It is OK. Note, the last instruction is ZwTerminateThread + 12. When debugger attached to the process or break into the attached process, windows create a special debug thread. This thread is current. After debug continuing this thread is terminated ( you have seen last moment of the thread life ntdll!ZwTerminateThread+0x12: ) and process stay in running mode. You can repeat this situation manually in windbg: after step through ntdll!ZwTerminateThread the process ill be in running state.

If you want to trace special piece of code, you should:
1) set breakpoint on this code.
2) call go() and wait for the breakpoint is hit.

Another approach:
switch to another thread ( but you should have an algorithm for interesting thread finding )
Jan 22, 2015 at 3:08 PM
Actually I want to build a script similar to this https://github.com/MarioVilas/winappdbg/blob/master/tools/ptrace.py using PyKD. It has a nice option --trace for one step debugging capabilities.
Developer
Jan 22, 2015 at 3:49 PM
Try to change 'step()' to 'trace()'. This routine looks similar, but they has quite different implementation on the CPU level. 'trace()' uses capability of CPU which generate exception ( trace ) after every instruction. 'step()' use software breakpoints and for some situation ( as a thread stopping ) can 'lose' execution flow.
Jan 22, 2015 at 6:05 PM
I believe the main problem I'm facing right now which "kernelnet" has mentioned..
When debugger attached to the process or break into the attached process, windows create a special debug thread. This thread is current. After debug continuing this thread is terminated
Is there any way you guys can suggest by which I can spontaneously shift to another active thread ??
Developer
Jan 22, 2015 at 8:21 PM
It is not possible in general. Debugger does not change real thread context, only OS can change current thread.
The only way: set breakpoint on the IP of the interesting thread and wait for breakpoint hitting.
But first of all, try to use trace() function: it will work through different thread.
Developer
Jan 22, 2015 at 9:13 PM
Try to add to your script:
class ExecutionMonitor(eventHandler):

    def onExecutionStatusChange(self, executionStatus):
    if executionStatus == executionStatus.Go:
            breakin()

mon = ExecutionMonitor()
This code will forcibly break running of the target process
Jan 23, 2015 at 2:37 PM
Code With Trace():
from pykd import *

pid = raw_input(' Enter PID >>> ')
d=attachProcess(int(pid))
print d
while 1:
    dprintln('Hello!!')
    r_o = dbgCommand('r')
    dprintln(r_o)
    trace()
Output :
C:\Program Files (x86)\Debugging Tools for Windows (x86)\winext>python db.py
[+] Starting...
 Enter PID >>> 1824
0
Hello!!
eax=7efd7000 ebx=00000000 ecx=00000000 edx=771cf8ea esi=00000000 edi=00000000
eip=7714000c esp=009bff5c ebp=009bff88 iopl=0         nv up ei pl zr na pe nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000246
ntdll!DbgBreakPoint:
7714000c cc              int     3

Hello!!
eax=7efd7000 ebx=00000000 ecx=00000000 edx=771cf8ea esi=00000000 edi=00000000
eip=7714000d esp=009bff5c ebp=009bff88 iopl=0         nv up ei pl zr na pe nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000244
ntdll!DbgBreakPoint+0x1:
7714000d c3              ret

Hello!!
eax=7efd7000 ebx=00000000 ecx=00000000 edx=771cf8ea esi=00000000 edi=00000000
eip=771cf926 esp=009bff60 ebp=009bff88 iopl=0         nv up ei pl zr na pe nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000246
ntdll!DbgUiRemoteBreakin+0x3c:
771cf926 eb07            jmp     ntdll!DbgUiRemoteBreakin+0x45 (771cf92f)

Hello!!
eax=7efd7000 ebx=00000000 ecx=00000000 edx=771cf8ea esi=00000000 edi=00000000
eip=771cf92f esp=009bff60 ebp=009bff88 iopl=0         nv up ei pl zr na pe nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000246
ntdll!DbgUiRemoteBreakin+0x45:
771cf92f c745fcfeffffff  mov     dword ptr [ebp-4],0FFFFFFFEh ss:002b:009bff84=00000000

Hello!!
eax=7efd7000 ebx=00000000 ecx=00000000 edx=771cf8ea esi=00000000 edi=00000000
eip=771cf936 esp=009bff60 ebp=009bff88 iopl=0         nv up ei pl zr na pe nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000246
ntdll!DbgUiRemoteBreakin+0x4c:
771cf936 6a00            push    0

Hello!!
eax=7efd7000 ebx=00000000 ecx=00000000 edx=771cf8ea esi=00000000 edi=00000000
eip=771cf938 esp=009bff5c ebp=009bff88 iopl=0         nv up ei pl zr na pe nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000246
ntdll!DbgUiRemoteBreakin+0x4e:
771cf938 e8df86fbff      call    ntdll!RtlExitUserThread (7718801c)

Hello!!
eax=7efd7000 ebx=00000000 ecx=00000000 edx=771cf8ea esi=00000000 edi=00000000
eip=7718801c esp=009bff58 ebp=009bff88 iopl=0         nv up ei pl zr na pe nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000246
ntdll!RtlExitUserThread:
7718801c 8bff            mov     edi,edi

Hello!!
eax=7efd7000 ebx=00000000 ecx=00000000 edx=771cf8ea esi=00000000 edi=00000000
eip=7718801e esp=009bff58 ebp=009bff88 iopl=0         nv up ei pl zr na pe nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000246
ntdll!RtlExitUserThread+0x2:
7718801e 55              push    ebp

Hello!!
eax=7efd7000 ebx=00000000 ecx=00000000 edx=771cf8ea esi=00000000 edi=00000000
eip=7718801f esp=009bff54 ebp=009bff88 iopl=0         nv up ei pl zr na pe nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000246
ntdll!RtlExitUserThread+0x3:
7718801f 8bec            mov     ebp,esp

Hello!!
eax=7efd7000 ebx=00000000 ecx=00000000 edx=771cf8ea esi=00000000 edi=00000000
eip=77188021 esp=009bff54 ebp=009bff54 iopl=0         nv up ei pl zr na pe nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000246
ntdll!RtlExitUserThread+0x5:
77188021 51              push    ecx

Hello!!
eax=7efd7000 ebx=00000000 ecx=00000000 edx=771cf8ea esi=00000000 edi=00000000
eip=77188022 esp=009bff50 ebp=009bff54 iopl=0         nv up ei pl zr na pe nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000246
ntdll!RtlExitUserThread+0x6:
77188022 56              push    esi

Hello!!
eax=7efd7000 ebx=00000000 ecx=00000000 edx=771cf8ea esi=00000000 edi=00000000
eip=77188023 esp=009bff4c ebp=009bff54 iopl=0         nv up ei pl zr na pe nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000246
ntdll!RtlExitUserThread+0x7:
77188023 33f6            xor     esi,esi

Hello!!
eax=7efd7000 ebx=00000000 ecx=00000000 edx=771cf8ea esi=00000000 edi=00000000
eip=77188025 esp=009bff4c ebp=009bff54 iopl=0         nv up ei pl zr na pe nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000246
ntdll!RtlExitUserThread+0x9:
77188025 56              push    esi

Hello!!
eax=7efd7000 ebx=00000000 ecx=00000000 edx=771cf8ea esi=00000000 edi=00000000
eip=77188026 esp=009bff48 ebp=009bff54 iopl=0         nv up ei pl zr na pe nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000246
ntdll!RtlExitUserThread+0xa:
77188026 6a04            push    4

Hello!!
eax=7efd7000 ebx=00000000 ecx=00000000 edx=771cf8ea esi=00000000 edi=00000000
eip=77188028 esp=009bff44 ebp=009bff54 iopl=0         nv up ei pl zr na pe nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000246
ntdll!RtlExitUserThread+0xc:
77188028 8d45fc          lea     eax,[ebp-4]

Hello!!
eax=009bff50 ebx=00000000 ecx=00000000 edx=771cf8ea esi=00000000 edi=00000000
eip=7718802b esp=009bff44 ebp=009bff54 iopl=0         nv up ei pl zr na pe nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000246
ntdll!RtlExitUserThread+0xf:
7718802b 50              push    eax

Hello!!
eax=009bff50 ebx=00000000 ecx=00000000 edx=771cf8ea esi=00000000 edi=00000000
eip=7718802c esp=009bff40 ebp=009bff54 iopl=0         nv up ei pl zr na pe nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000246
ntdll!RtlExitUserThread+0x10:
7718802c 6a0c            push    0Ch

Hello!!
eax=009bff50 ebx=00000000 ecx=00000000 edx=771cf8ea esi=00000000 edi=00000000
eip=7718802e esp=009bff3c ebp=009bff54 iopl=0         nv up ei pl zr na pe nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000246
ntdll!RtlExitUserThread+0x12:
7718802e 6afe            push    0FFFFFFFEh

Hello!!
eax=009bff50 ebx=00000000 ecx=00000000 edx=771cf8ea esi=00000000 edi=00000000
eip=77188030 esp=009bff38 ebp=009bff54 iopl=0         nv up ei pl zr na pe nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000246
ntdll!RtlExitUserThread+0x14:
77188030 8975fc          mov     dword ptr [ebp-4],esi ss:002b:009bff50=00000000

Hello!!
eax=009bff50 ebx=00000000 ecx=00000000 edx=771cf8ea esi=00000000 edi=00000000
eip=77188033 esp=009bff38 ebp=009bff54 iopl=0         nv up ei pl zr na pe nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000246
ntdll!RtlExitUserThread+0x17:
77188033 e8d07bfcff      call    ntdll!ZwQueryInformationThread (7714fc08)

Hello!!
eax=009bff50 ebx=00000000 ecx=00000000 edx=771cf8ea esi=00000000 edi=00000000
eip=7714fc08 esp=009bff34 ebp=009bff54 iopl=0         nv up ei pl zr na pe nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000246
ntdll!ZwQueryInformationThread:
7714fc08 b822000000      mov     eax,22h

Hello!!
eax=00000022 ebx=00000000 ecx=00000000 edx=771cf8ea esi=00000000 edi=00000000
eip=7714fc0d esp=009bff34 ebp=009bff54 iopl=0         nv up ei pl zr na pe nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000246
ntdll!ZwQueryInformationThread+0x5:
7714fc0d 33c9            xor     ecx,ecx

Hello!!
eax=00000022 ebx=00000000 ecx=00000000 edx=771cf8ea esi=00000000 edi=00000000
eip=7714fc0f esp=009bff34 ebp=009bff54 iopl=0         nv up ei pl zr na pe nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000246
ntdll!ZwQueryInformationThread+0x7:
7714fc0f 8d542404        lea     edx,[esp+4]

Hello!!
eax=00000022 ebx=00000000 ecx=00000000 edx=009bff38 esi=00000000 edi=00000000
eip=7714fc13 esp=009bff34 ebp=009bff54 iopl=0         nv up ei pl zr na pe nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000246
ntdll!ZwQueryInformationThread+0xb:
7714fc13 64ff15c0000000  call    dword ptr fs:[0C0h]  fs:0053:000000c0=73692320

Hello!!
eax=00000022 ebx=00000000 ecx=00000000 edx=009bff38 esi=00000000 edi=00000000
eip=73692320 esp=009bff30 ebp=009bff54 iopl=0         nv up ei pl zr na pe nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000246
73692320 ea1e2769733300  jmp     0033:7369271E

Hello!!
eax=771cf8ea ebx=00000000 ecx=00000000 edx=00000000 esi=00000000 edi=00000000
eip=771401b4 esp=009bfff0 ebp=00000000 iopl=0         nv up ei pl nz na po nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000202
ntdll!RtlUserThreadStart:
771401b4 89442404        mov     dword ptr [esp+4],eax ss:002b:009bfff4={ntdll!DbgUiRemoteBreakin (771cf8ea)}

Hello!!
eax=00000000 ebx=00000000 ecx=00000000 edx=00000000 esi=00000000 edi=00000000
eip=77150096 esp=009bff3c ebp=009bff54 iopl=0         nv up ei pl zr na pe nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000246
ntdll!ZwTerminateThread+0x12:
77150096 83c404          add     esp,4

After this target process is running but still no new entry in command prompt :(
Coordinator
Jan 26, 2015 at 8:39 AM
Do you want to trace the first thread?
>>> import pykd
>>> pykd.attachProcess(4828)
0
>>> pykd.setCurrentThread( pykd.getProcessThreads()[0] )
>>> bp = pykd.setBp( pykd.getStack()[0].ip )
>>> pykd.go()
pykd.executionStatus.Break
>>> bp.remove()
>>> for i in range(128):
...   print pykd.findSymbol(pykd.getStack()[0].ip)
...   x =pykd.trace()
...
USER32!GetMessageW+54
USER32!GetMessageW+58
USER32!GetMessageW+59
calc!WinMain+1dca
calc!WinMain+1dcd
calc!WinMain+1cbd
calc!WinMain+1cc4
calc!WinMain+1ccb
calc!WinMain+1cd3
USER32!TranslateAcceleratorW
USER32!TranslateAcceleratorW+4
USER32!TranslateAcceleratorW+7
USER32!TranslateAcceleratorW+d
....