glass
题目名称:glass
题目描述:Reverse sign in,flag形式为"CISCN{XXXXX}"
首先查看apk
界面如下
用AndroidKiller打开,反编译成java源码
这里只是声明了一下checkflag函数 要去native-lib里找
分析\glass\Project\lib\armeabi-v7a中的libnative-lib.so
IDA打开
怀疑是RC4加密 参考 https://www.cnblogs.com/SunsetR/p/12247041.html
bool __fastcall Java_com_ciscn_glass_MainActivity_checkFlag(int a1, int a2, int a3)
{
const char *v3; // r4
size_t v4; // r5
int v6; // [sp+0h] [bp-220h]
char v7; // [sp+100h] [bp-120h]
v3 = (const char *)sub_F0C(a1, a3);
if ( strlen(v3) != 39 ) //flag长度为39
return 0;
_aeabi_memclr8(&v7, 256);
_aeabi_memcpy8(&v6, "12345678", 256); //定义v6 v7 给v6赋值12345678
v4 = strlen((const char *)&v6); //v4为v6的长度 8
sub_FFC(&v7, &v6, v4); //RC4填充S盒,s盒乱序
sub_1088(&v7, v3, 39); //RC4计算密钥流,异或加密
sub_10D4(v3, 39, &v6, v4); //自己搞得加密
return memcmp(v3, &unk_497C, 0x27u) == 0;
}
unk_497C
0xa3, 0x1a, 0xe3, 0x69, 0x2f, 0xbb, 0x1a, 0x84, 0x65, 0xc2, 0xad, 0xad, 0x9e, 0x96, 0x5, 0x2, 0x1f, 0x8e, 0x36, 0x4f, 0xe1, 0xeb, 0xaf, 0xf0, 0xea, 0xc4, 0xa8, 0x2d, 0x42, 0xc7, 0x6e, 0x3f, 0xb0, 0xd3, 0xcc, 0x78, 0xf9, 0x98, 0x3f
sub_10D4(v3, 39, &v6, v4);
int __fastcall sub_10D4(int result, int a2, int a3, int a4)
{
int i; // r4
int v5; // r6
char v6; // r5
char v7; // lr
char v8; // r12
int j; // lr
int k; // r6
for ( i = 0; i < a2; i += 3 )
{
v5 = result + i;
v6 = *(_BYTE *)(result + i + 2);
v7 = *(_BYTE *)(result + i + 1);
v8 = *(_BYTE *)(result + i) ^ v6;
*(_BYTE *)(result + i) = v8;
*(_BYTE *)(v5 + 2) = v6 ^ v7;
*(_BYTE *)(v5 + 1) = v7 ^ v8; //交换异或
}
for ( j = 0; j < a2; j += a4 )
{
for ( k = 0; (a4 & ~(a4 >> 31)) != k && j + k < a2; ++k )
*(_BYTE *)(result + k) ^= *(_BYTE *)(a3 + k); //分别异或12345678
result += a4;
}
return result;
}
解题代码如下
#include <stdio.h>
#include <windows.h>
unsigned char *base64_encode(unsigned char *str)
{
long len;
long str_len;
unsigned char *res;
int i,j;
//定义base64编码表
unsigned char *base64_table="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
//计算经过base64编码后的字符串长度
str_len=strlen(str);
if(str_len % 3 == 0)
len=str_len/3*4;
else
len=(str_len/3+1)*4;
res=malloc(sizeof(unsigned char)*len+1);
res[len]='\0';
//以3个8位字符为一组进行编码
for(i=0,j=0;i<len-2;j+=3,i+=4) {
="" res[i]="base64_table[str[j]">>2]; //取出第一个字符的前6位并找出对应的结果字符
res[i+1]=base64_table[(str[j]&0x3)<<4 | (str[j+1]>>4)]; //将第一个字符的后位与第二个字符的前4位进行组合并找到对应的结果字符
res[i+2]=base64_table[(str[j+1]&0xf)<<2 | (str[j+2]>>6<