1

実行可能ファイルの周りのさまざまな場所で使用されている文字列リテラルがあります。

次のようなことを言いましょう:

const char *formatString = "Something I don't want to make obvious: %d";

int format1(char *buf) { sprintf(buf, formatString, 1); }
int format2(char *buf) { sprintf(buf, formatString, 2); }

//...

これで、この文字列リテラルは文字通り埋め込まれているため、実行可能コード内で非常に明白になります。

mov [ptr + 4], 0x65文字通り文字列を埋め込むのではなく、たとえば、アセンブリ命令(eg)命令を生成して文字列を作成するようにコンパイラに強制することで、これを回避する方法はありますか?

どんな種類の難読化もしたくありません-実行可能ファイル内で文字列を明確にしないようにしたいだけです。(また、文字列が使用されるすべての場所でコードを変更する必要はありません。)

これは可能ですか?

4

3 に答える 3

4

暗号化された文字列を手動でコードに貼り付けることを回避するために、難読化が必要な文字列をマークするマクロと、それらを復号化する関数を作成できます。

#define OB(s) dec("START_MARK_GUID" s "\0" "END_MARK_GUID")
const char* dec(const char* s) { ... }
...
const char* s = OB("not easily readable"); // on all strings needed
const char* s = OB("either");

関数は2つのことを実行する必要があります。

  1. パラメータがSTART_MARK_GUIDで始まる場合は、元の文字列(GUIDなし)を返すだけです。これにより、たとえばデバッグ時に、難読化されていない実行可能ファイルも使用できるようになります。

  2. ENCRYPTED_MARK_GUIDで始まる場合は、最初に難読化を解除してから、新しい文字列を返します。Cでは、ここでメモリの寿命を気にする必要があります。C ++では、単にstd :: string()を返すことができます。

最後に、コンパイルされたバイナリでGUIDを検索し、それらの間のデータを暗号化する難読化プログラムを作成します。Pythonまたは同様の言語ではほんの数行です。私のプログラムはそれがなくても機能しましたが、EXEのCRCを後で修正することもお勧めします。

一意の識別子が少ないGUIDを変更して、スペースを節約できます。また、これを改善して、復号化を1回だけ行うようにすることもできます(たとえば、ENCRYPTED_MARK_GUIDを使用して文字列IDを書き込み、復号化された文字列をそのIDで辞書に保持します)。

于 2011-10-02T07:43:34.567 に答える
2

難読化はおそらくあなたの最善の策です。単純な難読化(XORなど)を使用し、文字列を必要とするコードを実行する前に、プログラムの開始時に別の変数に難読化を解除します。

于 2011-10-02T04:42:06.510 に答える
0

間もなくC++11で、ユーザー定義のリテラルを使用できるようになります。

constexpr const char*
operator"" _decrypto(const char*, size_t len)
{
  //  decrypt input string.
}

const char* formatString = "encrypted gibberish"_decrypto;

int format1(char* buf) { sprintf(buf, formatString, 1); }
int format2(char* buf) { sprintf(buf, formatString, 2); }

int
main()
{
}

gccはこれに猛烈に取り組んでおり、 IBMはすでにこれを持っていると思います。VisualStudioのステータスがわからない。これはパッチを適用したgccでコンパイルされました。

于 2011-10-02T16:15:56.663 に答える