Bagikan melalui


Nomor dan Operator MASM

Topik ini menjelaskan penggunaan sintaks ekspresi Microsoft Macro Assembler (MASM) dengan alat Windows Debugging.

Debugger menerima dua jenis ekspresi numerik yang berbeda: ekspresi C++ dan ekspresi MASM. Masing-masing ekspresi ini mengikuti aturan sintaksisnya sendiri untuk input dan output.

Untuk informasi selengkapnya tentang kapan setiap jenis sintaks digunakan, lihat Mengevaluasi Ekspresi dan ? (Evaluasi Ekspresi).

Dalam contoh ini? perintah menampilkan nilai register pointer instruksi menggunakan evaluator ekspresi MASM.

0:000> ? @rip
Evaluate expression: 140709230544752 = 00007ff9`6bb40770

Mengatur Evaluator Ekspresi ke MASM

Gunakan .expr (Pilih Evaluator Ekspresi) untuk melihat apa itu evaluator ekspresi default dan mengubahnya menjadi MASM.

0:000> .expr /s masm
Current expression evaluator: MASM - Microsoft Assembler expressions

Sekarang evaluator ekspresi default telah diubah, ? (Evaluasi Ekspresi) perintah dapat digunakan untuk menampilkan ekspresi MASM. Contoh ini menambahkan nilai hex 8 ke rip register.

0:000> ? @rip + 8
Evaluate expression: 140709230544760 = 00007ff9`6bb40778

Referensi @rip register dijelaskan secara lebih rinci dalam Sintaks Register.

Angka dalam Ekspresi MASM Debugger

Anda dapat menempatkan angka dalam ekspresi MASM di basis 16, 10, 8, atau 2.

Gunakan perintah n (Atur Basis Angka) untuk mengatur radiks default ke 16, 10, atau 8. Semua angka yang belum diprefiks kemudian ditafsirkan dalam basis ini. Anda dapat mengganti radiks default dengan menentukan awalan 0x (heksadesimal), awalan 0n (desimal), awalan 0t (oktal), atau awalan 0y (biner).

Anda juga dapat menentukan angka heksadesimal dengan menambahkan h setelah angka. Anda dapat menggunakan huruf besar atau huruf kecil dalam angka. Misalnya, "0x4AB3", "0X4aB3", "4AB3h", "4ab3h", dan "4aB3H" memiliki arti yang sama.

Jika Anda tidak menambahkan angka setelah awalan dalam ekspresi, angka dibaca sebagai 0. Oleh karena itu, Anda dapat menulis 0 sebagai 0, awalan diikuti oleh 0, dan hanya awalan. Misalnya, dalam heksadesimal, "0", "0x0", dan "0x" memiliki arti yang sama.

Anda dapat memasukkan nilai heksadesimal 64-bit dalam format xxxxxxxx'xxxxxxxx . Anda juga dapat menghilangkan aksen kuburan ('). Jika Anda menyertakan aksen kuburan, ekstensi tanda otomatis dinonaktifkan.

Contoh ini menunjukkan cara menambahkan nilai desimal, oktal, dan biner untuk mendaftarkan 10.

? @r10 + 0x10 + 0t10 + 0y10
Evaluate expression: 26 = 00000000`0000001a

Simbol dalam Ekspresi MASM Debugger

Dalam ekspresi MASM, nilai numerik dari simbol apa pun adalah alamat memorinya. Tergantung pada apa yang dirujuk simbol, alamat ini adalah alamat variabel global, variabel lokal, fungsi, segmen, modul, atau label lain yang dikenali.

Untuk menentukan modul mana yang dikaitkan dengan alamat, sertakan nama modul dan tanda seru (!) sebelum nama simbol. Jika simbol dapat ditafsirkan sebagai angka heksadesimal, sertakan nama modul dan tanda seru, atau hanya tanda seru, sebelum nama simbol. Untuk informasi selengkapnya tentang pengenalan simbol, lihat Sintaks Simbol dan Pencocokan Simbol.

Gunakan dua titik dua (::) atau dua garis bawah (__) untuk menunjukkan anggota kelas.

Gunakan aksen makam (') atau apostrof (') dalam nama simbol hanya jika Anda menambahkan nama modul dan tanda seru sebelum simbol.

Operator Numerik dalam Ekspresi MASM

Anda dapat mengubah komponen ekspresi apa pun dengan menggunakan operator unary. Anda dapat menggabungkan dua komponen apa pun dengan menggunakan operator biner. Operator unary lebih diutamakan daripada operator biner. Saat Anda menggunakan beberapa operator biner, operator mengikuti aturan prioritas tetap yang dijelaskan dalam tabel berikut.

Anda selalu dapat menggunakan tanda kurung untuk mengambil alih aturan prioritas.

Jika bagian dari ekspresi MASM diapit dalam tanda kurung dan dua tanda (@@) muncul sebelum ekspresi, ekspresi ditafsirkan sesuai dengan aturan ekspresi C++. Anda tidak dapat menambahkan spasi antara keduanya pada tanda dan tanda kurung pembuka. Anda juga dapat menentukan evaluator ekspresi dengan menggunakan @@c++( ... ) atau @@masm( ... ).

Saat Anda melakukan komputasi aritmatika, evaluator ekspresi MASM memperlakukan semua angka dan simbol sebagai jenis ULONG64.

Operator alamat unary mengasumsikan DS sebagai segmen default untuk alamat. Ekspresi dievaluasi dalam urutan prioritas operator. Jika operator yang berdekatan memiliki prioritas yang sama, ekspresi dievaluasi dari kiri ke kanan.

Anda dapat menggunakan operator unary berikut.

Operator Makna

+

Nilai tambah unary

-

Minus tidak sah

not

Mengembalikan 1 jika argumen adalah nol. Mengembalikan nol untuk argumen nonzero apa pun.

Hai

Tinggi 16 bit

 Rendah

Rendah 16 bit

dengan

Byte urutan rendah dari alamat yang ditentukan.

$pby

Sama seperti dengan kecuali bahwa dibutuhkan alamat fisik. Hanya memori fisik yang menggunakan perilaku penembolokan default yang dapat dibaca.

Wo

Kata urutan rendah dari alamat yang ditentukan.

$pwo

Sama seperti wo kecuali bahwa dibutuhkan alamat fisik. Hanya memori fisik yang menggunakan perilaku penembolokan default yang dapat dibaca.

dwo

Kata ganda dari alamat yang ditentukan.

$pdwo

Sama seperti dwo kecuali bahwa dibutuhkan alamat fisik. Hanya memori fisik yang menggunakan perilaku penembolokan default yang dapat dibaca.

qwo

Quad-word dari alamat yang ditentukan.

$pqwo

Sama seperti qwo kecuali bahwa dibutuhkan alamat fisik. Hanya memori fisik yang menggunakan perilaku penembolokan default yang dapat dibaca.

Poi

Data berukuran pointer dari alamat yang ditentukan. Ukuran pointer adalah 32 bit atau 64 bit. Dalam penelusuran kesalahan kernel, ukuran ini didasarkan pada prosesor komputer target . Oleh karena itu, poi adalah operator terbaik untuk digunakan jika Anda ingin data berukuran pointer.

$ppoi

Sama seperti poi kecuali bahwa dibutuhkan alamat fisik. Hanya memori fisik yang menggunakan perilaku penembolokan default yang dapat dibaca.

Contoh

Contoh berikut menunjukkan cara menggunakan poi untuk mendereferensikan pointer untuk melihat nilai yang disimpan di lokasi memori tersebut.

Pertama-tama tentukan alamat memori yang menarik. Misalnya kita dapat melihat struktur utas dan memutuskan kita ingin melihat nilai 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 terletak 0x108 di luar awal TEB.

0:000> ? @$teb + 0x108
Evaluate expression: 613867303176 = 0000008e`ed57b108

Gunakan poi untuk mendereferensikan alamat tersebut.

0:000> ? poi(0000008e`ed57b108)
Evaluate expression: 1033 = 00000000`00000409

Nilai yang dikembalikan dari 409 cocok dengan nilai CurrentLocale dalam struktur TEB.

Atau gunakan poi dan tanda kurung untuk mendereferensikan alamat terhitung.

0:000> ? poi(@$teb + 0x108)
Evaluate expression: 1033 = 00000000`00000409

Gunakan oleh atau wo operator unary untuk mengembalikan byte atau kata dari alamat target.

0:000> ? by(0000008e`ed57b108)
Evaluate expression: 9 = 00000000`00000009
0:000> ? wo(0000008e`ed57b108)
Evaluate expression: 1033 = 00000000`00000409

Operator Biner

Anda dapat menggunakan operator biner berikut. Operator di setiap sel lebih diutamakan daripada operator dalam sel yang lebih rendah. Operator dalam sel yang sama memiliki prioritas yang sama dan diurai dari kiri ke kanan.

Operator Makna

*

/

mod (atau %)

Perkalian

Pembagian bilangan bulat

Modulus (sisanya)

+

-

Tambahan

Pengurangan

<<

>>

>>>

Shift kiri

Shift kanan logis

Shift kanan aritmatika

= (atau ==)

<

>

<=

>=

!=

Sama dengan

Kurang dari

Lebih besar dari

Kurang dari atau sama dengan

Lebih dari atau sama dengan

Tidak sama dengan

dan (atau &)

Bitwise AND

xor (atau ^)

Bitwise XOR (eksklusif OR)

atau (atau |)

Bitwise OR

Operator <perbandingan , , >=, ==, dan != mengevaluasi ke 1 jika ekspresi benar atau nol jika ekspresi salah. Tanda sama dengan tunggal (=) sama dengan tanda sama dengan ganda (==). Anda tidak dapat menggunakan efek samping atau penugasan dalam ekspresi MASM.

Operasi yang tidak valid (seperti pembagian berdasarkan nol) menghasilkan "Kesalahan operand" dikembalikan ke jendela Perintah Debugger.

Kita dapat memeriksa apakah nilai yang dikembalikan cocok dengan 0x409 dengan menggunakan operator perbandingan == .

0:000> ? poi(@$teb + 0x108)==0x409
Evaluate expression: 1 = 00000000`00000001

Operator Non-Numerik dalam Ekspresi MASM

Anda juga dapat menggunakan operator tambahan berikut dalam ekspresi MASM.

Operator Makna

$fnsucc(FnAddress, RetVal, Flag)

Menginterpretasikan nilai RetVal sebagai nilai pengembalian untuk fungsi yang terletak di alamat FnAddress . Jika nilai pengembalian ini memenuhi syarat sebagai kode keberhasilan, $fnsucc mengembalikan TRUE. Jika tidak, $fnsucc mengembalikan FALSE.

Jika jenis pengembalian adalah BOOL, bool, HANDLE, HRESULT, atau NTSTATUS, $fnsucc memahami dengan benar apakah nilai pengembalian yang ditentukan memenuhi syarat sebagai kode keberhasilan. Jika jenis pengembalian adalah penunjuk, semua nilai selain NULL memenuhi syarat sebagai kode keberhasilan. Untuk jenis lainnya, keberhasilan ditentukan oleh nilai Bendera. Jika Bendera adalah 0, nilai bukan nol RetVal berhasil. Jika Bendera adalah 1, nilai nol RetVal berhasil.

$iment (Alamat)

Mengembalikan alamat titik entri gambar dalam daftar modul yang dimuat. Alamat menentukan alamat dasar gambar Portable Executable (PE). Entri ditemukan dengan mencari titik entri gambar di header gambar PE dari gambar yang ditentukan Alamat .

Anda dapat menggunakan fungsi ini untuk kedua modul yang sudah ada dalam daftar modul dan untuk mengatur titik henti yang tidak terselesaikan dengan menggunakan perintah bu.

$scmp("String1", "String2")

Mengevaluasi ke -1, 0, atau 1, seperti strcmp dengan menggunakan fungsi C strcmp.

$sicmp("String1", "String2")

Mengevaluasi ke -1, 0, atau 1, seperti fungsi Microsoft Win32 yang ketat .

$spat("String", "Pola")

Mengevaluasi ke TRUE atau FALSE tergantung pada apakah String cocok dengan Pola. Pencocokan tidak peka huruf besar/kecil. Pola dapat berisi berbagai karakter kartubebas dan penentu. Untuk informasi selengkapnya tentang sintaks, lihat Sintaks Wildcard String.

$vvalid(Alamat, Panjang)

Menentukan apakah rentang memori yang dimulai pada Alamat dan memperluas untuk Byte Panjang valid. Jika memori valid, $vvalid mengevaluasi ke 1. Jika memori tidak valid, $vvalid mengevaluasi ke 0.

Contoh

Berikut ini menunjukkan cara menggunakan penyelidikan rentang memori yang valid di sekitar modul yang dimuat

Pertama-tama tentukan alamat area yang diminati, misalnya dengan menggunakan lm (perintah List Loaded Modules .


0:000> lm
start             end                 module name
00007ff6`0f620000 00007ff6`0f658000   notepad    (deferred)
00007ff9`591d0000 00007ff9`5946a000   COMCTL32   (deferred)        
...

Gunakan $vvalid untuk memeriksa rentang memori.

0:000> ? $vvalid(0x00007ff60f620000, 0xFFFF)
Evaluate expression: 1 = 00000000`00000001

Gunakan $vvalid untuk mengonfirmasi bahwa rentang yang lebih besar ini, adalah rentang memori yang tidak valid.

0:000> ? $vvalid(0x00007ff60f620000, 0xFFFFF)
Evaluate expression: 0 = 00000000`00000000

Ini juga merupakan rentang yang tidak valid.

0:000> ? $vvalid(0x0, 0xF)
Evaluate expression: 0 = 00000000`00000000

Gunakan untuk tidak mengembalikan nol ketika rentang memori valid.

0:000> ? not($vvalid(0x00007ff60f620000, 0xFFFF))
Evaluate expression: 0 = 00000000`00000000

Gunakan $imnet untuk melihat titik masuk COMCTL32 yang sebelumnya kami gunakan perintah lm untuk menentukan alamat. Dimulai pada 00007ff9'591d0000.

0:000> ? $iment(00007ff9`591d0000)
Evaluate expression: 140708919287424 = 00007ff9`59269e80

Bongkar alamat yang dikembalikan untuk memeriksa kode titik masuk.

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 ditampilkan dalam output yang mengonfirmasi bahwa ini adalah titik masuk untuk modul ini.

Daftar dan Pseudo-Registers dalam Ekspresi MASM

Anda dapat menggunakan register dan pseudo-registers dalam ekspresi MASM. Anda dapat menambahkan tanda di (@) sebelum semua register dan pseudo-registers. Tanda saat ini menyebabkan debugger mengakses nilai dengan lebih cepat. Tanda @ ini tidak perlu untuk register berbasis x86 yang paling umum. Untuk register lain dan pseudo-registers, kami sarankan Anda menambahkan tanda tangan, tetapi itu tidak benar-benar diperlukan. Jika Anda menghilangkan tanda saat untuk register yang kurang umum, debugger mencoba mengurai teks sebagai angka heksadesimal, lalu sebagai simbol, dan akhirnya sebagai register.

Anda juga dapat menggunakan titik (.) untuk menunjukkan penunjuk instruksi saat ini. Anda tidak boleh menambahkan tanda @ sebelum periode ini, dan Anda tidak dapat menggunakan titik sebagai parameter pertama perintah r. Periode ini memiliki arti yang sama dengan pseudo-register $ip .

Untuk informasi selengkapnya tentang register dan pseudo-registers, lihat Mendaftarkan Sintaksis dan Sintaks Pseudo-Register.

Gunakan perintah r register untuk melihat bahwa nilai @rip register adalah 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

Nilai yang sama ini dapat ditampilkan menggunakan . pintasan titik.

0:000> ? .
Evaluate expression: 140718141081456 = 00007ffb`7ed00770

Kita dapat mengonfirmasi bahwa nilai-nilai tersebut semuanya setara, dan mengembalikan nol jika ya, menggunakan ekspresi MASM ini.

0:000>  ? NOT(($ip = .) AND ($ip = @rip) AND (@rip =. ))
Evaluate expression: 0 = 00000000`00000000

Nomor Baris Sumber dalam Ekspresi MASM

Anda dapat menggunakan file sumber dan ekspresi nomor baris dalam ekspresi MASM. Anda harus mengapit ekspresi ini dengan menggunakan aksen kuburan ('). Untuk informasi selengkapnya tentang sintaks, lihat Sintaks Baris Sumber.

Lihat juga

Ekspresi MASM vs. Ekspresi C++

Contoh Ekspresi Campuran

Nomor dan Operator C++

Tanda tangani Ekstensi

? (Evaluasi Ekspresi)