2011-03-01 12 views
0

私はメモリ割り当てに関連するイベントをフックして、ソースコードに余分な実装を必要としない外部デバッガを作成しようとしています。 これを行うには、私は論文の呼び出しをフックする必要があります、いくつかの人はこれを行う方法を知っていますか? 何かのように、http://www.itworld.com/UIR000929interposersしかし、それはあまりにもウィンドウ上で実行されます。 C/C++の実装やアイデアも歓迎されています。答えをAllocMem()、FreeMem()などの呼び出しをフックする方法は?

TKS


TKSは、私は最善の選択肢を見つけるために、私のテストを行います。


回答をチェックアウトします。私は自分自身でも調査して研究しています。私が何か新しいことを発見したら、私はここに投稿します。

答えて

0

新しい情報:デバッガを作成するためのメモリ割り当てについて勉強しています。しかし、今私は本当にその点を発見した。私がDelphiに取り組んでいるとき、私はFastMMユニットがどのように動作するかを調べていました...

私自身の外部デバッガを作成するための最初のアイデアは何でしたか?アプリケーションからウィンドウへのメモリ割り当て要求をフックする。

しかし、私はそれがウィンドウにこれを要求するすべてのクラスのインスタンス化ではないことに気がつきました。今私はなぜあなたの返事のためにABounchezを理解したのですか?なぜなら、別のメモリ要求が行われたときにシステムに新しいメモリ空間を要求しないため、プールメモリを管理するため、RAMのメモリスペースを探すときに、FastMMは必要なときにメモリプールを作成するからです。それをより速く、より良くする。

私はVirtualAlloc()をフックしても、私は可能だったメモリの変更についての情報は完成しません。

しかし、これまでのところ、これらの情報は多くのドアを閉じて、他の多くのものを開いてしまいます。 確かに私はデバッグを作成していますが、最初はそうではありませんでしたが、いくつかの骨董き機能もあります。

Tksがこれに寄与してくれました。

0

これはどういう意味ですか?

Macro to replace C++ operator new

それは、これに最終的につながる:

http://blogs.msdn.com/b/calvin_hsia/archive/2009/01/19/9341632.aspx

それは、新しいオペレータまたはのmallocをキャプチャするための一般的な手法です。私たちは、私のポインタがCで間違っていた箇所を追いかけようとしました。私はもはやそれを使用しません。

+0

私はオプションを読んでいましたが、それは私にそれを外部的に接続するオプションを与えていないことに気づいた。私が間違っている? –

+0

私はあなたが外部に引っ掛けることによって何を意味するか分かりません。実行中の別のプログラムを調べることを意味しますか?おそらく、WOW64のようなエミュレータのようなデバッグツールを実行する方が良いでしょう(例:[link] http://msdn.microsoft.com/en-us/library/aa384249%28v=VS.85%29.aspx)。 Windowsのデバッグツールなどを使用します。 –

2

MicrosoftのDetoursにチェックを入れたい場合があります。 Windowsプログラミングに関するJeffrey Richterの書籍にも同様のライブラリが含まれています。

+0

DetoursはAFAIKという外部API呼び出しでのみ動作します。 1つの実行可能ファイルから外部ライブラリなどへ。そして、ほとんどのコンパイラはWindows APIを使ってメモリ割り当てを行うのではなく、VirtualAlloc()でいくつかの巨大なメモリブロックを取得し、それを小さな断片に分割してプログラムに戻します。 Cコンパイラの中には、CRTライブラリを使用するものがあります。しかし、例えば。 Delphiはメモリ割り当てに外部ライブラリを使用せず、VirtualAlloc()だけを呼び出します。それはタスクを実装するには高すぎるレベルかもしれない... –

2

すべてのコンパイラには、独自のメモリ管理システムがあります。正確に言えば、同じコンパイラで複数のMMを動作させることができます。アプリケーションの目的に応じて、使用するMMを選択できます。たとえば、サーバーではマルチスレッドスケーリングMMに興味があるかもしれませんが、シンプルなUIクライアントアプリケーションでは、MMを高速でメモリを消費しないようにしたいと考えています。

Windowsで提供される内部ヒープ管理は、すべてのコンパイラ/フレームワークが独自のメモリマネージャを実装するほど遅かった(少なくともXPまで)。

2006年以来、Delphiの「純粋なBorland」バージョンがあり、FastMM4という名前のオープンソースMMがメインの「Delphi」IDEに組み込まれました。

Delphiでは、メモリマネージャを簡単に変更できます。関数のレコードを作成した後、SetMemoryManager()を呼び出して、現在のMMを新しいものに置き換えます。例えば

、ここではデルファイのためのour Open Source scaling Memory Managerをインストールされている方法です。

{$if CompilerVersion >= 17} 
    {$define USEMEMMANAGEREX} 
{$ifend} 

var 
{$ifdef USEMEMMANAGEREX} 
    OldMM: TMemoryManagerEx; 
{$else} 
    OldMM: TMemoryManager; 
{$endif} 

const 
{$ifdef USEMEMMANAGEREX} 
    ScaleMM_Ex: TMemoryManagerEx = (
    GetMem: Scale_GetMem; 
    FreeMem: Scale_FreeMem; 
    ReallocMem: Scale_ReallocMem; 
    AllocMem: Scale_AllocMem; 
    RegisterExpectedMemoryLeak: Scale_RegisterMemoryLeak; 
    UnregisterExpectedMemoryLeak: Scale_UnregisterMemoryLeak); 
{$else} 
    ScaleMM_Ex: TMemoryManager = (
    GetMem: Scale_GetMem; 
    FreeMem: Scale_FreeMem; 
    ReallocMem: Scale_ReallocMem); 
{$endif} 

procedure ScaleMMInstall; 
begin 
    // Hook memory Manager 
    GetMemoryManager(OldMM); 
    if @OldMM <> @ScaleMM_Ex then 
    SetMemoryManager(ScaleMM_Ex); 

    // init main thread manager 
    GlobalManager.Init; 

このコードは、カスタムScale_GetMem/Scale_FreeMem/Scale_ReallocMem/Scale_AllocMem機能を経由して、私たち自身によるデルファイMMに置き換えられます。あなただけのOldMM変数を使用することにより、古いMMへのラッパーを作ることができます:あなたは正しいものを選択することがありますので、

function Scale_GetMem(aSize: Integer): Pointer; 
begin 
    // do some debugging here 
    result := OldMM.GetMem(aSize); 
end; 

MMのレコード構造は、時間に変更 - 私たちは、これがUSEMEMMANAGEREX条件を使用して行います。

+0

私はポスターが外部的にフックしたいと思う。 –

+1

@David外部からフックするには、System.pas _GetMem関数と_FreeMem関数をフックする必要があります。それを行う方法を見つけるのははるかに難しいでしょう!それを実装する妥当な唯一の方法は、元の_GetMem/_FreeMem asmバイナリパターン(使用されているRTLのバージョンに依存)を見つけ、EXEで検索してから、Win32のフックメカニズムでパッチを適用することです。 Delphiでは、ほとんどのCコンパイラのように、メモリを扱う外部ライブラリはありません。これは外部のフックをはるかに困難にします... –

+0

A.Bouchezさんが私の投稿に言ったように、外部プログラムで_GetMemと_FreeMemをフックする必要があると言ったように、問題は解決しません。どんな方法でも、あなたの説明は他人を確かに助けます –

関連する問題