Условная точка останова Windbg со сравнением строк во вложенной структуре

Я пытался попасть в точку останова внутри функции только в том случае, если строка во вложенной структуре в качестве аргумента соответствует определенному шаблону по моему выбору, например так:

bp `main.c:2236` ".block { .if ( $spat(\"@@(stNames->NameComponent.Buffer)\", \"*ab*\" )){.echo \"BKP HIT! \"; .printf \"%mu str\n\",> @@(NameInfo->FinalComponent.Buffer); } .else {.echo \"NO HIT \"; .printf \"%mu str:\n\", @@(stNames->NameComponent.Buffer); gc;} } "

Эта точка останова устанавливается в самом начале функции, после того как символы параметров уже разрешены. Он ведет себя странно, иногда срабатывает постоянно, даже если шаблон в $spat не совпадает, а иногда не срабатывает, даже если шаблон совпадает.

Я также пробовал это безуспешно, так как я не могу найти способ использовать команду poi() в случае вложенной структуры. Фрагмент ниже:

bp Kernel32!CreateFileW ".printf \"%mu\\n\", poi(esp+4); as /mu ${/v:FileName} poi(esp+4); .block{.if $spat(\"${FileName}\", \"*target*\") {.echo Hit} .else {.echo Not Yet;g;}}"

person lopan    schedule 13.05.2014    source источник


Ответы (2)


выражение \"@@(stNames->NameComponent.Buffer)\" вероятно does not evaluate to a quoted string оценивается независимо

при написании условных выражений разбивайте условные выражения как можно меньше
и поместите их в txt-файл, а файл скрипта укажите в точке останова
, например bp:32" $$>a< c:\\windscrypted.txt, это намного легче понять

также было бы полезно дать правильный ответ, если вопрос имеет независимо воспроизводимое содержание

поскольку я не могу оценить непонятное выражение в вопросе, я предоставил демонстрацию ниже, посмотрите, это то, что спрашивают

Помощник по компиляции и связыванию

structnest:\>type "c:\Program Files\Microsoft Visual Studio 10.0\VC\compile.bat"

@ECHO OFF
REM Compile and Link Helper Utility.
REM Add New Entry CompileMe in Visual_Studio_IDE->Tools->ExternalTools.
REM Provide path to this bat file in command
REM Provide $(ItemFileName)$(ItemExt) as Arguments
REM $(BinDir) as Initial Directory
REM Enjoy One Click Compile & link Simple Single File Demo Sources
@call "C:\Program Files\Microsoft Visual Studio 10.0\VC\vcvarsall.bat" x86
cl /Zi /nologo /W4 /analyze %1% /link /RELEASE
pause

Сведения об исходном файле

structnest:\>dir /b
structnest.cpp

structnest:\>type structnest.cpp
#include <windows.h>
#include <winternl.h>
#include <stdio.h>
#define SOMESIZE 20

typedef VOID (NTAPI *g_RtlInitUnicodeString) (PUNICODE_STRING DestinationStri
ng, PCWSTR SourceString );

#pragma pack (1)
typedef struct _OUTNEST
{
    int a;
    int b;
    short c;
    UNICODE_STRING Nestin;
}OutNest,*POutNest;
#pragma pack()

int main (void)
{
    POutNest MyNest = ( POutNest  ) calloc ( 0x01  , sizeof(OutNest)   );
    PWSTR    buff   = ( PWSTR     ) calloc ( 0x30 ,  sizeof(wchar_t)   );
    HMODULE hMod = LoadLibrary("ntdll.dll");
    if ( (hMod != NULL) && (MyNest != NULL)  && (buff != NULL))
    {
        g_RtlInitUnicodeString RtlInitUnicodeString = ( g_RtlInitUnicodeString )
 GetProcAddress ( hMod , "RtlInitUnicodeString");
        if (RtlInitUnicodeString != NULL )
        {
            for (int i = 0; i< SOMESIZE; i++)
            {
                swprintf_s(buff, 0x29 , L"this is string number %.2d",i);

                RtlInitUnicodeString(&MyNest->Nestin,buff);
                printf("%S\n",MyNest->Nestin.Buffer);
            }
            printf("done\n");
            goto getout;
        }
        printf("GetprocAddress failed\n");
        goto getout;
    }
    printf("calloc() %p %p LoadLib %p failed\n" , MyNest,buff,hMod);
getout:
    if (MyNest)
        free(MyNest);
    if(buff)
        free(buff);
    if(hMod)
        FreeLibrary(hMod);
    return 0;
}
structnest:\>"c:\Program Files\Microsoft Visual Studio 10.0\VC\compile.bat" stru
ctnest.cpp
Setting environment for using Microsoft Visual Studio 2010 x86 tools.
structnest.cpp
Press any key to continue . . .

structnest:\>dir /b *.exe
structnest.exe

structnest:\>structnest.exe
this is string number 00
this is string number 01
this is string number 02
this is string number 03
this is string number 04
this is string number 05
this is string number 06
this is string number 07
this is string number 08
this is string number 09
this is string number 10
this is string number 11
this is string number 12
this is string number 13
this is string number 14
this is string number 15
this is string number 16
this is string number 17
this is string number 18
this is string number 19
done

Сведения о файле сценария

structnest:\>type c:\nestedbreak.txt
as /mu ${/v:mystr} @@( MyNest->Nestin.Buffer );
.block { r $t0 = $spat( "${mystr}", "*11" ); }
.if( @$t0 != 1 ) { gc } ;

explanation of script file

as /mu ${/v:mystr}
Sets the alias equivalent equal to the null-terminated Unicode string 
that begins at Address @@( MyNest->Nestin.Buffer ). 
.block {} to force alias evaluation.
a Pseudo register $t0 is set to the result of $spat() can be 0 or 1

"${mystr}" on alias evaluation will become "this is string number 00" 
a Double Quoted string not address or some other expression 

"*11" is again a Double Quoted wild card pattern string it will match "11"
 at any position in the Input String .

.if is a conditinal that will break only when @$t0 == 1 

теперь, когда у нас есть немного более понятное условие, в котором каждое из выражений можно проверить независимо, мы продолжили использовать его в точке останова.

Сведения о выполнении

structnest:\>cdb -c ".lines;g main;r;.echo SET A CONDITINAL BREAK POINT AND RUN
THE EXE;bp `:32` \" $$^>a^< c:\\nestedbreak.txt \";g ;.lastevent;.echo why did w
e break here ? now that we broke lets go again;g;q " structnest.exe

explanation as follows

cdb.exe      console mode windbg;
.lines;     load line information (lineinfo default off in cdb.exe needed to set bp on src lines)
g main;     ( we are interested in our code for which we have src not some random system module)
r;      print the registers to confirm we reached main properly
.echo       just a signal to show that we are alive and kicking
`:32` "$$>a< c:\\nestedbreak.txt"   conditional break point on src line 32 ( inner double quotes/ unaccpetable > < chars escaped )
g;      run the exe
.lastevent;     shows the reason why we broke;
.echo       a signal to indicate that we broke
g;q;        finish running the exe and quit debugger

Сведения о результатах выполнения

structnest:\>cdb -c ".lines;g main;r;.echo SET A CONDITINAL BREAK POINT AND RUN
THE EXE;bp `:32` \" $$^>a^< c:\\nestedbreak.txt \";g ;.lastevent;.echo why did w
e break here ? now that we broke lets go again;g;q " structnest.exe

Microsoft (R) Windows Debugger Version 6.12.0002.633 X86

0:000> cdb: Reading initial command '.lines;g main;r;.echo SET A CONDITINAL BREA
K POINT AND RUN THE EXE;bp `:32` " $$>a< c:\\nestedbreak.txt ";g ;.lastevent;.ec
ho why did we break here ? now that we broke lets go again;g;q '

Line number information will be loaded

eax=00034180 ebx=7ffd6000 ecx=00000001 edx=0041a5f0 esi=00000000 edi=00000000
eip=00401000 esp=0013ff7c ebp=0013ffc0 iopl=0         nv up ei pl zr na pe nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000246
structnest!main:
00401000 55              push    ebp


SET A CONDITINAL BREAK POINT AND RUN THE EXE

this is string number 00
this is string number 01
this is string number 02
this is string number 03
this is string number 04
this is string number 05
this is string number 06
this is string number 07
this is string number 08
this is string number 09
this is string number 10
Last event: 16d0.2784: Hit breakpoint 0
  debugger time: Thu May 15 16:10:10.625 2014 (UTC + 5:30)
why did we break here ? now that we broke lets go again
this is string number 11
this is string number 12
this is string number 13
this is string number 14
this is string number 15
this is string number 16
this is string number 17
this is string number 18
this is string number 19
done
quit:

structnest:\>
person blabb    schedule 15.05.2014

Вы можете использовать расширение python для windbg. Это позволяет установить условную точку останова с обратным вызовом python.

kd>!pycmd
>>>myApp = module("MyApp.exe")
>>>setBp( myApp.Func1, lambda : getParam("var2").filed3 > 10 )
>>>quit()
kd>g

Вы видите: 1) myApp.Func1 - pykd находит смещения по символьной информации 2) getParam("var2") - pykd находит параметры функции 3) getParam("var2").filed3 - легко работать со структурами

person pykd team    schedule 16.05.2014
comment
Спасибо. Что было бы, если бы filed3 имел тип char * или wchar_t * и вам нужно было бы сравнить его, например, с my_pattern? - person lopan; 16.05.2014
comment
Конечно! Эта проверка field3 с помощью C-строки с помощью RE: setBp(myApp.Func1, lambda: re.match('Nt.*File', loadWStr(getParam(var2).filed3))) Я использую лямбда-функцию только для краткого объявления. Вы можете использовать любой вызываемый объект Python. - person pykd team; 19.05.2014