Hopper+qira作りたい②

【はじめに】
 昨日テンションあげあげで、@segfoさんと今後について話していた。
すると、昨日のブログ

のFeedbackにakiymさんから、


と返事が来た。

正直嗚咽をした。しかし、私と@segfoさんは+qiraだけをしたかったわけではない。し、したかったわけじゃないんだからね!諦める必要もないので、引き続き【Hopper+qira作りたい】という記事で書いていきたい。

【別のプロジェクト、Hopperの問題①】
 もう一つのプロジェクトに、IDAProとHopperのinstructionの相違を埋めたいというものがあった。@segfoさんによるとつまり、位置独立実行形式のバイナリはバイナリの中のアドレスが相対アドレスで書かれてるときがある。という。
下の図を見てもらいたい。
f:id:reonreon3reon:20140907001851p:plain

Hopper/Objdumpでは、call 0x8cdであるにも関わらず、
IDA Free,Pro/gdbでは、call putsというように、関数名として表示されている。

【問題改善、目標】
 端的に言えばHopperScript/SDKを使い、『アドレス解決をして関数名とリンクをする』というようなことが出来れば良いのではないかと考えた。
正解であるgdbとIDAの挙動としては、メモリ上にあるバイナリを読んで、それに対応する命令を置き換えたら良いのではないかということになった。
実際、実行してメモリにロードしてアドレスが解決されると正常に見える、という感じである。

【そのために】
 私はそのために、デバッガについて勉強するべきではと考えたが、@segfo氏曰く、「ローダーとは、プログラムを、メモリにロード(と必要であれば、メモリの初期化)して、
そのプログラムの実行必要なメモリを割り当てたり、Cのライブラリを初期化したり
最後にその実行したいプログラム(コンテキスト)に切り替える一連の作業をするプログラムであるから、call 0x8cdってなってるよく分からないアドレスが有りますけど、このアドレスを解決するのがローダのはず。このアドレスが解決されて、メモリの定位置を指すようにするのも多分OSの役目のはず。」という見解により、ローダーについて勉強しようと二人でなった。

「次の商品を購入しました:坂井 弘亮 『リンカ・ローダ実践開発テクニック―実行ファイルを作成するために必須の技術 (COMPUTER...#アマゾンポチ と入れて@返信でカートに追加・後で買う via @amazonJP」

本は即決で買った。明後日には届く。
楽しみだ。(テスト2週間前だけどそんなことどうでもいい)

【別のプロジェクト、Hopperの問題②】

以前、私と@_wata1221さんでpwnの問題を解いていた。すると、お互いの情報を交換している最中に、Hopperによりデコンパイルされた PseudoCがオカシイと@ucqさんに指摘された。

具体的に言うと、@ucqさん「memsetの関数呼び出しが消えて、rep stosdのようなものに置き換わる」とのことだった。

【問題改善、目標】
 ディスアセンブリの時点で本来のinstructionになっていないという可能性はあるのだろうかと考えたが、本来の命令というか、memsetなどの一部の関数はコンパイラによって最適化され、関数でなくinline化される。つまり、コンパイラについて勉強したほうが良い。それを勉強してHopperScriptでパース出来ればと考えている。

【そのために】
コンパイラがどのようにしてソースコードからバイナリを作成して、その際にどのような情報が失われているのか(=セマンティックギャップ)を理解があった方が良いらしい。
HopperScriptでコンパイラのセマンティックギャップを埋めるたいと考えている。
純粋にコンパイラの勉強も怠らずに、wikipediaに載っているインライン展開についても勉強しようと考えている。

【最後に】
 +qiraが出来ないのが非常にショックだったが、HopperのAuthorが処理にHookするような関数なり機能なりを作ってくれれば私と@segfoさんでどうにか出来ると考えている。(正直、デバッガがHookするための関数がないというのはオカシイはずなんだと思う)
それ以外にも課題はあるのでそれらの改善を目指していきたいと思う。

【追記】
某氏「たかがインライン展開のためにコンパイラについて学ぶのは非効率。
というかインライン展開はmemsetの様な有名標準関数以外では基本的に直すことにほとんど意味がない。IDAのデコンパイラでさえ、基本的に頭が悪いから、その頭の悪さと折り合いをつけてツールは使えるべきであって、直そうという努力も素晴らしいとはおもうけど、その前にそもそもデコンパイラなしで読めないのに使うなというのはあると思う。というだけなので別に間違ってはないと思うし頑張れ。まあ少し思うのは何でもかんでもソースコードと本読んで勉強するのが必ずしも良いことではないということですかね。そもそもよく知らないのに読んでも意味ないし。まあ実際努力次第では、インライン化されているかどうかを確率的に判定して読みやすくするみたいなことは可能だし、間違ってはないというのはそういう意味。インライン化されているかどうかなんて、セマンティックギャップ的にも判定出来ることじゃないから、単純に読みやすくするためにインライン化されていたと仮定するのはあり。」


↑感想、口悪い。


【追記②】

alcさん「最適化された命令列を最適化前の状態に戻したいということだよね。それめっちゃムズいやつ。de-optimizationって言ってやってる論文があるけど、一部の最適化に関してだけだねー。
Using de-optimization to re-optimize code ブログで言ってる②の方(インライン展開されたAPI呼び出しをcall api_nameっていう感じのシンボル使った呼び出しに直したいっていうやつ)だよね?FLIRTみたいなシグネチャベースでマッチさせるか、学習ベースでやるかのどっちかだと思うなぁ。手法的には学習使った方が賢いようにも思えるけど(汎化性能=ちょっと違う最適化された上でインライン展開されちゃったものにも対応できる性能を持たせられる)、かかる時間や誤認識がどれくらい出るか分からないし、実用的にはシグネチャを使うのがいいのかなぁ。という意味でIDAのFLIRTみたいにシグネチャをいっぱい用意しなきゃいけなくなりそうなので、②は超大変そう、っていう感じのツイートをしたのさー。(さっき」