amobbs.com 阿莫电子技术论坛

标题: 如何截获a.exe中的一个函数调用,加入处理后再执行后面的语句? [打印本页]

作者: adongliu    时间: 2015-11-2 21:57
标题: 如何截获a.exe中的一个函数调用,加入处理后再执行后面的语句?
就像hook截获鼠标和键盘的例子。
作者: SkyGz    时间: 2015-11-2 22:13
本帖最后由 SkyGz 于 2015-11-2 23:11 编辑

如果是 DLL, 到是好办,   EXE 就有点困难了,  要知道 该函数的内存地址 才可以..


我想问这EXE是运行中的么?
是的话,  写个HOOK DLL, 插入到该EXE的进程中..然后  , 晕  ,   三两句说不完,  久没玩了,  都忘了

贴点代码,  不知有没 给你带来思路,  我这个代码(截取INNO SETUP安装包的密码), 作用是 ,   将自已的函数 插入到 INNO安装程序里, 然后, 让他运行我的代码,  取出 程序的数据, 返回给我的程序用




Function MyGetCommandLineA: PAnsiChar; Stdcall;
Type
  PJmpCode = ^TJmpCode;
  TJmpCode = Packed Record
    JmpCode: Byte;
    Address: DWORD;
  End;
  TVarList = Record                     {变量列表}
    GetInnoPass: DWORD;
    CallAddr: DWORD;
  End;

Const
  HexStr = '53 83 C4 98 8B D8 8B C4 E8 ?? ?? ?? FF BA ?? ?? ?? 00 8B C4 B9 11 00' +
    '00 00 E8 ?? ?? ?? FF BA ?? ?? 49 00 8B C4 B9 08 00 00 00 E8 ?? ?? ?? FF 8B C3' +
    'E8 ?? ?? ?? FF 8B C8 8B D3 8B C4';  //目标进程要查找的数据
Var
  S: String;
  LibH: THandle;

  CurProc, ThreadHandle: THandle;
  Written, ThreadID: Cardinal;
  MemData: Pointer;
  JmpCode: TJmpCode;
  GetPwdPtr: DWORD;
//自已DLL内的 函数, 待插到程序内,
  Procedure GetPassCode;
  Var
    VarList: TVarList;
  Begin
    Asm
      MOV EAX, $FFFFFFFF
      MOV VarList.GetInnoPass, EAX
      MOV EAX, $FFFFFFFF
      MOV VarList.CallAddr, EAX
      PUSH EBX
      CALL VarList.GetInnoPass //将提取到内存中的密码,  附值给自已的一个 窗口函数里,  并弹出 窗口 显示 当前密码
    End;
  End;
Begin
  Result := GetCommandLineA; //通过HOOK 程序启动命令行的WINDOWS函数, 开始 进行将程序插入到进程里
  If Not Data^.IsReadMem Then
  Begin
    Data^.IsReadMem := True;
    If Pos(SkyGz, UpperCase(StrPas(Data^.FileDescription))) <> 0 Then Exit;
    S := StringReplace(HexStr, ' ', '', [rfReplaceAll]);
    CurProc := GetCurrentProcess;
    LibH := GetModuleHandleA(PAnsiChar(GetModuleName(0)));  
    BeginPos := HexFindMemory(CurProc, S, LibH + 400000, LibH + 800000); //在进程里 查找 主程序的 数据.
    If BeginPos <> -1 Then
    Begin
      {在目标进程中分配内存}
      MemData := VirtualAllocEx(CurProc, Nil, 4096, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
      JmpPos := BeginPos + 18 + 7; //在找到的数据里,  增加到 相应 位数才是 目标地址
      ReadProcessMemory(CurProc, Pointer(JmpPos), @BFD, 5, Written); //将当前位置及地址 保存 备份下来

      JmpCode.JmpCode := $E8;           //$E9  //待修改的跳转指令
      JmpCode.Address := LongInt(MemData) - 5 - (JmpPos); //跳转地址
      WriteProcessMemory(CurProc, Pointer(JmpPos), @JmpCode, 5, Written); //将跳转地址 写到 目标JmpPos地址里

      {把自定义函数写入到目标进程中}
      WriteProcessMemory(CurProc, MemData, @GetPassCode, 4096, Written);

      {以挂起方式建立远端线程,以便修改}
      ThreadHandle := CreateRemoteThread(CurProc, Nil, 0, MemData, Nil, CREATE_SUSPENDED, ThreadID);
      GetPwdPtr := DWORD(Windows.GetProcAddress(GetModuleHandleA(PAnsiChar(GetModuleName(HInstance))), 'GetInnoPass'));
      WriteProcessMemory(CurProc, Pointer(LongInt(MemData) + 7), @GetPwdPtr, SizeOf(DWORD), Written);

      BFD.NewAddress := BFD.Address + 5 + JmpPos; //运行完自已的代码后, 再恢复备份的地址数据 恢复, 继续运行
      BFD.NewAddress := BFD.NewAddress - 5 - (DWORD(MemData) + 14);
      //WriteProcessMemory(CurProc, Pointer(LongInt(MemData) + 14), @BFD.JmpCode, 1, Written);
      WriteProcessMemory(CurProc, Pointer(LongInt(MemData) + 15), @BFD.NewAddress, SizeOf(DWORD), Written);

      {释放在目标进程中分配的内存}
      //VirtualFreeEx(CurProc, MemData, 4096, MEM_DECOMMIT);
      //VirtualFreeEx(CurProc, MemData, 0, MEM_RELEASE);
      ResumeThread(ThreadHandle);
      CloseHandle(ThreadHandle);
    End;
  End;
End;
作者: nyszx    时间: 2015-11-2 22:32
感觉很高深很复杂~莫非这就是春说中的破解软件的方法
作者: wzda_gundam    时间: 2015-11-3 00:06
修改入口表
作者: gxnnhy    时间: 2015-11-3 00:43
这个专业术语叫做钩子函数,一般通过注入的当时把自己的钩子函数注入到目标进程。一般有三种,加载器注入,全局消息注入,远程线程注入
作者: jsntzxh    时间: 2015-11-3 06:33
如果能修改a.exe文件办法多的是,不能修改可以在其目录下放个lpk.dll
作者: qq854149876    时间: 2015-11-3 07:58
看上去很高深
作者: adongliu    时间: 2015-11-3 14:00
jsntzxh 发表于 2015-11-3 06:33
如果能修改a.exe文件办法多的是,不能修改可以在其目录下放个lpk.dll

有思路吗?
作者: SkyGz    时间: 2015-11-3 14:11
jsntzxh 发表于 2015-11-3 06:33
如果能修改a.exe文件办法多的是,不能修改可以在其目录下放个lpk.dll

LPK, 在WIN7以上系统  貌似没效果了...MS给补了洞
作者: TANK99    时间: 2015-11-3 14:15
2楼的代码要记录一下,说不定会遇到。
作者: jsntzxh    时间: 2015-11-3 20:53
SkyGz 发表于 2015-11-3 14:11
LPK, 在WIN7以上系统  貌似没效果了...MS给补了洞

WIN7用管理员权限将lpk.reg导入注册表,重启系统,就能用lpk了。

reg文件内容:

Windows Registry Editor Version 5.00

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager]
"ExcludeFromKnownDlls"=hex(7):6c,00,70,00,6b,00,2e,00,64,00,6c,00,6c,00,00,00,\
00,00




作者: canspider    时间: 2015-11-3 20:58
再写一个程序,在里面用ctreateprocess的方法打开a.exe
打开的时候加入所有权限,这样就能读写子进程的内存了


作者: adongliu    时间: 2015-11-3 21:45
原有的程序是用VB编写的,现在想增加一个功能,有一个函数是DOWNLOAD_RECIPT,我想在调用这个函数的时候检查PLC的输入点是否有信号,如果没有信号,跳出对话框,禁止下载程序,否则可以下载程序.

使用HOOK技术无法禁用菜单和toolbar类中的按钮.




欢迎光临 amobbs.com 阿莫电子技术论坛 (https://www.amobbs.com/) Powered by Discuz! X3.4