Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/69.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 嵌套结构中具有字符串比较的Windbg条件断点_C_Windbg_Windows Kernel - Fatal编程技术网

C 嵌套结构中具有字符串比较的Windbg条件断点

C 嵌套结构中具有字符串比较的Windbg条件断点,c,windbg,windows-kernel,C,Windbg,Windows Kernel,只有当嵌套结构中的字符串作为参数与我选择的特定模式相匹配时,我才尝试在函数中命中断点,如下所示: bp `main.c:2236` ".block { .if ( $spat(\"@@(stNames->NameComponent.Buffer)\", \"*ab*\" )){.echo \"BKP HIT! \"; .printf \"%mu str\n\",> @@(NameInfo->FinalComponent.Buffer); } .else {.echo \"NO

只有当嵌套结构中的字符串作为参数与我选择的特定模式相匹配时,我才尝试在函数中命中断点,如下所示:

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;}}"
表达式
\“@(stNames->NameComponent.Buffer)\”
可能不会计算为带引号的字符串

写条件句时,把条件句分解得尽可能小
并将它们放在一个txt文件中,并将脚本文件提供给断点
bp
:32
“$$>a
一样,比较容易

此外,如果问题已独立解决,则提供正确答案也会有所帮助 可复制内容

因为我无法计算问题中不可理解的表达式,所以我在下面提供了一个演示,看看这是否是问题所在

用于编译和链接的帮助程序

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:\>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:\>
现在我们有了一个稍微更容易理解的条件,其中 表达式是可独立验证的,我们在断点处使用它

执行细节

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“。行;g主要;Recho设置条件断点并运行
EXE;bp`:32`\“$$^>a^src第32行上的一个
执行输出详细信息

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:\>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:\>
structnest:\>cdb-c“。行;g主要;Recho设置条件断点并运行
EXE;bp`:32`\“$$^>a^cdb:正在读取初始命令'.lines;g main;r;.echo设置条件BREA
K点并运行EXE;bp`:32`“$$>a

您可以使用windbg的python扩展。它允许使用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-很容易使用结构

谢谢。如果“filed3”是char*或wchar_t*类型,并且您必须将其与“my_模式”进行比较,那会是什么情况?当然!这个检查字段3带有C字符串,通过RE:setBp(myApp.Func1,lambda:RE.match('Nt.*File',loadWStr(getParam(“var2”).filed3)))我只在简短的声明中使用lambda函数。您可以使用任何python“可调用”对象。