Windbg скриптинг, присваивающий результат переменной переменной
Я регулярно проверяю дампфайлы, всегда одинаково, и я хотел бы автоматизировать это. Я использую Windbg в качестве инструмента, и я думаю об использовании сценариев Windbg.
Я сделал несколько первых попыток с PYKD, но мне не очень нравятся накладные расходы, поэтому я выбрал стандартный сценарий Windbg, но это становится кошмаром, позвольте мне показать вам, что я хочу сделать:
0:001> kb
# RetAddr : Args to Child : Call Site
00 00007ffc`26272685 : ffffffff`fffffffe 00007ff7`06e563f0 00007ff7`00000000 0000005a`1fb6fd70 : user32!NtUserGetMessage+0xa
01 00007ff7`06d87596 : 00000000`00000008 00007ff7`06e5d048 00000000`00007c1c 0000005a`00000004 : user32!GetMessageW+0x25
02 00007ff7`06d87673 : 0000005a`1f2b3710 00007ff7`06e5c7d0 0000005a`1f2ac270 00000000`00000002 : <Application>!CServiceModule::Run+0x8ee [sourcefile.cpp @ 1905]
03 00007ffc`26875ada : 00000000`00000000 00000000`00000000 00000000`00000000 00000000`00000000 : <Application>!CServiceModule::ServiceMain+0x63 [sourcefile.cpp @ 1379]
04 00007ffc`26ef13d2 : 00007ffc`26875aa0 0000005a`1f2ac270 00000000`00000000 00000000`00000000 : sechost!ScSvcctrlThreadA+0x3a
05 00007ffc`270454f4 : 00007ffc`26ef13b0 00000000`00000000 00000000`00000000 00000000`00000000 : kernel32!BaseThreadInitThunk+0x22
06 00000000`00000000 : 00000000`00000000 00000000`00000000 00000000`00000000 00000000`00000000 : ntdll!RtlUserThreadStart+0x34
0:001> dx Debugger.Sessions[0].Processes[26520].Threads[14812].Stack.Frames[2].SwitchTo();dv /t /v
// The second command "dx ..." happens by clicking on the DML link of the line, corresponding with the line, containing "CServiceModule::Run".
Теперь, как это сделать в скрипте Windbg?
- Запустить
kb
команда и положить результат в переменную. (Как это сделать? Я уже пытался с помощьюas
а такжеaS
но ни одна из них не работает) Если я не могу получить весь
kb
результат в одну переменную, попробуйте использовать.foreach
, как в следующем примере:.foreach ( token { kb} ) { .printf "TEST\n" }
=> даже это не работает:
kb
имеет около 8 строк результатов, а словоTEST
печатается 78 раз.Вместо того, чтобы печатать слово "ТЕСТ", выведите переменную
token
и посмотрим, как это выглядит.
=> Как это сделать? Я уже пробовала.printf "%msu \n" , ${token}
, или же@$token
... но ничего не работает.Даже если мне это удастся: как я могу выполнять строковые операции, преобразование десятичных / шестнадцатеричных чисел, ...?
Не забыть: как мне скомпилировать такой скрипт? В настоящее время я пытаюсь запустить скрипт в Windbg, который иногда выдает ошибки компиляции, но они очень нечитаемы (я добавляю новую строку, вызывающую проблему, но ошибка усложнения (не опечатка) даже не упоминает, что недавно добавленные линия).
Вы можете сказать: просто посмотрите на примеры, упомянутые в этом URL, но я не могу найти один пример стандартной команды Windbg, которая выполняется, и ее результат хранится в переменной (это первое, что мне нужно сделать).
В случае, если мой скрипт работает, я могу превратить этот пост в общий "FAQ по скриптингу Windbg" для упомянутых (и недавно добавленных) вопросов.
Изменить после первого ответа
Я понимаю, что я ошибся с kb
команда: фактическая команда мне нужно использовать ~* k
, давая следующий результат:
(Небольшое замечание: у меня есть просто скриншот вместо текстовой копии, чтобы подчеркнуть гиперссылки DML)
Как видите, есть некоторые результаты DML, и я хотел бы "щелкнуть" по строке, содержащей CServiceModule::Run
, Когда я делаю это вручную, кажется, что есть перевод к следующей команде:
dx Debugger.Sessions[0].Processes[26520].Threads[14812].Stack.Frames[2].SwitchTo()
Здесь 26520 - это преобразование HexToDec в 6798,
и 14812 - это преобразование HexToDec в 39DC.
(Оба должны быть получены из скриншота Id: 6798.39dc
)
Поэтому мне "нужно" манипулирование строками и преобразование HexToDec, чтобы имитировать щелчки DML. Однако, если вы знаете более простой способ сделать это действие "щелчком" в сценарии, я был бы очень благодарен!
1 ответ
Для.foreach пробел является разделителем, эта команда не предназначена для чтения строк
если вы хотите распечатать токен, используйте его как в псевдониме интерпретатора
0:001> kb
# ChildEBP RetAddr Args to Child
00 0147fa44 7706f20f 7642d6f7 00000000 00000000 ntdll!DbgBreakPoint
01 0147fa74 75d1ed6c 00000000 0147fac0 770337eb ntdll!DbgUiRemoteBreakin+0x3c
02 0147fa80 770337eb 00000000 7642d643 00000000 kernel32!BaseThreadInitThunk+0xe
03 0147fac0 770337be 7706f1d3 00000000 00000000 ntdll!__RtlUserThreadStart+0x70
04 0147fad8 00000000 7706f1d3 00000000 00000000 ntdll!_RtlUserThreadStart+0x1b
0:001> r $t0 =0 ;.foreach (token { kb } ) { r $t0 = @$t0+1 ; .printf "\"token\" %2d ${token}\n" , @$t0 }
"token" 1 #
"token" 2 ChildEBP
"token" 3 RetAddr
"token" 4 Args
"token" 5 to
"token" 6 Child
"token" 7 00
"token" 8 0147fa44
"token" 9 7706f20f
"token" 10 7642d6f7
"token" 11 00000000
"token" 12 00000000
"token" 13 ntdll!DbgBreakPoint
"token" 14 01
"token" 15 0147fa74
"token" 16 75d1ed6c
"token" 17 00000000
"token" 18 0147fac0
"token" 19 770337eb
"token" 20 ntdll!DbgUiRemoteBreakin+0x3c
"token" 21 02
"token" 22 0147fa80
"token" 23 770337eb
"token" 24 00000000
"token" 25 7642d643
"token" 26 00000000
"token" 27 kernel32!BaseThreadInitThunk+0xe
"token" 28 03
"token" 29 0147fac0
"token" 30 770337be
"token" 31 7706f1d3
"token" 32 00000000
"token" 33 00000000
"token" 34 ntdll!__RtlUserThreadStart+0x70
"token" 35 04
"token" 36 0147fad8
"token" 37 00000000
"token" 38 7706f1d3
"token" 39 00000000
"token" 40 00000000
"token" 41 ntdll!_RtlUserThreadStart+0x1b
я не понимаю ваших дальнейших запросов, поэтому я предполагаю ваше намерение ниже
0:001> $$ putting the result of kb into a variable use javascript
0:001> dx @$foo = Debugger.Utility.Control.ExecuteCommand("kb")
@$foo = Debugger.Utility.Control.ExecuteCommand("kb")
[0x0] : # ChildEBP RetAddr Args to Child
[0x1] : 00 0147fa44 7706f20f 7642d6f7 00000000 00000000 ntdll!DbgBreakPoint
[0x2] : 01 0147fa74 75d1ed6c 00000000 0147fac0 770337eb ntdll!DbgUiRemoteBreakin+0x3c
[0x3] : 02 0147fa80 770337eb 00000000 7642d643 00000000 kernel32!BaseThreadInitThunk+0xe
[0x4] : 03 0147fac0 770337be 7706f1d3 00000000 00000000 ntdll!__RtlUserThreadStart+0x70
[0x5] : 04 0147fad8 00000000 7706f1d3 00000000 00000000 ntdll!_RtlUserThreadStart+0x1b
0:001> dx -r0 @$foo[1]
@$foo[1] : 00 0147fa44 7706f20f 7642d6f7 00000000 00000000 ntdll!DbgBreakPoint
0:001> dx -r0 @$foo[2]
@$foo[2] : 01 0147fa74 75d1ed6c 00000000 0147fac0 770337eb ntdll!DbgUiRemoteBreakin+0x3c
опять же я не знаю, что вы хотите конвертировать в шестнадцатеричное или декабрь
так предположение ниже
пытаясь определить гекс из стека, а также заглавные строки
такой сценарий
function log(a1,a2)
{
host.diagnostics.debugLog(a1 +" " +a2 + "\n");
}
function exec (cmdstr)
{
return host.namespace.Debugger.Utility.Control.ExecuteCommand(cmdstr);
}
function kbtok()
{
var temp = exec("kb")
for ( line of temp )
{
var token = line.split(" ")
for (tok of token)
{
//log(tok)
try {
var num = host.parseInt64(tok,16)
log(tok , num)
}
catch(err) {
log(tok.toUpperCase(), " ")
}
}
}
}
используя это как
.load jsprovider
.scriptload --- путь ----
dx @ $ scriptcontents.kbtok ()
пример вывода для стека в первом абзаце
0:001> dx @$scriptContents.kbtok()
#
CHILDEBP
RETADDR
ARGS
TO
CHILD
00 0
013bfef4 20709108
7706f20f 1996943887
763ed3a7 1983828903
00000000 0
00000000 0
NTDLL!DBGBREAKPOINT
01 1
013bff24 20709156
75d1ed6c 1976692076
00000000 0
013bff70 20709232
770337eb 1996699627
NTDLL!DBGUIREMOTEBREAKIN+0X3C
02 2
013bff30 20709168
770337eb 1996699627
00000000 0
763ed3f3 1983828979
00000000 0
KERNEL32!BASETHREADINITTHUNK+0XE
03 3
013bff70 20709232
770337be 1996699582
7706f1d3 1996943827
00000000 0
00000000 0
NTDLL!__RTLUSERTHREADSTART+0X70
04 4
013bff88 20709256
00000000 0
7706f1d3 1996943827
00000000 0
00000000 0
NTDLL!_RTLUSERTHREADSTART+0X1B
@$scriptContents.kbtok()
Вы не компилируете скрипт, который интерпретируется скриптами
для скрипта windbg используйте $$> a< --- путь к скрипту ----
для JavaScript используйте команду .scriptload