apk重打包动态调试

以一道apk题目学习apk重打包并进行动态调试

题目思路

看到题目,看解压的文件就知道有native层的操作

看到dex文件的onGoClick()

image-20220117204226432

判断的思路是:对输入进行encrypt getSecret方法的加密之后,和 getSecret方法加密的getFlag值进行比较。

两边都进行了同样的加密,所以可以简化程序为

1
2
3
4
if ( getFlag() .equal ( encrypt(input) ) )
{
success;
}

encrypt方法和getFlag方法都在lib文件里

看到lib文件,简单明了

encrypt函数

image-20220117204714356

先改第一个参数类型为JNIEnv *env,正确解析出两个函数,看到for循环,作用是把a1的每一个值-1。

getFlag函数

image-20220117204926055

考虑到这个函数没有输入对他的影响,所以这里直接动调得到返回值

经过JEB动调,返回值是:

1
ek`fz@q2^x/t^fn0mF^6/^rb`qanqntfg^E`hq|

思路就是我的输入每一个字节-1,等于返回值,所以直接把返回值每字节+1即可

1
2
3
for i in "ek`fz@q2^x/t^fn0mF^6/^rb`qanqntfg^E`hq|":
print(chr(ord(i)+1),end='')
#flag{Ar3_y0u_go1nG_70_scarborough_Fair}

JEB动态调试

0.大体步骤

image-20220117210304834

1.能否调试

查看

查看解压之后的 AndroidManifest.xml 文件,看是否有

image-20220117210502192

android:debuggable属性,如果没有就手动添加上 android:debuggable="true" ,如果是false的话就改成true。

解压方式:可以用一般的解压软件直接解压,或者是用apktool进行解压

apktool:

1
2
apktool d ###.apk
apktool b 文件夹名

修改

如果需要修改的话,就需要对apk文件进行解包修改,拆电视机容易,组装可就难了

再改完之后,通过apktool进行重打包

apk解包

image-20220117212514460

同目录下找到同名文件夹

这里如果是一般解压的话, AndroidManifest.xml 文件会被当作是二进制文件无法被打开,apktool解包的话,vscode正常打开,在进行必要的修改之后保存。

apk打包

image-20220117213017020

打包之后在文件夹中找到dist文件夹,里的新的apk文件。

apk签名

仅仅是打包的文件还是不能运行的,在adb insall 的时候也会报错,拖进模拟器会无法安装。

为什么要签名:

  • 由于开发商可能通过使用相同的 Package Name 来混淆替换已经安装的程序,以此保证签名不同的包不被替换

  • 保证信息传输的完整性。签名对于包中的每个文件进行处理,以此确保包中内容不被替换

  • 防止交易中的抵赖发生, Market 对软件的要求

这里使用jdk自带的两个工具:keytool和jarsigner工具,在jdk目录中,这里方便起见先把jdk的bin目录添加在环境变量。

用keytool获得密钥,用后者进行签名

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
>keytool -genkey -alias demo.keystore -keyalg RSA -validity 100 -keystore demo.keystore

输入密钥库口令:
密钥库口令太短 - 至少必须为 6 个字符
输入密钥库口令:
再次输入新口令:
您的名字与姓氏是什么?
[Unknown]: r
您的组织单位名称是什么?
[Unknown]: oo
您的组织名称是什么?
[Unknown]: t
您所在的城市或区域名称是什么?
[Unknown]: k
您所在的省/市/自治区名称是什么?
[Unknown]: i
该单位的双字母国家/地区代码是什么?
[Unknown]: t
CN=r, OU=oo, O=t, L=k, ST=i, C=t是否正确?
[否]: Y

输入 <demo.keystore> 的密钥口令
(如果和密钥库口令相同, 按回车):
1
2
3
4
>jarsigner -keystore demo.keystore -signedjar 新.apk 打包的.apk demo.keystore

输入密钥库的密码短语:
jar 已签名。

之后会生成一个新的apk文件,这个文件就可以正常使用了

2.推送到安卓设备

手机

adb连接,通过 adb install mulu/aaa.apk

模拟器

直接拖进去,命令 adb connect 127.0.0.1:端口,不同的模拟器有不同的端口,夜神模拟器的端口是62001.

3.JEB附加调试

apk文件拖进jeb,在disassemble界面通过ctrl+b下断点。

image-20220117211555191

点击调试器里的开始调试,弹出进程选择界面

image-20220117211711571

这里直接附上就可以调试了,这时可以看到jeb会出现三个窗口

image-20220117214426692

这里主要关注的是局部变量,输入之后停在断点处。

通过f6单步调试

image-20220117214735007

这里注意v1的变量类型,string的s小写,单击可以修改

image-20220117214818299

这就可以得到这个函数的返回值了,就可以解题了。