PC微信逆向) 定位微信浏览器打开链接的call

首发地址: https://mp.weixin.qq.com/s/Nik8fBF3hxH5FPMGNx3JFw

前言

最近想写一个免费的微信公众号自动采集的工具,我看公众号文章下载需求还挺多的。搜了下github,免费的工具思路大多都是使用浏览器打开公众号主页获取到需要的请求参数,例如key、uin等,然后再用参数请求历史。

优化

这些工具都需要自己复制公众号主页的链接发给文件传输助手然后打开,才能拦截到请求参数,那么能不能让这一步也让程序来完成呢?

简单的方式可以使用模拟点击,这个有兴趣的自行实现。这篇文章我说下基于逆向的方式在微信内置浏览器打开某个链接,这样实现可以更自动化一点,下面是具体的逆向和分析过程。

其他采集方案

在之前的一篇文章里我也说了其他一些采集方案,例如微信公众平台、微信读书等,有兴趣的可以看【Python微信机器人】写一个监控采集公众号文章的插件。不过听说微信读书已经开始加密了,而且采集的历史也不是很全,较早的文章可能获取不到。

对于微信公众平台来采集的可以参考aardio爬虫) 实战篇:采集自己的公众号粉丝列表,原理基本类似,都是先扫码获取到cookie,请求对应的接口,公众平台的接口都没加密。

还有基于逆向hook的采集方案,这个暂不公开。如果只是平时下载一下公众号文章的话,上面两种足够用了

方案优缺点

拦截参数对比逆向来说优点在于不需要固定微信的版本,更适合普通用户。因为逆向hook只能适用于特定版本,想不限版本,需要为每个版本做一遍适配,这明显不太可能。

而且基于逆向的方式采集还有可能有封号的风险,对于只想下几篇公众号文章的人来说,这个代价还是挺大的。当然逆向采集优点也很明显:稳定、无需人工操作、采集的数据量更多等。

逆向过程

下面逆向的版本选择的是3.9.6.32,选这个版本主要是之前的写的机器人用的这个版本,很多东西有现成的。最新的也没变,想看64位最新版的翻到最后,也会提几句。

日志定位

微信定位一个功能call最好也最方便的方式就是日志(肯定不是因为我只会这个)。打开链接的地方有多处,比如以下两个:

还有就是点击聊天记录里的链接来打开,这三种方式都试一下,看看日志之间有什么共同点,这样更容易定位到关键日志点。

方式1打开链接

方式2打开链接

聊天界面点击链接

前两个都有openUrlWithExtraWebview,看名称应该就是微信在调用打开浏览器,但是这里还处于比较上层的位置,如果你在这里打断点的话,会触发多次,不止打开浏览器才触发,并且看了下参数比较复杂,有一堆句柄和回调不好处理,所以这里先不考虑了。

WebViewMgr:user setting这个日志比较重要,因为三个日志里都有它,而且正好处于openUrlWithExtraWebviewAddTab的中间位置,看上去像是打开浏览器时初始化配置。

感觉在这里打上断点应该能在调用堆栈里找到打开浏览器的call。先在IDA里搜索user setting(x64dbg里搜索这个字符串也可以,我比较喜欢看IDA,有伪C代码看比汇编直观一点),然后定位到下面的位置:

接着翻到函数头,在x64dbg里函数头的位置打上断点,接着打开一个链接让断点断下

右键右下角堆栈的返回地址选择在反汇编中转到指定DWORD(也就是函数调用的地方),然后在IDA中查看这个地址,翻到函数头的位置看到了比较关键的日志信息(showWebView),在函数头继续打上断点

查看调用的位置,先看看IDA里这里所在的函数在做些什么操作,看上去是在解析json,而且看到了日志有OpenUrlWithExtraWebviewHandler,看名称这里就是处理OpenUrlWithExtraWebview事件的回调,那前面解析json就是在解析之前日志里的json

在头部打上断点,看看传入的参数是不是就是之前的json。如下图,虽然参数不是之前看到的json字符串,但是和json内容基本一样,估计上层函数又对json做了解析,那这里肯定是处理OpenUrlWithExtraWebview事件的回调函数,也就是在这个函数里打开的链接

那关键位置基本就是上面提到的showWebView函数了,下面开始分析函数的参数和几个需要调用的call。

分析参数

这里只有ecx是未知的,看了下ebp-0x90C在上面就有,估计是上面赋值的,打上断点看一下,一般复制的结构体都有函数可以生成,不需要去关心怎么构造。当然,如果构造的call离的太远且结构体也不负责的话也可以自己构造。

分析的结果如上,这里没什么复杂的参数,只需要传一个url就可以。前面在查看函数引用的时候,看到有的地方调用6CC52610时不是push的这几个值,也就是说这四个值并不是固定的,而是用于控制某些变量。

比如用系统默认浏览器打开则是下面的参数:

可能的组合(每行一种,最后一位是edx)

0 1 0 0 4
0 1 1 0 4
0 1 0 0 2
0 1 0 1 4
0 1 0 0 0
0 1 0 1 2
1 1 0 0 4
0 1 1 0 5
0 1 1 0 8
1 1 0 0 0
1 1 0 0 4

可以自己都测试一遍,不过看日志有的可能是打开小程序相关的,参数不一样也许会崩溃,具体案例具体分析吧。还有一个点,调用这四个call,堆栈不平衡,需要加上add esp, 0x10;(不一定这么处理,也可能是少call,单步走看看到哪个call平栈了),我看其他地方调用这个call都是使用的add esp, 0x10;,所以猜测这里加上这个也能运行。下面还有一个call是释放ebp-0x90C结构体里的内存,也需要调用一下。

完整代码
DWORD ShowVebView(wchar_t* url) {size_t urlLen = wcslen(url);DWORD WeChatWinBase = GetWeChatWinBase();DWORD dwCall1 = WeChatWinBase + 0x77A430;DWORD dwCall2 = WeChatWinBase + 0xF67310;DWORD dwCall3 = WeChatWinBase + 0x76CC70;DWORD dwCall4 = WeChatWinBase + 0x1602610;DWORD dwCall5 = WeChatWinBase + 0x77A790;DWORD ebp_0x90C[0x500] = { 0 };__asm {pushad;lea ecx, ebp_0x90C;call dwCall1;push urlLen;push url;lea eax, ebp_0x90C;lea ecx, [eax + 0x56C];call dwCall2;call dwCall3;push 0x0;push 0x1;push 0x0;push 0x0;xor edx, edx;lea ecx, ebp_0x90C;call dwCall4;add esp, 0x10;lea ecx, ebp_0x90C;call dwCall5;popad;}return 0;
}

编译成dll注入到进程,调用ShowVebView正常打开链接。

64位

以能下载到的最新版为例(3.9.10.27),其实32位和64位微信逻辑是一样的,同样在x64dbg里搜索user setting,在引用的函数头打断点找到调用点,然后接着在函数头打断点找到调用点,关键位置如下图(基址是00007FF86A160000):

逻辑一模一样,只是64位无法内联汇编,可以用函数指针来调用。大概代码如下:

typedef UINT64 (*dwCall1Ptr)(UINT64);
dwCall1Ptr dwCall1 = (dwCall1Ptr)0x7FF86BD82C70;
DWORD rbp_0x100[0x500] = {0};
UINT64 addr = dwCall1(&rbp_0x100);typedef UINT64 (*dwCall2Ptr)(UINT64,wchar_t*,UINT64);
dwCall2Ptr dwCall2 = (dwCall2Ptr)0x7FF86C840C10;
wchar_t* url = (wchar_t*)L"";
dwCall2(addr+0x***, url, wcslen(url));typedef UINT64 (*dwCall3Ptr)();
dwCall3Ptr dwCall3 = (dwCall3Ptr)0x7FF86BD72AE0;
dwCall3();typedef UINT64 (*dwCall4Ptr)(UINT64,UINT64,UINT64,UINT64,UINT64,UINT64);
dwCall4Ptr dwCall4 = (dwCall4Ptr)0x7FF86D24E9B0;
dwCall4(addr, 0,0,0,1,0);typedef UINT64 (*dwCall5Ptr)(UINT64);
dwCall5Ptr dwCall5 = (dwCall5Ptr)0x7FF86BD82EA0;
dwCall5(addr);

上面只是伪代码,需要自己调试改成能运行的代码。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/26349.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

uniapp scroll-view下拉刷新无法复位

动态设置refresher-triggered的值&#xff0c;当触发下拉刷新时&#xff0c;refresher-triggered true&#xff1b;当下拉刷新执行完之后refresher-triggered false。 <scroll-view :scroll-top"scrollTop" scroll-y"true":refresher-triggered"…

雷军出手,光储充一体化赛道可太行了

雷军出手&#xff0c;特斯拉、宁德时代、奥能电源持续加码&#xff0c;光储充一体化赛道可太行了 近几年&#xff0c;各地光储充一体化项目遍地开花&#xff0c;正式投入运营的新闻接连不断。被视为全球能源转型重要驱动力的光储充一体化&#xff0c;已成为各大企业竞相入局的新…

ReentrantLock的非公平锁(NonfairSync)深度解析:源码之旅与实战策略

1. 引言 在Java并发编程中,ReentrantLock作为一种可重入的互斥锁,提供了比synchronized更强大和灵活的功能。其中,NonfairSync作为ReentrantLock内部非公平锁的实现,其设计理念和源码实现都体现了对性能和公平性的权衡。 2. NonfairSync概述 非公平锁特性: 新到达的线程在…

FOXMAIL邮箱:高效办公,邮件管理新风尚

随着电子邮件在日常工作和生活中的普及&#xff0c;选择一个高效、易用的邮箱客户端变得尤为重要。FOXMAIL作为一款功能强大、操作简便的邮箱客户端&#xff0c;深受用户喜爱。下面将为您详细介绍FOXMAIL邮箱的使用方法&#xff0c;帮助您轻松掌握其各项功能。 一、下载安装与账…

【深度优先搜索 广度优先搜索】297. 二叉树的序列化与反序列化

本文涉及知识点 深度优先搜索 广度优先搜索 深度优先搜索汇总 图论知识汇总 LeetCode297. 二叉树的序列化与反序列化 序列化是将一个数据结构或者对象转换为连续的比特位的操作&#xff0c;进而可以将转换后的数据存储在一个文件或者内存中&#xff0c;同时也可以通过网络传…

App UI 风格,引领设计风向

App UI 风格&#xff0c;引领设计风向

vue3 proxy对象转为原始对象

https://cn.vuejs.org/api/reactivity-advanced.html#toraw import { toRaw } from "vue";const foo {} const reactiveFoo reactive(foo)console.log(toRaw(reactiveFoo) foo) // true 人工智能学习网站 https://chat.xutongbao.top

三人拼团模式的核心:二二公排

在电商市场中&#xff0c;拼团模型的玩法是层出不穷&#xff0c;不断有各种新的拼团模式出现&#xff0c;如&#xff1a;七人拼团、全民拼购、预售拼购等等&#xff0c;还有各大电商平台的拼购&#xff0c;如&#xff1a;拼夕夕的拼单购物、镁团的拼好饭等等。下面分享一个全新…

柏曼的台灯值得入手吗?书客、明基横向测评对比

据相关研究显示&#xff0c;我国青少年的近视问题尤为严峻&#xff0c;总体近视率已逼近53%&#xff0c;这一超过半数的数据令人触目惊心。随着孩子学龄的增长&#xff0c;学习负担不断加重&#xff0c;眼部的压力也随之剧增&#xff0c;从而导致近视率持续攀升。普通台灯可能发…

Chromium源码阅读:深入理解Mojo框架的设计思想,并掌握其基本用法(1)

Mojo简介 Mojo 是一个运行时库的集合&#xff0c;提供与平台无关的通用 IPC 原语抽象、消息 IDL 格式以及具有针对多种目标语言的代码生成的绑定库&#xff0c;以便于跨任意进程间和进程内边界传递消息。 Mojo 分为清晰分离的层&#xff0c;子组件的基本层次结构如下&#xff…

KVM+GFS高可用

资源列表 操作系统 IP 主机名 Centos7 192.168.10.51 gfs1 Centos7 192.168.10.52 gfs2 Centos7 192.168.10.53 kvm 在gfs节点部署GlusterFS #添加hosts解析 cat >> /etc/hosts << EOF 192.168.10.51 gfs1 192.168.10.52 gfs2 192.168.10.53 kvm EOF …

Chrome DevTools开发者调试工具

Chrome DevTools 是一个功能强大的网页开发工具&#xff0c;集成在谷歌浏览器中&#xff0c;帮助开发者调试和优化网页应用。以下是详细的功能说明和使用技巧&#xff1a; 1. 打开 DevTools 快捷键&#xff1a;按下 F12 或 CtrlShiftI&#xff08;Windows/Linux&#xff09;或…

jquery.PrintArea.js 设置不打印

jquery.PrintArea.js 是一个用于打印网页特定区域内容的 jQuery 插件。如果你想设置某些内容不被打印&#xff0c;可以使用 CSS 的 media print 媒体查询来控制。 例如&#xff0c;你可以给不想打印的内容添加一个类名&#xff0c;比如 no-print&#xff0c;然后在 CSS 中指定…

2024下《系统分析师》50个高频考点汇总!背就有效

宝子们&#xff01;上半年软考已经结束一段时间了&#xff0c;准备备考下半年软考高级-系统分析师的小伙伴可以开始准备了&#xff0c;毕竟高级科目的难度可是不低的&#xff0c;相信参加过上半年系分的小伙伴深有体会。 这里给大家整理了50个高频考点&#xff0c;涵盖全书90%…

透视环世物流:一个AI降本的产业典型样本

在过去的多年时间里&#xff0c;与其说低代码完成的数字原生的普惠&#xff0c;不如说其最强的能力恰是能帮助企业用最低的门槛、最高的效率构建出与自身适配的流程和业务应用&#xff0c;在底层帮助企业构建出一个被极致拆分和分子化的软件开发中台。 而透过环世物流&#x…

数据结构笔记-2、线性表

2.1、线性表的定义和基本操作 如有侵权请联系删除。 2.1.1、线性表的定义&#xff1a; ​ 线性表是具有相同数据类型的 n (n>0) 个数据元素的有限序列&#xff0c;其中 n 为表长&#xff0c;当 n 0 时线性表是一个空表。若用 L 命名线性表&#xff0c;则其一般表示为&am…

云主机主频不够导致业务卡顿的解决攻略

当云主机的主频不足以满足业务需求时&#xff0c;就可能出现业务卡顿的现象&#xff0c;影响用户体验和企业的运营效率。本文将针对这一问题&#xff0c;提供一套解决攻略&#xff0c;并在结尾处归纳使用弹性云服务器的好处。 一、解决云主机主频不够导致业务卡顿的攻略 ①检…

从报名到领证:软考初级【信息系统运行管理员】报名考试全攻略

本文共计9991字&#xff0c;预计阅读33分钟。包括七个篇章&#xff1a;报名、准考证打印、备考、考试、成绩查询、证书领取及常见问题。 一、报名篇 报名条件要求&#xff1a; 1.凡遵守中华人民共和国宪法和各项法律&#xff0c;恪守职业道德&#xff0c;具有一定计算机技术…

利用AI大模型,将任何文本语料转化为知识图谱,可本地运行!

几个月前&#xff0c;基于知识的问答&#xff08;KBQA&#xff09;还是一个新奇事物。 现在&#xff0c;对于任何 AI 爱好者来说&#xff0c;带检索增强生成&#xff08;RAG&#xff09;的 KBQA 就像小菜一碟。看到自然语言处理&#xff08;NLP&#xff09;的可能性领域由于大…

缓存与数据一致性问题

1、更新了数据库&#xff0c;再更新缓存 假设数据库更新成功&#xff0c;缓存更新失败&#xff0c;在缓存失效和过期的时候&#xff0c;读取到的都是老数据缓存。 2、更新缓存&#xff0c;更新数据库 缓存更新成功了&#xff0c;数据库更新失败&#xff0c;是不是读取的缓存的都…