首篇作為開始,先講講簡單的反編譯。反編譯通常有幾種目的:互相學習、借來用用、嘿嘿(干你,又分為小干干類似微信紅包,和大干干改別人的apk幫他上架)。
因為沒帶kvm回來,mbpr屏幕太小,所以下文環境為windows。
一、反編譯
讓我們從實戰開始,先實踐一下怎么去反編譯一個apk,看看某些功能的實現。畢竟沒有實踐的原理都是耍流氓。
這里我們保留互相學習的心態,所以是友善的第一種目的,嘻嘻。
1、準備
工具
安裝包
手機QQ 6.2.3 (目標就設定為看看口令紅包是怎么做的吧)
2、Apktool的使用
首先確保你安裝了java 7或以上,并能直接在命令行調用java。
Apktool v2.0.3 - a tool for reengineering Android apk fileswith smali v2.1.0 and baksmali v2.1.0usage: apktool -advance,--advanced prints advance information. -version,--version prints the version then exitsusage: apktool if|install-framework [options] <framework.apk> -p,--frame-path <dir> Stores framework files into <dir>. -t,--tag <tag> Tag frameworks using <tag>.usage: apktool d[ecode] [options] <file_apk> -f,--force Force delete destination directory. -o,--output <dir> The name of folder that gets written. Default is apk.out -p,--frame-path <dir> Uses framework files located in <dir>. -r,--no-res Do not decode resources. -s,--no-src Do not decode sources. -t,--frame-tag <tag> Uses framework files tagged by <tag>.usage: apktool b[uild] [options] <app_path> -f,--force-all Skip changes detection and build all files. -o,--output <dir> The name of apk that gets written. Default is dist/name.apk -p,--frame-path <dir> Uses framework files located in <dir>.
3、jadx的使用
4、分析APK文件
First Try
雖然我們可以用jadx直接打開apk傻瓜式地去查看源代碼,但是為了更理解反編譯的過程和工作原理,以便以后在碰到一些問題(比如加殼)的時候可以自己解決,這里我們先裝逼一下,使用Apktool去進行分析。
D:/dev/reverse>apktool d -o qq mobileqq_android_6.2.3.apkI: Using Apktool 2.0.3 on mobileqq_android_6.2.3.apkI: Loading resource table...Exception in thread "main" brut.androlib.AndrolibException: Multiple res specs: attr/name at brut.androlib.res.data.ResTypeSpec.addResSpec(ResTypeSpec.java:78) at brut.androlib.res.decoder.ARSCDecoder.readEntry(ARSCDecoder.java:248) at brut.androlib.res.decoder.ARSCDecoder.readTableType(ARSCDecoder.java:212) at brut.androlib.res.decoder.ARSCDecoder.readTableTypeSpec(ARSCDecoder.java:154) at brut.androlib.res.decoder.ARSCDecoder.readTablePackage(ARSCDecoder.java:116) at brut.androlib.res.decoder.ARSCDecoder.readTableHeader(ARSCDecoder.java:78) at brut.androlib.res.decoder.ARSCDecoder.decode(ARSCDecoder.java:47) at brut.androlib.res.AndrolibResources.getResPackagesFromApk(AndrolibResources.java:544) at brut.androlib.res.AndrolibResources.loadMainPkg(AndrolibResources.java:63) at brut.androlib.res.AndrolibResources.getResTable(AndrolibResources.java:55) at brut.androlib.Androlib.getResTable(Androlib.java:66) at brut.androlib.ApkDecoder.setTargetSdkVersion(ApkDecoder.java:198) at brut.androlib.ApkDecoder.decode(ApkDecoder.java:96) at brut.apktool.Main.cmdDecode(Main.java:165) at brut.apktool.Main.main(Main.java:81)
竟然報錯了,Multiple res specs: attr/name,在網上找了找資料,應該是騰訊利用Apktool的bug去進行了加殼,除了添加同名id外還做了若干加固,好,你狠,我們下篇文章針對騰訊的殼來分析并修改Apktool,這次先用jadx來試試。
Second Try
如果直接用jadx-gui打開QQ的apk,你會發現,卡死了。不錯,就是卡死了,因為太大了…
我們打開jadx-gui文件(其實就是個啟動的script),加上:
set JAVA_OPTS=-server -Xms1024m -Xmx8192m -XX:PermSize=256m -XX:MaxPermSize=1024m
就跟我們加速as/idea的原理差不多,多給點內存,這樣就能順利地打開了(可能會需要比較久的時間)。

5、字符串大法
為了找到我們的目標,紅包,我們首先嘗試用字符串搜索大法:在Resources -> resources.arsc -> res -> values -> strings.xml找到口令紅包對應的
<string name="qb_hbdetail_command_word">口令紅包</string>
然后Crtl+Shift+F進行Text Search,結果…沒找到。
我們再使用資源id大法,直接在resources.arsc找到
0x7f0a0e5a (2131365466) = string.qb_hbdetail_command_word: 口令紅包
再搜,好,你狠。。。還是沒有。是在下輸了。
6、類/函數名大法
我們再祭出第二大殺器,類/函數/變量名大法搜索大法。
通常類名符合的范圍更小,所以先只使用Class。
試試看紅包的英語:RedPacket(類名命名所以R和P大寫)

OK,我們找到了十幾條,開始逐一排查,第一條RedPacketInfo點進去一看就是個包含了各種field的ui用的vo類,跳過,再看下一個,從包名com.tencent.mobileqq.data看上去,似乎有戲,QQWalletRedPacketMsg:
package com.tencent.mobileqq.data;import android.text.TextUtils;import com.tencent.mobileqq.hotpatch.NotVerifyClass;import cooperation.qzone.util.WiFiDash;import java.io.IOException;import java.io.ObjectInput;import java.io.ObjectOutput;import tencent.im.msg.im_msg_body.QQWalletAioBody;/* compiled from: ProGuard */public class QQWalletRedPacketMsg { public String authkey; private int channelId; public int conftype; public QQWalletTransferMsgElem elem; public String envelopeName; public int envelopeid; public boolean isOpened; public int msgFrom; public String redPacketId; public int redtype; private int resend; public int templateId; ...串行化、讀寫、構建方法等,可以無視。
從field名來看,這里還是比較可疑的,猜測redtype是不是描述紅包類型的。
我們再次使用關鍵詞redtype進行搜索,這次選擇Code,只進行代碼內搜索,結果卻發現貌似不對,找到相關的字符串是”查看詳情”,貌似是描述紅包領取狀態的。
不放棄,繼續抓住QQWalletRedPacketMsg這個類進行搜索,看看是不是有外面包著這個類的Class,搜索QQWalletRedPacketMsg,范圍使用Field,排除掉類本身外,只有唯一的結果:MessageForQQWalletMsg:
public class MessageForQQWalletMsg extends ChatMessage { // 哦哦?COMMAND_REDPACKET?口令紅包 public static final int MSG_TYPE_COMMAND_REDPACKET = 6; public static final int MSG_TYPE_COMMON_REDPACKET = 2; public static final int MSG_TYPE_COMMON_THEME_REDPACKET = 4; public static final int MSG_TYPE_INDIVIDUAL_REDPACKET = 2001; public static final int MSG_TYPE_LUCY_REDPACKET = 3; public static final int MSG_TYPE_LUCY_THEME_REDPACKET = 5; public static final int MSG_TYPE_PUBLIC_ACCOUNT_REDPACKET = 2002; public static final int MSG_TYPE_TRANSFER = 1; ...我們找到了一個常量字段,目測就是這個描述了是否是口令紅包了。在該類搜索此字段還找到
public static boolean isCommandRedPacketMsg(MessageRecord messageRecord) { if (messageRecord != null && (messageRecord instanceof MessageForQQWalletMsg) && ((MessageForQQWalletMsg) messageRecord).messageType == MSG_TYPE_COMMAND_REDPACKET) { return true; } return false;}果然,我們再接著分別查找MSG_TYPE_COMMAND_REDPACKET和isCommandRedPacketMsg,結果只在TroopMessageManager里面找到了一段沒成功反編譯的代碼中對方法isCommandRedPacketMsg的引用:
L_0x0100: r2 = com.tencent.mobileqq.data.MessageForQQWalletMsg.isCommandRedPacketMsg(r25); if (r2 == 0) goto L_0x011e;
這里如果是口令紅包會繼續走下去,而如果不是則會跳到L_0x011e。
而從類的名字來看,TroopMessageManager應該是指群消息管理者,應該沒錯,畢竟紅包也是群消息的一種。
于是我們只能耐心地看下去這段神奇的充滿goto的代碼。暈著看完后大概看到就是各種邏輯判斷和調用MsgProxyUtils.java去處理消息處理邏輯和緩存。然后就沒了…好,你 主站蜘蛛池模板: 吴堡县| 临武县| 句容市| 台山市| 兴文县| 阳高县| 江山市| 长寿区| 沭阳县| 江华| 台安县| 汝阳县| 灌阳县| 宜黄县| 洪湖市| 南澳县| 柞水县| 竹北市| 三台县| 诏安县| 怀安县| 唐河县| 西青区| 南阳市| 温州市| 贞丰县| 塔城市| 怀来县| 中阳县| 沈阳市| 甘南县| 于都县| 铁力市| 淳安县| 凤山市| 郴州市| 三穗县| 吉木萨尔县| 桂平市| 新平| 花莲县|