Detour使用说明

来源:互联网 发布:sas安装数据sid无效 编辑:程序博客网 时间:2024/05/29 03:02

2.2 hook自定义函数

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

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&)RealRunCmdDetourRunCmd);

     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;
    return 0;
}

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
}
0 0
原创粉丝点击