もくじ
https://tera1707.com/entry/2022/02/06/144447
ダンプ関連記事
https://tera1707.com/entry/2022/02/06/144447#WindowsDump
やりたいこと
以前の記事で、WinDBGで.NETアプリのクラッシュダンプを解析したが、 そのときにアセンブラを見ないといけなかった。
その際に調べたことをメモしておく。 (まだ経験値が低いので、正確ではない可能性あり)
使用したアセンブラ命令(x64)
push rbp →rbpをスタックに積む(rspを更新(+8)) ※メソッドを呼んだ頭の部分で、必ずpush rbpをやるっぽい。
sub rsp,10h →rspから0x10減算する
lea rbp,[rsp+10h] →rbpにrsp+10h番地を入れる
xor eax,eax →XORをとる。同じレジスタ同士のXORは毎回0なので、0クリアするときにこれやるっぽい。
mov dword ptr [rbp-4],eax →rbp-4番地の値をeaxにする。(C言語の*(rbp-4)=*eax、みたいなものっぽい)
idiv eax,dword ptr [rbp+20h] →eaxを[rbp+20h]番地にある値で割って、eaxに入れる
add eax,2 →eaxに2を足して、eaxに入れる
pop rbp
メモ
マネージドコードの呼び出し規約は _CLRCALL規約
という。
(そのほかの呼び出し規約には_cdecl
やstdcall
などがある。→参考)
アセンブラのコードを見たときに、例えば何かのメソッドが呼ばれるときに、
- どこのレジスタにどういう値が入ってくるか、とか、
- ローカル変数がどこに入るか、とか
が、呼び出し規約によって変わってくる。
_CLRCALL規約では、 メソッドを呼んだときのアセンブラで、
- 引数の1個目は「EDX」
- 引数の2個目は「R8D」
- 引数の3個目は「R9D」
に入る。
[rbp+25h]という書き方は、
rbpの値+25h番地のアドレス、ということを表す。
dword ptr[rbp+25h]という書き方は、
rbp+25h番地にあるdwordの値、ということを表す。
アセンブラは、
- 左側が
デスティネーションレジスタ
- 右側が
ソースレジスタ
を表す。例えば
MOV m, rax
だったら、右に書かれたrax(RAXレジスタ)から、左に書かれたメモリに、値をコピーする、ということを表す。
r
は、レジスタm
は、メモリ#n
は、直値
RBPはそのメソッドにいる間は同じ。 RSPはメソッド内でpushがされたら積んだ分(+8)更新される。
参考
呼び出し規約の種類
https://learn.microsoft.com/ja-jp/cpp/cpp/argument-passing-and-naming-conventions?view=msvc-170
レジスタの説明など(x64)
https://learn.microsoft.com/en-us/windows-hardware/drivers/debugger/x64-architecture
アセンブラ命令の説明(x64)
https://learn.microsoft.com/en-us/windows-hardware/drivers/debugger/x64-instructions
https://learn.microsoft.com/en-us/windows-hardware/drivers/debugger/x86-instructions
レジスタの説明