NewStar2023-lazyActivity

前言

唉,去年的题,去年做法倒是蛮简单的,今年会了很多,记录一下。

最简单的方法

搜flag就行,能在资源部分找到:

image-20230925191914791

自己整的

观察整个用户代码:

image-20230925192040142

结合实机使用:

image-20230925192407500

不难猜测FlagActivity是真正的出flag:

Class FlagActivity

实际上安卓在启动时候会根据自身的一个XML资源文件从而选择启动的Activity:

image-20230925192802076

实际上,我们可以在安卓的shell中以管理员的身份执行以下命令,从而指定Activity:

1
am start -n com.example.app/com.example.app.MainActivity

重打包

可以通过apktool来将安装包来反编译,来修改这个XML:

修改完了再使用apktool在编译,但是编译的结果是没有签名文件的,安卓系统对于应用文件需要签名后才能进行安装,使用apk ez tool(是一个可视化工具)来进行方便快捷的签名,根据没有眼的鱼说,这样签名是属于二类签名,用java自带的签名是属于一类签名,现在的安卓系统可能会不怎么承认。

Frida Hook

分析具体的类:

Class FlagActivity

对于静态方法,不太好hook,可以考虑从onCreate()下手:

hook js

这样hook,实际运行结果就是照样进行界面的生成:

然后再把类的cnt的值进行修改:

hook结果

结合access$004()这个方法每次点击会自增1,从而达到(9999+1)>=1w这个目标,整个hook过程就结束了。

另一种hook

针对access$004()这个方法进行hook,一种hook是:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
Java.perform(() => {
// 在这定义一个const声明的变量,保存要hook的类
const MainActivity = Java.use('com.droidlearn.activity_travel.FlagActivity');

// 一个常量,记录触发的方法
const onCreate = MainActivity.access$004;
// send('sucess get onClick')
//重载onClick方法
onCreate.implementation = function (v) {
// Show a message to know that the function got called
send('access$004 called');
onCreate.call(this, v);
v.cnt.value += 9999;
send('value change')

// Log to the console that it's done, and we should have the flag!
console.log('Done:' + JSON.stringify(v.cnt));
return v.cnt.value;
};
});


另一种:

1
2
3
4
5
6
7
8
9
10
11
12
funtion hook(){
// 在这定义一个const声明的变量,保存要hook的类
const MainActivity = Java.use('com.droidlearn.activity_travel.FlagActivity');
MainActivity.access$004.overload('com.droidlearn.activity_travel.FlagActivity').implementation = function (fa){
send('access$004 called');
fa.cnt.value += 10000;
send('value change');
return fa.cnt.value;
}
}
setImmediate(hook)

重打包的方法

既然都重打包了,那可以考虑直接将这个>=10000修改成>=0,然后重打包,就不用hook了。