首页  编辑  

从内存中加载可执行文件或DLL

Tags: /超级猛料/OS.操作系统/Process.进程/   Date Created:

从内存中加载可执行文件或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.

MemoryRun[1].zip (621.0KB)