以前講到得 VirtualApp
免 Root
可能你們還沒實際體會到它的好處,這篇文章教你們如何拿到女神微信「朋友圈」的封面(邪惡臉)java
微信好友的頭像是可以直接保存到相冊的,可是朋友圈的封面,卻沒有提供保存的入口,下面咱們來一步步找到朋友圈封面的地址。android
說明一下:這裏是針對「微信 v6.6.7」 的源碼分析,不一樣版本的代碼由於混淆以後的緣故,不必定適用。若是想下載微信的歷史版本安裝包,能夠下載 「PP 助手」,就能找到微信的歷史版本。瀏覽器
定位到朋友圈當前的 Activity
是 com.tencent.mm.plugin.sns.ui.SnsUserUI
緩存
用 Jadx 將反編譯的源碼,另存爲 Gradle
項目,這樣能夠直接在 Android Studio
看源碼了,不過這樣導出來的,是不可以運行的。我我的習慣在 Android Studio
查看源碼,由於能夠方便地使用查找、跳轉和類結構等功能。bash
SnsUserUI
源碼,發現並無設置封面相關的地方,不過裏面有個相似乎把不少操做隱藏起來,而且傳入幾個關鍵字段信息進去,值得懷疑:onCreate()
方法裏面,找到了封面的封裝類 SnsHeader
SnsHeader
的源碼,找到封面設置的 ImageView
,應該就是圖片紅框的控件,爲啥這麼肯定?由於點擊封面會彈出更換封面的彈窗,裏面的 log 提示的也很明顯this.nWh.nWt
是在哪裏設置值,找到如下代碼,能夠看到給封面設置 bitmap
值以及默認封面的資源名稱,其中 bitmap
對應的變量名稱是 aaccSnsPath
,跟一下accSnsPath
有兩處賦值的地方,猜想封面圖片的處理應該是用了「三級緩存」機制的,先讀內存,內存沒有,就讀本地,本地沒有,再網絡請求獲取。因此對應的第一個賦值的地方是:本地存儲路徑;第二個賦值的地方是:網絡的 url
。根據上面的分析過程,對如下 3 個類,進行 hook ,這裏有個 「小技巧」,是「尼古拉斯·趙四」分享的,若是在進行代碼分析過程沒有頭緒的時候,能夠對 Log 類進行 hook,在打印出來的日誌,找尋蛛絲馬跡。微信
再次強調,hook 針對微信 v6.6.7 源碼,採用 YAHFA hook網絡
public class HookWxG {
public static String className = "com.tencent.mm.plugin.sns.model.g";
public static String methodName = "a";
public static String methodSig = "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;ZLcom/tencent/mm/storage/av;)Landroid/graphics/Bitmap;";
public static Bitmap hook(String str, String str2, String str3, boolean z, Object avVar) {
//圖片 url
Log.w("@@@", "url:" + str2);
return backup();
}
public static Bitmap backup() {
return null;
}
}
複製代碼
public class HookWxAf {
public static String className = "com.tencent.mm.plugin.sns.model.af";
public static String methodName = "getAccSnsPath";
public static String methodSig = "()Ljava/lang/String;";
public static String hook() {
String result = backup();
//圖片存儲路徑(不含id)
Log.w("@@@", "path:"+result);
return result;
}
public static String backup() {
return"";
}
}
複製代碼
public class HookWxLog {
public static String className = "com.tencent.mm.sdk.platformtools.x";
public static String methodName = "d";
public static String methodSig = "(Ljava/lang/String;Ljava/lang/String;)V";
public static void hook(String tag,String msg) {
if ("MicroMsg.SnsHeader".equals(tag)) {
Log.w("@@@", tag + ":" + msg);
}
}
public static void backup(String tag,String msg) {
return;
}
}
複製代碼
/storage/emulated/0/tencent/MicroMsg/c3d467aeabb4fae4b1bbf3a7a6839f5d/sns/b/c/snsb_12944115522489626761
),以圖片方式-打開便可。path: /storage/emulated/0/tencent/MicroMsg/c3d467aeabb4fae4b1bbf3a7a6839f5d/sns/
複製代碼
MicroMsg.SnsHeader:showName x452460984 get bgId : 12944115522489626761 olderBgId: null
複製代碼
public class HookWxSnsUserUI {
public static String className = "com.tencent.mm.plugin.sns.ui.SnsUserUI";
public static String methodName = "onCreate";
public static String methodSig = "(Landroid/os/Bundle;)V";
public static Activity SnsUserUI;
public static void hook(Object thiz, Bundle b) {
Log.w("@@@", "SnsUserUI oncreate");
SnsUserUI = (Activity) thiz;
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
View decorView = SnsUserUI.getWindow().getDecorView();
if (decorView != null && decorView instanceof ViewGroup) {
LinearLayout llContainer = new LinearLayout(SnsUserUI);
FrameLayout.LayoutParams containerLp = new FrameLayout.LayoutParams(-2, -2);
containerLp.gravity = Gravity.CENTER_VERTICAL | Gravity.RIGHT;
llContainer.setOrientation(LinearLayout.VERTICAL);
llContainer.setLayoutParams(containerLp);
llContainer.setGravity(Gravity.CENTER);
llContainer.setBackgroundColor(Color.parseColor("#ececec"));
Button btnCopy = new Button(SnsUserUI);
int wrapContent = LinearLayout.LayoutParams.WRAP_CONTENT;
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(wrapContent, wrapContent);
params.topMargin = SizeUtils.dp2px(8);
btnCopy.setLayoutParams(params);
btnCopy.setText("到瀏覽器打開");
btnCopy.setTextSize(12);
btnCopy.setIncludeFontPadding(false);
btnCopy.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (!HookWxG.URL.equals("empty")) {
ToastUtils.showShort("複製成功`");
// 複製
ClipboardManager clip = (ClipboardManager) SnsUserUI.getSystemService(Context.CLIPBOARD_SERVICE);
clip.setText(HookWxG.URL);
Intent intent = new Intent();
intent.setAction("android.intent.action.VIEW");
Uri content_url = Uri.parse(HookWxG.URL);
intent.setData(content_url);
SnsUserUI.startActivity(intent);
} else {
ToastUtils.showShort("哎呀,地址沒有賦值成功~");
}
}
});
llContainer.addView(btnCopy);
((ViewGroup) decorView).addView(llContainer);
}
}
}, 2000);
backup(thiz, b);
}
public static void backup(Object thiz, Bundle b) {
return;
}
}
複製代碼