Advertisement
Guest User

Hamtaro

a guest
May 15th, 2008
671
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Delphi 10.57 KB | None | 0 0
  1. {
  2. [===========================================]
  3. [?]uDllFromMem - Loading a DLL from Memory[?]
  4. [v]              Version 1.0              [v]
  5. [c]          Hamtaro aka CorVu5           [c]
  6. [@]     hamtaro.6x.to OR corvu5.6x.to     [@]
  7. [================Description================]
  8. [With this Code, you can load a DLL in your ]
  9. [application directly from Memory, the file ]
  10. [doesnt have to be present on your Harddrive]
  11. [===================Note====================]
  12. [   This example doesnt work with Bound     ]
  13. [       Import Tables at this time          ]
  14. [==================thx to===================]
  15. [              CDW, Cryptocrack             ]
  16. [           & Joachim Bauch for his         ]
  17. [      GetSectionProtection function        ]
  18. [===========================================]
  19. [  there must be 50 ways to learn to hover  ]
  20. [===========================================]
  21. }
  22. unit uDllfromMem;
  23.  
  24. interface
  25. uses windows;
  26. type
  27. PImageBaseRelocation = ^TImageBaseRelocation;
  28.   _IMAGE_BASE_RELOCATION = packed record
  29.     VirtualAddress: DWORD;
  30.     SizeOfBlock: DWORD;
  31. end;
  32. {$EXTERNALSYM _IMAGE_BASE_RELOCATION}
  33.   TImageBaseRelocation = _IMAGE_BASE_RELOCATION;
  34.   IMAGE_BASE_RELOCATION = _IMAGE_BASE_RELOCATION;
  35. {$EXTERNALSYM IMAGE_BASE_RELOCATION}
  36.  
  37.  
  38.  
  39.  
  40.  
  41. type
  42. PImageImportDescriptor = ^TImageImportDescriptor;
  43.   TImageImportDescriptor = packed record
  44.     OriginalFirstThunk: dword;
  45.     TimeDateStamp: dword;
  46.     ForwarderChain: dword;
  47.     Name: dword;
  48.     FirstThunk: dword;
  49. end;
  50.  
  51. type
  52. PImageImportByName = ^TImageImportByName;
  53.   TImageImportByName = packed record
  54.     Hint : WORD;
  55.     Name : array[0..255] of Char;
  56. end;
  57.  
  58. type
  59. PImageThunkData = ^TImageThunkData;
  60.   TImageThunkData = packed record
  61.     case integer of
  62.       0 : (ForwarderString: PBYTE);
  63.       1 : (FunctionPtr    : PDWORD);
  64.       2 : (Ordinal        : DWORD);
  65.       3 : (AddressOfData  : PImageImportByName);
  66. end;
  67.  
  68. type
  69.   TDllEntryProc = function(hinstdll: THandle; fdwReason: DWORD; lpReserved: Pointer): BOOL; stdcall;
  70.  
  71. function memLoadLibrary(FileBase : Pointer) : Pointer;
  72. function memGetProcAddress(Physbase : Pointer; NameOfFunction : String) : Pointer;
  73. function memFreeLibrary(physbase : Pointer) : Boolean;
  74. const
  75. IMAGE_REL_BASED_HIGHLOW = 3;
  76. IMAGE_ORDINAL_FLAG32 = DWORD($80000000);
  77. var DllentryProc : TDLLEntryProc;
  78. implementation
  79. //strComp Function from SysUtils
  80. function StrComp(const Str1, Str2: PChar): Integer; assembler;
  81. asm
  82.         PUSH    EDI
  83.         PUSH    ESI
  84.         MOV     EDI,EDX
  85.         MOV     ESI,EAX
  86.         MOV     ECX,0FFFFFFFFH
  87.         XOR     EAX,EAX
  88.         REPNE   SCASB
  89.         NOT     ECX
  90.         MOV     EDI,EDX
  91.         XOR     EDX,EDX
  92.         REPE    CMPSB
  93.         MOV     AL,[ESI-1]
  94.         MOV     DL,[EDI-1]
  95.         SUB     EAX,EDX
  96.         POP     ESI
  97.         POP     EDI
  98. end;
  99.  
  100. function GetSectionProtection(ImageScn: cardinal): cardinal;
  101.   begin
  102.     Result := 0;
  103.     if (ImageScn and IMAGE_SCN_MEM_NOT_CACHED) <> 0 then
  104.     begin
  105.     Result := Result or PAGE_NOCACHE;
  106.     end;
  107.     if (ImageScn and IMAGE_SCN_MEM_EXECUTE) <> 0 then
  108.     begin
  109.       if (ImageScn and IMAGE_SCN_MEM_READ)<> 0 then
  110.       begin
  111.         if (ImageScn and IMAGE_SCN_MEM_WRITE)<> 0 then
  112.         begin
  113.           Result := Result or PAGE_EXECUTE_READWRITE
  114.         end
  115.         else
  116.         begin
  117.           Result := Result or PAGE_EXECUTE_READ
  118.         end;
  119.       end
  120.       else if (ImageScn and IMAGE_SCN_MEM_WRITE) <> 0 then
  121.       begin
  122.         Result := Result or PAGE_EXECUTE_WRITECOPY
  123.       end
  124.       else
  125.       begin
  126.         Result := Result or PAGE_EXECUTE
  127.       end;
  128.     end
  129.     else if (ImageScn and IMAGE_SCN_MEM_READ)<> 0 then
  130.     begin
  131.       if (ImageScn and IMAGE_SCN_MEM_WRITE) <> 0 then
  132.       begin
  133.         Result := Result or PAGE_READWRITE
  134.       end
  135.       else
  136.       begin
  137.         Result := Result or PAGE_READONLY
  138.       end
  139.     end
  140.     else if (ImageScn and IMAGE_SCN_MEM_WRITE) <> 0 then
  141.     begin
  142.       Result := Result or PAGE_WRITECOPY
  143.     end
  144.     else
  145.     begin
  146.       Result := Result or PAGE_NOACCESS;
  147.     end;
  148.   end;
  149. function memLoadLibrary(FileBase : Pointer) : Pointer;
  150. var
  151. pfilentheader : PIMAGENTHEADERS;
  152. pfiledosheader: PIMAGEDOSHEADER;
  153. pphysntheader : PIMAGENTHEADERS;
  154. pphysdosheader: PIMAGEDOSHEADER;
  155. physbase  : Pointer;
  156. pphyssectionheader : PIMAGESECTIONHEADER;
  157. i : Integer;
  158. importsDir : PImageDataDirectory;
  159. importsBase: Pointer;
  160. importDesc :  PImageImportDescriptor;
  161. importThunk: PImageThunkData;
  162. dll_handle : Cardinal;
  163. importbyname : pimageimportbyname;
  164. relocbase : Pointer;
  165. relocdata : PIMAGeBaseRElocation;
  166. relocitem : PWORD;
  167. reloccount : Integer;
  168. dllproc : TDLLEntryProc;
  169. begin
  170. result := 0;
  171.  
  172. pfiledosheader := filebase;
  173. pfilentheader  := Pointer(Cardinal(filebase) + pfiledosheader^._lfanew);
  174.  
  175.  
  176. ////////////////////////
  177. /////////////allozieren/
  178. physbase := VirtualAlloc(Pointer(pfilentheader^.OptionalHeader.ImageBase),pfilentheader^.OptionalHeader.SizeOfImage,MEM_RESERVE,PAGE_READWRITE);
  179. if Cardinal(physbase) = 0 Then begin
  180. physbase := VirtualAlloc(0,pfilentheader^.OptionalHeader.SizeOfImage,MEM_RESERVE Or Mem_COMMIT,PAGE_READWRITE);
  181. end;
  182.  
  183.  
  184. /////////////////////////////
  185. /////////////header kopieren/
  186. CopyMemory(physbase,filebase,pfilentheader^.OptionalHeader.SizeOfHeaders);
  187.  
  188. //header im memory finden & anpassen
  189. pphysdosheader := physbase;
  190. pphysntheader := Pointer(Cardinal(physbase) + pphysdosheader^._lfanew);
  191. pphysntheader^.OptionalHeader.ImageBase := Cardinal(physbase);
  192.  
  193.  
  194. ///////////////////////////////
  195. /////////////sections kopieren/
  196. pphyssectionheader := Pointer(Cardinal(pphysntheader) + SizeOf(TIMAGENTHEADERS));
  197. for i := 0 To (pphysntheader^.FileHeader.NumberOfSections - 1) do begin
  198.   if pphyssectionheader^.SizeOfRawData = 0 Then begin
  199.     //keine raw data
  200.     ZeroMemory(Pointer(Cardinal(physbase) + pphyssectionheader^.VirtualAddress),pphyssectionheader^.Misc.VirtualSize);
  201.   end else begin
  202.     //raw data vorhanden
  203.     CopyMemory(Pointer(Cardinal(physbase) + pphyssectionheader^.VirtualAddress),Pointer(Cardinal(filebase) + pphyssectionheader^.PointerToRawData),pphyssectionheader^.SizeOfRawData);
  204.   end;
  205.   pphyssectionheader^.Misc.PhysicalAddress :=  Cardinal(physbase) + pphyssectionheader^.VirtualAddress;
  206.  
  207.   //next one please
  208.   pphyssectionheader :=  Pointer(Cardinal(pphyssectionheader) + SizeOf(TIMAGESECTIONHEADER));
  209. end;
  210.  
  211.  
  212. //////////////////////
  213. /////////////imports/
  214. importsBase := Pointer(Cardinal(physbase) + pphysntheader^.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress);
  215. importDesc := importsBase;
  216. while (importDesc.Name) <> 0 Do begin
  217.   dll_handle := LoadLibrary(pchar(Cardinal(physbase) + importdesc.Name));
  218.   importDesc.ForwarderChain := dll_handle;
  219.   importThunk := Pointer(Cardinal(physbase) +  importDesc.FirstThunk);
  220.   while importThunk.Ordinal <> 0 Do begin
  221.     importbyname := Pointer(Cardinal(physbase) + importThunk.Ordinal);
  222.     //Später noch überprüfen ob OriginalFirstThunk = 0
  223.     if (importThunk.Ordinal and IMAGE_ORDINAL_FLAG32) <> 0 Then
  224.     begin //ordinal
  225.       importThunk.FunctionPtr := GetProcaddress(dll_handle,pchar(importThunk.Ordinal and $ffff))
  226.     end else begin //normal
  227.       importThunk.FunctionPtr := GetProcAddress(dll_handle,importByname.name);
  228.     end;
  229.   //next one, please
  230.   importThunk := Pointer(Cardinal(importThunk) + SizeOf(TIMAGETHUNKDATA));
  231.   end;
  232. //next one, please
  233. importDesc := Pointer(Cardinal(importDesc) + sizeOf(TIMAGEIMPORTDESCRIPTOR));
  234. end;
  235.  
  236.  
  237. /////////////////////
  238. /////////////relocs/
  239. relocbase := Pointer(Cardinal(physbase) + pphysntheader.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress);
  240. relocData := RElocbase;
  241. while (Cardinal(relocdata) -  Cardinal(relocbase)) < pphysntheader.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].Size do begin
  242.   reloccount := trunc((relocdata.SizeOfBlock - 8) / 2);
  243.   relocitem  := Pointer(Cardinal(relocdata) + 8);
  244.   For i := 0 To (reloccount - 1) do begin
  245.     if (relocitem^ shr 12) = IMAGE_REL_BASED_HIGHLOW Then begin
  246.       Inc(PDWord(Cardinal(physbase) + relocdata.VirtualAddress + (relocitem^ and $FFF))^,(Cardinal(physbase) - pfilentheader.OptionalHeader.ImageBase));
  247.     end;
  248.     relocitem := Pointer(Cardinal(relocitem) + SizeOf(WORD));
  249.   end;
  250.  
  251.   //next one please
  252.   relocdata := Pointer(Cardinal(relocdata) + relocdata.SizeOfBlock);
  253. end;
  254.  
  255.  
  256. /////////////////////////////////
  257. ////////Section protection & so/
  258. pphyssectionheader := Pointer(Cardinal(pphysntheader) + SizeOf(TIMAGENTHEADERS));
  259. For i := 0 To (pphysntheader^.FileHeader.NumberOfSections - 1) do begin
  260.   VirtualProtect(Pointer(Cardinal(physbase) + pphyssectionheader^.VirtualAddress),pphyssectionheader^.Misc.VirtualSize,GetSectionProtection(pphyssectionheader.Characteristics),nil);
  261.   pphyssectionheader := Pointer(Cardinal(pphyssectionheader) + SizeOf(TIMAGESECTIONHEADER));
  262. end;
  263.  
  264.  
  265. ////////////////////////////////
  266. ////////////////Dll entry proc/
  267. dllEntryproc := Pointer(Cardinal(physbase) + pphysntheader.OptionalHeader.AddressOfEntryPoint);
  268. dllEntryproc(cardinal(physbase),DLL_PROCESS_ATTACH,nil);
  269.  
  270. result := physbase;
  271. end;
  272.  
  273. function memGetProcAddress(Physbase : Pointer; NameOfFunction : String) : Pointer;
  274. var
  275. pdosheader: PIMAGEDOSHEADER;
  276. pntheader : PIMAGENTHEADERS;
  277. pexportdir: PImageExportDirectory;
  278. i : Integer;
  279. pexportname : PDWORD;
  280. pexportordinal : PWORD;
  281. pexportFunction : PDWORD;
  282. begin
  283. result := 0;
  284. pdosheader := physbase;
  285. pntheader := Pointer(Cardinal(physbase) + pdosheader._lfanew);
  286. pexportdir := Pointer(Cardinal(physbase) + pntheader.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress);
  287. if pexportdir.NumberOfFunctions Or pexportdir.NumberOfNames  = 0 Then exit;
  288. pexportName    := Pointer(Cardinal(physbase) + Cardinal(pexportDir.AddressOfNames));
  289. pexportordinal := Pointer(Cardinal(physbase) + Cardinal(pexportDir.AddressOfNameOrdinals));
  290. pexportFunction:= Pointer(Cardinal(physbase) + Cardinal(pexportDir.AddressOfFunctions));
  291.  
  292. For i := 0 To (pexportdir.NumberOfNames - 1) Do begin
  293.   if StrComp(pchar(Pointer(Cardinal(physbase) + pexportName^)),pchar(NameOfFunction)) = 0 Then begin
  294.     result := pchar(Pointer(Cardinal(physbase) + pexportFunction^));
  295.     break;
  296.   end;
  297.  
  298.   //next one, please
  299.   Inc(pexportFunction);
  300.   Inc(pexportName);
  301.   Inc(pexportOrdinal);
  302. end;
  303. end;
  304. function memFreeLibrary(physbase : Pointer) : Boolean;
  305. begin
  306. try begin
  307.   //Keine Ahnung ob die DLL ihre Imports wieder "Free't" wenn man DLL_PROCESS_DETACH aufruft
  308.   result := true;
  309.   dllEntryProc(Cardinal(physbase),DLL_PROCESS_DETACH,0);
  310.   VirtualFree(physbase,0,MEM_RELEASE);
  311. end except
  312.   result := false;
  313. end;
  314. end;
  315. end.
  316.  
  317.  
  318.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement