forked from Sovos-Compliance/direct-bpl-loader
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmlLibrary.pas
195 lines (157 loc) · 6.72 KB
/
mlLibrary.pas
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
{*******************************************************************************
* Created by Vladimir Georgiev, 2014 *
* *
* Description: *
* Unit providing several methods to load and use a DLL/BPL library from *
* memory instead of a file. The methods are named after the original WinAPIs *
* like LoadLibrary, FreeLibrary, GetProcAddress, etc, but with a Mem suffix *
* for the Unhooked version and without a suffix for the Hooked version. *
* Same for LoadPackage and UnloadPackage for working with BPLs *
* The underlying functionality is provided by the TMl(Hooked)LibraryManager *
* class that manages the loading, unloading, reference counting, generation of*
* handles, etc. It uses the TMlBaseLoader for the loading/unloading of libs. *
* *
*******************************************************************************}
{$I MlDefines.inc}
{$I DelphiVersion_defines.inc}
unit mlLibrary;
interface
uses
SysUtils,
Classes,
SysConst,
Windows,
mlTypes,
mlManagers;
{$IFDEF MLHOOKED}
// DLL loading functions. They only forward the calls to the TMlLibraryManager instance
function LoadLibrary(aStream: TStream; lpLibFileName: PChar): HMODULE; overload;
function LoadLibrary(aStream: TStream; const aLibFileName: String): HMODULE; overload;
function LoadLibrary(lpLibFileName: PChar): HMODULE; overload;
/// BPL loading functions
function LoadPackage(aStream: TStream; const aLibFileName: String {$IFDEF DELPHI2007}; aValidatePackage:
TValidatePackageProc = nil{$ENDIF}): TLibHandle; overload;
{$ELSE}
// DLL loading functions. They only forward the calls to the TMlLibraryManager instance
function LoadLibraryMem(aStream: TStream; const aLibFileName: String): TLibHandle;
function FreeLibraryMem(hModule: TLibHandle): Boolean;
function GetProcAddressMem(hModule: TLibHandle; lpProcName: LPCSTR): FARPROC;
function FindResourceMem(hModule: TLibHandle; lpName, lpType: PChar): HRSRC;
function LoadResourceMem(hModule: TLibHandle; hResInfo: HRSRC): HGLOBAL;
function SizeOfResourceMem(hModule: TLibHandle; hResInfo: HRSRC): DWORD;
function GetModuleFileNameMem(hModule: TLibHandle): String;
function GetModuleHandleMem(const ModuleName: String): TLibHandle;
/// BPL loading functions
function LoadPackageMem(aStream: TStream; const aLibFileName: String {$IFDEF DELPHI2007}; aValidatePackage:
TValidatePackageProc = nil{$ENDIF}): TLibHandle; overload;
procedure UnloadPackageMem(Module: TLibHandle);
function MlGetGlobalModuleHandle(const aLibFileName: String): TLibHandle;
{$ENDIF MLHOOKED}
/// Helper functions to check module load status and set a callback function
function MlIsWinLoaded(hModule: TLibHandle): Boolean;
function MlIsMemLoaded(hModule: TLibHandle): Boolean;
procedure MlSetOnLoadCallback(aCallbackProc: TMlLoadDependentLibraryEvent);
//TODO VG 090714: This method is used only to reset the loader during unit testing. Can be removed
{$IFDEF _CONSOLE_TESTRUNNER}
procedure UnloadAllLibraries;
{$ENDIF _CONSOLE_TESTRUNNER}
implementation
{$IFDEF MLHOOKED}
{ ============ Hooked DLL Library memory functions ============ }
{ ============================================================= }
function LoadLibrary(aStream: TStream; lpLibFileName: PChar): HMODULE;
begin
Result := Manager.LoadLibraryMl(aStream, lpLibFileName);
end;
function LoadLibrary(aStream: TStream; const aLibFileName: String): HMODULE;
begin
Result := Manager.LoadLibraryMl(aStream, aLibFileName);
end;
function LoadLibrary(lpLibFileName: PChar): HMODULE;
begin
Result := Manager.LoadLibraryMl(lpLibFileName);
end;
{ ============ Hooked BPL Library memory functions ============ }
{ ============================================================= }
function LoadPackage(aStream: TStream; const aLibFileName: String {$IFDEF DELPHI2007}; aValidatePackage:
TValidatePackageProc = nil{$ENDIF}): TLibHandle;
begin
Result := Manager.LoadPackageMl(aStream, aLibFileName, {$IFDEF DELPHI2007} aValidatePackage {$ELSE} nil {$ENDIF});
end;
{$ELSE}
{ ============ Unhooked DLL Library memory functions ============ }
{ =============================================================== }
function LoadLibraryMem(aStream: TStream; const aLibFileName: String): TLibHandle;
begin
Result := Manager.LoadLibraryMl(aStream, aLibFileName);
end;
function FreeLibraryMem(hModule: TLibHandle): Boolean;
begin
Result := Manager.FreeLibraryMl(hModule);
end;
function GetProcAddressMem(hModule: TLibHandle; lpProcName: LPCSTR): FARPROC;
begin
Result := Manager.GetProcAddressMl(hModule, lpProcName);
end;
function FindResourceMem(hModule: TLibHandle; lpName, lpType: PChar): HRSRC;
begin
Result := Manager.FindResourceMl(hModule, lpName, lpType);
end;
function LoadResourceMem(hModule: TLibHandle; hResInfo: HRSRC): HGLOBAL;
begin
Result := Manager.LoadResourceMl(hModule, hResInfo);
end;
function SizeOfResourceMem(hModule: TLibHandle; hResInfo: HRSRC): DWORD;
begin
Result := Manager.SizeOfResourceMl(hModule, hResInfo);
end;
function GetModuleFileNameMem(hModule: TLibHandle): String;
begin
Result := Manager.GetModuleFileNameMl(hModule);
end;
function GetModuleHandleMem(const ModuleName: String): TLibHandle;
begin
Result := Manager.GetModuleHandleMl(ModuleName);
end;
{ ============ BPL Library memory functions ============ }
{ ====================================================== }
function LoadPackageMem(aStream: TStream; const aLibFileName: String {$IFDEF DELPHI2007}; aValidatePackage:
TValidatePackageProc = nil{$ENDIF}): TLibHandle;
begin
Result := Manager.LoadPackageMl(aStream, aLibFileName, {$IFDEF DELPHI2007} aValidatePackage {$ELSE} nil {$ENDIF});
end;
procedure UnloadPackageMem(Module: TLibHandle);
begin
Manager.UnloadPackageMl(Module);
end;
function MlGetGlobalModuleHandle(const aLibFileName: String): TLibHandle;
begin
Result := Manager.GetGlobalModuleHandle(aLibFileName);
end;
{$ENDIF MLHOOKED}
function MlIsWinLoaded(hModule: TLibHandle): Boolean;
begin
Result := Manager.IsWinLoaded(hModule);
end;
function MlIsMemLoaded(hModule: TLibHandle): Boolean;
begin
Result := Manager.IsMemLoaded(hModule);
end;
procedure MlSetOnLoadCallback(aCallbackProc: TMlLoadDependentLibraryEvent);
begin
Manager.OnDependencyLoad := aCallbackProc;
end;
//TODO VG 090714: This method is used only to reset the manager during unit testing. Can be removed
{$IFDEF _CONSOLE_TESTRUNNER}
procedure UnloadAllLibraries;
begin
Manager.Free;
{$IFDEF MLHOOKED}
Manager := TMlHookedLibraryManager.Create;
Manager.HookAPIs;
{$ELSE}
Manager := TMlLibraryManager.Create;
{$ENDIF}
end;
{$ENDIF _CONSOLE_TESTRUNNER}
end.