We don't display ads so we rely on your Bitcoin donations to 1KWEk9QaiJb2NwP5YFmR24LyUBa4JyuKqZ
Post date: Aug 25, 2010 1:48:21 PM
{[===========================================][?]uDllFromMem - Loading a DLL from Memory[?][v] Version 1.0 [v][c] Hamtaro aka CorVu5 [c][@] hamtaro.6x.to OR corvu5.6x.to [@][================Description================][With this Code, you can load a DLL in your ][application directly from Memory, the file ][doesnt have to be present on your Harddrive][===================Note====================][ This example doesnt work with Bound ][ Import Tables at this time ][==================thx to===================][ CDW, Cryptocrack ][ & Joachim Bauch for his ][ GetSectionProtection function ][===========================================][ there must be 50 ways to learn to hover ][===========================================]}unit uDllfromMem;interfaceuses windows;typePImageBaseRelocation = ^TImageBaseRelocation; _IMAGE_BASE_RELOCATION = packed record VirtualAddress: DWORD; SizeOfBlock: DWORD;end;{$EXTERNALSYM _IMAGE_BASE_RELOCATION} TImageBaseRelocation = _IMAGE_BASE_RELOCATION; IMAGE_BASE_RELOCATION = _IMAGE_BASE_RELOCATION;{$EXTERNALSYM IMAGE_BASE_RELOCATION}typePImageImportDescriptor = ^TImageImportDescriptor; TImageImportDescriptor = packed record OriginalFirstThunk: dword; TimeDateStamp: dword; ForwarderChain: dword; Name: dword; FirstThunk: dword;end;typePImageImportByName = ^TImageImportByName; TImageImportByName = packed record Hint : WORD; Name : array[0..255] of Char;end;typePImageThunkData = ^TImageThunkData; TImageThunkData = packed record case integer of 0 : (ForwarderString: PBYTE); 1 : (FunctionPtr : PDWORD); 2 : (Ordinal : DWORD); 3 : (AddressOfData : PImageImportByName);end;type TDllEntryProc = function(hinstdll: THandle; fdwReason: DWORD; lpReserved: Pointer): BOOL; stdcall;function memLoadLibrary(FileBase : Pointer) : Pointer;function memGetProcAddress(Physbase : Pointer; NameOfFunction : String) : Pointer;function memFreeLibrary(physbase : Pointer) : Boolean;constIMAGE_REL_BASED_HIGHLOW = 3;IMAGE_ORDINAL_FLAG32 = DWORD($80000000);var DllentryProc : TDLLEntryProc;implementation//strComp Function from SysUtilsfunction StrComp(const Str1, Str2: PChar): Integer; assembler;asm PUSH EDI PUSH ESI MOV EDI,EDX MOV ESI,EAX MOV ECX,0FFFFFFFFH XOR EAX,EAX REPNE SCASB NOT ECX MOV EDI,EDX XOR EDX,EDX REPE CMPSB MOV AL,[ESI-1] MOV DL,[EDI-1] SUB EAX,EDX POP ESI POP EDIend;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;function memLoadLibrary(FileBase : Pointer) : Pointer;varpfilentheader : PIMAGENTHEADERS;pfiledosheader: PIMAGEDOSHEADER;pphysntheader : PIMAGENTHEADERS;pphysdosheader: PIMAGEDOSHEADER;physbase : Pointer;pphyssectionheader : PIMAGESECTIONHEADER;i : Integer;importsDir : PImageDataDirectory;importsBase: Pointer;importDesc : PImageImportDescriptor;importThunk: PImageThunkData;dll_handle : Cardinal;importbyname : pimageimportbyname;relocbase : Pointer;relocdata : PIMAGeBaseRElocation;relocitem : PWORD;reloccount : Integer;dllproc : TDLLEntryProc;beginresult := 0;pfiledosheader := filebase;pfilentheader := Pointer(Cardinal(filebase) + pfiledosheader^._lfanew);/////////////////////////////////////allozieren/physbase := VirtualAlloc(Pointer(pfilentheader^.OptionalHeader.ImageBase),pfilentheader^.OptionalHeader.SizeOfImage,MEM_RESERVE,PAGE_READWRITE);if Cardinal(physbase) = 0 Then beginphysbase := VirtualAlloc(0,pfilentheader^.OptionalHeader.SizeOfImage,MEM_RESERVE Or Mem_COMMIT,PAGE_READWRITE);end;//////////////////////////////////////////header kopieren/CopyMemory(physbase,filebase,pfilentheader^.OptionalHeader.SizeOfHeaders);//header im memory finden & anpassenpphysdosheader := physbase;pphysntheader := Pointer(Cardinal(physbase) + pphysdosheader^._lfanew);pphysntheader^.OptionalHeader.ImageBase := Cardinal(physbase);////////////////////////////////////////////sections kopieren/pphyssectionheader := Pointer(Cardinal(pphysntheader) + SizeOf(TIMAGENTHEADERS));for i := 0 To (pphysntheader^.FileHeader.NumberOfSections - 1) do begin if pphyssectionheader^.SizeOfRawData = 0 Then begin //keine raw data ZeroMemory(Pointer(Cardinal(physbase) + pphyssectionheader^.VirtualAddress),pphyssectionheader^.Misc.VirtualSize); end else begin //raw data vorhanden CopyMemory(Pointer(Cardinal(physbase) + pphyssectionheader^.VirtualAddress),Pointer(Cardinal(filebase) + pphyssectionheader^.PointerToRawData),pphyssectionheader^.SizeOfRawData); end; pphyssectionheader^.Misc.PhysicalAddress := Cardinal(physbase) + pphyssectionheader^.VirtualAddress; //next one please pphyssectionheader := Pointer(Cardinal(pphyssectionheader) + SizeOf(TIMAGESECTIONHEADER));end;///////////////////////////////////imports/importsBase := Pointer(Cardinal(physbase) + pphysntheader^.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress);importDesc := importsBase;while (importDesc.Name) <> 0 Do begin dll_handle := LoadLibrary(pchar(Cardinal(physbase) + importdesc.Name)); importDesc.ForwarderChain := dll_handle; importThunk := Pointer(Cardinal(physbase) + importDesc.FirstThunk); while importThunk.Ordinal <> 0 Do begin importbyname := Pointer(Cardinal(physbase) + importThunk.Ordinal); //Später noch überprüfen ob OriginalFirstThunk = 0 if (importThunk.Ordinal and IMAGE_ORDINAL_FLAG32) <> 0 Then begin //ordinal importThunk.FunctionPtr := GetProcaddress(dll_handle,pchar(importThunk.Ordinal and $ffff)) end else begin //normal importThunk.FunctionPtr := GetProcAddress(dll_handle,importByname.name); end; //next one, please importThunk := Pointer(Cardinal(importThunk) + SizeOf(TIMAGETHUNKDATA)); end;//next one, pleaseimportDesc := Pointer(Cardinal(importDesc) + sizeOf(TIMAGEIMPORTDESCRIPTOR));end;//////////////////////////////////relocs/relocbase := Pointer(Cardinal(physbase) + pphysntheader.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress);relocData := RElocbase;while (Cardinal(relocdata) - Cardinal(relocbase)) < pphysntheader.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].Size do begin reloccount := trunc((relocdata.SizeOfBlock - 8) / 2); relocitem := Pointer(Cardinal(relocdata) + 8); For i := 0 To (reloccount - 1) do begin if (relocitem^ shr 12) = IMAGE_REL_BASED_HIGHLOW Then begin Inc(PDWord(Cardinal(physbase) + relocdata.VirtualAddress + (relocitem^ and $FFF))^,(Cardinal(physbase) - pfilentheader.OptionalHeader.ImageBase)); end; relocitem := Pointer(Cardinal(relocitem) + SizeOf(WORD)); end; //next one please relocdata := Pointer(Cardinal(relocdata) + relocdata.SizeOfBlock);end;/////////////////////////////////////////Section protection & so/pphyssectionheader := Pointer(Cardinal(pphysntheader) + SizeOf(TIMAGENTHEADERS));For i := 0 To (pphysntheader^.FileHeader.NumberOfSections - 1) do begin VirtualProtect(Pointer(Cardinal(physbase) + pphyssectionheader^.VirtualAddress),pphyssectionheader^.Misc.VirtualSize,GetSectionProtection(pphyssectionheader.Characteristics),nil); pphyssectionheader := Pointer(Cardinal(pphyssectionheader) + SizeOf(TIMAGESECTIONHEADER));end;////////////////////////////////////////////////Dll entry proc/dllEntryproc := Pointer(Cardinal(physbase) + pphysntheader.OptionalHeader.AddressOfEntryPoint);dllEntryproc(cardinal(physbase),DLL_PROCESS_ATTACH,nil);result := physbase;end;function memGetProcAddress(Physbase : Pointer; NameOfFunction : String) : Pointer;varpdosheader: PIMAGEDOSHEADER;pntheader : PIMAGENTHEADERS;pexportdir: PImageExportDirectory;i : Integer;pexportname : PDWORD;pexportordinal : PWORD;pexportFunction : PDWORD;beginresult := 0;pdosheader := physbase;pntheader := Pointer(Cardinal(physbase) + pdosheader._lfanew);pexportdir := Pointer(Cardinal(physbase) + pntheader.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress);if pexportdir.NumberOfFunctions Or pexportdir.NumberOfNames = 0 Then exit;pexportName := Pointer(Cardinal(physbase) + Cardinal(pexportDir.AddressOfNames));pexportordinal := Pointer(Cardinal(physbase) + Cardinal(pexportDir.AddressOfNameOrdinals));pexportFunction:= Pointer(Cardinal(physbase) + Cardinal(pexportDir.AddressOfFunctions));For i := 0 To (pexportdir.NumberOfNames - 1) Do begin if StrComp(pchar(Pointer(Cardinal(physbase) + pexportName^)),pchar(NameOfFunction)) = 0 Then begin result := pchar(Pointer(Cardinal(physbase) + pexportFunction^)); break; end; //next one, please Inc(pexportFunction); Inc(pexportName); Inc(pexportOrdinal);end;end;function memFreeLibrary(physbase : Pointer) : Boolean;begintry begin //Keine Ahnung ob die DLL ihre Imports wieder "Free't" wenn man DLL_PROCESS_DETACH aufruft result := true; dllEntryProc(Cardinal(physbase),DLL_PROCESS_DETACH,0); VirtualFree(physbase,0,MEM_RELEASE);end except result := false;end;end;end.