exe または dll 内の文字列を非表示にする方法は?
-
06-09-2019 - |
質問
バイナリからハードコードされた文字列を抽出できることを発見しました。
たとえば、次のプロパティ ビュー プロセスエクスプローラー 3 文字以上の文字列をすべて表示します。
これは、単純にテストするために作成した単純な実行可能ファイルのコードです。
#ifndef _WIN32_WINNT
#define _WIN32_WINNT 0x0501
#endif
#include <stdio.h>
#include <tchar.h>
#include <Windows.h>
int _tmain(int argc, _TCHAR* argv[])
{
_TCHAR* hiddenString1 =_T("4537774B-CC80-4eda-B3E4-7A9EE77991F5");
_TCHAR* hiddenString2 =_T("hidden_password_or_whatever");
for (int i= 0; i<argc; i++) {
if (0 == _tcscmp(argv[i],hiddenString1)) {
_tprintf (_T("The guid argument is correct.\n")); }
else if (0 == _tcscmp(argv[i],hiddenString2)) {
_tprintf (_T("Do something here.\n")); }
}
_tprintf (_T("This is a visible string.\n"));
//Keep Running
Sleep(60000);
return 0;
}
文字列は、対応する実行可能ファイルから明らかに抽出できます。
文字列を見つけるのが少し簡単すぎると思います。
私の質問は次のとおりです。
- 方法 単に 隠れる 隠し文字列1 または 隠し文字列2 実行可能ファイルで?
- 不明瞭な隠された入力を使用するよりも、「チートコード」を使用するより安全な方法はありますか?
解決
防御プログラミングのより広い世界へようこそ。
いくつかのオプションがありますが、それらはすべて何らかの形式の難読化に依存していると思います。完璧ではありませんが、少なくとも何かはあります。
直接の文字列値の代わりに、テキストを他のバイナリ形式 (16 進数?) で保存できます。
アプリに保存されている文字列を暗号化し、実行時に復号化できます。
これらをコード内のさまざまなポイントに分割し、後で再構成できます。
またはそれらの組み合わせ。
一部の攻撃は実際のバイナリを調べる以上のことを行うことを覚えておいてください。場合によっては、プログラムの実行中にそのメモリ アドレス空間を調査することもあります。MSは、と呼ばれるものを考え出しました .Net 2.0のSecureString. 。目的は、アプリの実行中に文字列を暗号化したままにすることです。
4 番目のアイデアは、文字列をアプリ自体に保存せず、制御するサーバーに送信される検証コードに依存することです。サーバー上で、それが正規の「チートコード」であるかどうかを確認できます。
他のヒント
の実行中にのあいまいのデータには多くの方法があります。他の人はここで良い解決策を掲載している - 他よりいくつか強いです。私はそのリストに追加されることはありません。
ただ、注意してください:それはすべてのいたちごっこだ:それは誰もがあなたの「秘密」を見つけるんだろうというの保証のへの不可能のです。
。どんなに多くの暗号化や他のトリックあなたが使用しています。あなたがそれに入れどのくらいの労力やお金に関係なく。 "NASA / MIT / CIA / NSA" タイプは、それを隠しに関与しているどのように多くどんなにます。
それはすべて、単純な物理学にダウンしています:
それは実行からあなたの秘密を引き出して、それを「再表示」にするのいずれかののユーザーのために不可能であった場合、そのコンピュータはどちらかそれを再表示することができないであろう、そしてあなたのプログラムを使用することはできませんそれ。十分なインセンティブを持つ任意の適度に熟練した開発者が秘密を再表示する方法を見つけるでしょう。
ユーザーにあなたの実行可能ファイルを渡してきた瞬間を、彼らは秘密を知るために必要なすべてを持っています。
あなたが望むことができる最高のは、あなたが面倒な価値はないになる秘密を知っているから得ることができる任意のメリットという秘密を明らかにのそれの懸命にすることです。
それは公共のであるために、それは単に「-素敵ではない」だ、またはそれの結果がなれば国民は単に「不便」であるかどうだから、それはデータをあいまいにしようとするOKです。しかし、たとえ、プライベートキー、または他のいくつかの重要な秘密「マスター・クライアントのデータベースへのパスワードを、」あなたのプログラムの中に隠れてないと思います。あなただけではないことができます。
あなたのプログラムが何らかの形で必要になりますが、(秘密鍵のような)公開情報となってはならないことを真に批判的に秘密情報を持っている場合は、、あなたは適切な認証を適用し、あなたのコントロール下で、リモートサーバへのプログラムの話を持っている必要がありますし、承認コントロール秘密にしておくと、それを使用し、そのサーバーを持っている(があること、唯一の承認の人やコンピュータがサーバーのに要求を行うことが可能であることを確認してください)。
最も簡単な方法は、XORのような些細なものでそれらを暗号化したり腐敗-13、およびそれらを使用しているとき、その場でそれらを解読することです。それは、それらのカジュアルな視聴が解消されますが、それは逆転で多くの経験を持つ人を停止することはありません。
Chris が言及したこれらの方法に加えて、ハッシュ アルゴリズムを使用することもできます。正しい ID が指定されたかどうかを確認したいだけの場合は、実際には ID 全体をプログラムに保存する必要はありません。
- 比較する文字列/パスワード/ID のハッシュ (MD5、SHA など) を作成し、それに「salt」値を追加します。これをプログラムに保存します
- プログラムの実行時に、入力文字列/パスワード/ID に対して同じアルゴリズムを実行し、2 つのハッシュを比較して一致するかどうかを確認します。
この方法では、実際のテキストがプログラムに保存されることはなく、ハッシュ アルゴリズムは一方向のみであるため、プログラムをリバース エンジニアリングして元のテキストが何であったかを知ることができません。
あなたのアプリが要求を行っている場合は、私はあまりにも非表示にしたいhttp要求のためのURLがあります。
は、これを隠しても意味がありません。シオマネキ、HTTPアナライザ、または他の自由で容易に利用可能な方法の数十のようなアプリを実行すると、アプリケーションが作成されたすべてのトラフィックを表示します。
すべてのあなたの秘密のコードは、GUIDがあるか、単なる一例ということだったのでしょうか?
おそらく、バイナリのGUIDとして、あなたの秘密を格納します:
const GUID SecretGuid =
{ 0x4537774B, 0xCC80, 0x4eda, { 0x7A, 0x9E, 0xE7, 0x79, 0x91, 0xF5 } };
次に、あなたの供給GUIDは、文字列からバイナリ形式に変換して、2つのバイナリGUIDを比較します。
特定の文字列がある場合、あなたはそれを暗号化し、実行時に復号化、人々が見ることができるようにしたくない。
あなたは、文字列から構築されたのではなく、その後、バイトからそれを構築し、人々はあなたのGUIDを表示したくない場合:
const GUID SecretGuid =
{ 0x4537774B, 0xCC80, 0x4eda, { 0x7A, 0x9E, 0xE7, 0x79, 0x91, 0xF5 } };
あなたができる最善のは、あなたに文字列を非表示にするパスワードやその他の文字列をコーディングすることです。たとえばます:
std::string s1 = "Hello"; // This will show up in exe in hex editor
char* s2 = "World"; // this will show up in exe in hex editor
char s3[] = {'G', 'O', 'D'}; // this will not show up in exe in hex editor.
この目的のために私が使用する方法は次のとおりです。まず、私が使用するのは、 文字列 ツールによる シスインターナル EXE または DLL 内の文字列を表示します。次に、私は 次の小さなツール (見る 記事) これらの文字列を算術式として保存された文字のスクランブル配列に置き換えます。例えば:文字列の代わりに:"これはテストです"次のコードを配置します。(これは自動的に生成されます) このツール)
WCHAR T1[28];
T1[22] = 69;
T1[15] = 121 - 17;
T1[9] = L':' + -26;
T1[12] = L't' - 1;
T1[6] = 116 - 1;
T1[17] = 117 - 12;
T1[3] = 116 - 1;
T1[14] = L'' - 3;
T1[13] = L'w' - 3;
T1[23] = 69;
T1[26] = L'Y' + 3;
T1[19] = 111 + 0;
T1[21] = L'k' - 34;
T1[27] = L'\\' - 8;
T1[20] = L'B' + 32;
T1[4] = 42 + -10;
T1[25] = L'm' - 17;
T1[16] = L'H' + 18;
T1[18] = L'A' + 56;
T1[24] = 68;
T1[1] = 105 - 1;
T1[11] = L'k' - 6;
T1[10] = 66 + 50;
T1[2] = 105;
T1[0] = 117 - 1;
T1[5] = L'k' - 2;
T1[8] = 89 + 8;
T1[7] = 32;
この問題には多くの解決策があり、(私を含めて) どれも完璧ではありませんが、機密文字列をスクランブルしたり、偽装したり、隠したりする方法はあります。もちろん、実行時にそれらを暗号化して復号化することもできますが (この記事を参照)、これらの文字列が実行可能ファイルのビットやバイトの中に消えるようにすることがより重要であり、それが機能することが私は重要です。私のツールを実行すると、実行可能ファイルに「これはテストです」という文字が表示されなくなります。