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?

  1. Запустить kb команда и положить результат в переменную. (Как это сделать? Я уже пытался с помощью as а также aS но ни одна из них не работает)
  2. Если я не могу получить весь kb результат в одну переменную, попробуйте использовать .foreach, как в следующем примере:

    .foreach ( token { kb} ) 
    {
     .printf "TEST\n"
    }
    

    => даже это не работает: kb имеет около 8 строк результатов, а слово TEST печатается 78 раз.

  3. Вместо того, чтобы печатать слово "ТЕСТ", выведите переменную token и посмотрим, как это выглядит.
    => Как это сделать? Я уже пробовала .printf "%msu \n" , ${token}, или же @$token... но ничего не работает.

  4. Даже если мне это удастся: как я могу выполнять строковые операции, преобразование десятичных / шестнадцатеричных чисел, ...?

  5. Не забыть: как мне скомпилировать такой скрипт? В настоящее время я пытаюсь запустить скрипт в 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

Другие вопросы по тегам