4

私は現在、C++ でポリモーフィズム エンジンを記述して、私が持っているきちんとしたアンチ ハッキング ステイアライブ チェックのアイデアをいじろうとしています。しかし、ポリモーフィズム エンジンを記述することはかなり困難であることがわかっています。どのようにそれを行うべきかを確立することさえできていません。アイデアは、実行可能コードをユーザー (つまり、私が保護しているアプリケーション) にストリーミングし、メモリ イメージでいくつかのチェックサムを実行してサーバーに返すコードをときどき送信することです。問題は、誰かが単純にハイジャックしたり、プログラムによって生存チェックをクラックしたりしたくないということです。代わりに、それぞれが単純なコードのスタブから動作し、ポリモーフィズム エンジンを介して実行されるサーバー上で生成されます。各Stay-Aliveチェックは、データのチェックサムと、Stay-Aliveチェック内に忍び込んだランダムなアルゴリズムに依存する値を返します。

私が取り組まなければならないもの:

*実行可能なイメージの PDB ファイル。*アセンブラーと逆アセンブラー エンジンのコードなどを再配置できるようにするそれらの間のインターフェイスを実装しました。

これが私がやろうと思っていたステップと、それらをどのように行うかです。Windows PE 実行可能ファイルで x86 命令セットを使用しています

私が取る予定のステップ(私の問題はステップ2にあります):

  1. 手順を展開

    • mov のような単純な命令を見つけたり、push して、より多くの命令で同じ目的を達成するいくつかの命令に置き換えます。このステップでは、大量のジャンク コードも追加します。
    • データベース内の一連の変換テーブルを使用するだけでこれを行う予定です。これはそれほど難しいことではありません。
  2. シャッフリング

    • これは私が最も苦労している部分です。コードを関数に分離する必要があります。次に、一連の命令依存関係ツリーを確立する必要があります。次に、依存関係に基づいてそれらを再配置する必要があります。pdb ファイルを解析することで関数を見つけることができますが、命令の依存関係ツリーを作成することは、私が完全に迷っているトリッキーな部分です。
  3. 圧縮命令

    • 命令を圧縮し、プロセス内の一連の一般的でない不明瞭な命令を実装します。そして、最初のステップと同様に、コード署名のデータベースを使用してこれを行います。

もう一度明確にするために、ステップ 2 を実行するのに助けが必要ですが、どのように始めればよいかわかりません。いくつかの図を作成してみましたが、従うのが非常にわかりにくくなっています。

OH: 明らかに、保護されたコードはあまり最適ではありませんが、これは学校で試してみたかった単なるセキュリティ プロジェクトです。

4

3 に答える 3

2

「命令依存関係ツリー」の目的は、データフロー分析だと思います。これは、コード要素 (プログラミング言語の基本操作) ごとに、他のコード要素からどのような情報が渡されるかを決定する従来のコンパイラ テクノロジです。完了すると、ノードがコード要素 (この場合は個々の命令) であり、それらの間の有向アークが、後の要素が生成された結果に対して実行できるように、どのような情報が流れなければならないかを示すグラフに相当するものになります。グラフ内の「前の」要素。

私のウェブサイトで、このようなフロー分析の例をいくつか見ることができます(プログラム分析を行うツールに焦点を当てています。このツールはおそらくバイナリ分析には適していませんが、例は役立つはずです)。

コンパイラの書籍には、データ フロー分析に関する膨大な文献があります。コンパイラの教科書を参照してください。

処理する必要がある問題がいくつかあります。

  • コードを解析してコード要素を抽出します。すでにすべての指示にアクセスできるようですね。

  • 各コード要素が必要とするオペランドと生成される値を決定します。これは、「ADD register,register」の場合は非常に単純ですが、驚くほど大きくクレイジーな命令セットを備えた製品 x86 CPU では、これが困難な場合があります。CPU が実行する可能性のある命令ごとにこれを収集する必要があります。つまり、ほとんどすべての命令を意味します。それにもかかわらず、これはただの汗であり、取扱説明書を読むのに多くの時間を費やしました.

  • ループ。値は命令から他の命令を経由して同じ命令に戻ることができるため、データフローはサイクル (複雑なループの場合は多数のサイクル) を形成できます。データフローの文献では、グラフ内のデータフロー アークの計算に関してこれを処理する方法が説明されています。これらがあなたの保護スキームにとって何を意味するのか、私にはわかりません。

  • 保守的な分析: 実際には任意のアルゴリズム (チューリング マシンなど) を分析しているため、理想的なデータ フローを得ることができません。ポインターはこの問題をかなり深刻に悪化させ、マシンコードはポインターでいっぱいです。そのため、「x が y をフィードする」かどうかを判断できない場合に、データ フロー分析エンジンがよく行うことは、単に「x が y をフィードする可能性がある」と想定することです。データフロー グラフは、概念的に「x (must) feed y」から実用的な「x (may) feed y」タイプのアークに変わります。実際、このため、文献には「しなければならない」および「かもしれない」アルゴリズムがたくさんあります。繰り返しになりますが、[保守的な] フロー分析を行うための多くの方法が文献に記載されています (ほとんどの場合、さまざまな程度の保守主義があります。実際、最も保守的なデータ フロー分析では、単に「すべての x がすべての y をフィードする」と書かれています!)。

バイナリ コード分析 (NSA など) に関心を持っている人はたくさんいます。彼らは、ポインター分析を備えたマシン命令のデータ フロー分析を行っています。このプレゼンテーションは興味深いかもしれません: http://research.cs.wisc.edu/wisa/presentations/2002/0114/gogul/gogul.1.14.02.pdf

于 2012-05-25T13:49:07.587 に答える
1

pdb ファイルを解析することで関数を見つけることができますが、命令の依存関係ツリーを作成することは、私が完全に迷っているトリッキーな部分です。

不可能。停止問題へようこそ。

于 2012-05-25T10:04:47.330 に答える
1

あなたがしようとしていることが、プロセスの改ざんを防ぐのに役立つかどうかはわかりません。誰かがデバッガー (プロセス) をアタッチし、送信/受信機能で中断した場合、メモリのチェックサムはそのまま残ります。このデバッガーまたは挿入されたコードは、プロセスで使用されているページを尋ねると、ユーザーを操作できます (挿入されたコードが存在するページがわからないため、挿入されたコードは表示されません)。

あなたの実際の質問に:

実行可能ファイルを再リンクしてシャッフルを実装できませんでした。リンカーは、.o ファイルがエクスポートおよびインポートするすべてのシンボルを追跡します。すべての .o ファイルが読み取られると、関数の実際のアドレスがインポートされたプレースホルダーに配置されます。すべての関数を個別の cpp ファイルに入れて .o ファイルにコンパイルする場合。リンカー呼び出しで .o ファイルの順序を変更すると、すべての関数が別のアドレスに配置され、実行可能ファイルは正常に実行されます。

これを Windows の gcc でテストしましたが、動作します。すべての関数をリンクするときに .o ファイルの順序を変更すると、別のアドレスに配置されます。

于 2012-05-20T06:09:35.493 に答える