10

アセンブラー、C++、および PE ファイルのしくみについてさらに学習する方法として、exe パッカー/プロテクターをコーディングしようとしています。現在、EP を含むセクションがキーと XOR され、復号化コードを含む新しいセクションが作成されるように動作しています。復号化後に元の EP に JMP しようとする場合を除いて、すべてうまくいきます。

基本的に私はこれを行います:

DWORD originalEntryPoint = optionalHeader->AddressOfEntryPoint;
// -- snip -- //
    crypted.put(0xE9);
 crypted.write((char*)&orginalEntryPoint, sizeof(DWORD)); 

しかし、エントリ ポイントにジャンプする代わりに、ollydbg は、このコードが次のように逆アセンブルすることを示しています。

00404030   .-E9 00100000    JMP 00405035 ; should be 00401000 =[

ollyで手動で変更しようとすると、新しいオペコードが次のように表示されます

00404030    -E9 CBCFFFFF    JMP crypted.00401000

0xCBCFFFFF はどこから来たのですか? C++ 側からどのように生成しますか?

4

3 に答える 3

19

あなたが使用することができます:

push DESTINATION_VA
ret

また

mov eax,DESTINATION_VA
jmp eax

相対 E9 jmp エンコーディングは次のように使用されます。

CURRENT_RVA: jmp (DESTINATION_RVA - CURRENT_RVA - 5 [sizeof(E9 xx xx xx xx)])

VA アドレスがあり、イメージが再配置されていない場合は、push + ret が最適なソリューションです。

于 2010-01-12T14:28:30.467 に答える
7

これは相対ジャンプのオペコードだと思いますE9。そのオペランドは、ジャンプする相対距離を次の命令の開始点からプラスまたはマイナスで指定します。

オペランドで絶対アドレスを指定する場合は、別のオペコードが必要になります。

于 2009-10-09T21:47:54.687 に答える
6

絶対間接ジャンプのオペコードは FF + 4byte アドレスです。これは、データに格納されたアドレスのジャンプテーブルに最もよく使用されます。

絶対アドレスは、予想されるアドレスにロードされない場合に再配置が必要になるため、一般的には相対アドレスが優先されます。相対ジャンプのコードも 2 バイト小さくなっています。

インテルの最適化マニュアルでは、cpu は call と ret がペアで使用されることを期待していると述べているため、回答 2 で提案されている呼び出しのない ret は、「パフォーマンス ペナルティ」と呼ばれるものを引き起こします。

また、コンパイラが想定したのと同じアドレスにコードがロードされなかった場合、ret によってプログラムがクラッシュする可能性があります。相対アドレスを計算する方が安全です。

于 2011-04-10T02:39:31.557 に答える