3
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

x64dbgによるIAT再構築(UPXのアンパック)

Posted at

概要

以下のプログラムをコンパイルして、 UPX 3.96 でパッキングし、それを手動でアンパックする。

sleep.cpp
#include <windows.h>
#include <stdio.h>

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) {
	for(int i=0; 1; i++) {
		if(i%5==0) printf("%d\n", i);
		Sleep(1000);
	}
	return TRUE;
}

IAT再構築をやる意味

パッキングすると、表層解析においてどんな Windows API がインポートされているのかの情報がかなり削減される。上記のプログラムをコンパイルした sleep.exe と、それを upx sleep.exe -o sleep-upx.exe でパックしたプログラム sleep-upx.exe のインポートをpestudioで見てみた結果が以下。

sleep.exe ↓
image.png

sleep-upx.exe ↓
image.png

おそらく pestudio のこのインポートの情報は、IAT(プログラムロード前はIATにはインポートする関数の名前等が書いてある)から得ていて、この情報が圧縮されているため sleep-upx.exe では Sleep の文字が見当たらない(ILTから得ているのかもしれないが…)。

しかし、パッキングは実行してる時には自分自身を解凍していて、かつインポートしている関数のアドレスがIATにセットされているので(プログラムロード後はIATにはインポート関数の実際のアドレスだけが格納される)、このタイミングでメモリダンプすればどんなコードなのかとか、インポートしてる関数は何かなどがわかり、Sleep 関数のアドレスもわかる。

また、パッキングされている場合、例えば sleep-upx.exe の Sleep をIATフックしたい場合、前回のフックのプログラムを見てもわかるが、Sleep のアドレスがIATにあったとしても、どのアドレスが Sleep のアドレスなのかというのは、ILT(OriginalFirstThunk)は圧縮された状態のインポート情報のままなので、わからないのでフックができない。実際にやってみる。

sleep.exe の Sleep をフックした場合(成功) ↓
image.png

sleep-upx.exe の Sleep をフックした場合(失敗) ↓
image.png

よって、実際に実行してみてIATがセットされた後、この情報をもとにIATを再構築して、全てのインポートの関数の情報を復元する必要がある。

OEPを見つける

パッキングされた実行ファイルのエントリーポイントには、オリジナルのコードを解凍する処理が並んでいるわけだが、オリジナルのコードの本来のエントリーポイントまでまずは実行する必要がある。ちなみにOEPにブレークポイントを打ってそこでブレークさせた状態でIAT再構築しないと上手く行かない。

注意として、UPXアンパックで調べると、pushadpopad に注目してOEPを見つける方法があるが、どうやら UPX 3.96 では pushad とかは使われていないので、別の方法で見つけないといけない。

とりあえず今回はオリジナルの sleep.exe も手元にあるので、これのエントリーポイント付近のアセンブラを覚えておく。
image.png
なんか sub rsp,28 から始まり、二つの mov 、二つの call が続くみたいに覚えておく。

そして、まずは sleep-upx.exe を何もブレークポイントも打たないでただ実行する。そして、適当なタイミングで一時停止して、その付近で同じようなアセンブラ命令が続く場所を探す。
image.png
なんかどうやら sleep.exe のエントリーポイントと同じ場所にあるっぽい。

それなので、0x4014eがOEPだとわかったので、ここにハードウェアブレークポイントをセットする(普通のソフトウェアブレークポイントだと別のアドレスにOEPが来てしまう… 検知されてるのか…?)。
image.png
この状態になったらそのまま、Plugin > Scylla を開き、File > Dump Memory して、Dump PE を押し、適当な場所に sleep-upx-dump.exe とかの名前で保存する。

その後、Scyllaの画面に戻り、IAT Autosearch を押した後、Get Imports を押し、Fix Dump を押して、先ほどの sleep-upx-dump.exe を選択する。
image.png
そうすると、同じディレクトリに sleep-upx-dump_SCY.exe という名前でファイルができているので、これで再構築完了!

ちゃんとできてるか確認

動作確認として、ちゃんと実行できるかまず確認する。
image.png

実行できてることを確認した後、ではちゃんとインポートの情報が復元できているか再びpestudioで確認する。
image.png
完璧にオリジナルの sleep.exe と同じようなインポート情報に復元されている。

それでは最後に API Hook ができるようになってるか確認する。
image.png
フックできるようになった!

3
1
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
3
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?