HOOK之APIhook(转)

日常抄好友代码,原文链接:https://www.jianshu.com/p/1c8280bc88a4

最近分析一个样本,发现其是hook一个API函数,逻辑如下:

HOOK之APIhook(转)_第1张图片

hook函数
1.获取ZwWriteVirtualMemory的基址

HMODULE ntdll = LoadLibraryA("ntdll.dll");
byte * ZwBase =(byte *)GetProcAddress(ntdll,"ZwWriteVirtualMemory");

2.修改内存保护属性使其可被修改

if(VirtualProtect(ZwBase,10,PAGE_EXECUTE_READWRITE,&lpflOldProtect))

3.创建一个全局空间,这个空间用来存放ZwWriteVirtualMemory的第一条指令和跳转到ZwWriteVirtualMemory的第二条指令。

VABase = (byte *)VirtualAlloc(0,10,MEM_COMMIT,PAGE_EXECUTE_READWRITE);
memcpy(VABase,ZwBase,5);
VABase[5] = 0xE9;
*(int *)(VABase+6) = ZwBase - VABase -5;//set jmp addr point

这里值得一提的是如何计算偏移。偏移 = 将要跳转到的地址 - jmp指令执行完后,下一条指令的起始地址,用上面的例子计算一下,要跳转到ZwWriteVirtualMemory的第二条指令,这里的地址等于(ZwBase+5)第一条指令长度为5,jmp指令在新创建的空间中,前面拷贝了5个字节的指令,后面的jmp一个字节,紧接着的偏移地址4个字节所以jmp指令后的地址是(VABase +10),结果:偏移 = ZwBase+5 - (VABase +10)=ZwBase - VABase -5


4.hook API ZwWriteVirtualMemory


       把API开头的第一条指令改成跳转到hook的函数地址

ZwBase[0] = 0xE9;
*(int *)(ZwBase+1) = (byte *)AttackFunc - ZwBase -5;

5.执行hook函数

上面的API被修改了,等等创建进程一定会用到ZwWriteVirtualMemory,就会跳入我们设定好的API函数,我们的API函数第一步先执行了ZwWriteVirtualMemory这个API没有执行完的部分,等这个函数执行完后,eip将会返回回来,执行我们设定好的恶意代码了。

void AttackFunc(IN HANDLE hProcess, IN PVOID BaseAddress, IN PVOID Buffer, IN ULONG BytesToWrite, OUT PULONG BytesWritten)
{
    func((DWORD)hProcess,(DWORD)BaseAddress,(DWORD)Buffer,BytesToWrite,(DWORD)BytesWritten);
    MessageBox(0,"infected",0,0);
}

6.创建进程。

我们废了那么大的劲,如果没创建进程就一点用没有了。

CreateProcessA("C:\\Users\\john\\Desktop\\calc.exe",0,0,0,0,0,0,0,&st,&pi);

7.源码

// ApiHook.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include 

byte * VABase;
typedef int (__stdcall *Func)(DWORD,DWORD,DWORD,DWORD,DWORD);
Func func;

void AttackFunc(IN HANDLE hProcess, IN PVOID BaseAddress, IN PVOID Buffer, IN ULONG BytesToWrite, OUT PULONG BytesWritten)
{
    func((DWORD)hProcess,(DWORD)BaseAddress,(DWORD)Buffer,BytesToWrite,(DWORD)BytesWritten);
    MessageBox(0,"infected",0,0);
}

int modifyApi()
{
    HMODULE ntdll = LoadLibraryA("ntdll.dll");
    byte * ZwBase =(byte *)GetProcAddress(ntdll,"ZwWriteVirtualMemory");
    DWORD lpflOldProtect=0;
    if(VirtualProtect(ZwBase,10,PAGE_EXECUTE_READWRITE,&lpflOldProtect))
    {
        VABase = (byte *)VirtualAlloc(0,10,MEM_COMMIT,PAGE_EXECUTE_READWRITE);
        memcpy(VABase,ZwBase,5);
        VABase[5] = 0xE9;
        *(int *)(VABase+6) = ZwBase - VABase -5;//set jmp addr point
        ZwBase[0] = 0xE9;
        *(int *)(ZwBase+1) = (byte *)AttackFunc - ZwBase -5;
        if(!VirtualProtect(VABase,10,PAGE_EXECUTE_READWRITE,&lpflOldProtect))
        {
            return -1;
        }
        func = (int (__stdcall *)(DWORD,DWORD,DWORD,DWORD,DWORD))VABase;

    }
    return 1;
}

int _tmain(int argc, _TCHAR* argv[])
{
    /*
        确定要几个数据
        ZwWriteVirtualMemory的第一条指令
        跳转到第二条指令
        把ZwWriteVirtualMemory第一条指令修改为跳转到指定内存空间
    */
    STARTUPINFO st ={0};
    PROCESS_INFORMATION pi = {0};
    if(modifyApi())
    {
        CreateProcessA("C:\\Windows\\System32\\calc.exe",0,0,0,0,0,0,0,&st,&pi);
        int err = GetLastError();
    }
    return 0;
}

8.效果

HOOK之APIhook(转)_第2张图片

你可能感兴趣的:(技巧)