Poznámka:
Přístup k této stránce vyžaduje autorizaci. Můžete se zkusit přihlásit nebo změnit adresáře.
Přístup k této stránce vyžaduje autorizaci. Můžete zkusit změnit adresáře.
Následující části popisují programy příkazů ladicího programu.
Použití tokenu .foreach
Následující příklad používá token .foreach k vyhledání hodnot WORDu 5a4d. Pro každou nalezenou hodnotu 5a4d ladicí program zobrazí 8 hodnot DWORD počínaje adresou, kde byl nalezen 5a4d DWORD.
0:000> .foreach (place { s-[1]w 77000000 L?4000000 5a4d }) { dc place L8 }
Následující příklad používá token .foreach k vyhledání hodnot WORDu 5a4d. Pro každou nalezenou hodnotu 5a4d ladicí program zobrazí 8 hodnot DWORD počínaje 4 bajty před adresou, kde byl nalezen 5a4d DWORD.
0:000> .foreach (place { s-[1]w 77000000 L?4000000 5a4d }) { dc place -0x4 L8 }
Následující příklad zobrazuje stejné hodnoty.
0:000> .foreach (place { s-[1]w 77000000 L?4000000 5a4d }) { dc ( place -0x4 ) L8 }
Poznámka Pokud chcete pracovat s názvem proměnné v části příkazu OutCommands části příkazu, musíte za název proměnné přidat mezeru. Například v přednabídce existuje mezera mezi proměnnou umístění a operátorem odčítání.
Možnost -[1] společně s příkazem s (Prohledávat paměť) způsobí, že jeho výstup bude obsahovat pouze adresy, které najde, ne hodnoty nalezené na těchto adresách.
Následující příkaz zobrazí podrobné informace o modulu pro všechny moduly umístěné v rozsahu paměti od 0x77000000 až po 0x7F000000.
0:000> .foreach (place { lm1m }) { .if ((${place} >= 0x77000000) & (${place} <= 0x7f000000)) { lmva place } }
Možnost 1m společně s příkazem lm (List Loaded Modules) způsobí, že jeho výstup bude obsahovat pouze adresy modulů, nikoli úplný popis modulů.
Předchozí příklad používá ${ } (interpret aliasu) token, aby se zajistilo, že aliasy budou nahrazeny, i když jsou vedle jiného textu. Pokud příkaz nezahrnul tento token, levá závorka vedle místo zabrání nahrazení aliasu. Všimněte si, že token ${} funguje na proměnných, které se používají v .foreach a na skutečných aliasech.
Procházení seznamu procesů
Následující příklad vás provede seznamem procesů v režimu jádra a zobrazí název spustitelného souboru pro každou položku v seznamu.
Tento příklad by se měl uložit jako textový soubor a spustitpříkazem$$>< (Spustit soubor skriptu). Tento příkaz načte celý soubor, nahradí všechny návraty na začátek řádku středníky a spustí výsledný blok. Tento příkaz umožňuje psát čitelné programy pomocí více řádků a odsazení, aniž byste museli stisknout celý program na jeden řádek.
Tento příklad ukazuje následující funkce:
$t 0, $t 1a $t 2 pseudoregistry se v tomto programu používají jako proměnné. Program také používá aliasy s názvem Procc a $ImageName.
Tento program používá vyhodnocovače výrazů MASM. Token @@c++( ) se však zobrazí jednou. Tento token způsobí, že program použije vyhodnocovače výrazů jazyka C++ k parsování výrazu v závorkách. Toto použití umožňuje programu používat tokeny struktury C++přímo.
? příznak se používá s příkazemr (Registers). Tento příznak přiřadí typové hodnoty pseudoregistru $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
}
Procházení seznamu LDR_DATA_TABLE_ENTRY
Následující příklad vás provede seznamem LDR_DATA_TABLE_ENTRY v uživatelském režimu a zobrazí základní adresu a úplnou cestu každé položky seznamu.
Podobně jako v předchozím příkladu by se tento program měl uložit do souboru a spustit se příkazem $$>< (Spustit soubor skriptu).
Tento příklad ukazuje následující funkce:
Tento program používá vyhodnocovače výrazů MASM. Na dvou místech se však zobrazí token @@c++(). Tento token způsobí, že program použije vyhodnocovače výrazů jazyka C++ k parsování výrazu v závorkách. Toto použití umožňuje programu používat tokeny struktury jazyka C++přímo.
? příznak se používá s příkazemr (Registers). Tento příznak přiřadí zadané hodnoty pseudoregistrům $t 0 a $t 1. V těle smyčky $t 1 má typ ntdll!_LDR_DATA_TABLE_ENTRY\*, aby program mohl vytvářet přímé členské odkazy.
Aliasy pojmenované uživatelem $Base a $Mod se používají v tomto programu. Známky dolaru snižují možnost, že tyto aliasy byly použity dříve v aktuální relaci ladicího programu. Znak dolaru není nutný. ${/v: } token interpretuje alias doslova a brání jeho nahrazení, pokud byl definován před spuštěním skriptu. Tento token můžete také použít společně s libovolným blokem, abyste zabránili definicím aliasů před použitím bloku.
Token .block slouží k přidání dalšího kroku nahrazení aliasu. Nahrazení aliasu nastane jednou pro celý skript při jeho načtení a jednou při každém zadání bloku. Bez tokenu .block a jeho složených závorek .echo neobdrží hodnoty $Mod a $Base aliasů, které jsou přiřazeny v předchozích řádcích.
$$ 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}
}