CTF

京津冀挑战赛 2016 possible writeup

Posted by Jieming Gu on 2016-12-10

本文为2016年京津冀挑战赛中possible的writeup。

Writeup

首先点我下载题目。直接使用jeb反编译,关键代码如下:

1

2

3

4

在SO层通过反射得到numindexArray两个数组,当符合一定条件时将answerNum设置成解密密钥,继而进行三重AES解密。符合SO层条件的answerNum会有多个,但是只有一个answerNum能解密密文,其他answerNum解密密文时会报错。

ARM子函数调用:当参数小于4个时,ARM首先会用R0-R3四个寄存器来传递参数;当参数个数大于4个时,使用栈来传递参数。函数返回值默认通过R0寄存器传递,但是不一定!具体根据ARM指令分析。

伪代码显示不全,没有将返回值赋给变量,这时要看ARM指令,分析过程如下。

5

6

最后可知R1寄存器存放idivmod的返回值。根据ARM指令可还原相关代码:

answerNum = 0;
int i = 0;
int v20 = 0;
int v15, v16, v17, result;
while (i < array.length) {
 v15 = array[i];
 i++;
 v16 = num[v15];
 v17 = v16 % 1011;
 v20 = (v20 + v17) % 1011;
 answerNum ^= v16;
}
 result = v20 % 1011;

注意:checkj_j___aeabi_idivmod伪代码显示错误,j_j___aeabi_idivmod表示取余。

7

AES解密是在Android环境下进行,故在Android下进行算法还原。经测试,Java下解密会报错。

解密程序点我下载。

答案:38508