• 【HookAPI】


    #include <IOSTREAM>
    #include <WINDOWS.H>
    
    using namespace std;
    
    
    
    void main()
    {
    
    //与静态库相关联
        HMODULE hDll = LoadLibrary("HookAPIDll.dll");
    
        printf("被钩掉的那个API,MessageBox,现在变成了打开calc.exe
    ");
        printf("你现在看的是一个计算器,对不对,哈哈!
    ");
    
    
     //第一个MessageBox
        MessageBox(NULL,"这是第一个MessageBox","Test",0);
    
        printf("观察发现,会出现第二个MessageBox
    ");
    
    //如果在静态库DLL中 没有    调用HookOff();的话,所有的messagebox都会被改掉,如果调用了的话,
    //    那么下面这个messagebox将能正常使用
    
    
    
    //第二个MessageBox
        MessageBox(NULL,"这是第二个MessageBox,如果你只看到这一个MessageBox的话,说明第一个MessageBox已经被钩掉了。,你能看到第二个MessageBox,那是因为这里用了OffHook,将地址又弄回去了,其实这里我也搞不太清楚,不过你可以去试试,如果不调用OffHook()函数的话,所有的MessageBox都出不来的,病毒思想,哈哈哈!","Test",0);
    }
    
    
    void Add()
    {
    
    }


    // HookAPIDll.cpp : Defines the entry point for the DLL application.
    //
    
    #include "stdAfx.h"
    
    
    //我们在这里定一个全局的函数指针可以用来保存原来的函数的地址
    
    PROC g_Func = NULL;
    BYTE g_NewFunc[5]; 
    BYTE g_OldFunc[5];
    
    //定义一个全局的句柄
    HANDLE g_hProcess = NULL;
    
    
    void WINAPI MyMessageBox(HWND hWnd,LPCTSTR lpText,LPCTSTR lpCaption,UINT uType);
    void WINAPI MyMainProc();
    
    BOOL APIENTRY DllMain( HANDLE hModule, 
                           DWORD  ul_reason_for_call, 
                           LPVOID lpReserved
                         )
    {
        switch (ul_reason_for_call)
        {
        case DLL_PROCESS_ATTACH:
            {
                
                MyMainProc();
                
                break;
            }
    
    
        case DLL_PROCESS_DETACH:
            {
                break;
            }
        }
    
        return TRUE;
    }
    
    
    void HookAPI(LPCTSTR ModuleName,LPCTSTR ApiName,FARPROC lpNewFunc)
    {
    
        //后面调用是这样的
        //    HookAPI("user32.dll","MessageBoxA",(FARPROC)MyMessageBox);
        // 这里传进来的是我们自己写的MyMessageBox,
        // 整个函数的功能就是(还要结合后面的两个函数)
        // 在user32.dll模块中,去找到MessageBox这个函数,
        // 然后计算出我们自己写的那个函数MyMessageBox 的偏移,
        // 最后将它盖掉原来的函数,也就是执行MessageBox 的时候实际上执行的是我们自己的MyMessageBox函数
    
    
        //FARPROC 是一个4字节指针,指向一个函数的内存地址
    
    
        //这里需要那个库 还有就是API函数的名字
    
        g_NewFunc[0] = 0xe9;   //这是我们构建的字符数组中的第一个字节
    
        //我们通过两个函数可以得到原来的那个API函数的地址
    
        g_Func=GetProcAddress(GetModuleHandle(ModuleName),ApiName);
        //给我一个模块,给我一个函数,GetProcAddress的返回值就是这个函数的偏移地址
        //这步骤执行之后,g_Func中保存的就是原先函数的地址,,也就是还没被钩掉的MessageBox函数的地址
    
        //e8 10ab
        memcpy(g_OldFunc,(void*)g_Func,5);
    
    
    
        g_hProcess = GetCurrentProcess();    //我们要这个值是为了能够往进程的内存中写值
    
        //GetCurrentProcess 获得当前进程,获开进程之后(获得进程的地址空间),需要把地址写进去,
        //g_hProcess是一个全局的句柄
    
        //覆盖函数的jmp后的4个字节指令
    
        DWORD* pStart = NULL;
    
        pStart = (DWORD*)&g_NewFunc[1] ; //pStart指向的是0xe9,也就是jmp后面的那个地址
    
        *pStart = (DWORD)lpNewFunc - (DWORD)g_Func - 5;   //计算我们实际要运行的函数和原来函数的偏移
        
        //这里lpNewFunc是一个 FARPROC 类型的指针,指向函数的内存地址,
    
    
    }
    
    
    void SetHook()
    {
        DWORD dwFlag;
        WriteProcessMemory(g_hProcess,(void*)g_Func,(void*)g_NewFunc,5,&dwFlag);
        //把g_NewFuc中保存的5个字节的内容,写到g_Func中去,
        //这里的意思,就是把我们自己写的MyMessaBox函数,去替换原来的MessageBox函数
        //因为通过HookAPI函数,g_Func存放的是原来函数的地址(0xe8 .....),
        //                       g_NewFunc存放的是现在函数的偏移地址以及一个jmp(0xe9 .....)
        //所以,进程中的内存地址空间的这5个字节就被改写了。
        //所以本来要执行系统的MessaBox,就变为执行我们自己写的MessagBox了。
    }
    
    
    //功能和SetHook相反
    void HookOff()
    {
        DWORD dwFlag;
        WriteProcessMemory(g_hProcess,(void*)g_Func,(void*)g_OldFunc,5,&dwFlag);
    }
    
    
    
    void WINAPI MyMainProc()
    {
        HookAPI("user32.dll","MessageBoxA",(FARPROC)MyMessageBox);
    
        SetHook();
    
    }
    
    
    
    void WINAPI MyMessageBox(HWND hWnd,LPCTSTR lpText,LPCTSTR lpCaption,UINT uType)
    {
        
        
        HookOff();
    //    MessageBoxA(hWnd,"Hooking MessageBox","Test",MB_OK); 
    
        STARTUPINFO si;
        PROCESS_INFORMATION pi;
        
        ZeroMemory( &si, sizeof(si) );
        si.cb = sizeof(si);
        ZeroMemory( &pi, sizeof(pi) );
    
        CreateProcess("C:\Windows\System32\calc.exe", // No module name (use command line). 
            NULL, 
            NULL,          
            NULL,           
            FALSE,          
            0,              
            NULL,          
            NULL,            
            &si,           
            &pi );
    
    //    SetHook();    //这里可以继续设置然后继续抓API函数
    }

  • 相关阅读:
    命令行net time同步时间(内网)
    清理树莓派系统垃圾
    树莓派常用功能的安装和使用
    树莓派的媒体播放软件omxplayer
    树莓派安装FTP服务器
    Raspbian 中国软件源
    树莓派挂载和卸载U盘或移动硬盘
    树莓派上搭建NAS
    Aria2+yaaw+Chrome插件BaiduExporter实现百度网盘下载
    树莓派做下载机+Web服务器(Aria2下载+yaaw做UI+nginx)
  • 原文地址:https://www.cnblogs.com/Lee-geeker/p/3413297.html
Copyright © 2020-2023  润新知