Использование расширения Python для Windbg PyKD для печати / разрыва только при вызове инструкций
Используя расширение Python WinDBG, я хочу печатать только инструкции вызова в консоли. [Своего рода один шаг отладки]
Мой код:
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
Я попробовал код выше и получил результат ниже.
Выход:
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
Здесь проблема, по-видимому, заключается в том, что после того, как отладчик врывается в процесс, поток отладки инициируется, а поток отладки завершается через некоторое время, потому что это текущий поток [Мы можем видеть, что последний вызов сделан для ntdll!RtlExitUserThread]. Следовательно, даже если приложение debugee запускается, я не вижу ничего в командной строке.
Я видел скрипт, который использует winappdbg и выполняет аналогичную операцию. Вот сценарий:
https://github.com/MarioVilas/winappdbg/blob/master/tools/ptrace.py
И я хочу построить нечто подобное.
2 ответа
Не pykd-ответ, а встроенный в windbgs pc / tc (шаг / трассировка до следующего вызова) распечатает все вызовы
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> тс 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
если вы следуете коду в образце msdn и хотите отследить, что поток вызывает точку останова (может быть использована в большинстве случаев, но не работает)
.prompt_allow
отключить все, кроме разборки
установить conditional break-point
на CreateThread
состояние setting another break point on poi(@esp+c)
LpThreadStartRoutine
а также continuing
next three pc 1000000
шаг до следующего звонка и one quit
мы know we have three threads
в образце, поэтому мы автоматизировали ПК 10000000
три раза if you don't know
сколько потоков до выполнения вручную 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\"; ПК 100000; ПК 1000000; ПК 1000000; ПК 1000000; ПК 10000000; ПК 1000000; ПК 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)]
trace()
вероятно, работает так же, как t
в WinDbg. Это означает, что он следует только за одним потоком, в то время как другие потоки заморожены (замороженные аналогичны приостановленным, но видимы только для отладчика, поэтому даже возобновление потока все равно не будет выполняться, если заморожено).
Когда вы отслеживаете поток отладчика, WinDbg выдаст вам предупреждение
ВНИМАНИЕ: шаг / трассировка завершена
если поток выходит. Если вы использовали Enter, чтобы повторить t
команда, он перестанет работать в это время. Если вы введете t
опять же, он ведет себя как g
(иди, без отслеживания).
Поскольку pykd использует WinDbg API, я думаю, он будет делать то же самое.
Чтобы проследить другой поток в WinDbg, вы должны использовать ~5t
где 5 - номер потока. Я не знаю способ в WinDbg отслеживать несколько потоков одновременно.
Смотрите также: Подобная тема, ответила команда pykd