zoukankan      html  css  js  c++  java
  • hook技术--优化代码hook

    .

    1.简介

    在代码hook中,由于频繁的进行hook和unhook,而且又加上多线程的一些不可靠的因素,会使程序执行效率降低而且可能会导致错误,即

    多线程对其hook和unhook导致不稳定的可能性增加, 因此需要找一种不需要频繁进行hook和unhook的方法.

    而windows的一些API提供了一种很好的优化方式. 即API代码以mov edi,edi 指令开头,这条执行占了2个字节,而且2个API之间

    有5个nop指令,这些nop在一个ret和一个API基址之间,不会被执行到.所以前5个字节可以放下一个远跳转指令,开头2个字节可以存放

    一个短跳转指令,通过短跳转指令跳到远跳转指令基址,即可实现hook,然后在hook函数中直接跳转或call到API基址+2的地方执行API.

    2.以hook explorer.exe进程的CreateProcessW函数为例, 对于路径中存在qq(不区分大小写)的的进程不予执行的功能的实现

    // dllmain.cpp : 定义 DLL 应用程序的入口点。
    #include "stdafx.h"
    #include <Windows.h>
    #include <wchar.h>
    #include <string.h>
    #define FuncName "CreateProcessW"
    #define DllName "kernel32.dll"
    
    
    typedef BOOL (WINAPI *lpCreateProcessW)
    (
        __in_opt    LPCWSTR lpApplicationName,
        __inout_opt LPWSTR lpCommandLine,
        __in_opt    LPSECURITY_ATTRIBUTES lpProcessAttributes,
        __in_opt    LPSECURITY_ATTRIBUTES lpThreadAttributes,
        __in        BOOL bInheritHandles,
        __in        DWORD dwCreationFlags,
        __in_opt    LPVOID lpEnvironment,
        __in_opt    LPCWSTR lpCurrentDirectory,
        __in        LPSTARTUPINFOW lpStartupInfo,
        __out       LPPROCESS_INFORMATION lpProcessInformation
    );
    
    
    BOOL MyCreateProcessW
    (
        __in_opt    LPCWSTR lpApplicationName,
        __inout_opt LPWSTR lpCommandLine,
        __in_opt    LPSECURITY_ATTRIBUTES lpProcessAttributes,
        __in_opt    LPSECURITY_ATTRIBUTES lpThreadAttributes,
        __in        BOOL bInheritHandles,
        __in        DWORD dwCreationFlags,
        __in_opt    LPVOID lpEnvironment,
        __in_opt    LPCWSTR lpCurrentDirectory,
        __in        LPSTARTUPINFOW lpStartupInfo,
        __out       LPPROCESS_INFORMATION lpProcessInformation
    );
    DWORD hook(DWORD funcBase, DWORD fakeBase);
    DWORD unhook(DWORD funcBase, DWORD fakeBase);
    
    BYTE orgCode[7] = { 0 };
    BYTE fakeCode[7] = { 0xe9 ,0,0,0,0, 0xeb,0xf9 };//短跳转部分直接硬编码
    DWORD functionBase;
    
    
    BOOL APIENTRY DllMain( HMODULE hModule,
                           DWORD  ul_reason_for_call,
                           LPVOID lpReserved
                         )
    {
        DWORD funcBase = (DWORD)GetProcAddress(GetModuleHandleA(DllName), FuncName);
        DWORD fakeBase = (DWORD)MyCreateProcessW;
        functionBase = funcBase + 2; //越过mov edi,edi 或者短跳转并不影响执行
    
        switch (ul_reason_for_call)
        {
        case DLL_PROCESS_ATTACH:
    
            hook(funcBase, fakeBase);
            break;
        case DLL_PROCESS_DETACH:
            unhook(funcBase, fakeBase);
            break;
        }
        return TRUE;
    }
    
    DWORD hook(DWORD funcBase, DWORD fakeBase)
    {
        if (*(BYTE*)funcBase==0xeb)
        {
            return 0;
        }
        DWORD page;
        DWORD opcode;
        VirtualProtect((LPVOID)(funcBase - 5), 7, PAGE_EXECUTE_READWRITE, &page);
        memcpy(orgCode , (LPVOID)(funcBase - 5), 7);
        opcode = fakeBase - funcBase;//fakeBase - (funcBase - 5) - 5=fakeBase - funcBase
        memcpy(fakeCode + 1, &opcode, 4);
        memcpy((LPVOID)(funcBase - 5), fakeCode, 7);
        VirtualProtect((LPVOID)(funcBase - 5), 7, page, &page);
        return 1;
    }
    
    DWORD unhook(DWORD funcBase, DWORD fakeBase)
    {
        if (*(BYTE*)funcBase != 0xeb)
        {
            return 0;
        }
        DWORD page;
        VirtualProtect((LPVOID)(funcBase - 5), 7, PAGE_EXECUTE_READWRITE, &page);
        memcpy((LPVOID)(funcBase - 5), orgCode, 7);
        VirtualProtect((LPVOID)(funcBase - 5), 7, page, &page);
        return 1;
    }
    BOOL MyCreateProcessW
    (
        __in_opt    LPCWSTR lpApplicationName,
        __inout_opt LPWSTR lpCommandLine,
        __in_opt    LPSECURITY_ATTRIBUTES lpProcessAttributes,
        __in_opt    LPSECURITY_ATTRIBUTES lpThreadAttributes,
        __in        BOOL bInheritHandles,
        __in        DWORD dwCreationFlags,
        __in_opt    LPVOID lpEnvironment,
        __in_opt    LPCWSTR lpCurrentDirectory,
        __in        LPSTARTUPINFOW lpStartupInfo,
        __out       LPPROCESS_INFORMATION lpProcessInformation
    )
    {
        WCHAR exeName[MAX_PATH] = { 0 };
        if (wcsstr(lpApplicationName,L"qq")|| wcsstr(lpApplicationName, L"QQ") || wcsstr(lpApplicationName, L"Qq")
            || wcsstr(lpApplicationName, L"qQ"))
        {
            wsprintfW(exeName, L"%s没交保护费,禁止启动", lpApplicationName);
            MessageBoxW(0, exeName, L"温馨提示", 0);
            return 0;
        }
        else
        {
            wsprintfW(exeName, L"%s交了保护费,予以启动", lpApplicationName);
            MessageBoxW(0, exeName, L"温馨提示", 0);
            return ((lpCreateProcessW)functionBase)( 
                lpApplicationName,
                lpCommandLine,
                lpProcessAttributes,
                lpThreadAttributes,
                bInheritHandles,
                dwCreationFlags,
                lpEnvironment,
                lpCurrentDirectory,
                lpStartupInfo,
                lpProcessInformation);
        }
    
    
    
    
    
    }
  • 相关阅读:
    ECharts之柱状图 饼状图 折线图
    Vue自定义指令(directive)
    HDU 1231 最大连续子序列
    POJ 2533 Longest Ordered Subsequence
    HDU 1163 Eddy's digital Roots
    HDU 2317 Nasty Hacks
    HDU 2571 命运
    HDU 4224 Enumeration?
    HDU 1257 最少拦截系统
    HDU 2740 Root of the Problem
  • 原文地址:https://www.cnblogs.com/freesec/p/6561656.html
Copyright © 2011-2022 走看看