• PE基础7-HOOK练习


    HOOK练习

    头文件内容

    #include <windows.h>// Inline Hook: 原理是修改程序执行流程上的代码,使代码可以从目标地址跳转到
    //              指定的位置,从而获取函数的调用情况。微软专门给所有的库函数
    //              提供了 6 字节的垃圾指令进行 Hook。
    // Inline Hook 要注意的地方: 线程安全。如果在修改指令的同时,其它的线程正
    //              在调用该地址的指令,那么由于指令修改完成了一半,得到的OpCode
    //              是不确定的,会导致崩溃。解决方式是
    //              ①:在 Hook 前,暂停当前进程的所有其它线程
    //              ②:使用原子操作: InterLocked 系列函数,原理是锁地址总线 lock
    // 保存 Hook 之前的原始 OpCode
    BYTE OldOpCode[5] = { 0x00 };
    ​
    // 保存新的用于跳转的 OpCode: E9 xxxxxxxx
    BYTE JmpOpCode[5] = { 0xE9 };
    ​
    // 保存需要修改的函数所在的地址
    LPVOID Addr = nullptr;
    ​
    // 保存需要保护的 PID 
    LONG Pid = 0;
    ​
    ​
    // 1. 我要 Hook 的是哪一个进程, OD 和 Taskmgr
    // 2. 为了 OD 不能附加目标进程,可以 Hook 函数 OpenProcess
    // 3. 编写自己的函数,务必保证原型完全一致,用于接管原始函数,主要执行[筛选]工作
    ​
    ​
    // 开启关闭 Hook
    void EnableHook(BOOL Enable = TRUE)
    {
        DWORD OldProtect = 0;
    ​
        // 1. 修改目标地址所在分页的属性
        VirtualProtect(Addr, 5, PAGE_EXECUTE_READWRITE, &OldProtect);
    ​
        // 2. 根据开启或关闭,向内填充新的旧的 OpCode
        memcpy(Addr, Enable ? JmpOpCode : OldOpCode, 5);
    ​
        // 3. 还原目标地址所在分页的属性
        VirtualProtect(Addr, 5, OldProtect, &OldProtect);
    }
    ​
    ​
    // 自己编写的函数,在不满足条件的情况下,应该要调用原始函数
    HANDLE WINAPI MyOpenProcess(DWORD dwDesiredAccess, BOOL bInheritHandle, DWORD dwProcessId)
    {
        HANDLE Handle = 0;
    ​
        // 如果 pid 是 0x1515 就返回 -1
        if (dwProcessId == Pid)
        {
            Handle = INVALID_HANDLE_VALUE;
        }
        else
        {
            // 为了不产生递归,应该先还原被 Hook 的指令
            EnableHook(FALSE);
            Handle = OpenProcess(dwDesiredAccess, bInheritHandle, dwProcessId);
            // 为了下一次,还会进入 MyOpenProcess,要继续 Hook 
            EnableHook();
        }
    ​
        return Handle;
    }
    ​
    ​
    // 执行初始化的函数,例如保存原始指令,构建新的指令
    void initialize()
    {
        // 1. 获取需要 Hook 的函数的地址,在系统运行时,
        //    所有[系统模块]在不同进程中的地址都是相同的
        Addr = GetProcAddress(LoadLibraryA("kernel32.dll"), "OpenProcess");
    ​
        // 2. 保存原始的指令,为了恢复原始代码 InterlockedExchang()
        memcpy(OldOpCode, Addr, 5);
    ​
        // 3. 计算跳转偏移: 新的函数地址 - 旧的函数地址 - 5(E9XXXXXXXX)
        DWORD Offset = (DWORD)MyOpenProcess - (DWORD)Addr - 5;
    ​
        // 4. 组合成新的 OpCode
        *(DWORD*)&JmpOpCode[1] = Offset;
    ​
        // 5. 获取需要保护的 Pid,第三个参数返回上一次的信号个数
        HANDLE Semaphore = OpenSemaphore(SEMAPHORE_ALL_ACCESS, FALSE, L"MYPID");
        ReleaseSemaphore(Semaphore, 1, &Pid);
    }

    Dllmain文件内容

    #include "framework.h"
    ​
    BOOL APIENTRY DllMain( HMODULE hModule,
                           DWORD  ul_reason_for_call,
                           LPVOID lpReserved
                         )
    {
        switch (ul_reason_for_call)
        {
        case DLL_PROCESS_ATTACH:
            initialize();
            EnableHook();
            break;
        case DLL_PROCESS_DETACH:
            EnableHook(FALSE);
            break;
        }
        return TRUE;
    }

    main

    #include <windows.h>// 务必确保使用的是绝对路径
    const char* DllName = "C:\Users\Administrator\Desktop\2\D15安全卫士0701\Debug\HookDll.dll";
    ​
    int main()
    {
        // 在编写 dll 时,最初应该在自己的程序上使用 LoadLibrary 进行测试
    // 创建了一个信号量,保存了一些数值(初始信号Pid,最大信号Pid+1)
        HANDLE Semaphore = CreateSemaphore(NULL, 
            GetCurrentProcessId(), GetCurrentProcessId() + 1, "MYPID");
    ​
        // 1. 通过窗口名称确定目标的 Pid
        DWORD Pid = 0, Size = 0;
        HWND hWnd = FindWindow(NULL, "任务管理器");
        //HWND hWnd = FindWindow(NULL, "吾愛破解 - [LCG]");
        GetWindowThreadProcessId(hWnd, &Pid);
    ​
        // 2. 使用对应的权限打开目标进程
        HANDLE Handle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, Pid);
    ​
        // 3. 申请空间,主要用于存放的是 LoadLibrary 的参数,务必确保版本(A/W)对应
        LPVOID Addr = VirtualAllocEx(Handle, NULL, 0x1000, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);
        
        // 4. 写入数据,注意写入的长度
        WriteProcessMemory(Handle, Addr, DllName, strlen(DllName) + 1, &Size);
    ​
        // 5. 创建远程线程,注意版本
        CreateRemoteThread(Handle, NULL, NULL, (LPTHREAD_START_ROUTINE)LoadLibraryA, Addr, NULL, NULL);
    ​
        system("pause");
    ​
        return 0;
    }

     

  • 相关阅读:
    HDU1542 Atlantis(矩形面积并)
    HDU4784 Dinner Coming Soon(dp)
    1023: [SHOI2008]cactus仙人掌图(DP+单调队列优化)
    BZOJ 1004: [HNOI2008]Cards(群论)
    BZOJ USACO 银组 水题集锦
    BZOJ 3401: [Usaco2009 Mar]Look Up 仰望(离线+平衡树)
    BZOJ 3404: [Usaco2009 Open]Cow Digit Game又见数字游戏(博弈论)
    BZOJ 3208: 花神的秒题计划Ⅰ
    BZOJ 2456: mode(乱搞)
    BZOJ 2424: [HAOI2010]订货(费用流)
  • 原文地址:https://www.cnblogs.com/ltyandy/p/11116917.html
Copyright © 2020-2023  润新知