从内存中加载可执行文件或DLL
来自:tt.t, 时间:2004-6-17 16:44:46, ID:2668559
内存执行exe文件,效果嘛,只能说是能够运行部分。。。
(*
这个程序是从2aA第6期的一篇文章中的C代码改写而来,仅将影响PE运行的最关键的部分进行了
处理,即引入表(.idata)和重定位表(.reloc),所以兼容性不佳,但思路清晰,结构简单,
值得一看。
未解决的问题:
1. 未处理export,tls,IAT等section,而导致某些程序无法运行
2. 对于那些运行期间修改自身或从自身读取数据释放为文件的程序无法运行
3. 未hook全部 需要module handle的api,因而可能因module handle为loader的handle,
导致程序无法运行。
4. 还有很多...
ps,似乎除了部分delphi编制的程序,运行起来都有问题。
已试验的能够运行的有:部分delphi编制的程序,如execope
你可以试试自己的delphi程序,说不定它就能运行的,good luck!
converted by tt.t @jun.2k+4
*)
program test; //Attention,it's a project file.
uses
windows,Messages,sysutils,classes,ShellAPI,Dialogs,PE;
const
appname='abc';
var
aMessage:tmsg;
hwindow:hwnd;
f:TMemoryStream;
imagebase:DWORD;
OrgFindResourceA:function (hModule: HMODULE; lpName, lpType: PChar): HRSRC; stdcall;
OrgLoadResource:function (hModule: HINST; hResInfo: HRSRC): HGLOBAL; stdcall;
function GetMyVirAddr:Pointer;
begin
result:= pointer(imagebase);//fs.Memory;
end;
procedure ByebyeWorld;
begin
VirtualFree(Pointer(imagebase),0,MEM_DECOMMIT or MEM_RELEASE);
PostQuitMessage(0);
// Halt(0);
end;
function FakeLoadResource(hModule: HINST; hResInfo: HRSRC): HGLOBAL; stdcall;
begin
//修正module handle
if (hModule=hinstance) or (hModule=0) then result:=FakeLoadResource(imagebase,hResInfo)
else result:=OrgLoadResource(hModule,hResInfo);
end;
function FakeFindResourceA(hModule: HMODULE; lpName, lpType: PChar): HRSRC; stdcall;
begin
//修正module handle
if (hModule=hinstance) or (hModule=0) then result:=OrgFindResourceA(imagebase,lpName, lpType)
else result:=OrgFindResourceA(hModule,lpName, lpType);
end;
function ExecInMem(FileBuf:Pointer):integer;
var
mz:PMZ_HEADER;
pe:PPE_HEADER;
oe:PPE_OBJENTRY;
im:PPE_IMPORT;
fx:PPE_FIXUP;
fx_size:DWORD;
viroff:DWORD;
i,j:integer;
h,tmp:cardinal;
addr:PDWORD;
begin
mz := PMZ_HEADER(FileBuf);
pe := PPE_HEADER(DWORD(mz)+mz^.mz_neptr);
oe := PPE_OBJENTRY(DWORD(pe)+$18+pe^.pe_ntheadersize);
imagebase := DWORD(VirtualAlloc(nil,pe^.pe_imagesize,MEM_COMMIT,PAGE_EXECUTE_READWRITE));
if (imagebase = 0 ) then
begin
messagebox(0,'IMC:ERROR:can not allocate memory','error',0);
result:=0;
exit;
end;
viroff:=imagebase-pe^.pe_imagebase;
copymemory(pointer(imagebase),mz,pe^.pe_headersize); //将PE文件头复制到内存
for i:=0 to pe^.pe_numofobjects-1 do
begin
copymemory(Pointer(imagebase+oe^.oe_virtrva),Pointer(DWORD(mz)+oe^.oe_physoffs),
oe^.oe_physsize);
inc(oe);
end; //将各个Section复制到文件头中制定的RVA处
im:=PPE_IMPORT(imagebase+pe^.pe_importrva);
while im^.im_name<>0 do
begin
// if GetModuleHandle(PChar(imagebase+im^.im_name))=0 then
h:=LoadLibrary(PChar(imagebase+im^.im_name));
if h=0 then
begin
messagebox(0,pchar('IMC:ERROR:can not LoadLibrary '+PChar(im^.im_name)),'error',0);
result:=0;
exit;
end;
addr:=PDWORD(imagebase+im^.im_lookup);
if DWORD(addr)=imagebase then addr:=PDWORD(imagebase+im^.im_addresstable);
tmp:=addr^;
while tmp<>0 do
begin
if (tmp and $80000000)<>0 then
begin
tmp := tmp and $7FFFFFFF; // by ordinal
if tmp=$12345 then addr^:=DWORD(@GetMyVirAddr) //这里hook编号为$12345的函数
else if tmp=$22345 then addr^:=DWORD(@ByebyeWorld)//这里hook编号为$22345的函数
else
addr^ := DWORD(GetProcAddress(h, pchar(tmp)));
end
else
begin
tmp := imagebase+tmp+2; // by name, skip word-hash
if pchar(tmp)='FindResourceA' then addr^ := DWORD(@FakeFindResourceA)
else if pchar(tmp)='LoadResource' then addr^ := DWORD(@FakeLoadResource)
else
addr^ := DWORD(GetProcAddress(h, pchar(tmp)));
end;
inc(addr);
tmp:=addr^;
end;
inc(im);
end; //修正引入表,load需要的dll
fx := PPE_FIXUP(imagebase+pe^.pe_fixuprva);
if ( ((pe^.pe_flags and 1)=0) and (fx<>nil) ) then
begin
fx_size := pe^.pe_fixupsize;
while (fx_size<>0) do
begin
for i:=0 to (fx^.fx_blocksize-8) div 2 -1 do
begin
j := PWORD(DWORD(@fx^.fx_typeoffs)+i*2)^;
if ((j shr 12) = 3) then
PDWORD(imagebase + fx^.fx_pagerva + (j and $0FFF))^ :=
PDWORD(imagebase + fx^.fx_pagerva + (j and $0FFF))^+viroff;
end;
fx_size := fx_size-fx^.fx_blocksize;
inc(DWORD(fx) , fx^.fx_blocksize);
end; //重定位修正
end;
OrgLoadResource:=GetProcAddress(GetModuleHandle('kernel32.dll'),'LoadResource');
OrgFindResourceA:=GetProcAddress(GetModuleHandle('kernel32.dll'),'FindResourceA');
i:=imagebase+pe^.pe_entrypointrva;
asm
push i
ret //ok了,开始运行,god bless me
end;
//should NEVER reutrn here.
result:=1;
VirtualFree(Pointer(imagebase),0,MEM_DECOMMIT or MEM_RELEASE);
end;
function WindowProc(window:hwnd;amessage,wparam,lparam:longint):longint;stdcall;export;
begin
case amessage of
WM_DESTROY:
begin
ByebyeWorld;
f.Free;
end;
end;
result:=defwindowproc(window,aMessage,wParam,lParam);
end;
function WinRegister:boolean;
var
mWindowClass:TWndClass;
begin
zeromemory(@mWindowClass,sizeof(TWndClass));
mwindowclass.lpfnWndProc:=@windowProc;
mwindowClass.cbClsExtra:=0;
mwindowClass.cbWndExtra:=0;
mwindowclass.hInstance:=hinstance;
mwindowclass.hCursor:=LoadCursor(0,IDC_ARROW);
mwindowclass.hbrBackground:=COLOR_BTNSHADOW;
mwindowclass.lpszMenuName:=nil;
mwindowclass.lpszClassName:=appname;
result:=windows.Registerclass(mwindowClass)<>0;
end;
function WinCreate:hwnd;
var
pchartemp:pchar;
begin
hwindow:=CreateWindowEx(WS_EX_RTLREADING or WS_EX_APPWINDOW,appname,'RIM Test',WS_OVERLAPPEDWINDOW,CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,0,0,hinstance,nil);
if hwindow<>0 then
begin
showwindow(hwindow,SW_HIDE);
f:=TMemoryStream.Create;
while true do
with TOpenDialog.Create(nil) do
begin
Filter:='Executable file|*.EXE';
if (Execute) then
if (uppercase(extractfileext(FileName))='.EXE') then
begin
if ExtractFilePath(FileName)<>'' then Chdir(ExtractFilePath(FileName));
f.LoadFromFile(FileName);
Free;
ExecInMem(f.Memory);
Break;
end
else
begin
Messagebox(0,'Please select an exe file to launch!','!!',0);
Free;
end
else
begin
Sendmessage(hwindow,WM_CLOSE,0,0);
Free;
Break;
end;
end;
end;
result:=hwindow;
end;
begin
if not winregister then
begin
MessageBox(0,'窗口注册失败','错误',MB_OK+MB_ICONINFORMATION);
exit;
end;
wincreate;
while GetMessage(aMessage,0,0,0) do
begin
TranslateMessage(amessage);
DispatchMessage(aMessage);
end;
halt(amessage.wParam);
end.
=============PE.pas===========
unit pe;
interface
uses Windows;
type
PMZ_HEADER=^MZ_HEADER;
MZ_HEADER=record
mz_id:WORD;
mz_last512:WORD;
mz_num512:WORD;
mz_relnum:WORD;
mz_headersize:WORD;
mz_minmem:WORD;
mz_maxmem:WORD;
mz_ss:WORD;
mz_sp:WORD;
mz_checksum:WORD;
mz_ip:WORD;
mz_cs:WORD;
mz_relofs:WORD;
mz_ovrnum:WORD;
mz_reserved:Array [0..31] of byte;
mz_neptr:DWORD;
end;
type
PPE_HEADER=^PE_HEADER;
PE_HEADER=record
pe_id:DWORD; // 00 01 02 03
pe_cputype:WORD; // 04 05
pe_numofobjects:WORD; // 06 07
pe_datetime:DWORD; // 08 09 0A 0B
pe_coffptr:DWORD; // 0C 0D 0E 0F
pe_coffsize:DWORD; // 10 11 12 13
pe_ntheadersize:WORD; // 14 15
pe_flags:WORD; // 16 17
// NT_Header {
pe_magic:WORD; // 18 19
pe_linkmajor:BYTE; // 1A
pe_linkminor:BYTE; // 1B
pe_sizeofcode:DWORD; // 1C 1D 1E 1F
pe_sizeofidata:DWORD; // 20 21 22 23
pe_sizeofudata:DWORD; // 24 25 26 27
pe_entrypointrva:DWORD; // 28 29 2A 2B
pe_baseofcode:DWORD; // 2C 2D 2E 2F
pe_baseofdata:DWORD; // 30 31 32 33
pe_imagebase:DWORD; // 34 35 36 37
pe_objectalign:DWORD; // 38 39 3A 3B
pe_filealign:DWORD; // 3C 3D 3E 3F
pe_osmajor:WORD; // 40 41
pe_osminor:WORD; // 42 43
pe_usermajor:WORD; // 44 45
pe_userminor:WORD; // 46 47
pe_subsysmajor:WORD; // 48 49
pe_subsysminor:WORD; // 4A 4B
pe_reserved:DWORD; // 4C 4D 4E 4F
pe_imagesize:DWORD; // 50 51 52 53
pe_headersize:DWORD; // 54 55 56 56
pe_checksum:DWORD; // 58 59 5A 5B
pe_subsystem:WORD; // 5C 5D
pe_dllflags:WORD; // 5E 5F
pe_stackreserve:DWORD; // 60 61 62 63
pe_stackcommit:DWORD; // 64 65 66 67
pe_heapreserve:DWORD; // 68 69 6A 6B
pe_heapcommit:DWORD; // 6C 6D 6E 6F
pe_loaderflags:DWORD; // 70 71 72 73
pe_numofrvaandsizes:DWORD; // 74 75 76 77
// rva and sizes
pe_exportrva:DWORD; // 78 79 7A 7B
pe_exportsize:DWORD; // 7C 7D 7E 7F
pe_importrva:DWORD; // 80 81 82 83
pe_importsize:DWORD; // 84 85 86 87
pe_resourcerva:DWORD; // 88 89 8A 8B
pe_resourcesize:DWORD; // 8C 8D 8E 8F
pe_exceptionrva:DWORD; // 90 91 92 93
pe_exceptionsize:DWORD; // 94 95 96 97
pe_securityrva:DWORD; // 98 99 9A 9B
pe_securitysize:DWORD; // 9C 9D 9E 9F
pe_fixuprva:DWORD; // A0 A1 A2 A3
pe_fixupsize:DWORD; // A4 A5 A6 A7
pe_debugrva:DWORD; // A8 A9 AA AB
pe_debugsize:DWORD; // AC AD AE AF
pe_descriptionrva:DWORD; // B0 B1 B2 B3
pe_descriptionsize:DWORD; // B4 B5 B6 B7
pe_machinerva:DWORD; // B8 B9 BA BB
pe_machinesize:DWORD; // BC BD BE BF
pe_tlsrva:DWORD; // C0 C1 C2 C3
pe_tlssize:DWORD; // C4 C5 C6 C7
pe_loadconfigrva:DWORD; // C8 C9 CA CB
pe_loadconfigsize:DWORD; // CC CD CE CF
pe_reserved_1:Array [0..7] of BYTE; // D0 D1 D2 D3 D4 D5 D6 D7
pe_iatrva:DWORD; // D8 D9 DA DB
pe_iatsize:DWORD; // DC DD DE DF
pe_reserved_2:Array [0..7] of BYTE; // E0 E1 E2 E3 E4 E5 E6 E7
pe_reserved_3:Array [0..7] of BYTE; // E8 E9 EA EB EC ED EE EF
pe_reserved_4:Array [0..7] of BYTE; // F0 F1 F2 F3 F4 F5 F6 F7
// ---- total size == 0xF8 ---------
end;
type
PPE_OBJENTRY=^PE_OBJENTRY;
PE_OBJENTRY=record
oe_name:Array [0..7] of BYTE; // 00 01 02 03 04 05 06 07
oe_virtsize:DWORD; // 08 09 0A 0B
oe_virtrva:DWORD; // 0C 0D 0E 0F
oe_physsize:DWORD; // 10 11 12 13
oe_physoffs:DWORD; // 14 15 16 17
oe_reserved:Array [0..11] of BYTE; // 18 19 1A 1B 1C 1D 1E 1F 20 21 22 23
oe_objectflags:DWORD; // 24 25 26 27
// ---- total size == 0x28 ---------
end;
type
PPE_EXPORT=^PE_EXPORT;
PE_EXPORT=record
ex_flags:DWORD; // 00 01 02 03
ex_datetime:DWORD; // 04 05 06 07
ex_major_ver:WORD; // 08 09
ex_minor_ver:WORD; // 0A 0B
ex_namerva:DWORD; // 0C 0D 0E 0F
ex_ordinalbase:DWORD; // 10 11 12 13
ex_numoffunctions:DWORD; // 14 15 16 17
ex_numofnamepointers:DWORD; // 18 19 1A 1B
ex_addresstablerva:DWORD; // 1C 1D 1E 1F
ex_namepointersrva:DWORD; // 20 21 22 23
ex_ordinaltablerva:DWORD; // 24 25 26 27
// ---- total size == 0x28 ---------
end;
type
PPE_IMPORT=^PE_IMPORT;
PE_IMPORT=record
im_lookup:DWORD; // 00
im_datetime:DWORD; // 04 ?
im_forward:DWORD; // 08 -1
im_name:DWORD; // 0C
im_addresstable:DWORD; // 10
// ---- total size == 0x14 ---------
end;
type
PPE_FIXUP=^PE_FIXUP;
PE_FIXUP=record
fx_pagerva:DWORD; // 00 01 02 03
fx_blocksize:DWORD; // 04 05 06 07
fx_typeoffs:WORD; // 08 09 .. .. ????
end;
implementation
end.
---------------------------------------
三个T.你上次问题我才看到.迟来的答案....
PS:你是想进程插入吧,XIXI
unit OpenThread;
interface
uses
Windows,TlHelp32;
function OpenThread2(dwThreadID : DWORD; bInherit : BOOL):THandle;stdcall;
function GetProcessID(strProcessName : string):DWORD;
function GetThreadID(dwOwnerProcessID : DWORD):DWORD;
implementation
const
THREAD_TERMINATE = $0001;
THREAD_SUSPEND_RESUME = $0002;
THREAD_GET_CONTEXT = $0008;
THREAD_SET_CONTEXT = $0010;
THREAD_SET_INFORMATION = $0020;
THREAD_QUERY_INFORMATION = $0040;
THREAD_SET_THREAD_TOKEN = $0080;
THREAD_IMPERSONATE = $0100;
THREAD_DIRECT_IMPERSONATION = $0200;
THREAD_ALL_ACCESS = STANDARD_RIGHTS_REQUIRED or SYNCHRONIZE or $3FF;
type
PPDB = ^T_PDB;
T_PDB = record
mType : WORD;
Refcount : WORD;
Unk0 : DWORD;
Unk1 : DWORD;
Unk2 : DWORD;
TermStatus : DWORD;
Unk3 : DWORD;
DefaultHeap : DWORD;
MemContext : DWORD;
Flags : DWORD;
pPsp : DWORD;
psSelector : WORD;
METIndex : WORD;
nThreads : WORD;
nThreadsNotTerm : WORD;
Unk5 : WORD;
nR0Threads : WORD;
HeapHandle : DWORD;
K16TDBSel : WORD;
Unk6 : WORD;
Unk7 : DWORD;
pEDB : DWORD;
pHandleTable : DWORD;
ParentPDB : PPDB;
ModRefList : DWORD;
ThreadList : DWORD;
DebugeeCB : DWORD;
LHFreeHead : DWORD;
InitialR0ID : DWORD;
end;
PDB = T_PDB;
T_TCB = record
mType : WORD;
RefCount : WORD;
Unk1 : DWORD;
pvExcept : DWORD;
TopOfStack : DWORD;
BaseOfStace : DWORD;
K16TDB : WORD;
StackSel16 : WORD;
Unk2 : DWORD;
UserPointer : DWORD;
pTIB : DWORD;
TIBFlags : WORD;
Win16MutxCnt : WORD;
DebugContext : DWORD;
PtrToCurPri : DWORD;
MsgQueue : DWORD;
pTLSarray : DWORD;
pParentPDB : PPDB;
SelmanList : DWORD;
Unk3 : DWORD;
Flags : DWORD;
status : DWORD;
TibSel : WORD;
EmulatorSel : WORD;
HandleCount : DWORD;
WaitNodeList : DWORD;
R0hThread : DWORD;
ptdbx : DWORD;
end;
TCB = T_TCB;
PTCB = ^T_TCB;
OBFUNC = function(dwPTID : DWORD):pointer;stdcall;
OTFUNC = function(pH : PHandle; dwVal : DWORD; var var1; var var2):DWORD;stdcall;
function GetTrueProcAddress(lpMod : PChar; lpFunc : PChar):pointer;stdcall;forward;
function OpenThreadNT(dwThreadID : DWORD; bInherit : BOOL):THandle;stdcall;forward;
function UpperCase(const S: string): string;
var
Ch: Char;
L: Integer;
Source, Dest: PChar;
begin
L := Length(S);
SetLength(Result, L);
Source := Pointer(S);
Dest := Pointer(Result);
while L <> 0 do
begin
Ch := Source^;
if (Ch >= 'a') and (Ch <= 'z') then
Dec(Ch, 32);
Dest^ := Ch;
Inc(Source);
Inc(Dest);
Dec(L);
end;
end;
function XORProcessThreadID(dwPTID : DWORD):pointer;stdcall;
var
obfuscate : OBFUNC;
dwMain : DWORD;
lpdw : PDWORD;
dw1 : DWORD;
begin
dwMain := DWORD(GetTrueProcAddress('Kernel32.dll', 'GetCurrentThreadId'));
// if dwMain = nil then begin result := nil; exit; end;
lpdw := PDWORD(dwMain+8);
dw1 := dwMain + 12;
obfuscate := OBFUNC(dw1 + lpdw^);
result := obfuscate(dwPTID);
end;
function OpenThread2(dwThreadID : DWORD; bInherit : BOOL):THandle;stdcall;
var
hThread, hPrc : THandle;
lp1 : PDWORD;
dwProcessID , dwWhere, dwTable : DWORD;
b1 : BOOL;
lpThreadObj : PTCB;
procpPdb : PPDB;
osvi : OSVERSIONINFO;
begin
osvi.dwOSVersionInfoSize := sizeof(osvi);
GetVersionEX(osvi);
SetLastError(50);
if osvi.dwPlatformId = VER_PLATFORM_WIN32_NT then
result := OpenThreadNT(dwThreadID, bInherit)
else begin
procpPdb := PPDB(XORProcessThreadID(GetCurrentProcessID()));
lpThreadObj := PTCB (XORProcessThreadID(dwThreadID));
if IsBadReadPtr(lpThreadObj, sizeof(TCB)) then begin
result := 0;
exit;
end;
if PBYTE(lpThreadObj)^ <> 7 then begin
result := 0;
exit;
end;
dwProcessID := DWORD(XORProcessThreadID(DWORD(lpThreadObj^.pParentPDB)));
if (dwProcessID = GetCurrentProcessID()) then
hPrc := GetCurrentProcess()
else begin
hPrc := OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwProcessID);
if (hPrc = 0) then begin
result := 0;
exit;
end;
end;
// 4 is the lowest handle in the table
// all proceses have this handle
b1 := DuplicateHandle(hPrc,
THandle(4),
GetCurrentProcess(),
@hThread,
THREAD_ALL_ACCESS,
bInherit, 0);
if (hPrc <> GetCurrentProcess()) then CloseHandle(hPrc);
if (b1=FALSE) then begin
result := 0;
exit;
end;
dwWhere := DWORD(hThread) shr 2;
dwTable := procpPdb^.pHandleTable;
lp1 := PDWORD (dwTable + dwWhere*8 + 8);
lp1^ := DWORD(lpThreadObj);
result := hThread;
end;
end;
{$J+}
function OpenThreadNT(dwThreadID : DWORD; bInherit : BOOL):THandle;stdcall;
const
hThread : THandle = 0;
struct1 : array [0..5] of DWORD = ($18, 0, 0, 0, 0, 0);
struct2 : array [0..1] of DWORD = (0, 0);
hLib : HModule = 0;
OpenThatNTThread : OTFUNC = nil;
begin
hLib := LoadLibrary('ntdll.dll');
OpenThatNTThread := OTFUNC(GetProcAddress(hLib, 'NtOpenThread'));
struct2[1] := dwThreadID;
struct1[3] := DWORD(bInherit);
OpenThatNtThread(@hThread, THREAD_ALL_ACCESS, struct1, struct2);
FreeLibrary(hLib);
result := hThread;
end;
{$J-}
function GetTrueProcAddress(lpMod : PChar; lpFunc : PChar):pointer;stdcall;
var
bla : pointer;
hMod : HModule;
begin
hMod := GetModuleHandle(lpMod);
if hMod=0 then begin
result := nil;
exit;
end;
bla := Pointer(GetProcAddress(hMod, lpFunc));
if (DWORD(bla) = 0) then begin
result := nil;
exit;
end;
if PByte(bla)^ = $68 then
bla := Pointer(PDWORD(DWORD(bla) + 1)^);
result := bla;
end;
function GetProcessID(strProcessName : string):DWORD;
var
dwRet : DWORD;
hSnapShot : THandle;
ProcessEntry : PROCESSENTRY32;
bFlag : BOOL;
begin
dwRet := 0;
hSnapshot := CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0);
if(hSnapshot <> INVALID_HANDLE_VALUE) then
begin
FillChar(ProcessEntry,sizeof(PROCESSENTRY32),0);
ProcessEntry.dwSize := sizeof(PROCESSENTRY32);
bFlag := Process32First(hSnapshot,ProcessEntry);
while (bFlag) do
begin
if Pos(UpperCase(strProcessName), UpperCase(ProcessEntry.szExeFile)) <> 0 then
begin
dwRet := ProcessEntry.th32ProcessID;
break;
end;
ProcessEntry.dwSize := sizeof(PROCESSENTRY32);
bFlag := Process32Next(hSnapshot,ProcessEntry);
end;
CloseHandle(hSnapshot);
end;
result := dwRet;
end;
function GetThreadID(dwOwnerProcessID : DWORD):DWORD;
var
dwRet : DWORD;
hThreadSnap : THandle;
te32 : THREADENTRY32;
begin
dwRet := 0;
FillChar(te32, SizeOf(te32), 0);
hThreadSnap := CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, 0);
if (hThreadSnap <> INVALID_HANDLE_VALUE) then begin
te32.dwSize := sizeof(THREADENTRY32);
if (Thread32First(hThreadSnap, te32)) then
repeat
if (te32.th32OwnerProcessID = dwOwnerProcessID) then begin
dwRet := te32.th32ThreadID;
break;
end;
until not (Thread32Next(hThreadSnap, te32));
CloseHandle (hThreadSnap);
end;
result := dwRet;
end;
end.
---------------------------------------
来自:WindDriver, 时间:2004-6-22 9:08:45, ID:2675646
在国外站点找到答案了 ;)
{
DLL Loader by Aphex
http://www.iamaphex.cjb.net
unremote@knology.net
Based on code from gmm@ufacom.ru
function xLoadLibrary(Src: Pointer; Imports: array of TImportItem): TLibInfo;
procedure xFreeLibrary(hModule: TLibInfo);
}
unit DLLUnit;
interface
uses
Windows;
type
TImportItem = record
Name: string;
PProcVar: ^Pointer;
end;
TwordArr = array [0..0] of word;
PwordArr = ^TwordArr;
TdwordArr = array [0..0] of dword;
PdwordArr = ^TdwordArr;
PImageImportDescriptor = ^TImageImportDescriptor;
TImageImportDescriptor = packed record
OriginalFirstThunk: dword;
TimeDateStamp: dword;
ForwarderChain: dword;
Name: dword;
FirstThunk: dword;
end;
PImageBaseRelocation= ^TImageBaseRelocation;
TImageBaseRelocation = packed record
VirtualAddress: cardinal;
SizeOfBlock: cardinal;
end;
TDllEntryProc = function(hinstDLL: HMODULE; dwReason: dword; lpvReserved: Pointer): Boolean; stdcall;
TStringArray = array of string;
TLibInfo = record
ImageBase: Pointer;
DllProc: TDllEntryProc;
LibsUsed: TStringArray;
end;
PLibInfo = ^TLibInfo;
PPointer = ^Pointer;
TSections = array [0..100000] of TImageSectionHeader;
const
IMPORTED_NAME_OFFSET = $00000002;
IMAGE_ORDINAL_FLAG32 = $80000000;
IMAGE_ORDINAL_MASK32 = $0000FFFF;
function xLoadLibrary(Src: Pointer; Imports: array of TImportItem): TLibInfo;
function xFreeLibrary(LoadedLib: TLibInfo): boolean;
implementation
function xFreeLibrary(LoadedLib: TLibInfo): boolean;
var
ObjectLoop: integer;
begin
Result := False;
with LoadedLib do
begin
if @DllProc <> nil then
begin
DllProc(HModule(LoadedLib.ImageBase), DLL_PROCESS_DETACH, nil);
end;
for ObjectLoop := 0 to Length(LibsUsed) - 1 do
begin
if ObjectLoop >= Length(LibsUsed) then Exit;
FreeLibrary(GetModuleHandle(pchar(LibsUsed[ObjectLoop])));
end;
SetLength(LibsUsed, 0);
end;
VirtualFree(LoadedLib.ImageBase, 0, MEM_RELEASE);
Result := True;
end;
function xLoadLibrary(Src: Pointer; Imports: array of TImportItem): TLibInfo;
var
ImageBase: pointer;
ImageBaseDelta: integer;
ImageNtHeaders: PImageNtHeaders;
PSections: ^TSections;
SectionLoop: integer;
SectionBase: pointer;
VirtualSectionSize, RawSectionSize: cardinal;
OldProtect: cardinal;
NewLibInfo: TLibInfo;
function StrToInt(S: string): integer;
begin
Val(S, Result, Result);
end;
procedure Add(Strings: TStringArray; Text: string);
begin
SetLength(Strings, Length(Strings) + 1);
Strings[Length(Strings)-1] := Text;
end;
function Find(Strings: array of string; Text: string; var Index: integer): boolean;
var
StringLoop: integer;
begin
Result := False;
for StringLoop := 0 to Length(Strings) - 1 do
begin
if lstrcmpi(pchar(Strings[StringLoop]), pchar(Text)) = 0 then
begin
Index := StringLoop;
Result := True;
end;
end;
end;
function GetSectionProtection(ImageScn: cardinal): cardinal;
begin
Result := 0;
if (ImageScn and IMAGE_SCN_MEM_NOT_CACHED) <> 0 then
begin
Result := Result or PAGE_NOCACHE;
end;
if (ImageScn and IMAGE_SCN_MEM_EXECUTE) <> 0 then
begin
if (ImageScn and IMAGE_SCN_MEM_READ)<> 0 then
begin
if (ImageScn and IMAGE_SCN_MEM_WRITE)<> 0 then
begin
Result := Result or PAGE_EXECUTE_READWRITE
end
else
begin
Result := Result or PAGE_EXECUTE_READ
end;
end
else if (ImageScn and IMAGE_SCN_MEM_WRITE) <> 0 then
begin
Result := Result or PAGE_EXECUTE_WRITECOPY
end
else
begin
Result := Result or PAGE_EXECUTE
end;
end
else if (ImageScn and IMAGE_SCN_MEM_READ)<> 0 then
begin
if (ImageScn and IMAGE_SCN_MEM_WRITE) <> 0 then
begin
Result := Result or PAGE_READWRITE
end
else
begin
Result := Result or PAGE_READONLY
end
end
else if (ImageScn and IMAGE_SCN_MEM_WRITE) <> 0 then
begin
Result := Result or PAGE_WRITECOPY
end
else
begin
Result := Result or PAGE_NOACCESS;
end;
end;
procedure ProcessExports(PExports: PImageExportDirectory; BlockSize: cardinal);
var
ExportLoop: byte;
ImportedFn: cardinal;
PFnName: pchar;
FnIndex: dword;
function IsForwarderString(Data: pchar): boolean;
begin
Result := Data > PExports;
if Result then Result := cardinal(Data - PExports) < BlockSize;
end;
function GetForwardedSymbol(ForwarderString: pchar):pointer;
var
sForwarderString, DllName: string;
ForwarderLoop: integer;
LibHandle: HModule;
begin
sForwarderString := ForwarderString;
while ForwarderString^ <> '.' do
begin
Inc(ForwarderString);
end;
DllName := Copy(sForwarderString, 1, pos('.', sForwarderString) - 1);
if not Find(NewLibInfo.LibsUsed, DllName, ForwarderLoop) then
begin
LibHandle := LoadLibrary(pchar(DllName));
Add(NewLibInfo.LibsUsed, DllName);
end
else
begin
LibHandle := cardinal(NewLibInfo.LibsUsed[ForwarderLoop]);
end;
if ForwarderString^ = '#' then ForwarderString := pointer(StrToInt((ForwarderString + 1)));
Result := GetProcAddress(LibHandle, ForwarderString);
end;
begin
for ExportLoop := 0 to PExports.NumberOfNames - 1 do
begin
PFnName := pchar(PdwordArr(cardinal(PExports.AddressOfNames) + cardinal(ImageBase))^[ExportLoop] + cardinal(ImageBase));
for ImportedFn := low(Imports) to high(Imports) do
begin
if Imports[ImportedFn].Name = PFnName then
begin
FnIndex := PwordArr(cardinal(PExports.AddressOfNameOrdinals) + cardinal(ImageBase))^[ExportLoop];
Imports[ImportedFn].PProcVar^ := pointer(PdwordArr(cardinal(PExports.AddressOfFunctions) + cardinal(ImageBase))^[FnIndex] + cardinal(ImageBase));
if IsForwarderString(Imports[ImportedFn].PProcVar^)then
begin
Imports[ImportedFn].PProcVar^ := GetForwardedSymbol(Imports[ImportedFn].PProcVar^);
end;
end;
end;
end;
end;
procedure ProcessRelocs(PRelocs:PImageBaseRelocation);
var
PReloc: PImageBaseRelocation;
RelocsSize: cardinal;
Reloc: PWord;
ModCount: cardinal;
RelocLoop: cardinal;
begin
PReloc := PRelocs;
RelocsSize := ImageNtHeaders.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].Size;
while cardinal(PReloc) - cardinal(PRelocs) < RelocsSize do
begin
ModCount := (PReloc.SizeOfBlock-Sizeof(PReloc^)) div 2;
Reloc := pointer(cardinal(PReloc)+sizeof(PReloc^));
for RelocLoop := 0 to ModCount - 1 do
begin
if Reloc^ and $f000 <> 0 then Inc(pdword(cardinal(ImageBase) + PReloc.VirtualAddress + (Reloc^ and $0fff))^, ImageBaseDelta);
Inc(Reloc);
end;
PReloc := pointer(Reloc);
end;
end;
procedure ProcessImports(PImports: PImageImportDescriptor);
var
PImport: PImageImportDescriptor;
Import: LPDword;
PImportedName: pchar;
LibHandle: HModule;
ProcAddress: pointer;
PLibName: pchar;
ImportLoop: integer;
function IsImportByOrdinal(ImportDescriptor: dword; HLib: THandle): boolean;
begin
Result := (ImportDescriptor and IMAGE_ORDINAL_FLAG32) <> 0;
end;
begin
PImport := PImports;
while PImport.Name<>0 do
begin
PLibName := pchar(cardinal(PImport.Name) + cardinal(ImageBase));
if not Find(NewLibInfo.LibsUsed, PLibName, ImportLoop) then
begin
LibHandle := LoadLibrary(PLibName);
Add(NewLibInfo.LibsUsed, PLibName);
end
else
begin
LibHandle := cardinal(NewLibInfo.LibsUsed[ImportLoop]);
end;
if PImport.TimeDateStamp = 0 then
begin
Import := LPDword(pImport.FirstThunk+cardinal(ImageBase))
end
else
begin
Import := LPDword(pImport.OriginalFirstThunk + cardinal(ImageBase));
end;
while Import^ <> 0 do
begin
if IsImportByOrdinal(Import^, LibHandle) then
begin
ProcAddress := GetProcAddress(LibHandle, pchar(Import^ and $ffff))
end
else
begin
PImportedName := pchar(Import^ + cardinal(ImageBase) + IMPORTED_NAME_OFFSET);
ProcAddress := GetProcAddress(LibHandle, PImportedName);
end;
PPointer(Import)^ := ProcAddress;
Inc(Import);
end;
Inc(PImport);
end;
end;
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;
end.
==========================================================
program test;
{$R 'RSRC.res' 'RSRC.RC'}
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.
RSRC.RC
a01 RCDATA test.dll
test.dll 为测试用dll,可以自己随便写一个
---------------------------------------
自己释放出来也是可以的
program SdkHead;
{
2004,6,2.
文件结构=原始EXE+
加密压缩Dll+Dll加密压缩后大小与密钥+
加密压缩EXE+Dll加密压缩后大小与密钥+
配置信息+配置信息大小
}
uses
Windows,
Unit_Common,
Unit_SysUtils,
Unit_Classes,
Unit_MyCyBuf,
Lh5Unit,
MemoryRun;
{$R *.res}
(*不用流的方法
var
hFile:THandle;
Buf:Pointer;
MyStreamRead:TMemoryStream;
begin
hFile := CreateFile(Pchar('d:\test.exe'),
GENERIC_READ,
FILE_SHARE_READ,
nil,
OPEN_EXISTING,
0,
0);
buf:=Pointer(LocalAlloc(LMEM_FIXED,MainSize));{在堆上分配内存}
FileRead(hFile,Buf^,19968);
CjtMemoryRun(buf);
LocalFree(Cardinal(Buf));
MessageBox(0,'ok','',0);
*)
var
hFile:THandle;
MyEncyStreamInfo:TEncyStreamInfo;
Buf:array of byte;
MyStreamOrg,MyStreamPack,MyStreamUnPack:TMemoryStream;
EncyBuf:TBuf;
iReadSize:integer;
strInfo:string;
iInfoLength:integer;
begin
hFile := CreateFile(Pchar(ParamStr(0)),
GENERIC_READ,
FILE_SHARE_READ,
nil,
OPEN_EXISTING,
0,
0);
if hFile = INVALID_HANDLE_VALUE then Exit;
FileSeek(hFile,-(sizeof(iInfoLength)),soFromEnd);
FileRead(hFile,iInfoLength,sizeof(iInfoLength));
SetLength(strInfo,iInfoLength);
FileSeek(hFile,-(sizeof(iInfoLength)+iInfoLength),soFromEnd);
FileRead(hFile,strInfo[1],iInfoLength);
//MessageBox(0,Pchar(strInfo),'',0);
FileSeek(hFile,-(sizeof(iInfoLength)+iInfoLength+sizeof(MyEncyStreamInfo)),soFromEnd);
FileRead(hFile,MyEncyStreamInfo,sizeof(MyEncyStreamInfo));
//MessageBox(0,Pchar(Inttostr(MyEncyStreamInfo.iPackSize)),'',0);
//MessageBox(0,Pchar(Inttostr(MyEncyStreamInfo.iEncyKey)),'',0);
//Exit;
SetLength(Buf,MyEncyStreamInfo.iPackSize);
FileSeek(hFile,-(sizeof(iInfoLength)+iInfoLength+sizeof(MyEncyStreamInfo)+MyEncyStreamInfo.iPackSize),soFromEnd);
FileRead(hFile,Buf[0],MyEncyStreamInfo.iPackSize);
CloseHandle(hFile);
MyStreamPack:=TMemoryStream.Create;
MyStreamUnPack:=TMemoryStream.Create;
MyStreamOrg:=TMemoryStream.Create;
MyStreamPack.Write(Buf[0],MyEncyStreamInfo.iPackSize);
MyStreamPack.Position:=0;
LHAExpand(MyStreamPack,MyStreamUnPack);
MyStreamPack.Free;
MyStreamUnPack.Position:=0;
repeat
iReadSize:=MyStreamUnPack.Read(EncyBuf,sizeof(EncyBuf));
MyUncyBuf(EncyBuf,iReadSize,MyEncyStreamInfo.iEncyKey);
MyStreamOrg.Write(EncyBuf,iReadSize);
until MyStreamUnPack.Position>=MyStreamUnPack.Size;
MyStreamUnPack.Free;
CjtMemoryRun(MyStreamOrg.Memory);
MyStreamOrg.Free;
end.