読者です 読者をやめる 読者になる 読者になる

Log.i53

Themidaのアンパックを目指すブログ改め使い物になるえんじにゃを目指すブログ

ODbgScriptを利用したUPXのOEP探索

 ODbgScriptを利用してUPXでパックされた実行ファイルのOEP探索を自動化してみましょう。前回説明したように、UPXではPUSHAD命令とPOPAD命令(全てのレジスタの退避と復帰)の対称性に着目したESPトリックという手法を用いることでOEPにジャンプする命令の直前まで一気に進むことができました。ESPトリックを利用する場合のOEP探索手順は以下のとおりでした。

  • PUSHAD命令に到達するまで実行
  • PUSHAD命令を実行したらESPにハードウェアブレークポイントを設置
  • F9で実行するとPOPAD命令直後でブレーク!
  • すぐ後ろにあるジャンプ命令(テールジャンプ)のジャンプ先がOEP!

UPX OEP Finder

 上記の操作を自動化するOllyScriptの例を以下に示します:

//////////////////////////////////////////////////
//
//  FileName    :  UPX OEP Finder
//  Author      :  i53
//  Date        :  2015-06-17
//  Comment     :  Use ESP Trick to get the OEP
//
//////////////////////////////////////////////////
INIT:
  bc      // SBPをすべてクリアしておく
  bphwc   // HBPをすべてクリアしておく

FIND_PUSHAD:
  gci eip, COMMAND      // GCIコマンドで現在の命令のオペコード文字列を取得
  cmp $RESULT, "PUSHAD" // PUSHAD命令に一致するまで
  sto                   // ステップオーバーを繰り返す
  jne FIND_PUSHAD 
  bphws esp, "r"        // PUSHAD命令実行後のESPにHBP(read)を設置
  eob FIND_JMP_OEP      // ブレーク時にFIND_JMP_OEPにジャンプ
  run                   // 実行(F9)

FIND_JMP_OEP:
  // log esp
  bphwc esp-20             // 先ほど設置したHBPをクリア
  findop eip, #E9????????# // 直近のJMP命令を検索
  cmp $RESULT, 0
  je NOT_FOUND
  gci $RESULT, DESTINATION // GCIコマンドでJMP先(=OEP)を取得
  bphws $RESULT, "x"       // OEPにHBP(execute)を設置
  eob OEP_FOUND            // ブレーク時にOEP_FOUNDにジャンプ
  run                      // 実行(F9) 

OEP_FOUND:
  bphwc $RESULT            // 先ほど設置したHBPをクリア
  an eip                   // 分析機能(Ctrl+A)実行 
  cmt eip, "This is the OEP!"
  msg "OEP is found :)"
  ret                      // スクリプト終了

NOT_FOUND:
  msg "JMP OEP instruction is not found :("
  ret

実行すると自動的にOEPに遷移します:
f:id:i53:20150617051622p:plain

OllyScriptの各種コマンドについては以下のリファレンス翻訳記事を参照して下さい。i53.hatenablog.jp

ハッピーアンパッキング:)