admin管理员组

文章数量:1530021

PC微信hook学习笔记(三)—— 获取登录二维码

  • 1. 二维码图片基址
    • 1.1 PNG文件在内存中的表现形式
    • 1.2 用CE查找变量所在地址
    • 1.3 用OD在地址附近打断点
    • 1.4 打印图片
    • 1.5 计算二维码图片基址
  • 2. 二维码内容基址
    • 2.1 获取二维码图片中包含的文本内容
    • 2.2 找到存放二维码内容的基址
  • 3. 编写程序显示二维码
    • 3.1 hook思路
    • 3.2 代码
      • hook.cpp
      • hook.h
      • dllmain.cpp
      • OD注入

本篇笔记学习教程:获取微信二维码基址,手动实现hook
本篇笔记参考博客:PC微信逆向:使用HOOK拦截二维码

1. 二维码图片基址

1.1 PNG文件在内存中的表现形式

微信的登录二维码是png格式,png图片在OD中能看到,就是png图片在内存中的表现形式。PNG文件头格式解析,这篇文章就介绍了png图片在内存中的数据表现。
在OD中,如果能看到某个数据块的前三行是这种样子的话,就说明这块内存存储了一个png图片。

1.2 用CE查找变量所在地址

  1. 打开微信,打开CE
  2. 在CE中,查询【未知的初始值】,此时,因为还没有获取登录二维码,所以存储二维码的变量尚未初始化。
  3. (1)微信点击【切换账号】,CE选择【变动的数值】,点击【再次扫描】。(2)手机扫一扫【登录二维码】,不要点登录,CE点击【再次扫描】
  4. 重复第3步,每次都滚动到最底下查看绿色基址。当绿色地址只剩下几个的时候,添加到下方窗口里,观察这几个地址的变化。

1.3 用OD在地址附近打断点

  1. 打开OD,附加进程,输入命令:【dd 776DC348】。注意,这个地址,是CE中刚才加入观察的数值长度为5个的,如15990
  2. 选中地址【776DC348】右击,添加断点,添加断点后微信点击【切换账号】。这一步有可能造成OD卡死,多试几次,或换一个地址试试,直到出现下图中的二维码还未刷新出来的场景(就算出现这个空白,地址也可能是错的,参见第6步)。


3. 在右下角窗口中,查找类似“返回到WeChatWi.0x地址 来自 WeChatWi.0x地址”的条目,选中右击【反汇编窗口中跟随】,并在左上角窗口中,选中在语句【lea ecx,dword ptr ss:[ebp+0xC]】接着的【call】语句,按F2加断点。找差不多三四个就可以了。

4. 【删除内存断点】,并点击小三角运行程序。让这次的二维码扫描掉,再来显示一次二维码,使得OD进入函数断点。
5. 进入某个断点后,输入命令:dc [ecx]查询数据。能出现下图所示数据的话,恭喜你找到了二维码图片。
6. 若是OD卡死,从第5步再来几次;若是没找到图片,或者输入dc [ecx]命令后是一串别的乱码,说明一开始用来打断点的地址不对,那么,不要着急,从第1步再来几次。(淡定如君子其实慌如疯狗…特喵的我找了近2小时!)

1.4 打印图片

OD打印数据的命令:dm 数据的地址,数据的长度,"文件名称"

dm 04D7DD80,EA2,"w_qrcode.png"
ret
  1. 将上面的命令,修改成自己的地址,保存到txt文件中。
  2. 在OD左上角的窗口中任意位置右击→选择【运行脚本】→选择刚才保存的命令文本。
  3. 保存的图片在微信的安装目录里。
  4. 验证图片的话,就删掉刚才保存的图片,重新显示出一张二维码,扫描OD保存的那张,观察微信是否有变化。

1.5 计算二维码图片基址

二维码图片基址:(call语句的地址)53C3ACE7 - WeChatWin.dll = 1F ACE7‬
WeChatWin.dll 的地址,可以在OD中点击【e-显示模块窗口】快速查找。

2. 二维码内容基址

2.1 获取二维码图片中包含的文本内容

首先,关于二维码生成原理,大家可看下这位大佬的博客:二维码原理详解。

识别二维码,就是将二进制编码的图片,按编码规则解码出来并解析所包含的内容(可能是字符串、网址等)。

怎么找出微信登录二维码中所包含的内容呢?

  1. 打开微信→切换账号→截图二维码→保存为图片
  2. 打开草料-二维码解码器→上传刚才的二维码截图,可得到解码结果:http://weixin.qq/x/4_QBLO7V2dAAUmd28I54
  3. 很显然,http://weixin.qq/是一个服务器地址。在浏览器里访问这个地址,首页显示pc版微信的下载;后面的x/4_QBLO7V2dAAUmd28I54,应该是接口和参数,只不过做了一些处理。

每一次点击切换账号,二维码都会变化,那么,上面的4_QBLO7V2dAAUmd28I54也是每次都不一样,我们需要找到的,就是存储这个变量的基址。

2.2 找到存放二维码内容的基址

  1. 打开CE→打开微信进程→搜索二维码解析出的字符串,如4_QBLO7V2dAAUmd28I54;需要注意的是,微信的二维码隔一段时间就会刷新,所以要以最新的二维码截图解析。
  2. 等待几秒钟,刚才扫描出的地址列表会变化,这时,切换到微信窗口,等到新的二维码刷新出来,会看到CE里有一个地址里的当前值,与搜索的字符串长度相等;此时,将刷新出来的二维码内容解析出来,正好与CE里变化的字符串相同。那么先记住这个地址,如下图的072FBFB0
  3. 打开OD→附加微信→在右下角命令框中输入:dd 072FBFB0
  4. 选中072FBFB0并右击→断点→内存写入,并点击小三角运行。
  5. 点击OD操作栏的【t】→在窗口内右击→“Resume All Threads”→点击【c】,切换回主窗口

    6.等到OD页面出现【暂停】时,说明断点起效,二维码刷新了!点击右下角第一行,则左下角的地址栏会显示对应地址信息。
    这里有几个地址信息:(1)WeChatWi.796CA008 (2)796CA010
  6. 用CE验证下刚才找到的地址:(1)手动添加地址→WeChatWin.dll→添加后右击,以十六进制显示。(2)手动添加地址→796CA010→添加后右击,以十六进制显示(3)用计算器计算基址偏移量:796CA010 - WeChatWin.dll地址 = 13AA010‬

    这样就得到存放二维码内容的基址: WeChatWin.dll + 0x13AA010‬

3. 编写程序显示二维码

首先,找到需要hook的call,在OD左上角窗口中右击,选择【转到】→【表达式】,输入二维码图片基址偏移量: 1FACE7

3.1 hook思路


在call语句前面,有个E8 747F2A00E8是call的机器码,747F2A00是函数地址相对于当前地址的偏移量。

  1. 第一步——截住信鸽
    首先修改内存,让call语句执行的程序整个变成执行我们自己的函数。将原来的E8 747F2A00,替换成E9 新的地址E9是jmp的机器码;新的地址 = 要跳转的地址 - hook的地址 - 5;减5是因为E9 新的地址占5个字节,要跳转的地址就是自定义函数的地址。
  2. 第二步——copy书信
    需要用一个变量pic,存储ecx里的png图片数据,并显示到自己的窗口中;
  3. 第三步——让信鸽按原来的方向继续飞
    jmp命令跳回到原来call语句的下一句,让程序继续执行。下一句的地址偏移为:78D9ACEC - WeChatWin.dll = 1FACEC

3.2 代码

  1. 打开VS2017→新建【动态链接库DLL】
  2. 在【资源文件】下右击→添加→资源→Dialog,并建立如下图的布局,对布局元素修改ID以便引用。
  3. 新建hook.cpphook.c
  4. 选中项目,右击,选择【重新生成】。

hook.cpp

#

本文标签: 学习笔记二维码PChook