下面这个函数可以让你知道一个函数来自那里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;