Anteckning
Åtkomst till den här sidan kräver auktorisering. Du kan prova att logga in eller ändra kataloger.
Åtkomst till den här sidan kräver auktorisering. Du kan prova att ändra kataloger.
I det här avsnittet beskrivs användningen av masm-uttryckssyntaxen (Microsoft Macro Assembler) med Windows felsökningsverktyg.
Felsökningsprogrammet accepterar två olika typer av numeriska uttryck: C++-uttryck och MASM-uttryck. Vart och ett av dessa uttryck följer sina egna syntaxregler för indata och utdata.
Mer information om när varje syntaxtyp används finns i Utvärdera uttryck och ? (Utvärdera uttryck).
I det här exemplet... kommandot visar värdet för instruktionspekarens register med hjälp av MASM-uttrycksutvärderingen.
0:000> ? @rip
Evaluate expression: 140709230544752 = 00007ff9`6bb40770
Ange uttrycksutvärderingen till MASM
Använd .expr (Välj uttrycksutvärdering) för att se vad standarduttrycksutvärderingen är och ändra den till MASM.
0:000> .expr /s masm
Current expression evaluator: MASM - Microsoft Assembler expressions
Nu när standarduttryckets utvärderare har ändrats, ? (Utvärdera uttryck) kan användas för att visa MASM-uttryck. Det här exemplet lägger till hexvärdet 8 i rip-registret.
0:000> ? @rip + 8
Evaluate expression: 140709230544760 = 00007ff9`6bb40778
Registerreferensen @rip för beskrivs mer detaljerat i Registersyntax.
Tal i MASM-uttryck för felsökningsprogram
Du kan placera tal i MASM-uttryck i bas 16, 10, 8 eller 2.
Använd kommandot n (Ange nummerbas) för att ange standardradixet till 16, 10 eller 8. Alla tal utan prefix tolkas sedan i denna bas. Du kan åsidosätta standardradixet genom att ange 0x-prefixet (hexadecimalt), 0n-prefixet (decimal), 0t-prefixet (oktalt) eller 0y-prefixet (binärt).
Du kan också ange hexadecimala tal genom att lägga till ett h efter talet. Du kan använda versaler eller gemener i siffror. Till exempel har "0x4AB3", "0X4aB3", "4AB3h", "4ab3h" och "4aB3H" samma betydelse.
Om du inte lägger till ett tal efter prefixet i ett uttryck läss talet som 0. Därför kan du skriva 0 som 0, prefixet följt av 0 och endast prefixet. I hexadecimalt har till exempel "0", "0x0" och "0x" samma betydelse.
Du kan ange hexadecimala 64-bitarsvärden i formatet xxxxxxxx'xxxxxxxx. Du kan också utelämna gravaccenten ('). När du inkluderar grav accent inaktiveras det automatiska teckentillägget.
Det här exemplet visar hur du lägger till ett decimal-, oktalt och binärt värde för att registrera 10.
? @r10 + 0x10 + 0t10 + 0y10
Evaluate expression: 26 = 00000000`0000001a
Symboler i MASM-uttryck för felsökningsprogram
I MASM-uttryck är det numeriska värdet för en symbol dess minnesadress. Beroende på vad symbolen refererar till är den här adressen adressen till en global variabel, lokal variabel, funktion, segment, modul eller någon annan identifierad etikett.
Om du vill ange vilken modul adressen är associerad med inkluderar du modulnamnet och ett utropstecken (!) före namnet på symbolen. Om symbolen kan tolkas som ett hexadecimalt tal ska du inkludera modulnamnet och ett utropstecken, eller bara ett utropstecken, före symbolnamnet. Mer information om symboligenkänning finns i Symbolsyntax och Symbolmatchning.
Använd två kolon (::) eller två understreck (__) för att ange medlemmarna i en klass.
Använd en grav accent (') eller en apostrofer (') i ett symbolnamn endast om du lägger till ett modulnamn och utropstecken före symbolen.
Numeriska operatorer i MASM-uttryck
Du kan ändra valfri komponent i ett uttryck med hjälp av en unary-operator. Du kan kombinera två komponenter med hjälp av en binär operator. Unary-operatorer har företräde framför binära operatorer. När du använder flera binära operatorer följer operatorerna de regler för fast prioritet som beskrivs i följande tabeller.
Du kan alltid använda parenteser för att åsidosätta prioritetsregler.
Om en del av ett MASM-uttryck omges av parenteser och två at-symboler (@@) förekommer före uttrycket, tolkas uttrycket enligt C++-uttrycksregler. Du kan inte lägga till ett blanksteg mellan de två vid tecken och den inledande parentesen. Du kan också ange uttrycksutvärderaren med hjälp av @@c++( ... ) eller @@masm( ... ).
När du utför aritmetiska beräkningar behandlar MASM-uttrycksutvärderingen alla tal och symboler som ULONG64 typer.
Unary-adressoperatorer förutsätter att DS är standardsegmentet för adresser. Uttryck utvärderas i ordning enligt operatorprecedens. Om intilliggande operatorer har samma prioritet utvärderas uttrycket från vänster till höger.
Du kan använda följande unary-operatorer.
| Operatör | Innebörd |
|---|---|
+ |
Unary plus |
- |
Unärt minus |
inte |
Returnerar 1 om argumentet är noll. Returnerar noll för alla argument som inte är noll. |
Hej |
Hög 16 bitar |
låg |
de låga 16 bitarna |
vid |
Byte med låg ordning från den angivna adressen. |
$pby |
Samma som by förutom att den tar en fysisk adress. Endast fysiskt minne som använder standardbeteendet för cachelagring kan läsas. |
Wo |
Ord med låg ordning från den angivna adressen. |
$pwo |
Samma som wo förutom att det tar en fysisk adress. Endast fysiskt minne som använder standardbeteendet för cachelagring kan läsas. |
dwo |
Dubbelord från den angivna adressen. |
$pdwo |
Samma som dwo förutom att den tar en fysisk adress. Endast fysiskt minne som använder standardbeteendet för cachelagring kan läsas. |
qwo |
64-bit värde från den angivna adressen. |
$pqwo |
Samma som qwo förutom att den tar en fysisk adress. Endast fysiskt minne som använder standardbeteendet för cachelagring kan läsas. |
Poi |
Data av pekarstorlek från den angivna adressen. Pekarstorleken är 32 bitar eller 64 bitar. Vid kernelfelsökning baseras den här storleken på måldatorns processor. Därför är poi den bästa operatorn att använda om du vill ha data i pekarstorlek. |
$ppoi |
Samma som poi förutom att den tar en fysisk adress. Endast fysiskt minne som använder standardbeteendet för cachelagring kan läsas. |
Exempel
I följande exempel visas hur du använder poi för att avreferera en pekare och visa värdet som lagras på den minnesplatsen.
Bestäm först minnesadressen av intresse. Vi kan till exempel titta på trådstrukturen och bestämma att vi vill se värdet för CurrentLocale.
0:000> dx @$teb
@$teb : 0x8eed57b000 [Type: _TEB *]
[+0x000] NtTib [Type: _NT_TIB]
[+0x038] EnvironmentPointer : 0x0 [Type: void *]
[+0x040] ClientId [Type: _CLIENT_ID]
[+0x050] ActiveRpcHandle : 0x0 [Type: void *]
[+0x058] ThreadLocalStoragePointer : 0x1f8f9d634a0 [Type: void *]
[+0x060] ProcessEnvironmentBlock : 0x8eed57a000 [Type: _PEB *]
[+0x068] LastErrorValue : 0x0 [Type: unsigned long]
[+0x06c] CountOfOwnedCriticalSections : 0x0 [Type: unsigned long]
[+0x070] CsrClientThread : 0x0 [Type: void *]
[+0x078] Win32ThreadInfo : 0x0 [Type: void *]
[+0x080] User32Reserved [Type: unsigned long [26]]
[+0x0e8] UserReserved [Type: unsigned long [5]]
[+0x100] WOW32Reserved : 0x0 [Type: void *]
[+0x108] CurrentLocale : 0x409 [Type: unsigned long]
CurrentLocale finns 0x108 bortom TEB:s början.
0:000> ? @$teb + 0x108
Evaluate expression: 613867303176 = 0000008e`ed57b108
Använd poi för att avreferera den adressen.
0:000> ? poi(0000008e`ed57b108)
Evaluate expression: 1033 = 00000000`00000409
Det returnerade värdet 409 matchar värdet för CurrentLocale i TEB-strukturen.
Eller använd poi och parenteser för att avreferera den beräknade adressen.
0:000> ? poi(@$teb + 0x108)
Evaluate expression: 1033 = 00000000`00000409
Använd operatorerna by eller wo unary för att returnera en byte eller ett ord från måladressen.
0:000> ? by(0000008e`ed57b108)
Evaluate expression: 9 = 00000000`00000009
0:000> ? wo(0000008e`ed57b108)
Evaluate expression: 1033 = 00000000`00000409
Binära operatorer
Du kan använda följande binära operatorer. Operatorerna i varje cell har företräde framför operatorerna i lägre celler. Operatorer i samma cell har samma prioritet och parsas från vänster till höger.
| Operatör | Innebörd |
|---|---|
* / mod (eller %) |
Multiplikation Heltalsdivision Modulus (rest) |
+ - |
Tillägg Subtraktion |
<< >> >>> |
Vänster skifte Logiskt högerskifte Aritmetisk högerförskjutning |
= (eller ==) < > <= >= != |
Lika med Mindre än Större än Mindre än eller lika med Större än eller lika med Inte lika med |
och (eller &) |
Bitvis OCH |
xor (eller ^) |
Bitvis XOR (exklusiv ELLER) |
eller (eller |) |
Bitvis ELLER |
Jämförelseoperatorerna <, >, =, == och != utvärderas till 1 om uttrycket är sant eller noll om uttrycket är falskt. Ett enda likhetstecken (=) är detsamma som ett dubbelt likhetstecken (==). Du kan inte använda biverkningar eller tilldelningar i ett MASM-uttryck.
En ogiltig åtgärd (till exempel division med noll) resulterar i att ett "Operand-fel" returneras till felsökningskommandofönstret.
Vi kan kontrollera att det returnerade värdet matchar 0x409 med hjälp av jämförelseoperatorn == .
0:000> ? poi(@$teb + 0x108)==0x409
Evaluate expression: 1 = 00000000`00000001
Icke-numeriska operatorer i MASM-uttryck
Du kan också använda följande ytterligare operatorer i MASM-uttryck.
| Operatör | Innebörd |
|---|---|
$fnsucc(FnAddress, RetVal, Flag) |
Tolkar RetVal-värdet som ett returvärde för funktionen som finns på FnAddress-adressen . Om det här returvärdet kvalificerar sig som en lyckad kod returnerar $fnsuccTRUE. Annars returnerar $fnsuccFALSE. Om returtypen är BOOL, bool, HANDLE, HRESULT eller NTSTATUS $fnsucc korrekt förstår om det angivna returvärdet kvalificerar sig som en lyckad kod. Om returtypen är en pekare kvalificeras alla andra värden än NULL som lyckade koder. För alla andra typer definieras framgång av värdet för Flagga. Om Flag är 0, betyder ett icke-noll värde på RetVal att det är en framgång. Om Flag är 1, innebär ett nollvärde för RetVal framgång. |
$iment (adress) |
Returnerar adressen till startpunkten för bilden i listan över inlästa moduler. Adress anger basadressen för PE (Portable Executable) avbildning. Posten hittas genom att leta upp startpunkten för bilden i PE-bildrubriken för den bild som Adress anger. Du kan använda den här funktionen för båda modulerna som redan finns i modullistan och för att ange olösta brytpunkter med hjälp av kommandot bu . |
$scmp("String1", "String2") |
Utvärderas till -1, 0 eller 1, likt strcmp genom att använda C-funktionen strcmp. |
$sicmp("String1", "String2") |
Utvärderas till -1, 0 eller 1, som Microsoft Win32-funktionen stricmp. |
$spat("String", "Pattern") |
Utvärderas till TRUE eller FALSE beroende på om Strängen matchar Mönster. Matchningen är inte skiftlägeskänslig. Mönstret kan innehålla en mängd olika jokertecken och specificerare. För mer information om syntaxen, se Strängsyntax för wildcards. |
$vvalid(adress,längd) |
Avgör om minnesintervallet som börjar på Adress och utökas för Längdbyte är giltigt. Om minnet är giltigt utvärderas $vvalid till 1. Om minnet är ogiltigt utvärderas $vvalid till 0. |
Exempel
Följande visar hur du undersöker intervallet av giltigt minne runt en inläst modul.
Bestäm först adressen för det intressanta området, till exempel med hjälp av kommandot lm (List Loaded Modules ).
0:000> lm
start end module name
00007ff6`0f620000 00007ff6`0f658000 notepad (deferred)
00007ff9`591d0000 00007ff9`5946a000 COMCTL32 (deferred)
...
Använd $vvalid för att kontrollera ett minnesintervall.
0:000> ? $vvalid(0x00007ff60f620000, 0xFFFF)
Evaluate expression: 1 = 00000000`00000001
Använd $vvalid för att bekräfta att det här större intervallet är ett ogiltigt minnesintervall.
0:000> ? $vvalid(0x00007ff60f620000, 0xFFFFF)
Evaluate expression: 0 = 00000000`00000000
Det här är också ett ogiltigt intervall.
0:000> ? $vvalid(0x0, 0xF)
Evaluate expression: 0 = 00000000`00000000
Använd inte för att returnera noll när minnesintervallet är giltigt.
0:000> ? not($vvalid(0x00007ff60f620000, 0xFFFF))
Evaluate expression: 0 = 00000000`00000000
Använd $imnet för att titta på startpunkten för COMCTL32 som vi tidigare använde lm-kommandot för att fastställa adressen. Den börjar på 00007ff9'591d0000.
0:000> ? $iment(00007ff9`591d0000)
Evaluate expression: 140708919287424 = 00007ff9`59269e80
Demontera den returnerade adressen för att undersöka ingångspunktkoden.
0:000> u 00007ff9`59269e80
COMCTL32!DllMainCRTStartup:
00007ff9`59269e80 48895c2408 mov qword ptr [rsp+8],rbx
00007ff9`59269e85 4889742410 mov qword ptr [rsp+10h],rsi
00007ff9`59269e8a 57 push rdi
COMCTL32 visas i utdata som bekräftar att det här är startpunkten för den här modulen.
Register och Pseudo-Registers i MASM-uttryck
Du kan använda register och pseudoregister i MASM-uttryck. Du kan lägga till ett vidtecken (@) innan alla register och pseudoregister. Vid-tecknet gör att felsökaren kommer åt värdet snabbare. Det här @-tecknet är onödigt för de vanligaste x86-baserade registren. För andra register och pseudoregister rekommenderar vi att du lägger till vid-tecknet, men det krävs faktiskt inte. Om du utelämnar vid tecknet för de mindre vanliga registren försöker felsökaren parsa texten som ett hexadecimalt tal, sedan som en symbol och slutligen som ett register.
Du kan också använda en punkt (.) för att ange den aktuella instruktionspekaren. Du bör inte lägga till ett @-tecken före den här perioden och du kan inte använda en punkt som den första parametern i r-kommandot. Den här perioden har samma betydelse som $ip pseudoregister.
Mer information om register och pseudoregister finns i Registersyntax och Pseudo-Register syntax.
Använd kommandot r register för att se att värdet för @rip registret är 00007ffb'7ed00770.
0:000> r
rax=0000000000000000 rbx=0000000000000010 rcx=00007ffb7eccd2c4
rdx=0000000000000000 rsi=00007ffb7ed61a80 rdi=00000027eb6a7000
rip=00007ffb7ed00770 rsp=00000027eb87f320 rbp=0000000000000000
r8=00000027eb87f318 r9=0000000000000000 r10=0000000000000000
r11=0000000000000246 r12=0000000000000040 r13=0000000000000000
r14=00007ffb7ed548f0 r15=00000210ea090000
iopl=0 nv up ei pl zr na po nc
cs=0033 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00000246
ntdll!LdrpDoDebuggerBreak+0x30:
00007ffb`7ed00770 cc int 3
Samma värde kan visas med hjälp av . periodgenväg.
0:000> ? .
Evaluate expression: 140718141081456 = 00007ffb`7ed00770
Vi kan bekräfta att alla dessa värden är likvärdiga och returnera noll om de är det, med hjälp av det här MASM-uttrycket.
0:000> ? NOT(($ip = .) AND ($ip = @rip) AND (@rip =. ))
Evaluate expression: 0 = 00000000`00000000
Källradsnummer i MASM-uttryck
Du kan använda källfils- och radnummeruttryck i MASM-uttryck. Du måste omsluta dessa uttryck med hjälp av allvarliga accenter ('). Mer information om syntaxen finns i Källradssyntax.