文章目录

  • 微信版本
  • 寻找微信二维码基址
    • PNG文件格式
    • 使用CE过滤基址
    • 使用OD确定二维码基址
    • 验证二维码基址
  • 寻找微信二维码内容的基址
    • 微信二维码的存储内容
    • 使用CE寻找二维码内容的基址
    • 验证基址
    • 定制微信登录二维码的可能性
  • 使用hook截取二维码
    • 最终效果

微信版本

寻找微信二维码基址

PNG文件格式

微信二维码在内存中存放形式是png格式的二进制数据,所以我们需要眼熟一下png的文件格式,如图

前32个字节是固定的,分别是btPngSignature和struct PNG_CHUNK chunk结构,其中保存有png图片的标识。

其中NG和IHDR是每个PNG文件都会有的标识,眼熟一下就好。微信的二维码图片就是通过这种格式在内存中存放

使用CE过滤基址

首先在微信未登录状态下附加微信,此时二维码还未加载

然后选择未知的数值,点击首次扫描

出现三百万个结果

此时我们再次点击切换账号,出现二维码,让保存二维码的地址被赋值

然后选择变动的数值 再次扫描

此时还剩下七万个结果

然后用手机扫描二维码 不要点击登录,再次扫描变动的数值,此时还剩三万多个结果

接着随意移动微信框,点击未变动的数值,还剩一万多个结果。返回二维码登录重复以上操作,直到地址栏还剩下两个绿色的基址,这两个绿色的基址就是我们要的。

因为随机基址的存在,这个地址在各位的电脑上是不一样的。但是低四位是一致的,这两个地址应该是xxxx9194和xxxx919C。

使用OD确定二维码基址

然后重启一次微信,再用CE附加,回到这个状态

用OD附加微信,在找到的第一个地址xxxx9194下内存写入断点

点击切换账号,在二维码未加载时程序会断下。注意,这个地方会断下来两次,第二次才是我们要的结果。

因为二维码是存放在微信的核心模块WeChatWin中的,所以我们在堆栈中找到所有的WeChatWin中的函数

像这种API的调用就可以直接排除掉,然后在每一个疑似函数上下断点。找的时候堆栈尽量往下拉,这个函数会比较靠后。

因为我已经找过一遍了,所以直接告诉你们是这一个。特征是有一个ecx传参。

接着在这个函数上下断点,删除内存访问断点,F9运行

然后扫一下二维码,点击返回二维码登录,程序断下

此时观察ecx指针的内容,明显是一个结构体,结构体的第一个是地址,第二个好像是大小。然后在这个地址上数据窗口跟随

里面是PNG文件的二进制数据,这个就是我们要找的微信二维码的基址

验证二维码基址

打开PCHunter,选择微信进程,查看->查看进程内存,输入地址和大小,然后将内存dump下来

打开图片


现在已经确定就是我们需要的二维码。然后我们将这个call的地址减去模块基址,记录下偏移。待会需要HOOK这个call

寻找微信二维码内容的基址

微信二维码的存储内容

二维码其实是一种开放性的信息存储器,它将固定的信息存储在自己的黑白小方块之间。大部分的二维码都有一个特点,就是里面存放的其实是一段文本。我们可以利用这个文本来寻找突破口

将微信的二维码截图保存,然后用在线的二维码解码器解析微信的二维码

可以看到解码之后的结果是一段网址

使用CE寻找二维码内容的基址

如果直接搜索这段网址是找不到任何结果的,原因是因为微信在保存这段位置的时候,实际上是将它分为了两部分存储

第一部分:http://weixin.qq.com/x
第二部分:/I-yOUnFpRaZOwZyVPC0H

第一部分的固定不变的,第二部分被当作一个参数传入,客户端从服务器获取的只是第二部分的内容。所以我们去搜索第二部分。

另外,微信的二维码会定时刷新,刷新的时候会改变第二部分的内容。如果你搜不到的话可能是因为之前的文本已经失效了。从解析文本到搜索文本最好在一分钟之内完成

此时 我们直接搜索第二部分的文本

搜索完成之后,等待二维码自动刷新,然后找到那个变化之后的地址,用截图上传的方式确保找到的是正确的地址

然后用OD附加微信,在找到的地址上下内存写入断点

等待二维码自动刷新,二维码刷新时会往原来存放二维码的地址写入新的二维码数据,程序就会断下

此时eax指向二维码的文本内容,我们找到堆栈中的第一个地址,在数据窗口显示,此时就能找到存放微信二维码数据的基址了

然后我们在CE中添加WeChatWin.dll模块,找到模块基址,算出偏移(用0x104CF618-0xF250000=127F618)。然后将这个地址换成模块基址+偏移的方式添加到CE地址栏。

验证基址

重新打开微信,用CE载入

保留当前列表,然后将二维码内容指针的值添加到列表

点击确定。此时二维码的内容和解析出来的内容一致,说明基址有效

定制微信登录二维码的可能性

那么我们拿到这个二维码的内容有什么作用呢?我们可以将这个获取到的二维码内容调用二维码生成器的API接口进行再次编码,然后生成一个更加漂亮好看专属二维码,效果如图:

使用hook截取二维码

接着我们编写一个dll,将这个dll注入到微信进程中,利用IAT Hook截取微信的二维码。部分关键代码如下:

开启HOOK

void StartHook(DWORD dwHookOffset,LPVOID pFunAddr, HWND hWnd)
{hDlg = hWnd;//拿到模块基址DWORD dwWeChatWinAddr = GetWeChatWinAddr();//需要HOOK的地址DWORD dwHookAddr = dwWeChatWinAddr + dwHookOffset;   //填充数据jmpCode[0] = 0xE9;//计算偏移*(DWORD*)(&jmpCode[1]) = (DWORD)pFunAddr - dwHookAddr-5;// 保存以前的属性用于还原DWORD OldProtext = 0;// 因为要往代码段写入数据,又因为代码段是不可写的,所以需要修改属性VirtualProtect((LPVOID)dwHookAddr, 5, PAGE_EXECUTE_READWRITE, &OldProtext);//保存原有的指令memcpy(backCode, (void*)dwHookAddr, 5);//写入自己的代码memcpy((void*)dwHookAddr, jmpCode, 5);// 执行完了操作之后需要进行还原VirtualProtect((LPVOID)dwHookAddr, 5, OldProtext, &OldProtext);
}

卸载HOOK

void UnHook(DWORD dwHookOffset)
{DWORD dwWeChatWinAddr = GetWeChatWinAddr();DWORD dwHookAddr = dwWeChatWinAddr + dwHookOffset;// 保存以前的属性用于还原DWORD OldProtext = 0;// 因为要往代码段写入数据,又因为代码段是不可写的,所以需要修改属性VirtualProtect((LPVOID*)dwHookAddr, 5, PAGE_EXECUTE_READWRITE, &OldProtext);// Hook 就是向其中写入自己的代码memcpy((LPVOID*)dwHookAddr, backCode, 5);// 执行完了操作之后需要进行还原VirtualProtect((LPVOID*)dwHookAddr, 5, OldProtext, &OldProtext);
}

保存图片

void SaveImg(DWORD qrcode)
{//获取图片长度DWORD dwPicLen = qrcode + 0x4;size_t cpyLen = (size_t)*((LPVOID*)dwPicLen);//拷贝图片的数据char PicData[0xFFF] = { 0 };memcpy(PicData, *((LPVOID*)qrcode), cpyLen);//将文件写到本地HANDLE hFile = CreateFileA("E:\\qrcode.png",GENERIC_ALL,0,NULL,CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL,NULL);if (hFile==NULL){MessageBox(NULL, "创建图片文件失败", "错误", 0);return;}DWORD dwRead = 0;if (WriteFile(hFile, PicData, cpyLen, &dwRead, NULL) == 0){MessageBox(NULL, "写入图片文件失败", "错误", 0);return;}CloseHandle(hFile);//显示图片CImage img;CRect rect;//拿到控件的句柄HWND hPic = GetDlgItem(hDlg, IDC_QRPIC);GetClientRect(hPic, &rect);//载入图片img.Load("E:\\qrcode.png");img.Draw(GetDC(hPic), rect);//显示二维码内容ShowQrCodeContent(hDlg);//完成之后卸载HOOKUnHook(QrCodeOffset);
}

最终效果

最终效果如图:

最后附上工程和成品DLL

目前微信机器人的成品已经发布,需要代码请移步Github。还请亲们帮忙点个star

https://github.com/TonyChen56/WeChatRobot

PC微信逆向:使用HOOK拦截二维码相关推荐

  1. 微信,支付宝,收款二维码实时生成订单监控,免签支,付支付系统,个人收款,收款二维码...

    微信,支付宝,收款二维码实时生成订单监控,免签支,付支付系统,个人收款,收款二维码 微信和支付宝个人支付二维码生成与监控!有PHP接口回调,个人收款好助手! 实现收款即时到个人微信或支付宝账户!方便安 ...

  2. (用微信扫的静态链接二维码)微信native支付模式官方提供的demo文件中的几个bug修正...

    原文:(用微信扫的静态链接二维码)微信native支付模式官方提供的demo文件中的几个bug修正 native支付模式一demo(用微信扫的静态链接二维码)BUG修复,一共4个BUG 1.nativ ...

  3. 微信生成带参数的二维码,合成海报,扫码后推送小程序?

    微信服务号渠道二维码功能,支持生成带参数二维码,合成海报二维码,微信扫码后推送内容:结合微号帮平台48小时信息推送,推送微信小程序. 带参二维码 海报二维码 微信扫码后回复 48小时信息推送 在微号帮 ...

  4. 微信公众平台----带参数二维码生成和扫描事件

    原文:微信公众平台----带参数二维码生成和扫描事件 摘要: 账号管理----生成带参数的二维码 消息管理----接收消息----接收事件推送 为了满足用户渠道推广分析和用户帐号绑定等场景的需要,公众 ...

  5. 微信小程序条码、二维码生成模块

    代码地址如下: http://www.demodashi.com/demo/13994.html 一.前期准备工作 软件环境:微信开发者工具 官方下载地址:https://mp.weixin.qq.c ...

  6. 基于JavaSSM和微信小程序的智能二维码门禁管理系统

    目录 1 引言 2 2 系统需求分析 2 2.1开发环境 2 2.2关键技术 2 2.2.1 Spring 框架 2 2.2.2 Spring MVC 框架 3 2.2.3 Mybatis 3 2.2 ...

  7. 怎么实现微信公众号生成专属二维码推广来源统计

    为了实现微信公众号生成专属二维码推广来源统计功能,第三方平台微号帮提供了渠道二维码生成功能实现,可以给微信公众号在线生成专属推广二维码,统计公众号各个渠道来源的粉丝,一个渠道对应一个推广二维码,可以生 ...

  8. 微信公众号生成临时二维码

    微信公众号生成临时二维码 微信公众平台生成带参数的二维码官方文档 分为三个部分: 获取access_token.通过ticket换取二维码.生成带参数的二维码 特别注意:需要有生成二维码的权限. 整个 ...

  9. 微信QQ支付宝三合一收款二维码实现原理

    大家可以先看看我网站的效果: 收款吧 - 三合一收款码在线生成 收款码三合一大致原理如下: 第一步.解析用户上传的微信支付.QQ钱包.支付宝收款二维码,获取收款链接地址. 第二步.用自己的网站程序生成 ...

最新文章

  1. 单片机自学多久可以成功?学单片机需要什么基础知识?
  2. java nonewithrsa,如何使“MessageDigest SHA-1和Signature NONEwithRSA”等同于“Signature SHA1withRSA”...
  3. 快速排序 python菜鸟教程-快速排序
  4. Codeforces 1016F Road Projects
  5. jquery--选择器sizzle源码分析
  6. 中单引号怎么打出来_怎么做打出来的豆浆会更好?
  7. 如何使frame能居中显示
  8. iOS开发之抽屉效果
  9. Bash脚本15分钟进阶教程-转
  10. IBM系统分析——领域建模
  11. 华为交换机配置Vlan
  12. opencv-3.0.0-beta和opencv2版本的区别
  13. APP设计之启动页和广告页
  14. ssh允许root账号登陆
  15. android获取手机短信记录,android 获取手机电话号码和短信内容
  16. 现代软件工程 课程总结
  17. Proxmox VE 桌面虚拟化(windows 10)集群尝试
  18. 腾讯笔试算法题-开锁
  19. 自动化测试框架详解【2022】
  20. python怎么去掉换行符_在Python中,如何去除行末的换行符?

热门文章

  1. BigData之Hive:Hive数据管理的简介、下载、案例应用之详细攻略
  2. 成功解决cv2.imwrite(filename, img)代码输出中文文件乱码的问题(cv2.imencode方法解决)
  3. Dataset之CIFAR-10:CIFAR-10数据集简介、下载、使用方法之详细攻略
  4. CSS样式优先级与权重计算方式
  5. L1,L2正则化分析
  6. GridSearchCV.grid_scores_和mean_validation_score报错
  7. mysqil操作数据库
  8. ng机器学习视频笔记(二) ——梯度下降算法解释以及求解θ
  9. Bootstrp--一个导航面板切换的实用例子
  10. 【linux开发】IO端口和IO内存的区别及分别使用的函数接口