zoukankan      html  css  js  c++  java
  • 学习c++ (六)注入和inline hook

    不知为何叫inlink hook 叫hot patch 更适合一点,说的是什么事呢,大概是这个意思

    int ccc(int a, int b)
    { 
        a++;
        b++;
        return a + b;
    }
    int main()
    {
        getchar();
        char k[] = "xxxx"; //写这一行,在OD上容易找到位置,要不还得麻烦!
        int c = ccc(1, 2);
        cout << c << endl;
     
     
        system("pause");
        return 0;
    }

    现在我想在跟一个第三方程序时,想获取ccc方法中a的值,或者说想修改参数a的值,那么就肯定要改ccc这个函数的一些东西 ,最后变成这样的

    int ccc(int a, int b)
    { 
        goto newaddress();
        backaddress:
        a++;
        b++;
        return a + b;
    }
    
    int newaddress()()
    {
        do sth....
        goto backaddress;
    }

    当然在c++里是不能这样写的,但在内存里执行指令的时候可以,当然也有区别,内存的指令是不可以插队的,但可以换个办法把某个指令换掉,后面再执行回来

    比如

    在内存里,调用ccc方法(call C2.012B10EB)之前,有两个指令push ,分别把1和2这个参数传给它了,就在这里下手

    一般情况下,为什么要用call来下手呢,因为刚好我们要用jmp xxxxxx 等5个字节替换它,长度一致,省得出问题,就直接替换成jmp  xxxxxxxx

    跳过去弄完自己的事,然后把这个call C2.012B10EB 执行一下,然后跳回012B6C11这个地址继续执行,即可达到自己的目的 ,这个哥们虽然没有完整代码,但写的较好理解 

    https://www.cnblogs.com/luoyesiqiu/p/12306336.html

    exe代码就上面那些,啥都没有,空壳,dll代码如下:

    //#include "stdafx.h";
    
    #include <iostream>;
    using namespace std;
    #include <windows.h>;
    #include <tlhelp32.h>;
    #include <tchar.h>;
    #include<stdio.h>;
    
     
    DWORD WINAPI MyThreadProc2( LPVOID pParam );
    DWORD WINAPI MyThreadProc1(LPVOID pParam);
     
    int StartHooks(DWORD hookAddr, BYTE backCode[5], void(*FuncBeCall)());
    BYTE backCode[5] = { 0 };
    DWORD baseaddr;
    DWORD calloriaddr;
    DWORD jmbback;
    BOOL isrun=TRUE;
    DWORD EXesp;
    char addInt[1] = {5};
    char testkk[1024] = { 0 };
    int Unhooks(DWORD hookAddr, BYTE backCode[5]);
    void Wchar_tToString(std::string& szDst, wchar_t* wchar);
    HANDLE hProcessForWrite;
    
    
    int StartHooks(DWORD hookAddr, BYTE backCode[5], void(*FuncBeCall)()) {
        DWORD jmpAddr = (DWORD)FuncBeCall - (hookAddr + 5);
        BYTE jmpCode[5];
        *(jmpCode + 0) = 0xE9;
        *(DWORD*)(jmpCode + 1) = jmpAddr;
        HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, NULL, GetCurrentProcessId());
        if (ReadProcessMemory(hProcess, (LPVOID)hookAddr, backCode, 5, NULL) == 0) {
            return -1;
        }
    
        if (WriteProcessMemory(hProcess, (LPVOID)hookAddr, jmpCode, 5, NULL) == 0) {
            return -1;
        }
    
        return 0;
    }
    int Unhooks(DWORD hookAddr, BYTE backCode[5]) {
        HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, NULL, GetCurrentProcessId());
        if (WriteProcessMemory(hProcess, (LPVOID)hookAddr, backCode, 5, NULL) == 0) {
            return -1;
        }
        return 0;
    }
    
    _declspec(naked) void OnCall() {
        calloriaddr = baseaddr + 0x110EB;
        jmbback= baseaddr + 0x16C11;
        __asm {
            mov EXesp, esp  //跟了一下,第一个参数传回的值在esp里,所以取了esp的值
            pushad        
        } 
    
        //修改传入的第一个参数的值
        hProcessForWrite = OpenProcess(PROCESS_ALL_ACCESS, NULL, GetCurrentProcessId());
        if (WriteProcessMemory(hProcessForWrite, (LPVOID)EXesp,addInt, sizeof(addInt), NULL) == 0) {
            MessageBox(NULL, "faild", "indll", NULL);
        }
        else
        {
            MessageBox(NULL, "success", "indll", NULL);
        }
     
        __asm {
            popad
            call calloriaddr
            jmp jmbback
        }
        isrun = FALSE;
    }
    
    DWORD WINAPI MyThreadProc1(LPVOID pParam)
    {
        while (isrun)
        {
                Sleep(100);
        }
        DWORD hkaddr = baseaddr + 0x16C0C;
        Unhooks(hkaddr, backCode);
        return 0;
    }
     
    DWORD WINAPI MyThreadProc2( LPVOID pParam )
    {
        isrun = TRUE;
        HMODULE hModule = GetModuleHandle(NULL);
        baseaddr = (DWORD) hModule;
        DWORD hkaddr = baseaddr+ 0x16C0C;
    
        char kk[1024] = { 0 };
        sprintf_s(kk, "%x", hkaddr);
    
        MessageBox(NULL, kk, "test", NULL);
    
        StartHooks(hkaddr, backCode,&OnCall);
        return 0;
    
    
    
    
    
     
    }
     
     
     
    BOOL APIENTRY DllMain(HANDLE hModule, DWORD ul_reason_for_call, LPVOID lpReserved)
    {
        switch (ul_reason_for_call)
        {
        case DLL_PROCESS_ATTACH:
        {
            isrun = TRUE;
            MessageBox(NULL, "DLL已进入目标进程。", "信息", MB_ICONINFORMATION);
            DWORD dwThreadId;
    
            HANDLE myThread2 = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)MyThreadProc2, NULL, 0, &dwThreadId);
            HANDLE myThread1 = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)MyThreadProc1, NULL, 0, &dwThreadId);
            break;
        }
        case DLL_PROCESS_DETACH:
        {
            MessageBox(NULL, "DLL已从目标进程卸载。", "信息", MB_ICONINFORMATION);
            break;
        }
        }
        return TRUE;
    }
     
  • 相关阅读:
    编译内核时出现drivers/mfd/mxchdmicore.c:36:24: fatal error: mach/clock.h: No such file or directory
    IE中iframe标签显示在DIV之上的问题解决方案
    Linux驱动学习1.hello world;
    Maven安装与配置(转)
    Jmeter阶梯式压测
    Jmeter的分布式测试
    adb connect命令连接多个Android设备
    Linux当中文件的显示命令
    软件测试流程
    测试时间不够,该怎么办?
  • 原文地址:https://www.cnblogs.com/szyicol/p/13031161.html
Copyright © 2011-2022 走看看