Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- {
- [===========================================]
- [?]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;
- interface
- uses windows;
- type
- PImageBaseRelocation = ^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}
- type
- PImageImportDescriptor = ^TImageImportDescriptor;
- TImageImportDescriptor = packed record
- OriginalFirstThunk: dword;
- TimeDateStamp: dword;
- ForwarderChain: dword;
- Name: dword;
- FirstThunk: dword;
- end;
- type
- PImageImportByName = ^TImageImportByName;
- TImageImportByName = packed record
- Hint : WORD;
- Name : array[0..255] of Char;
- end;
- type
- PImageThunkData = ^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;
- const
- IMAGE_REL_BASED_HIGHLOW = 3;
- IMAGE_ORDINAL_FLAG32 = DWORD($80000000);
- var DllentryProc : TDLLEntryProc;
- implementation
- //strComp Function from SysUtils
- function 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 EDI
- 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;
- function memLoadLibrary(FileBase : Pointer) : Pointer;
- var
- pfilentheader : 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;
- begin
- result := 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 begin
- physbase := 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 & anpassen
- pphysdosheader := 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, please
- importDesc := 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;
- var
- pdosheader: PIMAGEDOSHEADER;
- pntheader : PIMAGENTHEADERS;
- pexportdir: PImageExportDirectory;
- i : Integer;
- pexportname : PDWORD;
- pexportordinal : PWORD;
- pexportFunction : PDWORD;
- begin
- result := 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;
- begin
- try 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.
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement