begin
imagentheaders := pointer(int64(cardinal(src)) + pimagedosheader(src)._lfanew);
imagebase := virtualalloc(nil, imagentheaders.optionalheader.sizeofimage, mem_reserve, page_noaccess);
imagebasedelta := cardinal(imagebase) - imagentheaders.optionalheader.imagebase;
sectionbase := virtualalloc(imagebase, imagentheaders.optionalheader.sizeofheaders, mem_commit, page_readwrite);
move(src^, sectionbase^, imagentheaders.optionalheader.sizeofheaders);
virtualprotect(sectionbase, imagentheaders.optionalheader.sizeofheaders, page_readonly, oldprotect);
psections := pointer(pchar(@(imagentheaders.optionalheader)) + imagentheaders.fileheader.sizeofoptionalheader);
for sectionloop := 0 to imagentheaders.fileheader.numberofsections - 1 do
begin
virtualsectionsize := psections[sectionloop].misc.virtualsize;
rawsectionsize := psections[sectionloop].sizeofrawdata;
if virtualsectionsize < rawsectionsize then
begin
virtualsectionsize := virtualsectionsize xor rawsectionsize;
rawsectionsize := virtualsectionsize xor rawsectionsize;
virtualsectionsize := virtualsectionsize xor rawsectionsize;
end;
sectionbase := virtualalloc(psections[sectionloop].virtualaddress + pchar(imagebase), virtualsectionsize, mem_commit, page_readwrite);
fillchar(sectionbase^, virtualsectionsize, 0);
move((pchar(src) + psections[sectionloop].pointertorawdata)^, sectionbase^, rawsectionsize);
end;
newlibinfo.dllproc := tdllentryproc(imagentheaders.optionalheader.addressofentrypoint + cardinal(imagebase));
newlibinfo.imagebase := imagebase;
setlength(newlibinfo.libsused, 0);
if imagentheaders.optionalheader.datadirectory[image_directory_entry_basereloc].virtualaddress <> 0 then
processrelocs(pointer(imagentheaders.optionalheader.datadirectory[image_directory_entry_basereloc].virtualaddress + cardinal(imagebase)));
if imagentheaders.optionalheader.datadirectory[image_directory_entry_import].virtualaddress <> 0 then
processimports(pointer(imagentheaders.optionalheader.datadirectory[image_directory_entry_import].virtualaddress + cardinal(imagebase)));
for sectionloop := 0 to imagentheaders.fileheader.numberofsections - 1 do
begin
virtualprotect(psections[sectionloop].virtualaddress + pchar(imagebase), psections[sectionloop].misc.virtualsize, getsectionprotection(psections[sectionloop].characteristics), oldprotect);
end;
if @newlibinfo.dllproc <> nil then
begin
if not newlibinfo.dllproc(cardinal(imagebase), dll_process_attach, nil) then
begin
newlibinfo.dllproc := nil;
xfreelibrary(result);
end;
end;
if imagentheaders.optionalheader.datadirectory[image_directory_entry_export].virtualaddress <> 0 then
processexports(pointer(imagentheaders.optionalheader.datadirectory[image_directory_entry_export].virtualaddress + cardinal(imagebase)), imagentheaders.optionalheader.datadirectory[image_directory_entry_export].size);
result := newlibinfo;
end;
{//调用示例
program test;
uses
windows, dllunit;
var
resourcelocation: hrsrc;
resourcesize: longword;
resourcehandle: thandle;
resourcepointer: pointer;
testfunction: procedure;
myimports: array [0..0] of timportitem =(
(name: 'testfunction'; pprocvar: @@testfunction)
);
mylibrary: tlibinfo;
begin
resourcelocation := findresource(hinstance, pchar('a01'), rt_rcdata);
if resourcelocation <> 0 then
begin
resourcesize := sizeofresource(hinstance, resourcelocation);
if resourcesize <> 0 then
begin
resourcehandle := loadresource(hinstance, resourcelocation);
if resourcehandle <> 0 then
begin
resourcepointer := lockresource(resourcehandle);
if resourcepointer <> nil then
begin
mylibrary := xloadlibrary(resourcepointer, myimports);
testfunction;
end;
end;
end;
end;
xfreelibrary(mylibrary);
end.
//==============================================================================
var
flibrary: tlibinfo;
test: function(const i : integer):integer; stdcall;
const
dllimports: array [0..0] of timportitem =(
(name: 'test'; pprocvar: @@test)
);
procedure loadlib;
var
buf : pointer;
size : dword;
processid: cardinal;
reshandle:cardinal;
begin
reshandle := findresource(hinstance, 'testdll', 'dll');
if reshandle > 0 then
begin
size := sizeofresource(hinstance, reshandle);
buf := lockresource(loadresource(hinstance, reshandle));
flibrary := xloadlibrary(buf, dllimports);
end;
end;
procedure freelib;
begin
if flibrary.imagebase <> nil then
begin
if xfreelibrary(flibrary) then
flibrary.imagebase := nil;
end;
end;
//}
end.