Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

あなたの知らないnopたち@ラボユース合宿

628 views

Published on

x86/x64のいろんなnop

Published in: Technology
  • Be the first to comment

あなたの知らないnopたち@ラボユース合宿

  1. 1. あなたの知らないnopたち @ラボユース合宿 2017/8/24 光成滋生
  2. 2. • よく使われるループの先頭アドレスは 16byteアライメントされているとよいことが多い • そろえるために隙間を埋める • 隙間の命令は何もして欲しくない 何もしない(no operation)は何のため? アドレス 命令コード 命令コード 命令1 命令2LP: 0000xx11h 0000xx20h jnz LP 命令1 命令2LP: jnz LP 何もしない アライメント 2 / 10
  3. 3. • 何もしない1byteの命令 • xchg eax, eaxのalias(32bit時代) 90h(=0x90)
  4. 4. • 何もしない2byte命令(32bit) • lea eax, [eax] • 1byte nopを2個実行するより効率がよい(よかった) • 89 c0h • 別の何もしない2byte命令 • mov eax, eax • 8d 04 05 00 00 00 00h • 何もしない7byte命令 • lea eax, [eax * 1 + 0x00000000] • ... 8d 00h 4 / 10
  5. 5. • これらのnopたちは何もしないわけではなくなった • 32bitレジスタ操作命令は64bitレジスタの上位を クリアする • パーシャルレジスタストールを避けるために 値を保持する戦略はとらなかった(推測) • xchg eax, eax / lea eax, [eax]などもnopでなくなった • mov eax, eaxはxxxxxxxxを0にする • movzx rax, eaxと同じ(というかこの命令は存在しない) 64bit環境では rax(64) eax(32) ax(16) xxxxxxxx 5 / 10
  6. 6. • 90hは本当のnopになった • xchg eax, eaxではない • それではxchg eax, eaxはどうなった? • 87, c0h ; xchgの冗長表現 • xchg rax, raxは48 90h • 意味的には32bitのnopに対応するが内部的にはnopではない 64bitでのnop 6 / 10
  7. 7. • いつからnopが拡張された • nop r/m • nopがレジスタやメモリアドレッシングを引数に取る • 32/64bit両対応で同一コード multi byte nop 66 nop 66 90h nop dword ptr [eax] 0f 1f 00h nop dword ptr [eax + 00h] 0f 1f 40 00h nop dword ptr [eax + eax*1 + 00h] 0f 1f 44 00 00h 66 nop dword ptr [eax + eax*1 + 00h] 66 0f 1f 44 00 00h nop dword ptr [eax + 00000000h] 0f 1f 80 00 00 00 00h nop dword ptr [eax + eax*1 + 00000000h] 0f 1f 84 00 00 00 00 00h 66 nop dword ptr [eax + eax*1 + 00000000h] 66 0f 1f 84 00 00 00 00 00h 7 / 10
  8. 8. • multi byte nopはeax以外の引数も取れる • nop ecx, eax ; 0f 1f c1h • nop esp, [rax + rax] ; 0f 1a 04 00h • Intelはこの余ってるnopを拡張した multi byte nopの拡張 8 / 10
  9. 9. • バッファオーバーフローをOS/libレベルでチェック • 4個の128bit boundレジスタbnd0, bnd1, bnd2, bnd3 • 上位64bitは境界の上限, 下位64bitは境界の下限の値が入る • bndmk bnd, mem • memの値をbndレジスタに設定する • bndcl bnd, r/m • r/mの値がbndの下限より大きいかを確認 • bndcu bnd, r/m • r/mの値がbndの上限より小さいかを確認 • 範囲外ならbounds violationが発生 MPX(Memory Protection Extensions) 9 / 10
  10. 10. • MPX非対応CPU/OSで影響が出ないように拡張 • 対応していないとこう見える MPXエンコーディング bndmk bnd0, [rax] ; f3 0f 1b 00h bndcl bnd0, rax ; f3 0f 1a c0h bndcu bnd0, rax ; f2 0f 1a c0h bndldx bnd0, [rax+rax] ; 0f 1a 04 00h bndstx [rax+rax], bnd0 ; 0f 1b 04 00h nop eax, [rax] nop eax, eax nop eax, eax nop esp, [rax+rax] nop esp, [rax+rax] 10 / 10 [rax*2]と等しくない 省略可能な3引数オペランド の一部としてSIBを利用

×