[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;
}