0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

IA-32チートシート

Last updated at Posted at 2025-10-09

IA32 チートシート

Intel構文は<ニーモニック> <Destination>, <Source>となっている。

代表的なデータ型

型名 サイズ
Byte 1バイト
WORD 2バイト
DWORD 4バイト
QWORD 8バイト

レジスタ

汎用レジスタ

レジスタ 概要 下位16bit 下位16bitのうち上位8bit 下位16bitのうち下位8bit
EAX 算術計算の結果や戻り値が格納される AX AH AL
EBX 他のレジスタでは足りない時に利用される BX BH BL
ECX ループ操作などのカウンタが格納される CX CH CL
EDX 汎用計算に使用される DX DH DL
EBP スタックのベースポインタが格納される BP - -
ESP スタックポインタが格納される SP - -
ESI / EDI オペランドの Source / Destination に利用される - - -

EFLAGレジスタ

算術結果の状態を格納するためのレジスタ。代表的なものを以下に記載する。

名称 概要
CF / Carry Flag 桁上がりもしくは桁借りした場合に1
PF / Parity Flag 結果の最下位バイトに値1のビットが偶数個含まれている場合は1、奇数個の場合は0
ZF / Zero Flag 操作の結果が0になった場合に1
SF / Sign Flag 操作の結果がマイナスになった場合に1
OF / Overflow Flag 符号付き算術演算でオーバーフローが発生した場合に1

アドレッシングモード

モード サンプル 概要
レジスタアドレッシング mov eax, ebx レジスタの値をそのまま入れる
イミディエイト mov eax, 0Ah 値自体を入れる(0Ah = 10)
直接アドレッシング mov eax, [1234h] eaxにメモリアドレス1234hにある値を入れる
ベースポインタ相対アドレッシング mov eax, [1234h + 2] eaxにメモリアドレス1234hに2を加えたメモリ領域の値を入れる
間接アドレッシング mov eax, [edi] eaxにediレジスタに入っているアドレスのメモリ領域の値を入れる
ベース - インデックス mov eax, [ebx + edi] eaxにebxに入っているメモリアドレスにediを足した結果のメモリ領域の値を入れる

代表的な命令一覧

ニーモニック 命令 概要
mov mov A, B AにBの値を格納
add add A, B A = A + B
sub sub A, B A = A - B
mul mul A EAXの値とオペランドAの掛け算の結果(符号なし)を
EDX(上位ビット)とEAX(下位ビット)に格納
div div A EDX:EAXの値をオペランドAで割った結果(符号なし)を
EAX(商)とEDX(余り)に格納
inc inc A A = A + 1
dec dec A A = A - 1
imul imul A EAXの値とオペランドAの掛け算の結果(符号あり)を
EDX(上位ビット)とEAX(下位ビット)に格納
idiv idiv A EDX:EAXの値をオペランドAで割った結果(符号あり)を
EAX(商)とEDX(余り)に格納
and and A, B AにAとBの論理積を入れる
or or A, B AにAとBの論理和を入れる
xor xor A, B AにAとBの排他的論理和を入れる
xor eax, eaxと記載して初期化する(0になる)
not not A Aの否定(1の補数)をAに入れる
sal sal A, B AをBだけ算術左シフトした結果をAに入れる
A*(2^n)となる
sar sar A, B AをBだけ算術右シフトした結果をAに入れる
A/(2^n)となる
shl shl A, B AをBだけ論理左シフトした結果をAに入れる
A*(2^n)となる
shr shr A, B AをBだけ論理右シフトした結果をAに入れる
A/(2^n)となる
rol rol A, B Aを左にB回だけ回転させる
ror ror A, B Aを右にB回だけ回転させる
rcl rcl A, B A(+CF)を左にB回だけ回転させる
rcr rcr A, B (CF+)Aを右にB回だけ回転させる
push push A ESPを-4バイトしてAの値をスタックに入れる
pop pop A スタックから値を取り出しAに入れ、ESPを+4バイトする
pusha pusha ESPを-16バイトして16バイトレジスタの値をスタックに入れる
レジスタ:AX, CX, DX, BX, SP, BP, SI, DI
pushad pushad ESPを-32バイトして32バイトレジスタの値をスタックに入れる
レジスタ:EAX, ECX, EDX, EBX, ESP, EBP, ESI, EDI
popa popa スタックから値を取り出し16バイトレジスタに格納し、ESPを+16バイトする
レジスタ:AX, CX, DX, BX, SP, BP, SI, DI
popad popad スタックから値を取り出し32バイトレジスタに格納し、ESPを+32バイトする
レジスタ:EAX, ECX, EDX, EBX, ESP, EBP, ESI, EDI
call call A 戻り先をスタックにプッシュし、EIPにAを入れる
ret ret (A) ESPが示しているデータをEIPに入れる
Aがある場合、AバイトだけESPをマイナスする
test test A, B AとBの論理積で比較し結果をEFLAGSにセット
cmp cmp A, B AとBを比較(A-Bをする)
jmp jmp A Aにジャンプ
je / jz je(jz) A 結果が等しいか0のときにAへジャンプ
jne / jnz jne(jnz) A 演算結果が0でないときAへジャンプ
jg jg A 大きいときAにジャンプ
jge jge A 大きいか等しいときにAにジャンプ
ja ja A 大きいとき(符号なし)Aにジャンプ
jae jae A 大きいか等しいとき(符号なし)にAにジャンプ
jl jl A 小さいときAにジャンプ
jle jle A 小さいか等しいときAにジャンプ
jb jb A 小さいとき(符号なし)Aにジャンプ
jbe jbe A 小さいか等しいとき(符号なし)Aにジャンプ
lea lea A, B BのアドレスをAに入れる
nop nop 何もしない
int3 int 3 ソフトウェアブレークポイント用
loop loop A ECXのカウンタをデクリメントして0以外ならAにジャンプ、0なら次の命令を実行
cld cld DFをクリア
std std DFをセット
scasb scasb ALとEDIを比較しFLAGSを設定
DFが0:EDIをインクリメント
DFが1:EDIをデクリメント
repne repne scasb ECXをデクリメントし0になるかZFが1になるまでscasb命令をループ

代表的な処理の特徴

配列へのアクセス

mov ecx, [ebp+<var>] ; hoge[0] 
add ecx, [ebp+<counter>] ; hoge[0]からcounterバイト分アドレス加算
                         ; -> hoge[counter]
mov [ecx], <value>

j = j + S[i] + K[i % 128]のパターン

mov ecx, [ebp + <var_4>] ; var_4[0]
add ecx, [ebp + <counter>] ; var_4[0+i]
add ecx, [ebp + <var_14>] ; var[i] + j
mov eax, [ebp + <counter>] ; i
idiv [ebp + <key_length>] ; i % key_length
mov eax, [ebp + <arg_0>] ; 符号拡張
movsx edx, byte ptr [eax+edx] ; j + s[i] + K[ i % 128 ]
add ecx, edx
and ecx, 800000FFh

配列の初期化

xor     ebx, ebx ; ebx = 0
xor     eax, eax ; eax = 0
push    1Fh ; 1Fh = 31
lea     edi, [ebp+var_93] ; edi = var_93のアドレス
pop     ecx ; ecx = 31
mov     [ebp+var_94], bl ; var_94 = 0
rep stosd
        ; rep:ecxが0になるまで繰り返す(ecxの回数分繰り返す)
        ; stosdの挙動は以下の通り
        ; 1. ediが示すメモリアドレスにeaxの値を設定する
        ; 2. ediのアドレスを4バイト(dword分)加算する
        ; 3. ecxの値を1減らす
stosw
        ; 1. ediが示すメモリアドレスにeaxの下位2バイトを設定する
        ; 2. ediのアドレスを2バイト(word分)加算する
stosb
        ; 1. ediが示すメモリアドレスにeaxの下位1バイトを設定する
        ; 2. ediのアドレスを1バイト(byte分)加算する
アセンブリ 説明
xor ebx, ebx ebxレジスタを0で初期化する(eaxレジスタの値を同じ値でxorすると0となるため)
xor eax, eax eaxレジスタを0で初期化する
push 1Fh スタック領域に1Fh(16進数:0x1F, 10進数:31)を格納する
lea edi, [ebp+var_93] ediレジスタに変数var_93のメモリアドレスを格納する
pop ecx ・スタックの一番上に積まれている値を取り出しecxレジスタに格納する
・今回は1Fh(16進数:0x1F, 10進数:31)がレジスタに格納される
mov [ebp+var_94], bl var_94にebxの下位8ビットの値を格納する
・ebxは0であるため32bitすべて0であり、下位8ビットも0であるため、0をvar_94に格納している
rep stosd repstosdをecxが0になるまで繰り返す(ecxの回数分繰り返す)
stosdは以下の処理を行う
 1. ediが示すメモリアドレスにeaxの値を設定する
 2. ediのアドレスを4バイト(dword分)加算する
 3. ecxの値を1減らす
stosw 1. ediが示すメモリアドレスにeaxの下位2バイトを設定する
2. ediのアドレスを2バイト(word分)加算する
stosb 1. ediが示すメモリアドレスにeaxの下位1バイトを設定する
2. ediのアドレスを1バイト(byte分)加算する

インクリメント

mov eax, [ebp+<var>]
add eax, 1
mov [ebp+<var>], eax

swap関数呼び出し

swap(s[i], s[j])の場合

mov eax, [ebp+s]
add eax, [ebp+j]
push eax
mov eax, [ebp+s]
add eax, [epb+i]
push eax
call _func

関数

ポイントのサマリは以下の通り

  • []はその中に記載されたメモリアドレスが示すメモリ領域を示している
  • メモリアドレス(ポインタ)を渡す場合はleaニーモニックが利用される
  • 値渡しの場合、引数はそのままスタックにプッシュされ、サブルーチン内で直接使用される
  • ポインタ渡しの場合、引数としてメモリアドレスが渡され、サブルーチン内でそのアドレスが指す値にアクセスする

値渡しの場合

サブルーチン呼出し直前の処理

mov [esp + var_4], 2 ; 変数var_4に0x2を格納する
push [esp + var_4] ; スタックに変数var_4の値(0x2)を格納する
mov eax, 1 ; eaxに0x1を格納する
push eax ; スタックにeaxの値(0x1)を格納する

サブルーチン呼出し直後のサブルーチン側での処理

mov eax, [esp+arg_0] ; eaxに第1引数(0x1)を格納する
mov ebx, [esp+arg_4] ; ebxに第2引数(0x2)を格納する

ポインタ渡しの場合

サブルーチン呼出し直前の処理

lea eax, [esp + var_4] ; eaxにvar_4のメモリアドレスを格納する
push eax ; スタックにvar_4のメモリアドレスを格納する
call sub_1234E5 ; サブルーチンを実行する

サブルーチン呼出し直後のサブルーチン側での処理

mov eax, [esp + arg_0] ; eaxに第1引数であるメモリアドレスを格納する
mov ebx, [eax] ; ebxにeaxに格納されているメモリアドレスが示す先の値を格納する

IDA 操作テクニック

IDA Pythonによるcall命令のカラーコーディング

for head in Heads():
    op = print_insn_mnem(head)
    if op == "call" or op == "jmp":
        set_color(head, CIC_ITEM, 0xe0f0e0)

アセンブリコードに情報を追加

各行のメモリアドレスと値など自動的にコメントを付与する

  • Options > General > Disassembly > Display disassembly line parts
    • ☑ Line prefixes(graph)
    • ☑ Auto comments

ショートカットキー

ショートカットキー 名称 概要
F4 カーソル行まで実行 選択している行まで実行する
F7 ステップイン 1行ずつ実行する。callの場合は関数へ入る。
F8 ステップアウト 1行ずつ実行する。callの場合は関数へ入らず実行後の状態で次の行へ移る。
F9 続行 次のブレークポイントまで実行する
Ctrl + n EIP書き換え EIPのアドレスを選択している行のアドレスに書き換える
n rename 選択している変数の名前を変換する
: Enter comments コメントを追加する
x Jump to xref to operand 選択している関数を呼び出している場所を逆参照する
u undefine IDAが自動的に識別し設定した内容を解除する
h hex to decimal, decimal to hex 選択した値を16進数↔10進数の相互変換を行う
a hex to ascii, ascii to hex 選択した値を16進数↔ASCII文字の相互変換を行う

その他ショートカットは公式サイトを確認する。
Shortcuts | Hex-Rays Docs

実行命令の強制変更

  • 右クリックしてSet IPをクリックすると、設定したところから命令が開始される

構造体情報設定、追加

  • 該当の値が特定のキーの数値だった場合、特定のキーの名称に逆変換することが可能である
    • 該当の値を右クリックしてSymbolic constant -> Use standard symbolic constant
  • 動的ロードの場合は構造体情報がStructuresに入らないため、自身で追加する必要あり
    • 追加後、数値を右クリックして定義すればメンバーアクセス状況を文字化することができる
    • コード例
      mov     ecx, [eax+edx+8] ; 修正前
      mov     ecx, [eax+edx+_WTS_PROCESS_INFOA.pProcessName] ; 修正後
      
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?