Windbg скриптинг, присваивающий результат переменной переменной - PullRequest
0 голосов
/ 05 сентября 2018

Регулярно мне нужно исследовать файлы дампа, всегда одинаково, и я хотел бы автоматизировать это. Я использую 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. Вместо того, чтобы печатать слово "TEST", выведите переменную token и посмотрите, как она выглядит.
    => Как это сделать? Я уже пробовал .printf "%msu \n" , ${token} или @$token, ... но ничего не работает.

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

  5. Не забыть: как мне скомпилировать такой скрипт? В настоящее время я пытаюсь запустить скрипт в Windbg, который иногда выдает ошибки компиляции, но они очень нечитаемы (я добавляю новую строку, вызывающую проблему, но ошибка усложнения (не опечатка) даже не упоминает, что недавно добавленные линия).

Вы можете сказать: просто взгляните на примеры, упомянутые в this URL , но я не могу найти ни одного примера выполнения стандартной команды Windbg и сохранить ее результат в переменная (это первое, что мне нужно сделать).

Если мой скрипт заработает, я могу превратить этот пост в общий «FAQ по скриптингу Windbg» для упомянутых (и недавно добавленных) вопросов.

Редактировать после первого ответа
Я понимаю, что ошибся с командой kb: фактическая команда, которую мне нужно использовать, - ~* k, что дает следующий результат:

enter image description here

(Небольшое замечание: у меня есть просто скриншот вместо текстовой копии, чтобы подчеркнуть гиперссылки 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 Ответ

0 голосов
/ 05 сентября 2018

для. 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 <</strong> --- путь к скрипту ----
для JavaScript используйте .scriptload команда

...