易语言教程_易语言源码_易语言视频教程_易语言论坛

 找回密码
 点击注册

Vip新手入门区
新手学习指南  学员作品展示 Vip课程总纲  Vip绝密课程系列

Vip相关下载区
Vip模块下载   Vip模块绑定   Vip模块例子 魔鬼插件下载  魔鬼插件例子  教程工具下载

Vip论坛服务区
教程问题提问区   模块问题提问区 技术交流区   魔鬼插件建议   忘记密码找回

VIP会员办理QQ: 8643245   
【请先加好友,然后到好友列表双击联系客服,办理VIP会员。】
【基础篇】易语言辅助入门基础教程
VIP模块办理QQ: 7189694 办理正版魔鬼作坊VIP模块 【基础篇】OD与CE入门基础教程
办理【终身VIP会员】“秒杀价” 仅需 RMB278.00元… 【基础篇】零基础绝密汇编语言入门课程 (共26课已完成)…
办理VIP详情…猛击这里查看详情 【基础篇】VIP辅助入门基础教程-新手必学 已发布10课 ……
VIP教程免费试看章节…猛击下载 【第1款】制作“辅助挂”教程目录查看(共107+16_x64下更新课已完成)…
亲爱的VIP学员,请到此写下你学习的感受与发布作品截图… 【第2款】制作“任务挂”教程目录查看(共77+1_x64下更新课已完成)…
卍解吧!不用bp send类封包断点找CALL的各种通杀思路 【第3款】驱动过保护技术课程(共38课已完成)…
【绝密教程】VIP绝密教程系列---注意:随时会更新! 【第4款】VIP邪恶二叉树辅助课程 (共31+17_x64下更新课已完成)…
【精品第13款】3D射击游戏与页游透视 智辅课程 已完成17课… 【第5款】零基础易语言按键辅助教程 (30课已完成)…
【精品第14款】变态功能辅助是如何炼成的 已完成36课… 【第6款】从零开始学习封包辅助技术教程(20课已完成) …
【精品第15款】DNF商业变态辅助的修炼之路 已完成27课… 【第7款】大杀特杀分析来源与CALL吸血鬼课程 (56课已完成)
【精品第16款】中控台多线程多开自动化商业辅助课程 已完成66课… 【第8款】完全零基础网页辅助课程(40课已完成)
【全新精品第17款】检测原理与过游戏内存检测技术课程 已发布9课… 【第9款】自动登录与操控LUA技术课程 (共46+8_x64下更新课已完成)…
【全新精品第18款】手游全自动化任务脚本辅助课程 已发布25课…… 【第10款】网页辅助封包脱机进阶课程 已完成30课…
【全新精品第19款】D3D方框骨骼透视与自瞄辅助课程进阶篇 已发布34课…… 【第11款】VC++ Lua脚本辅助课程 已完成112课…
【全新精品第20款】 X64模拟器吃鸡游戏方框透视自瞄辅助课程 发布中... 【第12款】网游脱机封包智辅课程 已完成35课…
查看: 1200|回复: 0

Detours使用说明

[复制链接]

20

主题

4

回帖

32

积分

编程入门

Rank: 1

魔鬼币
574
发表于 2017-5-27 22:32:32 | 显示全部楼层 |阅读模式

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:etourRun(const char* cmd)
{
    //添加任意你想添加的代码
    int iRet = (this->*RealRun)(cmd);
    return iRet;
}


e) 调用detourAttach函数

    DetourTransactionBegin();

    DetourUpdateThread(GetCurrentThread());

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

    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   
}   
您需要登录后才可以回帖 登录 | 点击注册

本版积分规则

魔鬼作坊|易语言教程|易语言源码|易语言论坛|易语言视频教程| 论坛导航|免责申明|手机版||网站地图
拒绝任何人以任何形式在本论坛发表与中华人民共和国法律相抵触的言论,本站内容均为会员发表,并不代表魔鬼作坊立场!
任何人不得以任何方式翻录、盗版或出售本站视频,一经发现我们将追究其相关责任!
我们一直在努力成为最好的编程论坛!
Copyright© 2010-2019 All Right Reserved.
快速回复 返回顶部 返回列表