5

ここにこのプログラムがあるとしましょう

class Message{

public static SUPER_SECRET_STRING = "bar";

    public static void Main(){
        string SECRET = "foo";
        Console.Write(sha(SUPER_SECRET_STRING) + "" + sha(SECRET));
    }

}

さて、このプログラムをビルドした後、16 進エディタまたはその他のユーティリティを使用して、コンパイルされたバイナリ ファイルから値「foo」と「bar」を抽出する方法はありますか?

また、メモリ エディタが許可されていないと仮定しましょう。

これは、C++ などのすべてのコンパイル済み言語に適用できますか? Java や C# などの別の環境で実行されるものはどうですか?

4

2 に答える 2

7

Mene からの答えは正しいですが、(言語に関係なく) コンパイルされたバイナリから文字列を抽出することがいかに簡単であるかを知らせるために、2 セントを投入したいと思いました。Linux を使用している場合は、コマンドstrings <compiled binary>を実行するだけで抽出された文字列が得られます。これをやってのけるために、何らかのリバース エンジニアである必要はありません。UbuntuマシンでEclipseバイナリに対して実行し、(切り捨てられた)出力を確認しました:

> strings eclipse
ATSH
0[A\
8.uCH
The %s executable launcher was unable to locate its 
companion shared library.
There was a problem loading the shared library and 
finding the entry point.
setInitialArgs
-vmargs
-name
--launcher.library
--launcher.suppressErrors
--launcher.ini
eclipse

「%s 実行可能ランチャーは、そのコンパニオン共有ライブラリーを見つけることができませんでした。共有ライブラリーのロードとエントリー・ポイントの検索で問題が発生しました。」という文字列に注意してください。出力に表示されます。この文字列は、間違いなくプログラムにハード コードされています。

文字列 (およびその他のデータ) がプログラムにハードコードされている場合、ほとんどのコンパイラはそれらをバイナリの特別なセクションに配置し、必要に応じてプログラムがアクセスできるように直接メモリにマップできるようにします。バイナリを 16 進エディタで開くと、この文字列を簡単に見つけることができます。

于 2013-06-13T00:01:54.730 に答える
6

はい、逆コンパイラを使用して、これらの種類の定数、特に文字列を簡単に抽出できます (より大きなメモリ チャンクが必要になるため)。これはマシンコード バイナリでも機能し、Java や C# などの VM 言語ではさらに簡単です。

そこに何かを秘密にしておく必要がある場合は、かなりの時間を費やす必要があります. たとえば、文字列を単純に暗号化するだけでセキュリティのレイヤーが追加されますが、自分が何をしているのかを知っている人にとって、これは大きな障壁にはなりません。たとえば、一般的ではないエントロピーを持つ場所のファイルをスキャンすると、暗号化に使用されたキーが明らかになる可能性があります。バイナリで使用される低レベルのコマンドを変更することによって秘密をエンコードするシステムさえあります。これらのツールは、コマンドの特定の組み合わせを他の同等のコマンドに置き換えます。しかし、これらのシステムでさえ、回避するのはそれほど難しくありません。コマンドの珍しい組み合わせによって、そのようなツールの使用が明らかになるからです。

また、バイナリで何らかの暗号化によって文字列を保護できたとしても、ある時点で、実行のために復号化されたバージョンが必要になります。したがって、文字列が使用される時点でメモリ ダンプを作成すると、シークレット値のコピーも含まれます。これは、メモリのチャンクを解放できず、文字列が不変であるため (つまり、文字列への「変更」が新しいメモリのチャンクにつながることを意味します)、Java では特に問題になります。

ご覧のとおり、問題は簡単ではありません。そしてもちろん、100% のセキュリティを提供する方法はありません (クラックされたすべてのゲームなどを考えてみてください)。

安全な方法で実装できるものは、公開鍵暗号化を使用することです。その場合、秘密鍵を隠しておく必要があります。たとえば、サーバーに物事を送信して暗号化できる場合、またはトラステッド プラットフォーム モジュールを提供するハードウェアを使用している場合、これが可能になる可能性があります。しかし、それらのことはあなたのケースでは実行できないかもしれません.

于 2013-06-12T21:02:44.333 に答える