下面这个函数可以让你知道一个函数来自那里DLL或者是不是当前可执行文件内部实现的函数,参考代码如下:
uses psapi;
function GetCodeFileName(Addr: Pointer): QStringW;
var
AModules: array of THandle;
I, ACount: Cardinal;
APriorModule: THandle;
procedure QuickSort(L, R: Integer);
var
I, J: Integer;
P, T: THandle;
begin
repeat
I := L;
J := R;
P := AModules[(L + R) shr 1];
repeat
while AModules[I] < P do
Inc(I);
while AModules[J] > P do
Dec(J);
if I <= J then
begin
if I <> J then
begin
T := AModules[I];
AModules[I] := AModules[J];
AModules[J] := T;
end;
Inc(I);
Dec(J);
end;
until I > J;
if L < J then
QuickSort(L, J);
L := I;
until I >= R;
end;
function GetModuleFileName(AModule: THandle): QStringW;
begin
SetLength(Result, MAX_PATH);
SetLength(Result, GetModuleFileNameW(AModule, PWideChar(Result), MAX_PATH));
end;
begin
Result := '';
EnumProcessModules(GetCurrentProcess, nil, 0, ACount);
SetLength(AModules, ACount);
APriorModule := 0;
if EnumProcessModules(GetCurrentProcess, @AModules[0], ACount, ACount) then
begin
QuickSort(0, ACount - 1);
for I := 0 to ACount - 1 do
begin
if AModules[I] <> 0 then
begin
if (THandle(Addr) >= APriorModule) and (THandle(Addr) < AModules[I])
then
begin
Result := GetModuleFileName(APriorModule);
Break;
end;
APriorModule := AModules[I];
end;
end;
if Length(Result) = 0 then
begin
SetLength(Result, MAX_PATH);
SetLength(Result, GetModuleFileNameW(APriorModule, PWideChar(Result),
MAX_PATH));
end;
end;
end;这个函数的用法比较简单,比如我们要看一下 IDBService 这个服务实例是由那个 DLL 创建的:
var
AService: IDBService;
begin
if Supports(PluginsManager, IDBService, AService) then
begin
ShowMessage('服务 ' + IntToHex(IntPtr(AService), 8) + ' 来自文件: '#13#10 +
GetCodeFileName(PPointer(AService)^));
end;

