一、系统环境
OS: Windows_NT x64 10.0.19045
python:3.8.10
Node.js: 18.17.1
frida :14.2.14
objection:1.11.0
vscode: 1.87.2
device:nexus 5x-7.1.2
二、详细分析
前言:
通过界面文字可以发现 flag 要通过抽奖获取,点击十连抽之后大概率是无法抽到flag的,并且要等待很长时间后才能再次抽奖,很明显面对这种应用直接上工具盘它
正文:
应用没加壳,使用 jadx 打开后看到里面有两个 Activity,WishActivity和FlagActivity
两个Activity的主要逻辑都比较简单,WishActivity用于抽奖判断,FlagActivity用于 flag 计算
# 应用启动后就会启动定时器线程对抽奖次数进行累加
public int[] f2496o = {10, 0, 0};#10,0,0分别表示可抽奖次数,已抽奖次数,增加抽奖次数倒计时
/* renamed from: p */
public int[] f2497p = {1, 2, 4, 8, 16, 32, 64, 128};#增加抽奖次数每次倒计时
/* renamed from: q */
public Timer f2498q = new Timer();
/* renamed from: r */
public Runnable f2499r = new Runnable() { // from class: b.b.a.b
@Override // java.lang.Runnable
public final void run() {
WishActivity wishActivity = WishActivity.this;
TextView textView = (TextView) wishActivity.findViewById(R.id.tvResStatus);
int[] iArr = wishActivity.f2496o;
if (iArr[2] > 0) {
iArr[2] = iArr[2] - 1;
} else {
if (iArr[0] < 10) {
iArr[0] = iArr[0] + 1;
}
wishActivity.f2496o[2] = wishActivity.f2497p[Math.min((iArr[0] + iArr[1]) - 10, wishActivity.f2497p.length - 1)];
}
int[] iArr2 = wishActivity.f2496o;
textView.setText(iArr2[0] < 10 ? String.format(Locale.SIMPLIFIED_CHINESE, "当前已完成%d次祈愿,拥有%d个纠缠之缘\n%d秒后将为你补充一个", Integer.valueOf(iArr2[1]), Integer.valueOf(wishActivity.f2496o[0]), Integer.valueOf(wishActivity.f2496o[2])) : String.format(Locale.SIMPLIFIED_CHINESE, "当前已完成%d次祈愿,当前拥有%d个纠缠之缘\n纠缠之缘已满,%d秒后将溢出一个,请尽快使用!", Integer.valueOf(iArr2[1]), Integer.valueOf(wishActivity.f2496o[0]), Integer.valueOf(wishActivity.f2496o[2])));
}
};
public class C0377a extends TimerTask {
public C0377a() {
}
@Override // java.util.TimerTask, java.lang.Runnable
public void run() {
WishActivity wishActivity = WishActivity.this;
wishActivity.runOnUiThread(wishActivity.f2499r);
}
}
#WishActivity
public void onCreate(Bundle bundle) {
super.onCreate(bundle);
setContentView(R.layout.activity_wish);
this.f2498q.schedule(new C0377a(), 1000L, 1000L);
findViewById(R.id.btn_action).setOnClickListener(new View.OnClickListener() { // from class: b.b.a.a
@Override // android.view.View.OnClickListener
public final void onClick(View view) {
String str;
WishActivity wishActivity = WishActivity.this;
if (wishActivity.f2496o[0] < 10) {
str = "纠缠之缘不足,无法进行祈愿";
} else {
for (int i = 0; i < 10; i++) {
int[] iArr = wishActivity.f2496o;
iArr[0] = iArr[0] - 1;
iArr[1] = iArr[1] + 1;
if (Math.random() < (wishActivity.f2496o[1] <= 80 ? 0.006d : (r6[1] - 80) * 0.1d)) {
Toast.makeText(wishActivity, "恭喜你十连出金了,奖品为 flag 提示!", 1).show();
wishActivity.startActivity(new Intent(wishActivity, (Class<?>) FlagActivity.class));
return;
}
}
str = "哎呀呀,(又)没抽中,一会再试试吧";
}
Toast.makeText(wishActivity, str, 0).show();
}
});
}
public class FlagActivity extends ActivityC0012h {
/* renamed from: o */
public static byte[] f2495o = {86, -18, 98, 103, 75, -73, 51, -104, 104, 94, 73, 81, 125, 118, 112, 100, -29, 63, -33, -110, 108, 115, 51, 59, 55, 52, 77};
@Override // p000a.p002b.p003c.ActivityC0012h, p000a.p042i.p043a.ActivityC0257d, androidx.activity.ComponentActivity, p000a.p024f.p025b.ActivityC0182g, android.app.Activity
public void onCreate(Bundle bundle) {
byte[] bArr;
Signature[] signatureArr;
super.onCreate(bundle);
setContentView(R.layout.activity_flag);
byte[] bArr2 = f2495o;
try {
signatureArr = getPackageManager().getPackageInfo(getPackageName(), 64).signatures;
} catch (PackageManager.NameNotFoundException unused) {
bArr = new byte[0];
}
if (signatureArr != null && signatureArr.length >= 1) {
byte[] byteArray = signatureArr[0].toByteArray();
ByteBuffer allocate = ByteBuffer.allocate(bArr2.length);
for (int i = 0; i < bArr2.length; i++) {
allocate.put((byte) (bArr2[i] ^ byteArray[i % byteArray.length]));
}
bArr = allocate.array();
TextView textView = (TextView) findViewById(R.id.tvFlagHint);
StringBuilder m1162d = C0374a.m1162d("for honest players only: \n");
m1162d.append(new String(bArr));
textView.setText(m1162d.toString());
}
bArr = new byte[0];
TextView textView2 = (TextView) findViewById(R.id.tvFlagHint);
StringBuilder m1162d2 = C0374a.m1162d("for honest players only: \n");
m1162d2.append(new String(bArr));
textView2.setText(m1162d2.toString());
}
}
要获得这个flag有几种方法
1.修改smali代码中的判断
找到代码中 if 判断的位置直接注释掉判断保存文件即可,因为flag是由签名计算而来,所以不能对apk进行重签名(NP工具设置里面取消勾选APK自动签名),可以使用【核心破解】 工具安装未签名的应用(需要先安装Xposed或LSPosed,并且要在 Xposed或LSPosed中启用【核心破解】模块)
重新安装修改后 未签名 的APK打开,点击十连抽就会跳转到 flag 界面
2.直接启动FlagActivity
adb shell am start-activity -n com.kbtx.redpack_simple/.FlagActivity
3.修改可抽奖次数
4.修改抽奖概率值
if (Math.random() < (wishActivity.f2496o[1] <= 80 ? 0.006d : (r6[1] - 80) * 0.1d)) {
#用NP工具修改dex smali
const-wide v6, 0x3f789374bc6a7efaL # 0.006
const-wide v8, 0x3fb999999999999aL # 0.1
#改成
const-wide v6, 0x3FF0000000000000L # 1.0
const-wide v8, 0x3FF0000000000000L # 1.0