CreateProcessを使用してEXEを起動できます。 EXEの内容をメモリバッファに入れて、ファイルに書き込まずにCreateProcess(または同等のもの)を実行したい。それを行う方法はありますか?
裏話:私たちはゲームを作ります。プレーンなEXEをディストリビューターに送信し、お気に入りのDRMを使用してそれをラップしてユーザーに販売します。ユーザーがクラッシュを見つける場合があります。ほとんどのクラッシュは修正に5分かかりますが、パッチはディストリビュータを通過する必要があり、数日から数週間かかる場合があります。パッチを適用したEXEは、ディストリビューターのDRMがないため、プレーヤーに送信することはできません。暗号化されたデータファイル内に実際のゲームEXEを配布して、ラップされるもの(外部EXE)が実際のEXEを復号化して起動することを考えています。このようにして、DRMを無効にすることなく修正を安全に配布できました。
実はとても簡単です。同様のテクニックは、私が3年前に読んだ論文に記載されています。
Windowsでは、CREATE_SUSPENDEDフラグを指定して CreateProcess 関数を呼び出すことができます。これにより、APIは-までプロセスを一時停止し続けるように指示されます。 ResumeThread 関数が呼び出されます。
これにより、中断されたスレッドのコンテキストを GetThreadContext 関数を使用して取得する時間が与えられ、EBXレジスタは PBE(Process Enviroment Block) 構造へのポインタを保持します。ベースアドレスを決定します。
PBE構造のレイアウトから、ImageBaseAddressが8バイト目に格納されていることがわかります。したがって、[EBX + 8]は、中断されているプロセスの実際のベースアドレスを示します。
ここで、メモリ内EXEが必要であり、メモリとメモリ内EXEの配置が異なる場合は、適切な配置を行います。
中断されたプロセスとメモリ内のexeのベースアドレスが一致する場合、およびメモリ内のexeのimageSizeが中断されたプロセス以下の場合、 ' WriteProcessMemory を使用してメモリ内に書き込むことができます。中断されたプロセスのメモリ空間にexeを実行します。
しかし、前述の条件が満たされない場合は、もう少し魔法が必要です。まず、 ZwUnmapViewOfSection を使用して元のイメージのマップを解除し、次に VirtualAllocEx を使用して中断されたプロセスのメモリスペース内に十分なメモリを割り当てる必要があります。次に、中断されたプロセスのメモリスペースに WriteProcessMemory 関数を使用して、インメモリexeを書き込む必要があります。
次に、インメモリexeのBaseAddressを、中断されたプロセスのPEB-> ImageBaseAddressにパッチします。
スレッドコンテキストのEAXレジスタはEntryPointアドレスを保持します。これは、メモリ内のexeのEntryPointアドレスで書き換える必要があります。次に、 SetThreadContext 関数を使用して、変更されたスレッドコンテキストを保存する必要があります。
出来上がり!中断されたプロセスで ResumeThread 関数を呼び出して実行する準備ができました!
ゲームをDLLとしてコンパイルし、DLLを暗号化されたデータファイルに入れます。ADLLディスクに書き込まずにメモリから。このチュートリアル(最後にサンプルコードを含む)を参照してください。 Loading a DLL From Memory
やりたいことにはNtCreateProcessが必要ですが、文書化されていないため、脆弱です。 この本 は明らかにその使用法をカバーしています。
おそらく、パッチシステムを構築できますか?例えば。起動時に、プログラムは同じディレクトリでパッチDLL=をチェックし、存在する場合はそれをロードします。
なぜ新しいプロセスを作成する必要があるのですか?解凍/復号化を行うプロセスのコンテキストで実行できると思いました。
あなたが望むことは「パッカー」と呼ばれるもので達成することができます。実際にメモリから実行ファイルを起動することは可能かもしれませんが、それはパッカーよりもはるかに難しいです;)
最もよく知られているパッカーの1つはUPX(google it)です。それを解読するためのツールがありますが、それは少なくともあなたがフロムで働くための出発点を与えるはずです。また、UPXがオープンソースであることも確かです。