Nuta
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować się zalogować lub zmienić katalog.
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować zmienić katalogi.
W poniższych sekcjach opisano programy poleceń debugera.
Korzystanie z tokenu foreach
W poniższym przykładzie użyto tokenu .foreach, aby wyszukać wartości programu WORD 5a4d. Dla każdej znalezionej wartości 5a4d debuger wyświetla 8 wartości DWORD, począwszy od adresu, pod którym znaleziono 5a4d DWORD.
0:000> .foreach (place { s-[1]w 77000000 L?4000000 5a4d }) { dc place L8 }
W poniższym przykładzie użyto tokenu .foreach, aby wyszukać wartości programu WORD 5a4d. Dla każdej znalezionej wartości 5a4d debuger wyświetla 8 wartości DWORD, począwszy od 4 bajtów przed adresem, w którym znaleziono 5a4d DWORD.
0:000> .foreach (place { s-[1]w 77000000 L?4000000 5a4d }) { dc place -0x4 L8 }
W poniższym przykładzie są wyświetlane te same wartości.
0:000> .foreach (place { s-[1]w 77000000 L?4000000 5a4d }) { dc ( place -0x4 ) L8 }
Uwaga Jeśli chcesz pracować na nazwie zmiennej w OutCommands części polecenia, musisz dodać spację po nazwie zmiennej. Na przykład w przypadku preceedingu między zmienną umieść a operatorem odejmowania.
Opcja -[1] wraz z s (pamięć wyszukiwania) polecenie powoduje, że dane wyjściowe zawierają tylko znalezione adresy, a nie wartości znalezione na tych adresach.
Poniższe polecenie wyświetla pełne informacje o module dla wszystkich modułów znajdujących się w zakresie pamięci od 0x77000000 przez 0x7F000000.
0:000> .foreach (place { lm1m }) { .if ((${place} >= 0x77000000) & (${place} <= 0x7f000000)) { lmva place } }
Opcja 1m wraz z lm (lista załadowanych modułów) polecenie powoduje, że jego dane wyjściowe zawierają tylko adresy modułów, a nie pełny opis modułów.
W poprzednim przykładzie użyto ${ } (Interpreter aliasu) tokenu, aby upewnić się, że aliasy są zastępowane, nawet jeśli znajdują się obok innego tekstu. Jeśli polecenie nie zawiera tego tokenu, nawias otwierający obok umieść uniemożliwia zastąpienie aliasu. Należy pamiętać, że token ${} działa na zmiennych używanych w .foreach i na prawdziwych aliasach.
Przechodzenie z listy procesów
Poniższy przykład zawiera listę procesów trybu jądra i wyświetla nazwę pliku wykonywalnego dla każdego wpisu na liście.
Ten przykład powinien być przechowywany jako plik tekstowy i wykonywany za pomocą $$>< (Uruchom plik skryptu) polecenia. To polecenie ładuje cały plik, zastępuje wszystkie powroty karetki średnikami i wykonuje wynikowy blok. To polecenie umożliwia zapisywanie programów do odczytu przy użyciu wielu wierszy i wcięcia, zamiast ściskać cały program w jednym wierszu.
W tym przykładzie przedstawiono następujące funkcje:
Pseudorejestracje $t 0, $t 1i $t 2 pseudorejestracje są używane jako zmienne w tym programie. Program używa również aliasów o nazwie Procc i $ImageName.
Ten program używa ewaluatora wyrażeń MASM. Jednak token @@c++( ) pojawia się jednorazowo. Ten token powoduje, że program używa ewaluatora wyrażeń języka C++, aby przeanalizować wyrażenie w nawiasach. To użycie umożliwia programowi bezpośrednie używanie tokenów struktury języka C++.
? flaga jest używana z poleceniemr (Registers). Ta flaga przypisuje wpisane wartości do pseudorejestrowania $t 2.
$$ Get process list LIST_ENTRY in $t0.
r $t0 = nt!PsActiveProcessHead
$$ Iterate over all processes in list.
.for (r $t1 = poi(@$t0);
(@$t1 != 0) & (@$t1 != @$t0);
r $t1 = poi(@$t1))
{
r? $t2 = #CONTAINING_RECORD(@$t1, nt!_EPROCESS, ActiveProcessLinks);
as /x Procc @$t2
$$ Get image name into $ImageName.
as /ma $ImageName @@c++(&@$t2->ImageFileName[0])
.block
{
.echo ${$ImageName} at ${Procc}
}
ad $ImageName
ad Procc
}
Spacer po liście LDR_DATA_TABLE_ENTRY
W poniższym przykładzie przedstawiono listę LDR_DATA_TABLE_ENTRY trybu użytkownika i wyświetla podstawowy adres i pełną ścieżkę każdego wpisu listy.
Podobnie jak w poprzednim przykładzie, ten program powinien zostać zapisany w pliku i wykonany za pomocą $$>< (Uruchom plik skryptu) polecenia.
W tym przykładzie przedstawiono następujące funkcje:
Ten program używa ewaluatora wyrażeń MASM. Jednak w dwóch miejscach zostanie wyświetlony token @@c++( ). Ten token powoduje, że program używa ewaluatora wyrażeń języka C++, aby przeanalizować wyrażenie w nawiasach. To użycie umożliwia programowi bezpośrednie używanie tokenów struktury języka C++.
? flaga jest używana z poleceniemr (Registers). Ta flaga przypisuje wpisane wartości do pseudorejestrujących $t 0 i $t 1. W treści pętli $t 1 ma typ ntdll!_LDR_DATA_TABLE_ENTRY\*, aby program mógł tworzyć bezpośrednie odwołania do składowych.
Aliasy o nazwie użytkownika $Base i $Mod są używane w tym programie. Znaki dolara zmniejszają możliwość użycia tych aliasów wcześniej w bieżącej sesji debugera. Znaki dolara nie są konieczne. ${/v: } token interpretuje alias dosłownie, uniemożliwiając jego zastąpienie, jeśli został zdefiniowany przed uruchomieniem skryptu. Możesz również użyć tego tokenu razem z dowolnym blokiem, aby zapobiec używaniu definicji aliasów przed użyciem bloku.
Token .block służy do dodawania dodatkowego kroku zastępowania aliasu. Zamiana aliasu występuje jeden raz dla całego skryptu, gdy jest ładowany i jeden raz po wprowadzeniu każdego bloku. Bez tokenu .block i jego nawiasów klamrowych polecenie .echo nie odbiera wartości $Mod i aliasów $Base przypisanych w poprzednich wierszach.
$$ Get module list LIST_ENTRY in $t0.
r? $t0 = &@$peb->Ldr->InLoadOrderModuleList
$$ Iterate over all modules in list.
.for (r? $t1 = *(ntdll!_LDR_DATA_TABLE_ENTRY**)@$t0;
(@$t1 != 0) & (@$t1 != @$t0);
r? $t1 = (ntdll!_LDR_DATA_TABLE_ENTRY*)@$t1->InLoadOrderLinks.Flink)
{
$$ Get base address in $Base.
as /x ${/v:$Base} @@c++(@$t1->DllBase)
$$ Get full name into $Mod.
as /msu ${/v:$Mod} @@c++(&@$t1->FullDllName)
.block
{
.echo ${$Mod} at ${$Base}
}
ad ${/v:$Base}
ad ${/v:$Mod}
}