Catatan
Akses ke halaman ini memerlukan otorisasi. Anda dapat mencoba masuk atau mengubah direktori.
Akses ke halaman ini memerlukan otorisasi. Anda dapat mencoba mengubah direktori.
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 heksadesimal 8 ke register RIP.
0:000> ? @rip + 8
Evaluate expression: 140709230544760 = 00007ff9`6bb40778
Referensi register @rip dijelaskan lebih rinci dalam Sintaks Register.
Angka pada Ekspresi Debugger MASM
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 dua 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.
| Pengoperasi | Makna |
|---|---|
+ |
Nilai tambah unary |
- |
Minus tidak sah |
tidak |
Mengembalikan 1 jika argumen adalah nol. Mengembalikan nol untuk argumen nonzero apa pun. |
Hai |
Bit lebih tinggi dari 16-bit |
rendah |
16 bit bagian bawah |
oleh |
Byte urutan rendah dari alamat yang ditentukan. |
$pby |
Sama seperti oleh kecuali dibutuhkan alamat fisik. Hanya memori fisik yang menggunakan perilaku caching 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 cache 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 cache bawaan 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 cache bawaan yang dapat dibaca. |
Poi |
Data berukuran pointer dari alamat yang ditentukan. Ukuran pointer adalah 32 bit atau 64 bit. Dalam debugging kernel, ukuran tersebut 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 penyimpanan sementara 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 benang dan memutuskan untuk melihat nilai dari 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 operator unary by atau wo untuk mengembalikan byte atau word 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.
| Pengoperasi | Makna |
|---|---|
* / mod (atau %) |
Perkalian Pembagian bilangan bulat Modulus (sisanya) |
+ - |
Penambahan Pengurangan |
<< >> >>> |
Shift kiri Shift kanan logis Shift kanan aritmatika |
= (atau ==) < > <= >= != |
Sama dengan Kurang dari Lebih besar dari Kurang dari atau sama dengan Lebih besar dari atau sama dengan Tidak sama dengan |
dan (atau &) |
Bitwise DAN |
xor (atau ^) |
Bitwise XOR (eksklusif OR) |
atau (atau |) |
Bitwise ATAU |
Operator perbandingan <, >, =, ==, dan != mengevaluasi ke 1 jika ekspresi benar atau ke nol jika ekspresi salah. Tanda sama dengan tunggal (=) setara dengan tanda sama dengan ganda (==). Anda tidak dapat menggunakan efek samping atau pemberian nilai dalam ekspresi MASM.
Operasi yang tidak valid (seperti pembagian dengan nol) akan menghasilkan "Kesalahan operand" yang 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.
| Pengoperasi | 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 Flag adalah 0, nilai RetVal yang bukan nol menunjukkan keberhasilan. Jika Flag adalah 1, nilai nol dari RetVal menunjukkan keberhasilan. |
$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 stricmp. |
$spat("String", "Pattern") |
Mengevaluasi ke TRUE atau FALSE tergantung pada apakah String sesuai dengan pola. Pencocokan tidak mempertimbangkan huruf besar dan kecil. Pola dapat berisi berbagai karakter pengganti dan spesifikator. Untuk informasi selengkapnya tentang sintaks, lihat Sintaks Wildcard String. |
$vvalid(Alamat,Panjang) |
Menentukan apakah rentang memori yang dimulai pada Alamat dan mencakup Panjang byte valid. Jika memori valid, $vvalid mengevaluasi ke 1. Jika memori tidak valid, $vvalid mengevaluasi ke 0. |
Contoh
Berikut ini menunjukkan cara menyelidiki 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 tidak untuk mengembalikan nol jika 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.
Register dan Pseudo-Registers dalam Ekspresi MASM
Anda dapat menggunakan register dan pseudo-register dalam ekspresi MASM. Anda dapat menambahkan tanda di (@) sebelum semua register dan pseudo-register. Tanda '@' membuat debugger mengambil nilai dengan lebih cepat. Tanda @ ini tidak perlu untuk register berbasis x86 yang paling umum. Untuk register lainnya dan pseudo-register, kami sarankan Anda menambahkan tanda @, tetapi tidak benar-benar diperlukan. Jika Anda menghilangkan tanda @ untuk register yang kurang umum, debugger mencoba membaca teks sebagai angka heksadesimal, lalu sebagai simbol, dan akhirnya sebagai register.
Anda juga dapat menggunakan tanda 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-register, lihat Sintaks Register dan sintaksPseudo-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 tanda aksen (`). Untuk informasi selengkapnya tentang sintaks, lihat Sintaks Baris Sumber.