Сравнение строк в Windbg script

Использование Windbg script Я хочу проверить наличие определенной строки в аргументе любой функции.

0:000> g
Breakpoint 0 hit
eax=00000001 ebx=00000000 ecx=00422fc6 edx=00000000 esi=03d574e8 edi=00000005
eip=76d8fd3f esp=000cf7ac ebp=000cf7c8 iopl=0         nv up ei pl nz na po nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000202
USER32!MessageBoxW:
76d8fd3f 8bff            mov     edi,edi

0:000> du poi(esp+8)
03d574e8  "Cannot find "hello""

Здесь второй параметр, переданный в MessageBoxW, равен Cannot find "hello".

Поэтому я хочу проверить наличие строки hello внутри второго аргумента.

Основываясь на этой статье MSDN, я пробовал следующие команды, но не работал:

0:000> r $t1 = poi(esp+8)
0:000> as /mu $MSG $t1
0:000> .echo ${$MSG}
Cannot find "hello"
0:000> .if ($spat(@"${MSG}","*hello*") == 0) {.echo NotFound} .else {.echo Found}
NotFound

Он должен вернуться Found Я думаю!

Спасибо.

Ответ 1

Что не так с экранированием ${MSG}?

В команде .if, которую вы использовали, ${MSG} не заменяется из-за отсутствия $. Попробуйте найти MSG в качестве доказательства:

0:001> .if ($spat(@"${MSG}","*MSG*") == 0) {.echo NotFound} .else {.echo Found}
Found

Он заменяется на

0:001> .if ($spat(${$MSG},"*hello*") == 0) {.echo NotFound} .else {.echo Found}
Syntax error at '(Cannot find "hello","*hello*") == 0) {.echo NotFound} .else {.echo Found}'

но отсутствует код с кавычками до Can not. Он также заменяется на

0:001> .if ($spat("${$MSG}","*hello*") == 0) {.echo NotFound} .else {.echo Found}
Syntax error at '("Cannot find "hello"","*hello*") == 0) {.echo NotFound} .else {.echo Found}'

но там кавычки закрываются кавычками внутри строки. Кроме того, символ @ не помогает:

0:001> .if ($spat(@"${$MSG}","*hello*") == 0) {.echo NotFound} .else {.echo Found}
Syntax error at '(@"Cannot find "hello"","*hello*") == 0) {.echo NotFound} .else {.echo Found}'

Итак, это один из тех случаев, когда ИМХО они забыли рассмотреть escape-символы в WinDbg. Очень расстраивает и всегда является источником ошибок.

Решение с расширением PyKD

К счастью, есть PyKD, а код для проверки строки -

>>> "hello" in loadWStr(ptrPtr(reg("esp")+8))
True

reg("esp") получает значение регистра ESP. +8 добавляет 8, конечно. ptrPtr() получает значение указателя с этого адреса. loadWStr() читает это значение до тех пор, пока оно не достигнет символа NUL. "hello" in выполняет операцию поиска. Вы также можете использовать .find("hello")>0.

Вот как я попробовал:

0:003> .dvalloc 2000
Allocated 2000 bytes starting at 00470000
0:003> eu 00470000 "Cannot find \"hello\""
0:003> du 00470000 
00470000  "Cannot find "hello""
0:003> ep 00470000+1008 00470000 
0:003> r esp=00470000+1000
0:003> .load E:\debug\Extensions\pykd\x86\pykd.dll
0:003> !pycmd
Python 2.7.8 |Anaconda 2.1.0 (32-bit)| (default, Jul  2 2014, 15:13:35) [MSC v.1500 32 bit (Intel)] on win32
Type "help", "copyright", "credits" or "license" for more information.
(InteractiveConsole)
>>> "hello" in loadWStr(ptrPtr(reg("esp")+8))
True
>>> exit()

Вы можете поместить следующий код в файл .PY

from pykd import * 
print "hello" in loadWStr(ptrPtr(reg("esp")+8))

И затем запустите его без интерактивной консоли следующим образом:

0:003> !py e:\debug\hello.py
True

Решение с WinDbg

В WinDbg вам нужно избавиться от кавычек. Один из способов сделать это: .foreach:

0:001> .foreach (token {.echo $MSG}){.echo ${token}}
Cannot
find
hello

Вывод не содержит кавычек. Пусть этот вывод будет присвоен другому псевдониму:

0:001> as /c NOQ .foreach (token {.echo ${$MSG}}){.echo ${token}}

С помощью этого нового псевдонима ваша команда будет работать:

0:001> .if ($spat("${NOQ}","*hello*") == 0) {.echo NotFound} .else {.echo Found}
Found

Ответ 2

Из комментариев:

Посмотрим, получаю ли я какой-либо ответ на WDS.

Трудно поверить, что вы хотите пойти длинным бродягой. Но хорошо, вот оно, встроенное решение WinDbg:

r $t9=1;.foreach /ps fffff (endaddr {s -[1]w 00570000 L1000 0}) {.foreach /ps fffff (findaddr {s -[1]u 00570000 ${endaddr} "hello"}) {r $t9=2} }; .if (@$t9==2) { .echo "Found"} .else {.echo "Not Found"}

Что он делает? Ну, я оставляю это как упражнение для вас, спойлеры ниже.

r $t9=1; устанавливает псевдо регистр T9 в определенное значение, чтобы оно не было случайно равно значению, используемому для сравнения позже.

s -[1]w 00570000 L1000 0 выполняет поиск по памяти для DWORD (w) значения 0, который равен концу строки Unicode. [1] ограничивает вывод только адресом.

.foreach /ps fffff (endaddr { ... }) {...}; присваивает адрес переменной endaddr. /ps fffff пропускает другие результаты, если их много.

s -[1]u 00570000 ${endaddr} "hello" выполняет поиск в памяти, на этот раз для строки Unicode (u), также ограничивая вывод адреса ([1]).

.foreach /ps fffff (findaddr {...}) {...} выводит результат поиска. Здесь переменная findaddr не используется, но может быть полезной в последней команде, в зависимости от того, чего вы пытаетесь достичь.

r $t9=2 изменяет псевдо регистр T9 на значение, указывающее, что поисковый запрос найден.

.if (@$t9==2) { ... } .else { ... } делает что-то на основе псевдорегистра T9.

Ответ 3

wow Томас, который, вероятно, называется как выход в крайности

@deb, если поиск соответствия является основным требованием, вы можете попробовать что-то вроде этого

0:000> .printf "%y\n" , @eip
USER32!MessageBoxW (7e466534)
0:000> $ ----------------------------------------------------------------------------------------------------------------------
0:000> du poi(@esp+8)
00408168  "cannot find "hello""
0:000> $ ----------------------------------------------------------------------------------------------------------------------
0:000> .foreach /pS 1 /ps 100 (place { dpu @esp+8 l1 }) { s -u place l100 "\"hello\"" }
00408180  0022 0068 0065 006c 006c 006f 0022 0000  ".h.e.l.l.o."...
0040827a  0022 0068 0065 006c 006c 006f 0022 0020  ".h.e.l.l.o.". .
0:000> $ ----------------------------------------------------------------------------------------------------------------------
0:000> .foreach /pS 1 /ps 100 (place { dpu @esp+8 l1 }) { s -u place l100 "\"z\"" }
0:000> $ ----------------------------------------------------------------------------------------------------------------------
0:000> .foreach /pS 1 /ps 100 (place { dpu @esp+8 l1 }) { s -u place l100 "\"zoop\"" }
0:000> $ ----------------------------------------------------------------------------------------------------------------------
0:000> .foreach /pS 1 /ps 100 (place { dpu @esp+8 l1 }) { s -[l 20]u place l100 "can" }
00408168  0063 0061 006e 006e 006f 0074 0020 0066  c.a.n.n.o.t. .f.
0040819c  0063 0061 006e 006e 006f 0074 0020 0066  c.a.n.n.o.t. .f.
004081d0  0063 0061 006e 006e 006f 0074 0020 0066  c.a.n.n.o.t. .f.
00408204  0063 0061 006e 006e 006f 0074 0020 0066  c.a.n.n.o.t. .f.
00408238  0063 0061 006e 006e 006f 0074 0020 0066  c.a.n.n.o.t. .f.
0:000> $ ----------------------------------------------------------------------------------------------------------------------
0:000> .foreach /pS 1 /ps 100 (place { dpu @esp+8 l1 }) { s -[1]u place l100 "can" }
0x00408168
0x0040819c
0x004081d0
0x00408204
0x00408238
0:000> $ ----------------------------------------------------------------------------------------------------------------------
0:000> .foreach /pS 1 /ps 100 (place { dpu @esp+8 l1 }) { .foreach (vlace { s -[1]u place l100 "can"} ) {du vlace} }
00408168  "cannot find "hello""
0040819c  "cannot find "iello""
004081d0  "cannot find "jello""
00408204  "cannot find "fello""
00408238  "cannot find "kello""
0:000> $ ----------------------------------------------------------------------------------------------------------------------
0:000> .foreach /pS 1 /ps 100 (place { dpu @esp+8 l1 }) { .foreach (vlace { s -[1]u place l100 "ello"} ) {du vlace} } 
00408184  "ello""
004081b8  "ello""
004081ec  "ello""
00408220  "ello""
00408254  "ello""
0040827e  "ello" baby"
0:000> $ ----------------------------------------------------------------------------------------------------------------------
0:000> lsf msgboxw.cpp
msgboxw.cpp
0:000> $ ----------------------------------------------------------------------------------------------------------------------
0:000> ls 0,15
     1: #include <windows.h>
     2: #pragma comment(lib,"user32.lib")
     3: int main (void)
     4: {
     5:     MessageBoxW(0,L"cannot find \"hello\"",L"test",0);
     6:     MessageBoxW(0,L"cannot find \"iello\"",L"test",0);
     7:     MessageBoxW(0,L"cannot find \"jello\"",L"test",0);
     8:     MessageBoxW(0,L"cannot find \"fello\"",L"test",0);
     9:     MessageBoxW(0,L"cannot find \"kello\"",L"test",0);
    10:     MessageBoxW(0,L"saying \"hello\" baby",L"test",0);
    11: return 0;
    12: }
    13: 
    14: 
0:000> $ ----------------------------------------------------------------------------------------------------------------------