前言:
前段时间,我哥让我分析一款加速器,我一看,好家伙,又是开局送三天的货色,这不白嫖一波?思路参考芽衣大佬,代码是偷鸭鸭大佬的,你们要感谢的话,就感谢两位大佬提供的白嫖方法吧
过程:
一、抓包分析
首先我在模拟器抓包看了一下数据,从包里不难看出软件在启动的时候会发送一段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的情况下来对比会比较明显。结果很成功!