吾爱破解 - LCG - LSG |安卓破解|病毒分析|www.52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 3326|回复: 2
收起左侧

[C&C++ 原创] C++ inline hook 获取模块名之GetModuleFileNameW

  [复制链接]
bester 发表于 2019-12-5 15:09
本帖最后由 bester 于 2019-12-5 15:14 编辑

环境:win10+VS2019+动态链接库项目+unicode字符集

效果图:
1.jpg

2.jpg

3.jpg

重点难点:
首先我们来看一下OD的调用情况 大概是这样的
push 缓冲区 (此时假设缓冲区地址是12345678)

call GetModuleFileNameW

然后如果我们将缓冲区的地址给改成我们自定义的字符串指针的地址,那么就会导致这个缓冲区里面是空的,也就是说程序不会从我们修改的缓冲区读取内容,所以我们需要做的就是写入这个缓冲区内容

当然我们也可以直接对这个缓冲区写入字符串,然后直接在API头部retn ,不让其调用API,这个方法也是可以的,但是有的时候会导致一些错误,因为寄存器的值没有改变。

[C++] 纯文本查看 复制代码
// dllmain.cpp : 定义 DLL 应用程序的入口点。
#include "pch.h" //这个是动态链接库必写头文件,好像删除了就会出错,不管他
#pragma warning(disable : 4996) //这个是屏蔽不安全函数的一个提示,因为使用了wcscpy函数拷贝字符串
//EXTERN_C _declspec(dllexport) void MyMain();  //这个是声明导出函数,供其他语言调用,但是我没有写Mymain函数,我把代码写到dllmain函数下了
typedef DWORD(WINAPI* MyGetNameW)(HMODULE, LPWSTR , DWORD ); //这个是声明一个函数类型,然后使用指针调用,这里用不上 可以不管他,删除也无所谓
BYTE buffer[5] = { 0 }; //这个是保存API头部5个字节,全局变量
BYTE buffer1 = { 0 }; //这里是判断我有没有写入hook,全局变量
DWORD Apiaddr = NULL; //这里是获得API地址,全局变量
int mylen(int x, int y) //这个函数是计算jmp距离
{
        return x - y - 5;
}
DWORD WINAPI MyGetModuleFileNameW(HMODULE hModule, LPWSTR lpFilename, DWORD nSize)  //这个是我自己构造的GetModuleFileNameW函数的原型,HOOK以后调用的API就会来到这个函数下面
{
        
        WriteProcessMemory(GetCurrentProcess(), (LPVOID)Apiaddr, &buffer, 5, NULL);  //这里先还原我的HOOK,相当于易语言的hook.暂停,因为这个函数比较特殊,他需要先调用API函数,写入缓冲区内容,因为被
我hook了,所以没法调用原函数,所以先需要还原,等调用完,再继续hook
        DWORD myret=GetModuleFileNameW(hModule, lpFilename, nSize); //这里就是调用原函数,跟易语言的一样
    LPWSTR myname = (LPWSTR)(L"C:\\Program Files (x86)\\Nwt\\Bester123.exe"); //这里呢就是准备好我需要让他返回的字符串,
        wcscpy(lpFilename, myname); //将我的字符串拷贝到缓冲区,千万不能lpFilename=myname,为什么?因为myname是一个字符串指针,是一个地址,lpFilename是一个堆栈地址,堆栈地址保存着字符串指针,字符串指针是一个地址,如果我们这样写的话,会导致原来的字符串缓冲区没有内容,程序只会从原来的缓冲区读内容,给大家打个比方就是,我提了一个红色的篮子去店里买苹果,我原本是要老板给我这个红色篮子装满,但是老板给了我一个绿色篮子,里面装满了苹果,虽然结果都是买到了苹果,但是在程序看来,我这个红色篮子是没有东西的,所以即使我这个买苹果的结果是成功的,但是程序本身是不承认的。
        WriteProcessMemory(GetCurrentProcess(), (LPVOID)Apiaddr, &twbuffer, 1, NULL); //这里就是恢复hook
        int lens = mylen((int)&MyGetModuleFileNameW, (int)Apiaddr); //依旧是计算jmp距离
        WriteProcessMemory(GetCurrentProcess(), LPVOID((int)Apiaddr + 1), &lens, 4, NULL); //写入jmp距离
        return myret; //正常返回
}


BOOL APIENTRY DllMain(HMODULE hModule, DWORD  ul_reason_for_call, LPVOID lpReserved)
{

        Apiaddr=(DWORD)GetProcAddress(LoadLibrary(TEXT("KernelBase.dll")), "GetModuleFileNameW"); //先获取api地址
        ReadProcessMemory(GetCurrentProcess(), (LPVOID)Apiaddr, &buffer1, 1, NULL); //判断是否hook过,因为这个dllmain会被调用多次,如果不判断会导致我们取的原字节是我们hook的字节,就会导致还原hook失败
        if (buffer1!= 233)
        {
                ReadProcessMemory(GetCurrentProcess(), (LPVOID)Apiaddr, &buffer, 5, NULL); //如果没有hook过,就读取5个字节
        }
        BYTE wbuffer = 233;
        WriteProcessMemory(GetCurrentProcess(), (LPVOID)Apiaddr, &wbuffer, 1,NULL); //写入jmp
        int lens = mylen((int)&MyGetModuleFileNameW, (int)Apiaddr); //计算距离
        WriteProcessMemory(GetCurrentProcess(), LPVOID((int)Apiaddr+1), &lens, 4, NULL); //写入距离
        return TRUE;
}

免费评分

参与人数 2吾爱币 +4 热心值 +2 收起 理由
白影33 + 1 + 1 十分感谢,自己的函数全用汇编很麻烦,我一直想不明白函数怎么用c++写,看.
苏紫方璇 + 3 + 1 欢迎分析讨论交流,吾爱破解论坛有你更精彩!

查看全部评分

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

白影33 发表于 2020-1-30 15:46
我的想法是WriteProcessMemory修改函数汇编的retn
跳到我的汇编代码,然后跳回retn,只想到用汇编怎么写
但是太麻烦了,不知道怎么用c++写,
没想到c++是可以这么写,
不知道楼主从那学的这些?能不能说一下学习学习
白影33 发表于 2020-2-6 12:39
老哥你的代码有点问题, WriteProcessMemory前要用VirtualProtect改变内存属性可读可写,系统dll的权限都是read,没有VirtualProtect写不进去的
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则 警告:本版块禁止灌水或回复与主题无关内容,违者重罚!

快速回复 收藏帖子 返回列表 搜索

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-5-19 18:04

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表