微信逆向之朋友圈

打开观察之后,发现这里面有个setAdapter的地方,对的!肯定数据就在这个Adapter里面,因为我们平时写list 渲染的时候数据都是通过adapter 渲染到list 上的,我们继续点进去看看这个adapter 是如何写的。

朋友圈Adapter深入

我们通过上述的方法已经找到了Adapter了,我们点击(this.qXz)这个字段发现他的类名是as,点击进去发现,果然没错。

public final class as extends BaseAdapter {
private Activity coM;
boolean cog = false;
private String country;
List list = new ArrayList();
String lnO = “”;
private String ngt = “”;
Map<Integer, Integer> qBc = new HashMap();
Map<Integer, Integer> qBd = new HashMap();
int qBe = 0;
int qBf = 0;
String qHI = “”;
private bd qKW = null;
private az qQo;
Map<Integer, Integer> qQp = new HashMap();
private f qQq;
boolean qQr = false;
at qQs;
private c qQt;
int qQu = BaseClientBuilder.API_PRIORITY_OTHER;
int qQv = 0;
private long qQw = 0;
private long qQx = 0;
int qQy = 0;
protected OnClickListener qQz = new OnClickListener() {
public final void onClick(View view) {
if (view.getTag() instanceof TimeLineObject) {
TimeLineObject timeLineObject = (TimeLineObject) view.getTag();
if (as.Yp(timeLineObject.Id)) {
h.ptS.X(10231, “1”);
com.tencent.mm.av.a.agc();
} else {
h.ptS.X(10090, “1,0”);
if (!(com.tencent.mm.q.a.bN(as.this.coM) || com.tencent.mm.q.a.bL(as.this.coM))) {
com.tencent.mm.av.e a = g.a(af.getAccPath(), timeLineObject, 8);
a.fuR = as.this.userName;
com.tencent.mm.av.a.b(a);
}
}
as.this.notifyDataSetChanged();
}
…省略很多代码…

那我们接下来怎么找呢,Adapter已经拿到了,难道还是一点点翻吗?当然不是了,想想我们日常写listview的Adapter时候,是不是在getView的时候进行给view赋值的操作,这时候微信也一样,我们同样打开as这个类的structure目录

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

从图中可以发a这个方法嫌疑很大,里面有各种view

private void a(int i, QFadeImageView qFadeImageView, TextView textView, TextView textView2, TextView textView3, TextView textView4, int i2, d dVar, int i3) {
n nVar = (n) getItem(i);
TimeLineObject cmi = nVar.cmi();
bys q = aj.q(nVar);
Object obj = null;
if (q != null && (((q.vUS & 2) == 2 && q.wnx != null) || ((q.vUS & 4) == 4 && q.vTG != null))) {
obj = 1;
}
if (!(!this.cog || q == null || obj == null || this.userName == null || !this.userName.equals(nVar.field_userName))) {
textView3.setBackgroundResource(com.tencent.mm.plugin.sns.i.e.personactivity_sharephoto_icon);
textView3.setVisibility(0);
}

…省略很多代码…

我们点进去可以看到,果然如同我们所想一样,第一行就暴露了, n nVar = (n) getItem(i); 可以发现这个n类就是每个item的数据源,而且往下看一行,这个类名也很有嫌疑TimeLineObject,而且是通过n 调用cmi方法返回的,那会不会是数据库里面的那个BLOB字段呢。容我们点进去看看

Map<String, TimeLineObject> qAb = new ConcurrentHashMap();
…省略很多代码…

public final TimeLineObject cmi() {
if (this.field_content == null) {
return e.ahM();
}
TimeLineObject timeLineObject;
if (this.qzT == null) {
this.qzT = g.u(this.field_content) + g.u(this.field_attrBuf);
}
if (qAb.containsKey(this.qzT)) {
timeLineObject = (TimeLineObject) qAb.get(this.qzT);
if (timeLineObject != null) {
return timeLineObject;
}
}
try {
timeLineObject = (TimeLineObject) new TimeLineObject().parseFrom(this.field_content);
qAb.put(this.qzT, timeLineObject);
return timeLineObject;
} catch (Exception e) {
ab.e(“MicroMsg.SnsInfo”, “error get snsinfo timeline!”);
return e.ahM();
}
}

这时候发现了不可思议的东西 field_contentfield_attrBuf 这两个字段,这个不就是数据库里面定义的content和attrbuf字段吗。原来是通过这样的方式转化的。继续往下看,可以发现如果 ’ qAb.get(this.qzT) ’ 拿不到TimeLineObject的话,就会自己new 一个然后存储到这个Map集合中,做缓存作用,那我们是不是可以通过这种方式呢拿到这个TimeLineObject,当然是可以的。

解码朋友圈BLOB字段

通过上面我们已经知道了如何解析朋友圈数据库content 字段了,通过TimeLineObject的parseFrom方法进行转化。但是当我们点到TimeLineObject这个类里面你会发现,卧槽,怎么这样。

public class TimeLineObject extends a {
public String Id;
public int dhE;
public int eRm;
public String hPC;
public String jfn;
public int ozl;
public String qEy;
public String qXr;
public av qiN;
public csw qiP;
public String uzJ;
public int vTa;
public int wsA;
public String wsB;
public ccr wsC;
public cqv wsD;
public int wsE;
public String wsu;
public axc wsv;
public du wsw;
public ta wsx;
public String wsy;
public int wsz;

可以发现里面嵌套了很多的类。这是我时候我们怎么做呢。我也没有很好的办法,然后就通过一个类一个类的点开,然后打印它里面是String字段,这里应该来个表情捂脸,有好方法的同学们可以留言区交流,但是当我打印到了wsu这个字段的时候发现,可以拿得到我们发朋友圈时的标题了。瞬间感觉到了轻松。但是这只是一个很小的进步,我们要拿的可是朋友圈图片视频评论点赞所有内容啊。

获取朋友圈信息源具体内容

那么如何获取到图片视频等信息呢。那么我们还是要回到adapter 这个类里面。在他的a方法中有个构造参数QFadeImageView看到ImageView 感觉离获取图片地址不远了。那么我们继续观察这个方法。

private void a(int i, QFadeImageView qFadeImageView, TextView textView, TextView textView2, TextView textView3, TextView textView4, int i2, d dVar, int i3) {
n nVar = (n) getItem(i);
TimeLineObject cmi = nVar.cmi();
bys q = aj.q(nVar);
Object obj = null;
if (q != null && (((q.vUS & 2) == 2 && q.wnx != null) || ((q.vUS & 4) == 4 && q.vTG != null))) {
obj = 1;
}
…省略很多代码…
if (cmi.wsx.vqt == 1) {
qFadeImageView.setVisibility(0);
af.cjr().a(cmi.wsx.vqu, (View) qFadeImageView, this.coM.hashCode(), com.tencent.mm.plugin.sns.model.g.a.IMG_SCENE_SNSSUSER, azVar);
} else if (cmi.wsx.vqt == 2) {
textView4.setText(bp.bb(cmi.wsx.Desc, “”));
textView4.setVisibility(0);
} else if (cmi.wsx.vqt == 21) {
nVar.cmA();
boolean z = true;
if (this.cog) {
z = true;
} else if (m.a(nVar, q)) {
z = false;
}
qFadeImageView.setVisibility(0);
af.cjr().a(cmi.wsx.vqu, (View) qFadeImageView, this.coM.hashCode(), com.tencent.mm.plugin.sns.model.g.a.IMG_SCENE_SNSSUSER, azVar, z);
}
…省略很多代码…

从上面的代码中我们可以看得到,微信这边调用了这个方法把 af.cjr().a(xxxxx)把Imageview 传入了进入,点击查看了其他的参数只有cmi.wsx.vqu这个参数有用。可以发现他调用了TimeLineObject里面ta这个类里面的集合vqu字段。

public final class ta extends a {
public String Desc;
public String Title;
public String Url;
public int vqt;
public LinkedList vqu = new LinkedList();
public int vqv;
public String vqw;
public ayd vqx;

先不管调用了imageview 这个方法干了什么,我们先把这个集合里面的东西给打印出来。

azc.toString{id:13055580620160049319 Desc:黄昏 Title: Url:http://mmsns.qpic.cn/mmsns/kEgG3ynkRxponsiaCyzhl9Gniaz7GdWLujZdSMV4kmlME6fia07m577MQ3OU9kMKibjAIiaMc7MWHKF0/0 ckO:null qDg: vSY:http://mmsns.qpic.cn/mmsns/kEgG3ynkRxponsiaCyzhl9Gniaz7GdWLujZdSMV4kmlME6fia07m577MQ3OU9kMKibjAIiaMc7MWHKF0/150 vTc: vTf: vTh: vTi: vTj: vTm:f814a6351db8cd3ef118e14e6ff70b80 vTn:WSEN6qDsKwV8A02w3onOGQYfxnkibdqSOkmHhZGNB4DFJ9qdBeATTF8UiaDA1go3GLryav2ukPJK06SOFjchiaqJA vTp:14604729124651202068 vTq:WSEN6qDsKwV8A02w3onOGQYfxnkibdqSOkmHhZGNB4DFJ9qdBeATTF8UiaDA1go3GLwHGCkbxWxDWW5dsMhLsBUg vTs:14604729124651202068 vTt:}

不出我们所料,里面果然有我们需要的东西,而且把Desc,url都给了我们,通过我的测试发现图片的url并不能打开。但是视频链接的url是可以打开的。是不是很happy。这时候我们已经拿到了视频源和分享的链接源,但是如何拿到图片源呢。那我们继续查看源码,发现点击刚刚给上述调用了这个集合的方法里面并没有什么东西,都是一些赋值的操作。没有获取具体图片源信息的位置。

这时候我是这样操作的,因为这个获取到的Url虽然我们解析不了,但是我们可以点击查看Url的引用,看哪里有着对这个Url字段的引用,微信内部是如何解析的 当你点击开的时候会发现并没有什么用处,见下图

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

引用的地方太多了,根本不知道如何下手。这时候又会一头雾水不知道如何进行下一步。那么我们只能回到起点,再次寻找下一个hook点。

进入朋友圈详情二次Hook

既然上一个页面我们拿不到图片的数据,那我们就深入进入朋友圈具体内容页面,然后进行二次Hook,获取到朋友圈具体图片内容。我们还是以同样的方法进行,hook,打开此页面然后通过 dumpsys 获取当前的activity,进入这个activity查看源码下手找到图片的具体位置。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

通过代码查看到这是一个com.tencent.mm.plugin.sns.ui.SnsGalleryUI,顾名思义,朋友圈相册页面。那么我们点进去看看具体写了些什么东西

public class SnsGalleryUI extends SnsBaseGalleryUI implements a {
private int qKn = 0;
private String userName = “”;

public void onCreate(Bundle bundle) {
super.onCreate(bundle);
getWindow().addFlags(128);
wS(this.mController.xyi.getResources().getColor(c.dark_actionbar_color));
LV(this.mController.xyi.getResources().getColor(c.dark_actionbar_color));
initView();
}
…省略很多代码…

并没有什么东西可看的。没有具体的内容,我们进入父类SnsBaseGalleryUI看看做了些什么进入看了一下,发现方法体也没有什么东西,但是一个字段引起了我的注意

public abstract class SnsBaseGalleryUI extends MMActivity implements a {
private boolean jop = true;
private LinearLayout qKf;
r qKg;
private LinearLayout qKh;
s qKi;
private boolean qKj = true;
private TextView qKk = null;
protected SnsInfoFlip qKl;
protected Button qKm;
…省略很多代码…

我们从上面的字段可以猜到哪一个是引起了我的注意,很明显那就是SnsInfoFlip这个类。继续点击去看看里面写了些什么内容。据我猜测这应该也是个adapter,viewpager的adapter,通过structure目录可以发现里面有个getView的方法,但是反编译并没有完全把smail 内容转换成java 类型,看着比较费劲,那我们继续往下寻找,这时候你会有惊喜

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

可以看到这个函数里面参数是azc记忆力好的小伙伴应该还记得,前面所说的,azc这个类里面包含着url,这时候找到了用的地方了。把代码贴上大家可以看一下

private void a(azc azc, int i, String str) {
String str2;
long j = 0;
if (this.qNm != null && (this.qNm instanceof MMGestureGallery)) {
float f;
float f2;
float f3;
if (azc.vTb != null) {
f = azc.vTb.vTP;
f2 = azc.vTb.vTO;
} else {
f = 0.0f;
f2 = 0.0f;
}
if (f <= 0.0f || r5 <= 0.0f) {
if (azc.Id.startsWith(“Locall_path”)) {
str2 = an.fQ(af.getAccSnsPath(), azc.Id) + com.tencent.mm.plugin.sns.data.i.m(azc);
} else {
str2 = an.fQ(af.getAccSnsPath(), azc.Id) + com.tencent.mm.plugin.sns.data.i.d(azc);
}
Options akG = com.tencent.mm.sdk.platformtools.d.akG(str2);
…省略很多代码…

上面的字段local_path,博主感觉找到了那个点,开始hook这个method an.fQ(af.getAccSnsPath(), azc.Id) + com.tencent.mm.plugin.sns.data.i.m(azc);,surprise这个方法返回的值就是朋友圈图片的本地路径。打印下来是这样的路径
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数初中级Android工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则近万的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年Android移动开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。

img

img

img

img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Android开发知识点,真正体系化!

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!

如果你觉得这些内容对你有帮助,可以扫码获取!!(备注:Android)

学习分享

在当下这个信息共享的时代,很多资源都可以在网络上找到,只取决于你愿不愿意找或是找的方法对不对了

很多朋友不是没有资料,大多都是有几十上百个G,但是杂乱无章,不知道怎么看从哪看起,甚至是看后就忘

如果大家觉得自己在网上找的资料非常杂乱、不成体系的话,我也分享一套给大家,比较系统,我平常自己也会经常研读。

2021最新上万页的大厂面试真题

七大模块学习资料:如NDK模块开发、Android框架体系架构…

只有系统,有方向的学习,才能在段时间内迅速提高自己的技术。

这份体系学习笔记,适应人群:
**第一,**学习知识比较碎片化,没有合理的学习路线与进阶方向。
**第二,**开发几年,不知道如何进阶更进一步,比较迷茫。
第三,到了合适的年纪,后续不知道该如何发展,转型管理,还是加强技术研究。如果你有需要,我这里恰好有为什么,不来领取!说不定能改变你现在的状态呢!
由于文章内容比较多,篇幅不允许,部分未展示内容以截图方式展示

《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!

这份体系学习笔记,适应人群:
**第一,**学习知识比较碎片化,没有合理的学习路线与进阶方向。
**第二,**开发几年,不知道如何进阶更进一步,比较迷茫。
第三,到了合适的年纪,后续不知道该如何发展,转型管理,还是加强技术研究。如果你有需要,我这里恰好有为什么,不来领取!说不定能改变你现在的状态呢!
由于文章内容比较多,篇幅不允许,部分未展示内容以截图方式展示

《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!

  • 17
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
微信SDK是一款非常方便的工具,可以在我们的应用中集成微信的分享功能,包括分享到朋友圈。通过微信SDK,用户可以直接将应用中的内容、图片、链接等分享到自己的朋友圈中,与朋友们分享自己的想法、心情和发现。 在集成微信SDK分享朋友圈的过程中,首先需要在应用中申请一个微信开放平台的App Key,这个App Key将用于验证应用的合法性,并进行用户身份的认证。然后,我们需要在应用中引入微信SDK的相关代码和资源,并完成一些必要的配置。接下来,我们可以调用微信SDK提供的接口,实现将特定内容分享到朋友圈的功能。 在调用接口之前,我们需要先实例化一个WXMediaMessage对象,并设置其中的分享内容。例如,我们可以设置分享的标题、描述、缩略图和链接等。然后,我们再创建一个SendMessageToWX.Req对象,并将前面创建的WXMediaMessage对象作为其成员变量,进行进一步的配置。最后,我们可以通过调用IWXAPI对象的sendReq方法,将SendMessageToWX.Req对象发送给微信客户端,从而实现分享操作。 值得注意的是,我们需要在自己的应用中校验微信客户端是否已安装,并合理处理客户端不存在或版本过低的情况。此外,我们还可以根据微信SDK的回调接口获取分享结果,并根据结果进行相应的逻辑处理,提升用户体验。 总之,微信SDK的分享功能可以让我们的应用更加社交化,方便用户与朋友分享精彩内容,增加用户的活跃度和粘性。通过合理使用微信SDK,我们可以为用户提供更好的服务和体验。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值