前言:
前段时间,我哥让我分析一款加速器,我一看,好家伙,又是开局送三天的货色,这不白嫖一波?思路参考芽衣大佬,代码是偷鸭鸭大佬的,你们要感谢的话,就感谢两位大佬提供的白嫖方法吧
过程:
一、抓包分析
首先我在模拟器抓包看了一下数据,从包里不难看出软件在启动的时候会发送一段post请求,其中的imsi,imei,androidid等一般都是来判断是否是新用户的依据。
二、apk分析
接着打开安装包,搜索imsi关键词,根据包名筛选原则,点击第一个进入,很明显这里就是我们要找的地方,imsi,imei,androidId,versionName等跟我们刚才抓包的信息一致,接着转java看一下
代码如下(我这里只截取了部分代码):
JSONObject jSONObject = new JSONObject(); try { jSONObject.put("imsi", str); jSONObject.put("imei", str2); jSONObject.put("androidId", o(context)); jSONObject.put("versionName", str5); jSONObject.put("versionCode", i2); jSONObject.put("model", str7); jSONObject.put("versionApi", i3); jSONObject.put("versionRelease", str9); jSONObject.put("username", string); jSONObject.put("password", string2); jSONObject.put("phoneName", str4); jSONObject.put("jerryali", d()); jSONObject.put("channel", f2); jSONObject.put("language", language); jSONObject.put("pkgname", u); jSONObject.put("installedgoogleplay", g(context)); return jSONObject;
很明显这里会返回一个json对象,我们可以打印一下log,对这些数据再进行甄别,看看真正的关键数据的哪一个,这里我们选择用mt的log注入(用其他注入也可以,自行选择),不会mt注入的可以参考我以前写的帖子,点击这里跳转。注入关键如下:
根据我们打印出来的数据和抓包的数据进行对比,imsi和imei可以为未知,而androidId才是我们真正需要改的数据,并且它是一串随机的十六位字符串,那么这里就可以借用小白鸭大佬的代码(省去我们再造轮子的功夫),具体代码如下:
import android.content.Context; import android.content.SharedPreferences; import java.util.Date; import static android.content.Context.MODE_PRIVATE; public class Utils { public static SharedPreferences sp; public static String getRandom(Context context) { sp = context.getSharedPreferences("Config", MODE_PRIVATE); String id; int a = 16; String KeyString = "123456789abcdef"; int len = KeyString.length(); StringBuffer sb = new StringBuffer(); for(int i=0;i<a;i++){ sb.append(KeyString.charAt((int) Math.round(Math.random()*(len-1)))); } id =sp.getString("id",KeyString); if(needupdate()){ id = sb.toString(); sp.edit().putString("id",id).commit(); } return id; } public static boolean needupdate(){ Date date = new Date(System.currentTimeMillis()); //以十二小时为界限,可自行更改。 if(sp.contains("temp")&&date.getTime()-sp.getLong("temp",date.getTime())<43200000)return false; sp.edit().putLong("temp", date.getTime()).commit(); return true; } }
转smali代码:
.class public LlittleWhiteDuck/Utils; .super Ljava/lang/Object; .source "Utils.java" # static fields .field public static sp:Landroid/content/SharedPreferences; # direct methods .method public constructor <init>()V .registers 1 .line 10 invoke-direct {p0}, Ljava/lang/Object;-><init>()V return-void .end method .method public static getRandom(Landroid/content/Context;)Ljava/lang/String; .registers 8 const-string v0, "Config" const/4 v1, 0x0 .line 15 invoke-virtual {p0, v0, v1}, Landroid/content/Context;->getSharedPreferences(Ljava/lang/String;I)Landroid/content/SharedPreferences; move-result-object p0 sput-object p0, LlittleWhiteDuck/Utils;->sp:Landroid/content/SharedPreferences; .line 20 new-instance p0, Ljava/lang/StringBuffer; invoke-direct {p0}, Ljava/lang/StringBuffer;-><init>()V :goto_e const/16 v0, 0x10 const-string v2, "123456789abcdef" if-ge v1, v0, :cond_2f .line 22 invoke-static {}, Ljava/lang/Math;->random()D move-result-wide v3 const/16 v0, 0xe int-to-double v5, v0 invoke-static {v5, v6}, Ljava/lang/Double;->isNaN(D)Z mul-double v3, v3, v5 invoke-static {v3, v4}, Ljava/lang/Math;->round(D)J move-result-wide v3 long-to-int v0, v3 invoke-virtual {v2, v0}, Ljava/lang/String;->charAt(I)C move-result v0 invoke-virtual {p0, v0}, Ljava/lang/StringBuffer;->append(C)Ljava/lang/StringBuffer; add-int/lit8 v1, v1, 0x1 goto :goto_e .line 24 :cond_2f sget-object v0, LlittleWhiteDuck/Utils;->sp:Landroid/content/SharedPreferences; const-string v1, "id" invoke-interface {v0, v1, v2}, Landroid/content/SharedPreferences;->getString(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String; move-result-object v0 .line 25 invoke-static {}, LlittleWhiteDuck/Utils;->needupdate()Z move-result v2 if-eqz v2, :cond_4e .line 27 invoke-virtual {p0}, Ljava/lang/StringBuffer;->toString()Ljava/lang/String; move-result-object v0 .line 29 sget-object p0, LlittleWhiteDuck/Utils;->sp:Landroid/content/SharedPreferences; invoke-interface {p0}, Landroid/content/SharedPreferences;->edit()Landroid/content/SharedPreferences$Editor; move-result-object p0 invoke-interface {p0, v1, v0}, Landroid/content/SharedPreferences$Editor;->putString(Ljava/lang/String;Ljava/lang/String;)Landroid/content/SharedPreferences$Editor; move-result-object p0 invoke-interface {p0}, Landroid/content/SharedPreferences$Editor;->commit()Z :cond_4e return-object v0 .end method .method public static needupdate()Z .registers 7 .line 36 new-instance v0, Ljava/util/Date; invoke-static {}, Ljava/lang/System;->currentTimeMillis()J move-result-wide v1 invoke-direct {v0, v1, v2}, Ljava/util/Date;-><init>(J)V .line 38 sget-object v1, LlittleWhiteDuck/Utils;->sp:Landroid/content/SharedPreferences; const-string v2, "temp" invoke-interface {v1, v2}, Landroid/content/SharedPreferences;->contains(Ljava/lang/String;)Z move-result v1 if-eqz v1, :cond_2b invoke-virtual {v0}, Ljava/util/Date;->getTime()J move-result-wide v3 sget-object v1, LlittleWhiteDuck/Utils;->sp:Landroid/content/SharedPreferences; invoke-virtual {v0}, Ljava/util/Date;->getTime()J move-result-wide v5 invoke-interface {v1, v2, v5, v6}, Landroid/content/SharedPreferences;->getLong(Ljava/lang/String;J)J move-result-wide v5 sub-long/2addr v3, v5 const-wide/32 v5, 0x2932e00 cmp-long v1, v3, v5 if-gez v1, :cond_2b const/4 v0, 0x0 return v0 .line 40 :cond_2b sget-object v1, LlittleWhiteDuck/Utils;->sp:Landroid/content/SharedPreferences; invoke-interface {v1}, Landroid/content/SharedPreferences;->edit()Landroid/content/SharedPreferences$Editor; move-result-object v1 invoke-virtual {v0}, Ljava/util/Date;->getTime()J move-result-wide v3 invoke-interface {v1, v2, v3, v4}, Landroid/content/SharedPreferences$Editor;->putLong(Ljava/lang/String;J)Landroid/content/SharedPreferences$Editor; move-result-object v0 invoke-interface {v0}, Landroid/content/SharedPreferences$Editor;->commit()Z const/4 v0, 0x1 return v0 .end method
这里讲一下如何把这段smali插入apk中,让小白听得明白些,首先dex++打开dex,在浏览界面长按任何一个路径,点击添加,包名填littleWhiteDuck,类名填Utils,然后确定,最后把上面的smali代码复制粘贴即可。
最后,我们需要再分析一下在哪里插入调用代码,根据上面的信息,我们把目标锁定在Lcc/dingnet/和谐/a/a;这个类中,已知代码中会调用Lcc/dingnet/和谐/a/a;类中的o方法获得androidId并put进json对象中,所以我们只需要将
invoke-static {p0}, Lcc/dingnet/和谐/a/a;->o(Landroid/content/Context;)Ljava/lang/String;
替换成
invoke-static {p0}, LlittleWhiteDuck/Utils;->getRandom(Landroid/content/Context;)Ljava/lang/String;
最后:
我们来测试一下效果,最好是在打了log的情况下来对比会比较明显。结果很成功!