添加链接
link之家
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接

转自: http://www.cnblogs.com/flywuya/archive/2010/12/01/1893729.html

1 介绍
Api hook包括两部分:api调用的截取和api函数的重定向。通过api hook可以修改函数的参数和返回值。关于原理的详细内容参见《windows核心编程》第19章和第22章。

2 Detours API hook
"Detours is a library for intercepting arbitrary Win32 binary functions on x86 machines. Interception code is applied dynamically at runtime. Detours replaces the first few instructions of the target function with an unconditional jump to the user-provided detour function. Instructions from the target function are placed in a trampoline. The address of the trampoline is placed in a target pointer. The detour function can either replace the target function, or extend its semantics by invoking the target function as a subroutine through the target pointer to the trampoline."

在Detours库中,驱动detours执行的是函数 DetourAttach(…).

LONG DetourAttach(

PVOID * ppPointer,

PVOID pDetour

这个函数的职责是挂接目标API,函数的第一个参数是一个指向将要被挂接函数地址的函数指针,第二个参数是指向实际运行的函数的指针,一般来说是我们定义的替代函数的地址。但是,在挂接开始之前,还有以下几件事需要完成:

需要对detours进行初始化.
需要更新进行detours的线程.
这些可以调用以下函数很容的做到:

DetourTransactionBegin()
DetourUpdateThread(GetCurrentThread())
在这两件事做完以后,detour函数才是真正地附着到目标函数上。在此之后,调用DetourTransactionCommit()是detour函数起作用并检查函数的返回值判断是正确还是错误。

2.1 hook DLL 中的函数

在这个例子中,将要hook winsock中的函数 send(…)和recv(…).在这些函数中,我将会在真正调用send或者recv函数前,把真正说要发送或者接收的消息写到一个日志文件中去。注意:我们自定义的替代函式一定要与被hook的函数具有相同的参数和返回值。例如,send函数的定义是这样的:

int send(

__in  SOCKET s,

__in  const char *buf,

__in  int len,

__in  int flags

因此,指向这个函数的指针看起来应该是这样的:

int (WINAPI *pSend)(SOCKET, const char*, int, int) = send;

把函数指针初始化成真正的函数地址是ok的;另外还有一种方式是把函数指针初始化为NULL,然后用函数 DetourFindFunction(…) 指向真正的函式地址.把send(…) 和 recv(…)初始化:

int (WINAPI *pSend)(SOCKET s, const char* buf, int len, int flags) = send;

int WINAPI MySend(SOCKET s, const char* buf, int len, int flags);

int (WINAPI *pRecv)(SOCKET s, char* buf, int len, int flags) = recv;

int WINAPI MyRecv(SOCKET s, char* buf, int len, int flags);

现在,需要hook的函数和重定向到的函数已经定义好了。这里使用 WINAPI 是因为这些函数是用 __stdcall 返回值的导出函数,现在开始hook:

INT APIENTRY DllMain(HMODULE hDLL, DWORD Reason,LPVOID Reserved)
    switch(Reason)
        caseDLL_PROCESS_ATTACH: 
            DisableThreadLibraryCalls(hDLL);  
            DetourTransactionBegin();
            DetourUpdateThread(GetCurrentThread());
            DetourAttach(&(PVOID&)pSend, MySend);
            if(DetourTransactionCommit() == NO_ERROR)
                OutputDebugString("send() detoured successfully");
            break;


它基本上是用上面介绍的步骤开始和结束 —— 初始化,更新detours线程,用DetourAttach(…)开始hook函数,最后调用DetourTransactionCommit() 函数, 当调用成功时返回 NO_ERROR, 失败是返回一些错误码.下面是我们的函数的实现,我发送和接收的信息写入到一个日志文件中:

int WINAPI MySend(SOCKET s, const char* buf, intlen, int flags) 
    fopen_s(&pSendLogFile,"C:\\SendLog.txt","a+"); 
    fprintf(pSendLogFile,"%s\n", buf); 
    fclose(pSendLogFile);
    returnpSend(s, buf, len, flags); 
int WINAPI MyRecv(SOCKET s, char* buf,int len, int flags) 
    fopen_s(&pRecvLogFile,"C:\\RecvLog.txt","a+"); 
    fprintf(pRecvLogFile,"%s\n", buf); 
    fclose(pRecvLogFile);
    returnpRecv(s, buf, len, flags); 

2.2 自定义c 函数

举例来说明,假如有一个函数,其原型为

int RunCmd(const char* cmd);

如果要hook这个函数,可以按照以下几步来做:

a)     include 声明这个函数的头文件

b)     定义指向这个函数的函数指针,int (* RealRunCmd)(const char*) = RunCmd;

c)     定义detour函数,例如: int DetourRunCmd(const char*);

d)     实现detour函数,如:

Int DetourRunCmd(const char* cmd)

   //extend the function,add what you want :)

   Return RealRunCme(cmd);

这样就完成了hook RunCmd函数的定义,所需要的就是调用DetourAttack

    DetourTransactionBegin();

     DetourUpdateThread(GetCurrentThread());

     DetourAttach(&(PVOID&)RealRunCmd, DetourRunCmd);

     if(DetourTransactionCommit() == NO_ERROR)

         //error

2.3 hook类成员函数
   Hook类成员函数通过在static函数指针来实现

   还是举例说明,假如有个类定义如下:

class CData

public:

    CData(void);

    virtual ~CData(void);

    int Run(const char* cmd);

现在需要hook int CData::Run(const char*) 这个函数,可以按照以下几步:

a) 声明用于hook的类

class CDataHook

public:

    int DetourRun(const char* cmd);

    static int (CDataHook::* RealRun)(const char* cmd);

b) 初始化类中的static函数指针

     int (CDataHook::* CDataHook::RealRun)(const char* cmd) = (int (CDataHook::*)(const char*))&CData::Run;

c) 定义detour函数

   int CDataHook::DetourRun(const char* cmd)

    //添加任意你想添加的代码

    int iRet = (this->*RealRun)(cmd);

    return iRet;

e)     调用detourAttach函数

    DetourTransactionBegin();

    DetourUpdateThread(GetCurrentThread());

    DetourAttach(&(PVOID&)CDataHook::RealRun, (PVOID)(&(PVOID&)CDataHook::DetourRun));

    if(DetourTransactionCommit() == NO_ERROR)

        //error

2.4 DetourCreateProcessWithDll

使用这个函数相当于用CREATE_SUSPENDED 标志调用函数CreateProcess. 新进程的主线程处于暂停状态,因此DLL能在函数被运行钱被注入。注意:被注入的DLL最少要有一个导出函数. 如用testdll.dll注入到notepad.exe中:

#undef UNICODE
#include <cstdio>
#include <windows.h>
#include <detours\detours.h> 
int main() 
    STARTUPINFO si;    
    PROCESS_INFORMATION pi;
    ZeroMemory(&si,sizeof(STARTUPINFO));    
    ZeroMemory(&pi,sizeof(PROCESS_INFORMATION));    
    si.cb =sizeof(STARTUPINFO);    
    char* DirPath =new char[MAX_PATH];    
    char* DLLPath =new char[MAX_PATH];//testdll.dll     
    char* DetourPath =new char[MAX_PATH];//detoured.dll   
    GetCurrentDirectory(MAX_PATH, DirPath);    
    sprintf_s(DLLPath, MAX_PATH,"%s\\testdll.dll", DirPath);    
    sprintf_s(DetourPath, MAX_PATH,"%s\\detoured.dll", DirPath);    
    DetourCreateProcessWithDll(NULL,"C:\\windows\\notepad.exe", 
        NULL,NULL, FALSE, CREATE_DEFAULT_ERROR_MODE, NULL, NULL,&si, &pi, DetourPath, DLLPath, NULL);    
    delete[] DirPath;     
    delete[] DLLPath;     
    delete[] DetourPath;     
    return0; 


2.5 Detouring by Address

假如出现这种情况怎么办?我们需要hook的函数既不是一个标准的WIN32 API,也不是导出函数。这时我们需要吧我们的程序和被所要注入的程序同事编译,或者,把函数的地址硬编码:

 

#undef UNICODE 
#include <cstdio> 
#include <windows.h> 
#include <detours\detours.h>  
typedef void (WINAPI *pFunc)(DWORD); 
void WINAPI MyFunc(DWORD);  
pFunc FuncToDetour = (pFunc)(0x0100347C); //Set it at address to detour in                     
//the process 
INT APIENTRY DllMain(HMODULE hDLL, DWORD Reason, LPVOID Reserved) 
    switch(Reason)     
    case DLL_PROCESS_ATTACH:         
            DisableThreadLibraryCalls(hDLL);             
            DetourTransactionBegin();             
            DetourUpdateThread(GetCurrentThread());             
            DetourAttach(&(PVOID&)FuncToDetour, MyFunc);             
            DetourTransactionCommit();         
        break;     
    case DLL_PROCESS_DETACH:         
        DetourTransactionBegin();         
        DetourUpdateThread(GetCurrentThread());         
        DetourDetach(&(PVOID&)FuncToDetour, MyFunc);         
        DetourTransactionCommit();         
        break;     
    case DLL_THREAD_ATTACH:     
    case DLL_THREAD_DETACH:         
        break;     
    return TRUE; 
void WINAPI MyFunc(DWORD someParameter) 
    //Some magic can happen here 
 你可以使用任何你想安装java的方法。 我已经按照 Webupd8 中的描述安装了 。
Python
 我目前正在使用从 Ubuntu 14.04 规范源安装的 Python3。
阿帕奇自由云
您可以通过 PIP3 安装它,也可以通过 Ubuntu 源安装它。 我刚刚安装了 python3-libcloud 。
ZeroMQ 和 Java 绑定
您可以从 Ubuntu 源(libzmq3 和 libzmq3-dev)安装它或从下载 tarball。
 如果您使用的是 tarball,只需按照 INSTALL 文件中的说明进行操
                                    原文地址:http://www.codeproject.com/Articles/30140/API-Hooking-with-MS-Detours
在这篇文章里,我将要介绍API拦截技术的相关理论和实现方式。API拦截是一项强大的技术,他让你可以拦截某些函数,重定位到自定义的函数上。在将控制权交给原始API之前,你可以在这个自定义的函数里做任何想做的事。
本文中,我将讨论API拦
                                    Detours 是Microsoft开发一个库,下载地址http://research.microsoft.com/en-us/projects/detours/,它具有两方面的功能:
1 拦截x86机器上的任意的win32 API函数。
2 插入任意的数据段到PE文件中,修改DDL文件的导入表。
Detours库可以拦截任意的API调用,拦截代码是在动态运行时加载的。Detours替换目标API最前面的几条指令,使其无条件的跳转到用户提供的拦截函数。被替换的API函数的前几条指令被保存到tram
                                    因为才接触Detours Hook,所以按照网上的去官网下了一个DetoursExpress30.msi 下载的地方也只有这一个可供下载。
(后来查资料才知道还有一个收费版的detour professional 3.0,听说蛮贵的,去官网也没有找到)
http://download.csdn.net/download/staver102/7648875这个是别人自己改写的专业版的 ,...
detours是微软提供的一套工具,主要用于win32 API的拦截。
准备工作(环境)
首先下载detours的资源,地址:https://github.com/microsoft/detours
下载到本地后解压至任意文件夹;
打开cmd终端进到这个文件夹下,键入nmake;
编译完成后:
新建一个工程,将include中的detours.h移动至工程文件下;
将lib.X64(X86也有对应目录)下的detours.lib移动至工程文件下;
示例代码:
#include &l
                                    Detours
当然是用detours,微软明显高腾讯一筹,同上,至今没失败过.写这种HOOK一定要再写个测试程序,不要直接HOOK你的目的程序,例如QQ,因为这样不方面更灵活的测试.
说明一下:Detours是微软开发的一个函数库(源代码可在http://research.microsoft.com/sn/detours 免费获得)用于修改运行中的程序在内存中的影像,从而即使没有源代码也能改
                                    拦截二进制函数
        Detours库可以在运行过程中动态拦截函数调用。detours将目标函数钱几个指令替换为一个无条件跳转,跳转到用户定义的detour函数。被拦截的函数保存在trampoline函数中。trampoline保存了目标函数移除的指令和一个无条件跳转,可以跳转到目标函数的执行体部分(未被移除的部分)。
        当执行到目标函数的时候,直接跳转到用户提供的de
                                    Detours是微软开发的一个函数库,可用于捕获系统API。在用其进行程序开发之前,得做一些准备工作:一.下载Detours 
     在http://research.microsoft.com/sn/detours 可免费下载Detours 
二.安装Detours 
        一路NEXT 
三.生成Detours库 
        在安装后的文件夹下找不到直接可以拿来用的LIB文件