吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 7673|回复: 44
收起左侧

[Android 原创] 【2021春节】Android中级题

  [复制链接]
漁滒 发表于 2021-3-5 12:54
逆向之前需要准备以下一些工具
1.ApkScan-PKID(用于apk查壳)
2.jadx-gui-1.2.0(用于反编译apk)
3.IDA_Pro_v7.0(用于静态分析so文件)
4.python(运行frida注入js代码)
首先打开ApkScan-PKID,将待分析的apk拖进去,发现没有加固
0.jpg
那么就可以直接拉进jadx进行反编译,安装好apk后随便输入一个值,会提示【flag格式错误,请重试】
0.png
那么就在jadx中搜索这个字符串,可以找到在【cn.pojie52.cm01.MainActivity】这个类下
1.jpg
这里可以看到检测了输入的文本长度是否等于30,如果不是一律显示【flag格式错误,请重试】。长度是30的时候,会调用这个类下的check方法,如果返回真,则flag正确
但是这里的check方法是一个native函数,方法体在libnative-lib.so中,那么接着用ida分析这个so。ida加载so后,加载jni.h分析头文件,查看导出函数,发现是一个静态注册的方法
2.jpg
双击进入这个函数,然后按F5转换为伪C代码,大概浏览一下,发现有一个与处级题中相似的结构
3.jpg
也就是说只要拿到v11与v27,就可以知道在对比什么了。首先分析v11,网上可以看到,输入的内容经过sub_B90和sub_D90两个函数以后,就得到了v11
4.jpg
那么首先来hook一下这两个函数
python代码
[Python] 纯文本查看 复制代码
import frida
import sys

def message(message, data):
    pass

with open('jscode.js', 'r', encoding='utf-8') as f:
    jscode = f.read()

process = frida.get_remote_device().attach('cn.pojie52.cm01')
script = process.create_script(jscode)
script.on("message", message)
script.load()
sys.stdin.read()


js代码
[JavaScript] 纯文本查看 复制代码
function main() {
	Java.perform(function (){
		var libnative = Module.findBaseAddress("libnative-lib.so");
		console.log("libnative: " + libnative);
		var sub_B90 = libnative.add(0xB90);
		var sub_B90arge0;
		console.log("sub_B90: " + sub_B90);
		Interceptor.attach(sub_B90, {
			onEnter: function(args){
				console.log("sub_B90 onEnter");
				sub_B90arge0 = args[0];
				console.log("参数1:");
				console.log(Memory.readCString(args[0]));
				console.log("参数2:");
				console.log(args[1].toInt32());
				console.log("参数3:");
				console.log(Memory.readCString(args[2]));
			},
			onLeave: function(){
				console.log("sub_B90 onLeave");
				console.log("运算结果");
				console.log(Memory.readByteArray(sub_B90arge0, 30));
			}
		});
		var sub_D90 = libnative.add(0xD90);
		console.log("sub_D90: " + sub_D90);
		Interceptor.attach(sub_D90, {
			onEnter: function(args){
				console.log("sub_D90 onEnter");
				console.log("参数1:");
				console.log(Memory.readByteArray(args[0], 30));
				console.log("参数2:");
				console.log(args[1].toInt32());
			},
			onLeave: function(retval){
				console.log("sub_D90 onLeave");
				console.log("运算结果");
				console.log(Memory.readCString(retval));
			}
		});
	})
}
main();


开启hook脚本后,随意输入30位字符,例如【111112222233333444445555566666】,可以得到下面内容
5.jpg
可以看到sub_B90对输入的内容进行了加密,而sub_D90实际是一个base64编码。接下来看看v27,v27没有比较好的函数可以hook,那么就需要考虑hook寄存器的值
回到一开始汇编指令的图,找到进行对比前面的汇编指令
6.jpg
这里还需要设置显示汇编指令的地址,教程链接:https://blog.csdn.net/weixin_45780275/article/details/109600482
此时可以看到汇编指令的地址是【B34】,同时我们需要的是x9寄存器的值
7.jpg
js代码
[JavaScript] 纯文本查看 复制代码
function main() {
	Java.perform(function (){
		var libnative = Module.findBaseAddress("libnative-lib.so");
		console.log("libnative: " + libnative);
		//获取flag加密后的内容
		var LDRB = libnative.add(0xB30);
		send("LDRB: " + LDRB);
		Interceptor.attach(LDRB, {
			onEnter: function(args){
				send("LDRB onEnter");
				console.log(Memory.readCString(this.context.x9));
			}
		});
	})
}
main();

继续输入30位字符进行hook,就可以得到进行对比的值【5Gh2/y6Poq2/WIeLJfmh6yesnK7ndnJeWREFjRx8】
8.jpg
也就是说,我们输入的字符串是正确的,那么经过sub_B90加密,然后base64编码,应该是要与前面的值完全一样,这时重点就来到了sub_B90函数
进入sub_B90函数,大致浏览一下,a1就是我们输入的字符串,然后a1赋值给了v4,而v4只有一个地方进行了异或变化
9.jpg
既然是异或,那么就好解决很多了,因为我们已经拿到了异或后的结果,如果能知道异或的内容是什么,就可以直接拿到异或前的内容了
那么就直接hook这条异或的汇编指令,可以看到汇编指令的地址是【D58】,需要的寄存器是x12
js代码
[JavaScript] 纯文本查看 复制代码
function main() {
	Java.perform(function (){
		var libnative = Module.findBaseAddress("libnative-lib.so");
		console.log("libnative: " + libnative);
		// 获取异或的字节,开了会报错,但是可以获取
		var ishook = true;
		var EOR = libnative.add(0xD58);
		var eor = [];
		var eorlen = 0;
		send("EOR: " + EOR);
		Interceptor.attach(EOR, {
			onEnter: function(args){
				if (ishook){
					if (eorlen < 30){
						eor.push(this.context.x12);
						eorlen += 1;
					}else{
						ishook = false;
						console.log(eor);
					}
				}
			}
		})
	})
}
main();

最后一次hook,但是这次hook会闪退,原因我也不知道,但是已经拿到了需要的内容
0xd1,0x5a,0x6,0x90,0x44,0xe6,0xc7,0xe5,0xde,0x28,0xf7,0xf2,0x66,0x91,0xc8,0x85,0x42,0xdf,0xf9,0xe0,0x82,0x1,0x2b,0x3b,0x38,0x63,0x37,0xbd,0x2e,0x4d
11.jpg

这时可以用python进行异或还原
[Python] 纯文本查看 复制代码
import base64
xordata = [0xd1,0x5a,0x6,0x90,0x44,0xe6,0xc7,0xe5,0xde,0x28,0xf7,0xf2,0x66,0x91,0xc8,0x85,0x42,0xdf,0xf9,0xe0,0x82,0x1,0x2b,0x3b,0x38,0x63,0x37,0xbd,0x2e,0x4d]
data = base64.b64decode('5Gh2/y6Poq2/WIeLJfmh6yesnK7ndnJeWREFjRx8'.encode())
flag = bytes([xordata[i] ^ data[i] for i in range(len(xordata))]).decode()
print(flag)

得到flag【52pojieHappyChineseNewYear2021】
输入apk里面尝试一下
1.png
结果正确
6.jpg
7.jpg

免费评分

参与人数 13威望 +2 吾爱币 +115 热心值 +13 收起 理由
天空宫阙 + 2 + 1 欢迎分析讨论交流,吾爱破解论坛有你更精彩!
tuier + 1 + 1 热心回复!
qtfreet00 + 2 + 100 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
17376777302 + 1 + 1 热心回复!
dada98 + 1 + 1 我很赞同!
zhukun1980 + 1 + 1 谢谢@Thanks!
blackzhangwei + 1 + 1 我很赞同!
佚名RJ + 1 + 1 我很赞同!
ogli324 + 1 + 1 谢谢@Thanks!
jason903 + 1 + 1 谢谢@Thanks!
浅笑心柔 + 1 + 1 我很赞同!
逍遥一仙 + 3 + 1 欢迎分析讨论交流,吾爱破解论坛有你更精彩!
asojdp + 1 + 1 我很赞同!

查看全部评分

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

goda 发表于 2021-3-7 11:51
感谢楼主又学到了,还能hook寄存器
        var libnative = Module.findBaseAddress("libnative-lib.so");
        var LDRB = libnative.add(0xB30);
        Interceptor.attach(LDRB, {
            onEnter: function(args){
                send("LDRB onEnter");
                console.log(Memory.readCString(this.context.x9));   //hook LDRB位置的x9寄存器
            }
        });
xyc520 发表于 2021-3-5 13:11
asojdp 发表于 2021-3-5 13:25
爱玩的蛋黄 发表于 2021-3-5 13:33
一脸懵进来,一脸懵出去。
单纯滴情 发表于 2021-3-5 14:27
试试看,虽然挺蒙蔽的
罩到胸前必有沟 发表于 2021-3-5 14:28
乍一看很难,其实对于我这种外行人来说,根本看不懂
DearRoach 发表于 2021-3-5 16:06
        谢谢@Thanks!
szslzx 发表于 2021-3-5 16:09

试试看,虽然挺蒙蔽的
mo211683 发表于 2021-3-5 16:51
这是那方大佬,这么牛皮。佩服佩服
blackzhangwei 发表于 2021-3-5 17:01
学习了!! 真的确实牛啊~~
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-11-28 08:23

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表