バイナリからソース言語を特定しますか?
-
19-09-2019 - |
質問
私 答えた 非 Objective-C 言語での iPhone 向けの開発に関する別の質問に対して、私は、たとえば iPhone 向けに書くために C# を使用すると、Apple のレビュー担当者は間違っていると主張しました。私は主に、問題の ObjC ライブラリと C# ライブラリの間で異なる UI 要素について話していましたが、コメント投稿者が興味深い指摘をしたため、次の質問につながりました。
プログラムが書かれている言語をバイナリだけから判断することは可能ですか? そのような方法がある場合、それは何ですか?
質問の目的のために次のように仮定してみましょう。
- インタラクションの観点 (コンソールの動作、GUI の外観など) から見ると、この 2 つは同一です。
- そのパフォーマンスは言語の信頼できる指標ではありません (たとえば、Java と C を比較することはできません)。
- あなたと言語の間にはインタプリタなどはなく、生の実行可能バイナリだけが存在します。
可能な限り言語に依存しない人にはボーナスポイント。
解決
私は(私は願って、いつか)コンパイラハッカーないんだけど、私はあなたがそれとなどの使用コンパイラオプションのいくつかを、生成されたどのようなコンパイラ示唆するバイナリファイルでの証拠となる兆候を見つけることができるかもしれませんことを把握指定された最適化のレベルます。
厳密に言えば、しかし、何を求めていることは不可能です。それは誰かがペンと紙で座って、彼らが書きたかったプログラムに対応するバイナリコードを働いて、その後、バイナリエディタでその原料を入力した可能性があります。基本的に、彼らはアセンブラツールなしでアセンブリでプログラミングすることと思います。同様に、あなたはネイティブバイナリがインラインアセンブリとストレートアセンブラやCで書かれていたかどうかを確実に知ることができないことがあります。
などJVMや.NETなどの仮想マシン環境については、あなたがバイナリ実行中のバイトコードでVMを識別することができるはず、私は期待します。しかし、あなたがそのような存在しない限り、C#は、Visual Basicの対、特定のコンパイラは、その先端にあなたをオフに癖として、ソース言語が何であったか言うことができない場合があります。
他のヒント
短い答え:はい
長い答えます:
。MSVCRT.DLL、KERNEL32.dllから、NTDLL.DLL:あなたがバイナリを見れば、あなたがリンクされているライブラリの名前を見つけることができます。TextPadのでオープニングcmd.exeのは簡単進で次のようにオフセット0x270が見つかりました、USER32.dllの、などMSVCRTは、マイクロソフト「C」のランタイム・サポート関数です。 KERNEL32、NTDLL、およびUSER32.dllのはあなたのターゲットプラットフォーム、またはクロスプラットフォーム開発環境は、2つを分離どれだけに依存し、それが構築されたプラットフォーム、どちらかを教えてくれOS固有のライブラリです。
これらの手がかりをさておき、ほとんどすべてのC / C ++コンパイラはバイナリに関数の名前を挿入する必要があります。、テーブルに格納されているすべての機能(またはエントリポイント)のリストがあります。 C ++マングル "オーバーロードされたメソッドをサポートするために、引数とその型をエンコードする関数名を。関数名を難読化することが可能であるが、彼らはまだ存在することになります。関数シグネチャは、システムまたはプログラムで使用される内部呼び出しに追跡するために使用することができる引数の数とタイプを含むであろう。 0x4190のオフセットでは、<のhref =「http://msdn.microsoft.com/en-us/library/dd374053(VS.85).aspx」のrelについて多くを見つけるために検索することができる「SetThreadUILanguage」であります= "noreferrer">開発環境に。私は、オフセット0x1ED8Aでエントリポイントテーブルを見つけました。私は簡単にprintf関数、終了、およびscanfのような名前を見ることができました。 __p__fmodeとともに、__p__commode、および__initenv
x86プロセッサのための任意の実行可能ファイルは、プログラムに含まれた静的テキストを含むことになるデータセグメントを有するであろう。戻るCMD.EXEには(0x42C8オフセット)テキストである "S.o.f.t.w.a.r.e..P.o.l.i.c.i.e.s..M.i.c.r.o.s.o.f.t..W.i.n.d.o.w.s..S.y.s.t.e.m。"。それはおそらく、国際化のために、ダブルワイド文字を使用して格納されたため、通常は必要であるなどの文字列は、2倍の数の文字を取ります。エラーコードやメッセージは、ここではプライム源です。
は、オフセットB1B0でます。mkdir、rmdirを、CHDIR、MD、RD、およびCDに続いて "p.u.s.h.d" です。私は読みやすさのために印刷できない文字を残しました。これらは、CMD.EXEに、すべてのコマンド引数です。
他のプログラムのために、私は時々、プログラムがコンパイルされたパスを見つけることができました。
だから、はいは、バイナリからソース言語を決定することが可能です。
私は、あなたは可能性が期待しない、またはすべてのコンパイラがそうのObjective-CとGNU Cは、ここでは異なる必要があり、例えばprintf
に同じコードを使用するように、少なくともあなたは、コンパイラを知っているかもしれません。
あなたはこの問題が予想よりもあまり一般的であることを行っているように、すべてのバイトコード言語を除外しています。
まず、いくつかのバイナリにwhat
を実行し、出力を見てください。 CVS(およびSVN)識別子は、二値画像全体に散在しています。そして、それらのほとんどは図書館からです。
また、様々なライブラリ関数への「マップ」は、しばしばあります。それはまた、大きなヒントです。
ライブラリが実行可能ファイルにリンクされている場合、、名前とオフセットを持つバイナリファイルに含まれているマップがしばしばあります。それは、「位置独立コード」を作成するの一部です。あなたは、さまざまなオブジェクトファイルを一緒に単に「ハードリンク」することはできません。あなたは、マップを必要としますがメモリにバイナリをロードするとき、いくつかの検索を行う必要があります。
最後に、C、C ++(と私はC#のを想像する)ためのスタートアップモジュールは、ライブラリのコンパイラのdefaiultセットに固有のものです。
さて、Cは当初、ASMが変換されます。
いいえ、バイトコードは言語に依存しないです。異なるコンパイラでも同じコードソースを取り、別のバイナリを生成することができます。あなたは、バイナリ上で動作する汎用逆コンパイラが表示されていない理由です。
「コマンド文字列が」(例えば、私はちょうど私が書いたCアプリケーションの剥奪バイナリ上でそれを実行し、最初に見つかったエントリはによってリンクされたライブラリですいくつかのヒントを得るために使用することができ実行可能)。