添加链接
link之家
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接
首发于 hookwechat
C++ DLL注入微信实现自动接收、发送消息

C++ DLL注入微信实现自动接收、发送消息

用了半个暑假学C++,hook WX,成功调用发送消息call,接收消息响应call。在B站参考了Hezone和Hellmessage两位大神的视频,虽然WX更新较快,汇编代码已经面目全非,但思路很有启发性。写篇文章记下实现过程,方便日后复习。

用到的工具有:visual studio,cheat engine,ollydbg。


写一个DLL

这个DLL相当于我们的间谍,潜入WX内部,然后和外部主程序通信进行相应操作。

  1. 打开VS,创建新项目,选择”动态链接库“

创建了一个名为Dll1的DLL,dllmain.cpp里有vs为我们准备好的DLL程序入口。

我们的执行的代码要在DLL_PROCESS_ATTACH下面写。

BOOL APIENTRY DllMain( HMODULE hModule,
                       DWORD  ul_reason_for_call,
                       LPVOID lpReserved
    switch (ul_reason_for_call)
    case DLL_PROCESS_ATTACH:
        /*我们的代码,注入DLL后会执行*/
    case DLL_THREAD_ATTACH:
    case DLL_THREAD_DETACH:
    case DLL_PROCESS_DETACH:
        break;
    return TRUE;

先打开头文件pch.h,然后写上

#include <windows.h>

再回到dllmain,加一个弹窗。

case DLL_PROCESS_ATTACH:
        /*我们的代码,注入DLL后会执行*/
        MessageBox(0,L"成功潜入微信内部!",L"报告主人",NULL);

按F5生成。

打开项目目录下的Debug文件夹,我们可以看到我们生成的Dll1.dll和Dll1.pdb。

DLL注入程序

写完简单的DLL,然后写一个Inject DLL 注入程序(exe),用远程线程注入的方法,把自己的DLL注入到WX进程。

我们再创建一个新项目,选择“控制台程序”,将项目命名为Inject。

方法是先通过WX程序的Pid,调用OpenProcess用可获得的所有权限打开进程,再用VirtualAllocEx在WX进程的地址空间开辟一块内存,调用WriteProcessMemory把我们写的DLL的路径写到WX的内存里。 [1]

我们要想办法创建一个远程线程(CreateRemoteThreadEx),让线程执行“LoadLibrary"让微信载入我们的DLL。我们不能直接&LoadLibrary取到函数地址然后传过去让线程执行,因为我们的注入程序的LoadLibrary地址和WX地址空间的LoadLibrary地址不一致。所以我们要用GetProcAddress获取LoadLibrary的地址。

完整代码如下:

int main() {
	DWORD pid = 0;
        scanf("%d",pid);
	HANDLE hprocess = OpenProcess(PROCESS_ALL_ACCESS, false, pid);
	if (!hprocess) {
		std::cout << "can not get handle" << std::endl;
		return 1;
	SIZE_T PathSize = (strlen(DLLPath) + 1) * sizeof(TCHAR);
	LPVOID StartAddress = VirtualAllocEx(hprocess, NULL, PathSize, MEM_COMMIT, PAGE_READWRITE);
	if (!StartAddress) {
		std::cout << "开辟内存失败" << std::endl;
		return 1;
	if (!WriteProcessMemory(hprocess, StartAddress, DLLPath, PathSize, NULL)) {
		std::cout << "无法写入DLL路径" << std::endl;
		return 1;
	PTHREAD_START_ROUTINE pfnStartAddress = (PTHREAD_START_ROUTINE)GetProcAddress(GetModuleHandle(_T("kernel32.dll")), "LoadLibraryA");
	if (!pfnStartAddress) {
		std::cout << "无法获取函数地址" << std::endl;
		return 1;
	HANDLE hThread = CreateRemoteThreadEx(hprocess, NULL, NULL, pfnStartAddress, StartAddress, NULL, NULL, NULL);
	if (!hThread) {
		std::cout << "创建线程失败" << std::endl;
		return 1;
	//WaitForSingleObject(hThread, INFINITE);//等待DLL结束
	std::cout << "注入成功!\n";
	CloseHandle(hThread);
	CloseHandle(hprocess);
	return 0;

然后生成。

登录WX,我们再在cmd输入tasklist,找到WeChat.exe,这个WX的主进程,记下PID,之后运行我我们写的Inject.exe,输入pid。

成功显示,任务栏下方还光明正大的表示成WX的图标,真是血统正宗!


还是来更新一下,做个预告吧。

上面我们让我们的DLL注入到WX里了,这相当于我们光明正大的闯进了他的房子,可以为所欲为!

是的,我们的DLL可以像操作自己的内存一样,读取修改WX的内存,甚至调用和修改他的执行代码!

接下来会以获取到用户信息,如昵称,WX号,电话号码,头像等,讲怎么读取他的内存。

经评论区知友好心提醒,怕被抓,所以
#define WX 微信

我又回来啦!

DLL读取用户信息

登录微信后,打开CE,添加微信。

将Value Type改成String,然后输入我们的微信号,一定要一字符不差。

然后first scan扫描,会发现两个绿色的地址。绿色就代表着这个地址的相对位置是不变的,因为我们的微信号、手机号这些,登录之后就不会变化,所以这两个地址符合我们的条件。把他们添加到下栏。

鼠标悬停在上面可以看到,如果你的绿色地址和我一样是一个dll加一个十六进制数,那么后面的0x1D29B60就是我们要找的偏移量。我们可以用WeChatWin.dll基址加上偏移量,就能得出每次运行微信后,微信号的地址。

如果你只是个绿色的地址,那就点击add address manually,输入WeChatWin.dll,然后OK,下栏会多出一个以4个0结尾的地址,这就是这次启动微信WeChatWin.dll的值。

打开计算器,选程序员模式,换到十六进制,用刚刚的一个绿色地址和这个值相减,得出的数值便是偏移。

得到偏移后,找个踏实的地方记下来,以免丢失,又要重新来过。可以直接define到我们的DLL源码里。

用同样方法可以找出微信昵称和电话号码、微信头像什么的。

所以,要获取微信号的地址,只要获取WeChatWin模块基址和偏移然后相加,我们已经找到偏移,怎么让dll知道基址呢?

因为这会我们的DLL已经注入进去,是和WeChatWin.dll等同属一个进程,所以我们可以直接调用GetModuleHandle:

GetModuleHandle(L"WeChatWin.dll");

为了方便易理解,我们封装成函数:

HMODULE GetWechatWin() {
    return GetModuleHandle(L"WeChatWin.dll");