首页
社区
课程
招聘
[求助]APIHOOK的问题
发表于: 2008-1-14 21:16 4229

[求助]APIHOOK的问题

2008-1-14 21:16
4229
为啥一直出错呀?
unit   apihook   ;

interface   

uses   
  SysUtils,   Windows,   WinSock,  Dialogs;

type
  {   要HOOK的API函数定义   }
    TWideToMulti   =   function   (cp:cardinal;  dwflags:cardinal; lpWideChar:PWideChar;
    cchWideChar:Integer;    lpMultiByteStr:PAnsiChar;   cchMultiByte:Integer;
    lpDefaultChar:PAnsiChar;   lpUsedDefaultChar:PBOOL):   Integer;   stdcall;
      

  procedure   HookAPI;
  procedure   UnHookAPI;

var
    ProcessHandle:   HWND;
    BaseAddress:   Pointer;
    OldProc:   array   [0..7]   of   Byte;
    NewPorc:   array   [0..7]   of   Byte;

implementation

function   MyWideToMulti(cp:cardinal;  dwflags:cardinal; lpWideChar:PWideChar;
    cchWideChar:Integer;    lpMultiByteStr:PAnsiChar;   cchMultiByte:Integer;
    lpDefaultChar:PAnsiChar;   lpUsedDefaultChar:PBOOL):   Integer;   stdcall;
var
    nSize:   Cardinal;
begin
    {   显示}
    ShowMessage(string(lpWideChar));

    WriteProcessMemory(ProcessHandle,   BaseAddress,   @OldProc,  8,   nSize);//這一句是修改成原來函數的地址,
    Result   := WideCharToMultiByte(cp,  dwflags, lpWideChar,
    cchWideChar,    lpMultiByteStr,   cchMultiByte,
    lpDefaultChar,   lpUsedDefaultChar) ;
     WriteProcessMemory(ProcessHandle,   BaseAddress,   @NewPorc,  8,   nSize);//在程序正常打開後再修改成自定義函數的地址,使所有程序在下次打開時都要先調用自定義函數
    // UnHookAPI;
end;

procedure   HookAPI;
var
    DLLModule:   THandle;
    nSize:   Cardinal;
    Dat:   DWORD;
    Tmp   :   array   [0..3]   of   Byte;
begin
    ProcessHandle   :=   GetCurrentProcess();
    DLLModule   :=   LoadLibrary('kernel32.dll');
    {   系统函数入口点地址   }
    BaseAddress   :=   GetProcAddress(DLLModule,'WideCharToMultiByte');
    Dat   :=   DWORD(@MyWideToMulti);
    Move(Dat,   Tmp,   4);
    NewPorc[0]   :=   $B8;   {B8 00400000   mov eax,4000}
    NewPorc[1]   :=   Tmp[0];   {   跳转到自身的函数   }
    NewPorc[2]   :=   Tmp[1];
    NewPorc[3]   :=   Tmp[2];
    NewPorc[4]   :=   Tmp[3];
    NewPorc[5]   :=   $FF;         {FFE0     jmp eax}
    NewPorc[6]   :=   $E0;
    NewPorc[7]   :=   0;
    {   读取系统函数内存地址   }
    ReadProcessMemory(ProcessHandle,   BaseAddress,   @OldProc,   8,   nSize);
    {   用自己的函数地址覆盖系统的函数地址   }
    WriteProcessMemory(ProcessHandle,   BaseAddress,   @NewPorc,  8,   nSize);
    CloseHandle(ProcessHandle);
end;

procedure   UnHookAPI;
var
    nSize:   Cardinal;
begin
    {   恢复所修改的地址   }
    WriteProcessMemory(ProcessHandle,   BaseAddress,   @OldProc, 8,   nSize);
end;

end.

[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)

收藏
免费 0
支持
分享
最新回复 (5)
雪    币: 321
活跃值: (271)
能力值: ( LV13,RANK:1050 )
在线值:
发帖
回帖
粉丝
2
,你在这里采用的是Inline hook的一种挂接方式。
你使用的机器码0x0B8, 0x0, 0x0, 0x40, 0x0, 0x0FF, 0x0E0;
意思是 mov eax,addr
          jmp eax

我对Delphi不懂,但是显然你的做法是错误的。
1)为啥要使用二维数组?
2)你没有理解这个机器码的意思,更没有在里面填充上自己的api函数address.

我给你贴一个c++的代码,你参考下吧
class CHookApi_Jmp2  
{
public:
        CHookApi_Jmp2();
        virtual ~CHookApi_Jmp2();

public:
        void HookOneAPI(LPCTSTR ModuleName,LPCTSTR ApiName,FARPROC lpNewFunc);
        void SetHookOn();
        void SetHookOff();

protected:
        HANDLE m_hProc;
        BYTE m_OldFunc[8];
        BYTE m_NewFunc[8];
        PROC m_lpHookFunc;
};

CHookApi_Jmp2::CHookApi_Jmp2()
{
        BYTE str[8] = { 0x0B8, 0x0, 0x0, 0x40, 0x0, 0x0FF, 0x0E0,0};  // mov eax,addr  jmp eax
        memcpy(m_NewFunc,str,8);
}

//---------------------------------------------------------------------------
CHookApi_Jmp2::~CHookApi_Jmp2()
{
        CloseHandle(m_hProc);
}

//---------------------------------------------------------------------------
void CHookApi_Jmp2::SetHookOn()
{
        DWORD dwOldFlag;
        WriteProcessMemory(m_hProc, (void *)m_lpHookFunc,
                               (void *)m_NewFunc, 8, &dwOldFlag);
}

//---------------------------------------------------------------------------
void CHookApi_Jmp2::SetHookOff()
{
        DWORD dwOldFlag;
        WriteProcessMemory(m_hProc, (void *)m_lpHookFunc,
                      (void *)m_OldFunc, 8, &dwOldFlag);
}

//---------------------------------------------------------------------------
void CHookApi_Jmp2::HookOneAPI
      (LPCTSTR ModuleName, LPCTSTR ApiName, FARPROC lpNewFunc)
{
        m_lpHookFunc = GetProcAddress(GetModuleHandle(ModuleName),ApiName);
        m_hProc = GetCurrentProcess();

        // 复制m_lpHookFunc前8个字节代码到m_OldFunc.
        memcpy(m_OldFunc,(char *)m_lpHookFunc,8);
        *(DWORD *)( m_NewFunc + 1 ) = (DWORD)lpNewFunc;
}
2008-1-15 22:38
0
雪    币: 193
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
为啥这个可以啊?只是换了个想要HOOK的API就不行了?

unit   apihook1   ;

interface   

uses   
  SysUtils,   Windows,   WinSock,   Dialogs;

type
  {   要HOOK的API函数定义   }
    TCreatePW   =   function   (lpApplicationName:   PWideChar;   lpCommandLine:   PWideChar;
        lpProcessAttributes,   lpThreadAttributes:   PSecurityAttributes;
        bInheritHandles:   BOOL;   dwCreationFlags:   DWORD;   lpEnvironment:   Pointer;
        lpCurrentDirectory:   PWideChar;   const   lpStartupInfo:   TStartupInfo;
        var   lpProcessInformation:   TProcessInformation):   BOOL;   stdcall;

  procedure   HookAPI;
  procedure   UnHookAPI;

var
    ProcessHandle:   HWND;
    BaseAddress:    Pointer;
    OldProc:   array   [0..7]   of   Byte;
    NewPorc:   array   [0..7]   of   Byte;

implementation

{   自定义的函数,用于覆盖系统的CreateProcessW函数   }
function   MyCreatePW(lpApplicationName:   PWideChar;   lpCommandLine:   PWideChar;
        lpProcessAttributes,   lpThreadAttributes:   PSecurityAttributes;
        bInheritHandles:   BOOL;   dwCreationFlags:   DWORD;   lpEnvironment:   Pointer;
        lpCurrentDirectory:   PWideChar;   const   lpStartupInfo:   TStartupInfo;
        var   lpProcessInformation:   TProcessInformation):   BOOL;   stdcall;
var
    nSize:   Cardinal;
begin
    {   显示打开程序的命令行和文件名}
    MessageBoxW(0,   lpCommandLine ,lpApplicationName   ,   0);
    WriteProcessMemory(ProcessHandle,   BaseAddress,   @OldProc,   8,   nSize);//這一句是修改成原來函數的地址,讓程序能正常打開
    Result   :=   CreateProcessW(lpApplicationName,   lpCommandLine,   lpProcessAttributes,
      lpThreadAttributes,   bInheritHandles,   dwCreationFlags,   lpEnvironment,
      lpCurrentDirectory,   lpStartupInfo,   lpProcessInformation);
    WriteProcessMemory(ProcessHandle,   BaseAddress,   @NewPorc,   8,   nSize);//在程序正常打開後再修改成自定義函數的地址,使所有程序在下次打開時都要先調用自定義函數
end;

procedure   HookAPI;
var
    DLLModule:   THandle;
    nSize:   Cardinal;
    Dat:   DWORD;
    Tmp   :   array   [0..3]   of   Byte;
begin
    ProcessHandle   :=  GetCurrentProcess();
    DLLModule   :=   LoadLibrary('kernel32.dll');
    {   系统函数入口点地址   }
    BaseAddress   :=   GetProcAddress(DLLModule,   'CreateProcessW');
    Dat   :=   DWORD(@MyCreatePW);
    Move(Dat,   Tmp,   4);
    NewPorc[0]   :=   $B8;
    NewPorc[1]   :=   Tmp[0];
    NewPorc[2]   :=   Tmp[1];
    NewPorc[3]   :=   Tmp[2];
    NewPorc[4]   :=   Tmp[3];
    NewPorc[5]   :=   $FF;
    NewPorc[6]   :=   $E0;
    NewPorc[7]   :=   0;
    {   读取系统函数内存地址   }
    ReadProcessMemory(ProcessHandle,   BaseAddress,   @OldProc,   8,   nSize);
    {   用自己的函数地址覆盖系统的函数地址   }
    WriteProcessMemory(ProcessHandle,   BaseAddress,   @NewPorc,   8,   nSize);
    CloseHandle(ProcessHandle);
end;

procedure   UnHookAPI;
var
    nSize:   Cardinal;
begin
    {   恢复所修改的地址   }
    WriteProcessMemory(ProcessHandle,   BaseAddress,   @OldProc,   8,   nSize);
end;

end.
2008-1-15 23:59
0
雪    币: 193
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
这几句就是  填充上自己的api函数address

ProcessHandle   :=  GetCurrentProcess();
    DLLModule   :=   LoadLibrary('kernel32.dll');
    {   系统函数入口点地址   }
    BaseAddress   :=   GetProcAddress(DLLModule,   'CreateProcessW');
    Dat   :=   DWORD(@MyCreatePW);
    Move(Dat,   Tmp,   4);  //这个不知道是为什么
    NewPorc[0]   :=   $B8;
    NewPorc[1]   :=   Tmp[0];
    NewPorc[2]   :=   Tmp[1];
    NewPorc[3]   :=   Tmp[2];
    NewPorc[4]   :=   Tmp[3];
    NewPorc[5]   :=   $FF;
    NewPorc[6]   :=   $E0;
    NewPorc[7]   :=   0;
   WriteProcessMemory(ProcessHandle,   BaseAddress,   @NewPorc,   8,   nSize);
2008-1-16 00:03
0
雪    币: 1205
活跃值: (5094)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
5
Result   := WideCharToMultiByte(cp,  dwflags, lpWideChar,
    cchWideChar,    lpMultiByteStr,   cchMultiByte,
    lpDefaultChar,   lpUsedDefaultChar) ;

这个错了吧?

你要定义一个要勾的API,先保存旧的地址,勾了后,用旧的处理, 再写入新的地址,还有....我最怕的"NP"

我以前做过,虽然做出来了, 但还不能理解 :
2008-1-16 04:55
0
雪    币: 193
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
就是那样做的呀
2008-1-16 08:24
0
游客
登录 | 注册 方可回帖
返回
//