生のバイナリコードからプロセッサタイプを識別しますか?


19

実際にはチップとは関係ありませんが、うまくいけばここからいくつかの指示を得ることができます。

私はコードの塊を手に入れましたが、それがどのプロセッサを対象としているかはわかりません。コードの種類を特定するのに役立つツールはありますか?どの統計手法が役立ちますか?バイト分布?ペア分布など?多分マルコフ連鎖?


7
生の16進数の最初の200バイトを教えてください。
-pingswept

これは楽しい質問です。どのようなデバイスをハッキングしていますか?
DavidEGrayson

1
それをいくつかの異なる逆アセンブラーに供給して、何が起こるかを見てみてください。
ジャストジェフ

2
そのコードに100バイトで名前を付けます!= P
ジャストジェフ

いい質問ですね。ただし、StackOverflowに適している場合があります。
sharptooth

回答:


16

GNUファイルで実行してみてください。標準のヘッダーがある場合は、それを取得します。

例えば。

jrt@lin:~/src$ file foo
foo: ELF 32-bit LSB executable, Atmel AVR 8-bit, version 1 (SYSV), statically linked, not stripped

それを試しました。GNUファイルは、それが「データ」であると言います。
メンタリスト

3
いくつか投稿していただけますか?「文字列」でASCIIを検索しようとしましたか?
トビージャフィー

9

これは非常に興味深い質問です。そこには何百万もの命令セットがありますが、非常に一般的に使用されるものはほんの一握りです。

私が最初に見たいのは、起源と使用目的です。疑った場合は米国で設計されたは、たとえば、主に英語版のデータシートでプロセッサをターゲットにしています。アジアで設計された場合、米国のエンジニアがめったに見ない大量生産デバイスに使用するプロセッサが多数あります。ヨーロッパでも、他のプロセッサよりも一般的なプロセッサがいくつかあります。

次に、コードのサイズと機能を調べます(コードがある程度実行することを知っていると仮定します)。数メガバイトのコードであれば、ほとんどの組み込み8ビットプロセッサを大幅に割引き、外部メモリを備えたより大きなデバイスを検討することができます。数キロバイト以下の場合は、代わりに小さくて安価なデバイスに焦点を当てたいと思うでしょう。機能が単純な場合、4ビットプロセッサ用のコードである場合もあります。

この時点で、メモリ構造を見る価値があります。少なくともプログラムセクションとデータセクションが存在する可能性があります。バイナリファイルの場合(インテルの16進数やモトローラのレコードとは異なります)、特定のデータチャンクがメモリ内のどこに配置されているかについてはほとんどわかりません。16進エディターには、いくつかのパターンが表示される場合があります。16進数またはsレコード形式である場合は、目的のプロセッサのメモリ構造に関する詳細情報がある可能性があります。一部のプロセッサはプログラムメモリロケーション0でリセットし、一部は最高のメモリロケーションでリセットします。プログラムには、別のメモリ位置にEEPROM初期値が含まれている場合があります。(銀行で使用されるような)安全なプロセッサ向けである場合、奇妙なメモリの場所のセキュリティキーさえ持っているかもしれません。

プログラムされた言語に応じて、追加の手がかりが得られる場合があります。Cまたは同様の手続き言語でプログラムされた場合、関数はほとんどの場合、特定のレジスタをスタックに保存する一連の命令(プッシュのロット)で始まり、その後、大量のポップを返す直前にスタックから元の値を返します。パターン認識を行うことができれば、これらのシーケンスの多くを見つけることができ、プッシュ/ポップ命令、リターンなどの可能性が最も高い命令を判断できる可能性があり、選択を少し絞り込むことができます。

割り込みを備えた組み込みデバイスの場合、割り込みベクターテーブルがあります。これは、おそらく便利な場所(たとえば、0x ??? 0のアドレス)にある大きなブロック内のさまざまなメモリ位置へのジャンプの束のように見えます。 。ジャンプテーブルは他の場所でも使用されますが、ジャンプ先のアドレスを除いて同一に見える一連の命令を見つけることができる場合、ジャンプ命令がどのように見えるかを推測できる可能性があります。あなたの選択はダウンします。

その時点で、最も一般的なプロセッサアーキテクチャから始めて、何か相関があるかどうかを確認します。x86、arm、mips、8051、avr、pic、powerpc、Z80、68k、6502などなど。少なくとも英語圏では、一般的なプロセッサと命令セットのリストが有用であることがわかります。

これに役立つ自動化ツールはありませんが、MAMEは非常に多くのプロセッサアーキテクチャをエミュレートします。1つの可能な方法は、多くのプロセッサでコードを実行し、何に応じてクリックするかを確認するレジスタを監視することですあなたはデザインについて知っています。


「ヨーロッパでも、他のプロセッサよりも一般的なプロセッサがいくつかあります。」ヨーロッパに住んでいて、これは私には決して起こりませんでした。例を挙げていただけますか?
-stevenvh

@stevenvh Acorn社とSinclair社のおかげで、6502およびZ80ベースの組み込みシステムは非常に人気がありました。そしてもちろん、ARMプロセッサはAcorn Computersで始まりました。
アダムデイビス

5

アイデア:ソースコードの年齢、つまり、作成された時期/年を知っていますか?

十分に古い場合は、どのプロセッサ向けに書かれているのかを知る手がかりになるかもしれません。作成された年/年を取得し、その期間に人気のあるプロセッサを特定し、それらのhexファイルをロード/実行してみてください。

考え直してみると、過去20年間にプロセッサーが大量に普及していることを考えると、これはニードル・イン・ザ・ヘイスタック技術であり、あまり実りのないものかもしれません。


4

何ヶ月も前、それほど多くの異なるプロセッサコアが存在していなかったとき、周波数分析を通じてZ80コードを数回特定しました。Z80 CDのマシンコードはcall subroutineC9ありreturn from subroutine(私は決して忘れません)、これらは最も頻繁に発生するコードです。ただし、これには、マシンコードレベルで設定された命令に精通している必要があります。手作業での組み立ての経験があると助かります(それはたくさんありましたが、オフセットを計算するために16進数で逆算することもできます)。


3

ファイルが12ビットまたは14ビットPIC用である場合、すべてのバイトペアは12ビットまたは14ビットワードになり、通常はLSBが最初に格納され、最上位の2つまたは4つのビットがクリアされます。


1

CやPascalのような言語からコンパイルされた場合、特定のバイナリシーケンスを探すことができます。たとえば、Cでは、ほとんどすべての関数は、スタックポインターを「フレーム」または「リンク」ポインターに保存するもので始まります。特定のプロセッサでは、通常、これを行う方法は2つだけです。したがって、これらのシーケンスのXのバイナリを検索することにより、「このプロセッサXのコード」と答えることができます。

とは言うものの、ヒストグラムを使用するだけで、8088、6502、および68000バイナリを区別できる運がありました。特定のプロセッサには特定の正当な命令オペコードがあり、これらは平均よりもわずかに頻繁に使用される傾向があります。十分な大きさのバイナリチャンクを使用すると、特定の傾向を確認できます。ただし、これは、特定のバイナリ内のすべてのオペランドが特定のプロセッサタイプと相関しない傾向があるという事実により困難になり、これは本質的にヒストグラムデータにノイズを発生させるだけです。また、同じプロセッサ用の2つの異なるプログラムでさえ、著しく異なるヒストグラムを持つ場合があります。それでも、それはあなたに出発点を与えることができます。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.