吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 243|回复: 1
收起左侧

[求助] delphi 远程注入 GetProcAddress 一直获取不到

[复制链接]
千影 发表于 2025-3-28 08:41
25吾爱币
以下下为 dll,已经用 exe 注入到第三方进程,第三方进程也是我自己做的,上边就是一个按钮  输出  memo1.lines.add(datetimetostr(now));
;library TimeHookDLL;

uses
  Windows, SysUtils, DDetours,inifiles;

type
  TGetLocalTime = procedure(var lpSystemTime: TSystemTime); stdcall;

var
  TrampolineGetLocalTime: TGetLocalTime = nil;
procedure WriteLog(const Msg: string);
var
  LogFile: TextFile;
begin
  AssignFile(LogFile, 'D:\1.txt');
  try
    if FileExists('D:\1.txt') then
      Append(LogFile)
    else
      Rewrite(LogFile);
    Writeln(LogFile, FormatDateTime('yyyy-mm-dd hh:nn:ss.zzz', Now) + ' - ' + Msg);
    CloseFile(LogFile);
  except
    // 忽略文件写入错误
  end;
end;

function readiniint(path1111,lei1,xiang1:string):Integer ;
var
inifile:TIniFile;
begin

  inifile:=nil;
              try
              begin
              inifile:=Tinifile.Create(path1111);
              result:=inifile.ReadInteger(lei1,xiang1,0);
              End;
              except
              Result:=0;
              end;
               inifile.Free;

end;

procedure HookedGetLocalTime(var lpSystemTime: TSystemTime); stdcall;


begin
  WriteLog('DLL: HookedGetLocalTime被调用');

  if Assigned(TrampolineGetLocalTime) then
    TrampolineGetLocalTime(lpSystemTime);



if readiniint('d:\date.ini','config','change' )=1 then
begin
lpSystemTime.wYear:=readiniint('d:\date.ini','config','Year' );
lpSystemTime.wMonth:=readiniint('d:\date.ini','config','Month' );
lpSystemTime.wDay:=readiniint('d:\date.ini','config','Day' );
lpSystemTime.wHour:=readiniint('d:\date.ini','config','Hour' );
lpSystemTime.wMinute:=readiniint('d:\date.ini','config','Minute' );
lpSystemTime.wSecond:=readiniint('d:\date.ini','config','Second' );


end;
  // 修改时间
// lpSystemTime.wYear := 2023;
// lpSystemTime.wMonth := 1;
// lpSystemTime.wDay := 1;

   // Result := TrampolineGetLocalTime(lpSystemTime);



  WriteLog(PChar('DLL: 修改后的时间: ' +
    IntToStr(lpSystemTime.wYear) + '/' +
    IntToStr(lpSystemTime.wMonth) + '/' +
    IntToStr(lpSystemTime.wDay)));
end;




procedure Runtest; stdcall;
begin
  WriteLog('DLL: runtest');

end;

procedure InstallHook; stdcall;
begin
  WriteLog('DLL: 正在安装Hook');
  try
    @TrampolineGetLocalTime := InterceptCreate(kernel32, 'GetLocalTime', @HookedGetLocalTime);
    if Assigned(TrampolineGetLocalTime) then
      WriteLog('DLL: Hook安装成功,原始函数地址: ' + IntToHex(NativeInt(@TrampolineGetLocalTime), 8))
    else
      WriteLog('DLL: Hook安装失败 - InterceptCreate返回nil');
  except
    on E: Exception do
      WriteLog('DLL: Hook安装异常: ' + E.Message);
  end;
end;

procedure RemoveHook; stdcall;
begin
  WriteLog('DLL: 正在移除Hook');
  if Assigned(TrampolineGetLocalTime) then
  begin
    InterceptRemove(@TrampolineGetLocalTime);
    TrampolineGetLocalTime := nil;
    WriteLog('DLL: Hook已移除');
  end;
end;


// DLL 入口(初始化)
procedure DLLMain(Reason: DWORD);
begin
  case Reason of
    DLL_PROCESS_ATTACH:
     begin

        WriteLog('DLL 已开始运行: ' + IntToStr(GetCurrentProcessId));  end;
    DLL_PROCESS_DETACH:
     begin
         WriteLog('DLL 已卸载');     end;
  end;
end;

exports
InstallHook name 'InstallHook',
  RemoveHook name 'RemoveHook',
  Runtest     name 'Runtest';
begin
  WriteLog('DLL已加载,正在自动安装Hook');
  DLLProc := @DLLMain;
  DLLMain(DLL_PROCESS_ATTACH);
  InstallHook;
end.
exe中的注入 代码 function InjectDll(pid: Cardinal; Dll: string): Cardinal;
var
  hProc: Cardinal;
  wDllPath: PwideChar;
  pRemote: Pointer;
  cbSize: Cardinal;
  TempVar: Cardinal;
  BytesWritten: SIZE_T; // 改为 SIZE_T 类型
begin
  Result := 0;
  if pid = 0 then
    Exit;
  EnabledDebugPrivilege(true);
  cbSize := Length(Dll) * 2 + 21;
  GetMem(wDllPath, cbSize);
  StringToWideChar(Dll, wDllPath, cbSize);
  hProc := OpenProcess(PROCESS_ALL_ACCESS, False, pid);
  try
    pRemote := VirtualAllocEx(hProc, nil, cbSize, MEM_COMMIT, PAGE_READWRITE);

    // WriteProcessMemory(hProcess, pDLLPath, PChar(DLLPath), Length(DLLPath) + 1, BytesWritten)
    if WriteProcessMemory(hProc, pRemote, wDllPath, cbSize, BytesWritten) then
    begin
      TempVar := 0;
      Result := CreateRemoteThread(hProc, nil, 0,
        GetProcAddress(GetModuleHandle('Kernel32'), 'LoadLibraryW'), pRemote, 0,
        PDWORD(nil)^);
    end;
  finally
    CloseHandle(hProc);
    FreeMem(wDllPath);
  end;
end;   


exe里一直已经注入成功,现在想运行里边的函数  
procedure runProcess(ProcessID: DWORD; const DllPath: string; hanshu: string);
var
  hProcess, hThread: THandle;
  pRemoteMemory: Pointer;
  ThreadId: DWORD;
  BytesWritten: SIZE_T;
  LoadLibAddr: Pointer;
  dwExitCode: DWORD;
  hDll: HMODULE;
  pInstallHook: Pointer; // 改为 Pointer 类型
  DllName: string;
begin
  // 添加调试输出
  WriteLog('准备注入DLL到进程: ' + inttostr(ProcessID));
  WriteLog('DLL路径: ' + DllPath);

  // 获取目标进程句柄
  hProcess := OpenProcess(PROCESS_CREATE_THREAD or PROCESS_QUERY_INFORMATION or
    PROCESS_VM_OPERATION or PROCESS_VM_WRITE or PROCESS_VM_READ, False,
    ProcessID);
  if hProcess = 0 then
  begin
    WriteLog('打开进程失败,错误代码: ' + inttostr(GetLastError));
    RaiseLastOSError;
  end;

  try
    // 在目标进程中分配内存
    pRemoteMemory := VirtualAllocEx(hProcess, nil, Length(DllPath) + 1,
      MEM_COMMIT or MEM_RESERVE, PAGE_READWRITE);
    if pRemoteMemory = nil then
    begin
      WriteLog('分配远程内存失败');
      RaiseLastOSError;
    end;

    try
      // 写入DLL路径到目标进程
      if not WriteProcessMemory(hProcess, pRemoteMemory, PChar(DllPath),
        Length(DllPath) + 1, BytesWritten) then
      begin
        WriteLog('写入远程内存失败');
        RaiseLastOSError;
      end;

      // 获取 LoadLibraryA 地址
      LoadLibAddr := GetProcAddress(GetModuleHandle('kernel32.dll'),
        'LoadLibraryA');
      if LoadLibAddr = nil then
      begin
        WriteLog('获取LoadLibraryA地址失败');
        RaiseLastOSError;
      end;

      // 创建远程线程调用 LoadLibraryA
      hThread := CreateRemoteThread(hProcess, nil, 0, LoadLibAddr,
        pRemoteMemory, 0, ThreadId);
      if hThread = 0 then
      begin
        WriteLog('创建远程线程失败');
        RaiseLastOSError;
      end;

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

        // 获取线程退出代码
        GetExitCodeThread(hThread, dwExitCode);
        WriteLog('远程线程退出代码: ' + IntToHex(dwExitCode, 8));

        // 获取DLL模块句柄
        DllName := ExtractFileName(DllPath);
        hDll := GetRemoteModuleHandle(hProcess, DllName);
        if hDll <> 0 then
        begin
          WriteLog('DLL已加载,模块句柄: ' + IntToHex(hDll, 8));

          // 获取 Runtest 函数地址
           pInstallHook := GetProcAddress(hDll, PAnsiChar(AnsiString(hanshu)));
        //  pInstallHook := GetProcAddress(hDll, PwideChar( String(hanshu)));
          if Assigned(pInstallHook) then
          begin
            WriteLog('找到 ' + hanshu + ' 函数,准备调用');
            hThread := CreateRemoteThread(hProcess, nil, 0, pInstallHook, nil,
              0, ThreadId);

            if hThread <> 0 then
            begin
              WaitForSingleObject(hThread, INFINITE);
              WriteLog(hanshu + ' 调用完成');
              CloseHandle(hThread);
            end
            else
              WriteLog('创建远程线程调用 ' + hanshu + ' 失败,错误代码: ' +
                inttostr(GetLastError));
          end
          else
            WriteLog('无法获取 ' + hanshu + ' 函数地址,错误代码: ' +
              inttostr(GetLastError));
        end
        else
          WriteLog('DLL未正确加载到目标进程');
      finally
        CloseHandle(hThread);
      end;
    finally
      VirtualFreeEx(hProcess, pRemoteMemory, 0, MEM_RELEASE);
    end;
  finally
    CloseHandle(hProcess);
  end;
  WriteLog('DLL注入完成');
end;

运行到 pInstallHook := GetProcAddress(hDll, PAnsiChar(AnsiString(hanshu)));  一直找不到函数 。。    使用的DELPHI10。。。用  DEEPSEEK 看来看去越整越错 。 请高手来看看哪里错了。
全部代码 已上传度盘
通过网盘分享的文件:HOOK系统时间3_xe10_0006.rar
链接: https://pan.baidu.com/s/1e8Bp6HYmPfDxEJ3TjI7YDQ?pwd=52pj 提取码: 52pj
--来自百度网盘超级会员v8的分享

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

lies2014 发表于 2025-3-29 08:57
GetProcAddress 只能获取本进程模块的函数地址,pInstallHook := GetProcAddress(hDll, PAnsiChar(AnsiString(hanshu))) 中的 hDll 是其他进程的,当然得不到结果
想取其他进程的函数,你需要远程执行 GetProcAddress,再通过进程间通信机制拿到返回结果
上面的 GetProcAddress(GetModuleHandle('Kernel32'), 'LoadLibraryW') 之所以成功,是因为本进程也有 Kernel32.Dll,实际你取到的是本进程的 LoadLibraryW 地址
只是因为系统模块的地址在不同的进程中通常(不是绝对)是固定的,所以远程执行才可能会成功,实际上这样实现是不严谨的
如何获取远端模块函数地址,这贴有一个 GetRemoteProcAddress 实现方案,你可以参考一下:
https://www.52pojie.cn/thread-1935674-1-1.html
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2025-4-7 18:01

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表