最近一直在折騰ollvm,結果折騰了幾天一直編譯不通過,持續踩坑中,只好暫時放在一邊整點app分析分析
該app爲某動畫app,我在看雪上看到有人分析過這個app:https://bbs.pediy.com/thread-258593.htm,
感覺分析的不是很詳細,就自己分析了一下,寫了一篇分析過程
目的:修改該app爲永久會員
首先打開apk看了一下:
顯然想要修改會員日期就需要找到該界面對應的activity,修改方式很多,比如直接搜索會員字符串,然後就能定位到相關位置UserInfoActivity
查看getExpire:
查看setExpire:
發現就是dateFormat對象進行了幾次轉換變成字符串和“2100-01-01”字符串進行比較,只要大於等於該值就是永久會員了。
那麼久很簡單了,直接使用androidKiller修改getExpire返回值就可。
然後當我反編譯之後開始運行的時候,卻發現並不行
那怎麼辦呢,我首先考慮到的是搜索字符串,果然軟件沒有這麼單純,搜不到,所以估計是在服務器端進行的驗證
使用fiddler抓個包:
imei映入眼簾,直接搜索一下試試:
果然搜到了,查看getV():
原來是一個native方法,返回類型爲String,傳入了一個當前的時間戳,想來直接修改返回值是不現實的了,只能看so層代碼分析校驗碼是怎麼產生的了。
然而不幸的是使用ida靜態分析發現有些參數沒有顯示,所幸找到了參數的位置,可以根據動態調試找到具體的值:
但是網上說jeb也有了查看so的功能,用其查看發現非常的清晰:
由圖中可知,一共有三個check分別和定值"dt8re"+"rt9ws"拼接其中有兩個參數一個hash1,一個hash2
經過計算得出
目前想到過兩種方法動態調試也可以:(1)動態調試獲取該值;(2)使用hook技術取定值的時間戳並打印返回值,按照控制變量法計算出結果
下面僅展示hook法:
(1)首先使用frida hook js腳本
Java.perform(function () {
var CheckUtils = Java.use("info.zzjian.dididh.util.CheckUtils");
CheckUtils.getV.overload("long").implementation = function (j) {
var ret = this.getV(j);
console.log(this.getV(0));
return (ret);
};
});
打印結果爲:
33cc6f39fdt8re3af08b80crt9ws3ff2a033f
根據結果拆分爲:
(check1)33cc6f39f + dt8re + (check2)3af08b80c + 9ws3f + (check3)f2a033f
根據控制變量法求出
hash1 = -1916912749L;
hash2 = 1344359219L;
求出最終的字符串爲:
String check1 = Long.toHexString(13904573343L + ts * 2);
String check2 = Long.toHexString(15821486092L + ts);
String check3 = Long.toHexString(17165845311L + ts);
return check1 + "dt8re" + check2 + "rt9ws" + check3;
根據還原的算法,重寫一個CheckUtils.java讓它在java層直接返回字符串
public class CheckUtils {
public CheckUtils() {
}
public String getV(long ts) {
String check1 = Long.toHexString(13904573343L + ts * 2);
String check2 = Long.toHexString(15821486092L + ts);
String check3 = Long.toHexString(17165845311L + ts);
return check1 + "dt8re" + check2 + "rt9ws" + check3;
}
}
使用命令行將編寫的java文件轉化爲smali文件,這裏有寫好的腳本可以在我的資源文件中查看下載(轉化的根據實際情況對包名進行更改):
.class public Linfo/zzjian/dididh/util/CheckUtils;
.super Ljava/lang/Object;
.source "CheckUtils.java"
# direct methods
.method public constructor <init>()V
.registers 1
.prologue
.line 3
invoke-direct {p0}, Ljava/lang/Object;-><init>()V
.line 4
return-void
.end method
# virtual methods
.method public getV(J)Ljava/lang/String;
.registers 8
.prologue
.line 7
const-wide v0, 0x33cc6f39fL
const-wide/16 v2, 0x2
mul-long/2addr v2, p1
add-long/2addr v0, v2
invoke-static {v0, v1}, Ljava/lang/Long;->toHexString(J)Ljava/lang/String;
move-result-object v0
.line 8
const-wide v2, 0x3af08b80cL
add-long/2addr v2, p1
invoke-static {v2, v3}, Ljava/lang/Long;->toHexString(J)Ljava/lang/String;
move-result-object v1
.line 9
const-wide v2, 0x3ff2a033fL
add-long/2addr v2, p1
invoke-static {v2, v3}, Ljava/lang/Long;->toHexString(J)Ljava/lang/String;
move-result-object v2
.line 10
new-instance v3, Ljava/lang/StringBuilder;
invoke-direct {v3}, Ljava/lang/StringBuilder;-><init>()V
invoke-virtual {v3, v0}, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder;
move-result-object v0
const-string v3, "dt8re"
invoke-virtual {v0, v3}, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder;
move-result-object v0
invoke-virtual {v0, v1}, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder;
move-result-object v0
const-string v1, "rt9ws"
invoke-virtual {v0, v1}, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder;
move-result-object v0
invoke-virtual {v0, v2}, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder;
move-result-object v0
invoke-virtual {v0}, Ljava/lang/StringBuilder;->toString()Ljava/lang/String;
move-result-object v0
return-object v0
.end method
再用寫好的代碼覆蓋androidkiller中的類
然後在反編譯就成功的得到了結果:
補:當然由於這個apk是沒有檢測hook的,我們可以直接通過Xposed或者fridahook實現破解VIP的功能,當我查看作者聲明的時候發現作者也不反對使用Xposed等進行修改:
因此還是非常感謝作者給了我這個學習的機會,但是破解版的apk就不在這裏提供了,如果大家有需要可以直接上官網下載原版:http://dddh.pub/