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);
        }
    
    
    
    
    
    }
  • 相关阅读:
    ASP.NET编程的十大技巧
    ADO.NET实用经验总结(5大对象访问数据库)
    一些讲C#3.0 的好文章收集
    新打开窗口,MD5加密,实体类方式保存在Session中,获得系统根路径,分页,动态获取XML数据到页面
    System.Drawing.Color.FromArgb(144,238,255);
    重要社区链接(资源技术网站)
    case when factsqy is NULL then '0' when factsqy is NOT NULL then factsqy end as factqtys
    了解Linq之前需要知道的一些概念
    sql left out join http://hi.baidu.com/llscompazz/blog/item/dc5e23d9ce2b62eb39012fb4.html
    正則表達式驗證通用方法
  • 原文地址:https://www.cnblogs.com/freesec/p/6561656.html
Copyright © 2011-2022 走看看