2014年4月12日土曜日

久しぶりに逆アセンブラでbug発見

以前いじっていたラインアセンブラ&逆アセンブラのコードを何気なく見ていたら、Bugを発見した。
最初、おかしいなと感じるけど、しばらくいじってなかったので、判断できない。
MSP430は、アセンブリ言語とマシン語が一対一ではないので、バイナリが一致していなくても、同じニーモニックになる事がある。
それと区別するのがやや手間である。

SVNのメッセージやログ、テストコード、ソースコード内のコメント、そしてこのブログの記事を読んで、その当時のことをだんだん思い出してきた。
テストコードがERRORと判断したものは、14個ある。
それらすべては、逆アセンブルして、アセンブルしなおした内容が、元のマシン語に一致しないというものだ。
同じ異常が複数回報告されているので、種類数でいうと4種類になる。
そのうち、3つは表現が違うだけで、問題はないことがわかった。
残りの1つは、やはりBugだった。

ブログの記事を見直すと、正常系しかテストできてないみたいなことが書いてある。
このBugは、異常系のコードを扱う時の問題だ。異常系の処理も最初から実装しているものの、とりあえずテスト内容からは除外していた。しらみつぶしテストを作るときに、それらのテストも行う用意を始めたのだが、何らかの事情で、途中で投げていたようだ。

Bugを修正した後、残りの3つについても、どうするか検討した。
表現が違うのは、元のマシン語が特殊すぎるものだからだ。
これらは、無駄に長いワードで表現された命令や、アドレス範囲が狭いものなど、通常使われないマシン語だ。
これを逆アセンブルして、アセンブルしなおした時、アセンブラが適切なマシン語にしてしまうため、元のバイナリとは違ってくる。

色々考えたのだが、逆アセンブラがこのような通常使わない命令に遭遇するのは、コード領域以外の部分を逆アセンブルしてしまった時が多いだろう。
本来、これらの領域を逆アセンブルする必要はない。しかし、どういう命令なの解かっているのに示さないというのも、逆アセンブラとしては片手落ちだ。そのため、逆アセンブラとしては、アセンブリ言語で表示すべきだ。しかし、アセンブリ言語になってしまうと、普通の命令と区別がつかなくなる。
元のバイナリが普通ではないという事が区別できるようにしておきたい。そうすることで「ここはコード領域ではない可能性が高い」というのがわかりやすくもなる。
区別のため、そのような命令の後ろに、コメント文で"WARNING: Inefficient instruction."とか、"WARNING: Restricted DST ADDR."とかをつけるようにした。
とりあえず、実装してみたが、Warningと言いたくなるような命令は他にもたくさんある。
今回は、問題を検出したその場所で表示するようにしたが、もっと統一的な手段で実装したほうがいいかもしれない。

その修正をするのはいつになるだろう。また来年かな。
納期があるわけではない。のんびりやろう。

関連する過去の記事:
ラインアセンブラ
ラインアセンブラ2
ラインアセンブラ3
ラインアセンブラ4

0 件のコメント:

コメントを投稿