3

アセンブリスキルが低いdllファイルを分析しようとしているので、非常に些細なことを達成できなかった場合はご容赦ください。私の問題は、アプリケーションのデバッグ中に、デバッグセッションでのみ探しているコードを見つけ、デバッガーを停止した後、アドレスが失われることです。コードの多くは読み取り可能であるため、dllは難読化されているようには見えません。スクリーンショットを見てください。私が探しているコードは、debug376セクションのアドレス07D1EBBFにあります。ところで、このdebug376セクションはどこで入手できましたか?

だから私の質問は、デバッグしていないときにこの関数を見つけるにはどうすればよいですか?ありがとう

アップデート

さて、私が言ったように、デバッガーを停止するとすぐに、コードは消えます。バイトシーケンスで見つけることさえできません(ただし、デバッグモードでは見つけることができます)。デバッガーを起動すると、コードはすぐに逆アセンブルされません。その場所にハードウェアブレークポイントを追加する必要があります。ブレークポイントに到達した場合にのみ、IDAは逆アセンブルされたコードを表示します。このスクリーンショット を見てください。興味のあるコード行が表示されます。これは、プログラムがデバッグモードで実行されていない場合は表示されません。よくわかりませんが、実行時にコードを解凍するようなもので、設計時には表示されないと思います。

とにかく、どんな助けもいただければ幸いです。ブレークポイントがヒットするまで(「db8Bh」などと表示されるまで)そのコードが非表示になっている理由と、可能であればデバッグせずにそのアドレスを見つける方法を知りたいです。ところで、これは別のモジュール(dll)からのコードでしょうか?

ありがとう

更新2

debug376は実行時に作成されるセグメントであることがわかりました。とても簡単な質問:このセグメントがどこから来たのかをどうやって知ることができますか:)

4

2 に答える 2

7

したがって、プログラムが実行されるとデバッガウィンドウにコードが表示され、実行されなくなると生の16進ダンプでまったく同じオペコードが見つからないように見えますか?

メモリースナップショットを撮るのに役立つかもしれません。関心のある命令の近くでプログラムの実行を一時停止して、命令がそこにあることを確認してから、[デバッガー]メニューから[メモリスナップショットの取得]を選択します。次に、IDAは、「ローダーセグメント」(PEローダーが事前定義されたテーブルから作成するセグメント)または現在デバッグされているプログラムに属していると思われる「すべてのセグメント」(を含む)として定義されているセグメントで見つかったデータのみをコピーするかどうかを尋ねます。解凍ルーチン、復号化ツールなどによって作成された可能性があります)。「すべてのセグメント」に移動すると、デバッグセグメントを含むメモリの内容がよく表示されます。(デバッグ中に作成または認識されたセグメント)アプリケーションをデバッグしていないときのIDA。

Shift + F7を押すか、[表示] > [サブビューを開く]から[セグメント]をクリックすると、いつでもセグメントのリストを表示できます。

分析しようとしているプログラムが、次にロードされるときにセグメントを別の場所に作成することを選択して、何が起こっているのかを理解しにくくする可能性があることに注意してください。

2番目の質問に一致するように更新します

プログラムがどこかからデータを解凍しているときは、どこかにデータをコピーする必要があります。Windowsは仮想マシンであり、許可されていない場所でコードを実行または記述しようとすると、最近は非常に厄介になります。だから、私たちが窓の下にいる限り、どんなプログラムでもどういうわけか

  1. たくさんの新しいメモリを登録するか、すでに所有しているメモリを上書きします。これは通常、mallocなどを呼び出すことによって行われます[コードは非常にポインタを多用する言語である可能性があるように見えます... VBまたはオブジェクト指向の何か]ほとんどの場合、WindowsからVirtualAllocまたはVirtualAllocExを呼び出すことになります。 kernel32.dllの呼び出し規約の詳細については、 http: //msdn.microsoft.com/en-us/library/windows/desktop/aa366887(v = vs.85).aspxを参照してください。
  2. おそらく、その上でWindows例外処理を設定し、VirtualAllocを呼び出すときにまだ実行可能でない場合は、メモリ範囲を実行可能としてマークします。これは、kernel32.dllからVirtualProtectを呼び出すことで実行されます。http://msdn.microsoft.com/en-us/library/windows/desktop/aa366898(v=vs.85).aspxおよびhttp://msdn.microsoft.com/en-us/library/windows/を参照してください。詳細については、 desktop / aa366786(v = vs.85).aspxを参照してください。

したがって、ここで、デフォルトのエントリポイント(OEP)から始めて、プログラムを介してステップを実行し、メモリ保護がPAGE_EXECUTEまたは子孫に設定されている可能性があるこれらの関数の1つに対する呼び出しを探す必要があります。その後、メモリの内容を復号化して新しい場所にコピーする、ある種のループが発生する可能性があります。プログラムへの関心に応じて、ループの後にカーソルを置き(通常はIDAの太い青い線)、右クリックすると表示されるメニューから[カーソルまで実行]をクリックするだけで、ステップオーバーすることができます。アセンブラコード。

それが失敗した場合は、kernel32.dllのVirtualAllocにハードウェアブレークポイントを配置して、returnステートメントにステップインするときに何か興味があるかどうかを確認してください。そうすれば、AllocまたはProtect呼び出しの後に実行チェーンが移動する場所に行き着きます。

于 2012-06-13T23:14:18.827 に答える
1

そのコードの相対仮想アドレスを見つける必要があります。これにより、ロードアドレスに関係なく、コードを再度見つけることができます(最近、ASLRを使用しているほとんどすべてのシステムで非常に便利です)。RVAは通常、として計算されvirtual address - base load address = RVAますが、セクションベースも考慮する必要がある場合があります。

別の方法は、IDAのリベースツールを使用して、dllを毎回同じアドレスにリベースすることです。

于 2012-06-05T06:59:20.137 に答える