文章目录
glass.apk
直接分析jni的函数:
这里的话,三个有用函数,第一个sub_FFC((int)&v7, (int)&v6, v4);
是RC4算法初始化函数,第二个sub_1088((int)&v7, v3, 39);
RC4算法加密函数,第三个sub_10D4((int)v3, 39, (int)&v6, v4);
进行一番异或操作,也就是说,只需要分析第三个函数即可。前面的两个函数直接用工具
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);
result += a4;
}
baby.bc
.bc转换为可执行程序
第一次拿到.bc的文件
查了一下,LLVM IR bitcode
,二进制文件。想办法转换成.s,然后再转成可执行文件。(windows里面无法转成elf,最后编译成elf时,需要在linux
里面进行
由此看出input长度为25;数组元素大小可取 0 ~ 5
fill_number(__int64)input)
v1 = (char *)(a1 + 4);
v2 = 0LL;
do
{
v3 = *(v1 - 4);
if ( map[5 * v2] )
{
if ( v3 != 48 )
return 0;
}
else
{
map[5 * v2] = v3 - 48;
}
v4 = *(v1 - 3);
if ( byte_601051[5 * v2] )
{
if ( v4 != 48 )
return 0;
}
else
{
byte_601051[5 * v2] = v4 - 48;
}
v5 = *(v1 - 2);
if ( byte_601052[5 * v2] )
{
if ( v5 != 48 )
return 0;
}
else
{
byte_601052[5 * v2] = v5 - 48;
}
v6 = *(v1 - 1);
if ( byte_601053[5 * v2] )
{
if ( v6 != 48 )
return 0;
}
else
{
byte_601053[5 * v2] = v6 - 48;
}
v7 = *v1;
if ( byte_601054[5 * v2] )
{
if ( v7 != 48 )
return 0;
}
else
{
byte_601054[5 * v2] = v7 - 48;
}
++v2;
v1 += 5;
}
while ( v2 < 5 );
return 1;
}
unsigned char map[] =
{
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 4, 0, 0, 0, 0, 0, 3, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 1, 1, 0, 0, 0,
2, 0, 0, 1, 0, 0, 0, 0, 1, 0,
1, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0
};
这个函数的作用也正如函数名所述,用来填充map数组中的0
if ( map[5 * v2] )
{
if ( v3 != '0' )
return 0;
}
else
{
map[5 * v2] = v3 - 48;
}
map的起始地址是0x601050
, 这个也就是如果map元素为0,那么就是用v3来做相应填充,而这里的v3也就是我们所做的input。else中减掉48,是想把字符元素转换为数字元素,然后赋值于map数组
if ( v3 != '0' )
return 0;
这里按照逻辑我觉得是当map中的元素不为0时,那么就来判断input相应输入位置,input这个输入位置必须为字符0,否则退出
docheck(input, input):z3约束
v25 = 0;
v24 = 0;
v1 = (unsigned __int8)map[5 * v0];
if ( *((_BYTE *)&v24 + v1) )
break;
*((_BYTE *)&v24 + v1) = 1;
v2 = (unsigned __int8)byte_601051[5 * v0];
if ( *((_BYTE *)&v24 + v2) )
break;
*((_BYTE *)&v24 + v2) = 1;
v3 = (unsigned __int8)byte_601052[5 * v0];
if ( *((_BYTE *)&v24 + v3) )
break;
*((_BYTE *)&v24 + v3) = 1;
v4 = (unsigned __int8)byte_601053[5 * v0];
if ( *((_BYTE *)&v24 + v4) )
break;
*((_BYTE *)&v24 + v4) = 1;
if ( *((_BYTE *)&v24 + (unsigned __int8)byte_601054[5 * v0]) )
break;
这里刚开始我也没看出有什么用,一调试才知道。这里的作用也就是把它所以的元素连续的五个分成五个一组,然后判断这组值中不能出现两两重复。
v23 = 0;
v22 = 0;
v6 = (unsigned __int8)map[v5];
if ( *((_BYTE *)&v22 + v6) )
break;
*((_BYTE *)&v22 + v6) = 1;
v7 = (unsigned __int8)byte_601055[v5];
if ( *((_BYTE *)&v22 + v7) )
break;
*((_BYTE *)&v22 + v7) = 1;
v8 = (unsigned __int8)byte_60105A[v5];
if ( *((_BYTE *)&v22 + v8) )
break;
*((_BYTE *)&v22 + v8) = 1;
v9 = (unsigned __int8)byte_60105F[v5];
if ( *((_BYTE *)&v22 + v9) )
break;
*((_BYTE *)&v22 + v9) = 1;
if ( *((_BYTE *)&v22 + (unsigned __int8)byte_601064[v5]) )
break;
这里的话,也就是把连续的五个元素分成一组,总共有五组,每组有五个元素,然后每组同时选出一个相同下标的元素,判断五个组所选出的五个元素不能两两重复。
unsigned char row[] =
{
0, 0, 0, 1, 1, 0, 0, 0, 2, 0,
0, 1, 0, 0, 0, 0, 1, 0, 1, 0,
0, 0, 0, 0, 0
};
v11 = row[4 * v10];
if ( v11 == 2 )
{
if ( (unsigned __int8)map[5 * v10] > (unsigned __int8)byte_601051[5 * v10] )
return 0;
}
else if ( v11 == 1 && (unsigned __int8)map[5 * v10] < (unsigned __int8)byte_601051[5 * v10] )
{
return 0;
}
v12 = byte_601071[4 * v10];
if ( v12 == 1 )
{
if ( (unsigned __int8)byte_601051[5 * v10] < (unsigned __int8)byte_601052[5 * v10] )
return 0;
}
else if ( v12 == 2 && (unsigned __int8)byte_601051[5 * v10] > (unsigned __int8)byte_601052[5 * v10] )
{
return 0;
}
v13 = byte_601072[4 * v10];
if ( v13 == 2 )
{
if ( (unsigned __int8)byte_601052[5 * v10] > (unsigned __int8)byte_601053[5 * v10] )
return 0;
}
else if ( v13 == 1 && (unsigned __int8)byte_601052[5 * v10] < (unsigned __int8)byte_601053[5 * v10] )
{
return 0;
}
v14 = byte_601073[4 * v10];
if ( v14 == 2 )
{
if ( (unsigned __int8)byte_601053[5 * v10] > (unsigned __int8)byte_601054[5 * v10] )
return 0;
}
else if ( v14 == 1 && (unsigned __int8)byte_601053[5 * v10] < (unsigned __int8)byte_601054[5 * v10] )
{
return 0;
}
这里的话,把map数组照样分成五组,连续的五个元素为一组,然后把row作为4个元素为一组(5个元素,相邻两个相比较,只需要比较四次),因为input长度为25,所以map也就是25,map分小组可以分为5组,那么row也就可以分为5组:
- row第1组的第四个元素为1;
else if ( v14 == 1 && (unsigned __int8)byte_601053[5 * v10] < (unsigned __int8)byte_601054[5 * v10] )
{
return 0;
}
这是第一组,也就代表了map[3]>map[4];
- row第2组的第一个元素为1;
else if ( v11 == 1 && (unsigned __int8)map[5 * v10] < (unsigned __int8)byte_601051[5 * v10] )
{
return 0;
}
这是第二组,也就代表了map[5]>map[6];
- row第3组的第一个元素为2;第四个元素为1
if ( v11 == 2 )
{
if ( (unsigned __int8)map[5 * v10] > (unsigned __int8)byte_601051[5 * v10] )
return 0;
}
else if ( v14 == 1 && (unsigned __int8)byte_601053[5 * v10] < (unsigned __int8)byte_601054[5 * v10] )
{
return 0;
}
这是第三组,也就代表了map[10]<map[11];map[13]>map[14]
- row第5组的第一个元素为1;第三个元素为1
else if ( v11 == 1 && (unsigned __int8)map[5 * v10] < (unsigned __int8)byte_601051[5 * v10] )
{
return 0;
}
else if ( v13 == 1 && (unsigned __int8)byte_601052[5 * v10] < (unsigned __int8)byte_601053[5 * v10] )
{
return 0;
}
这是第五组,也就代表了map[20]>map[21];map[22]>map[23]
row[]约束总结为:
map[3]>map[4];
map[5]>map[6];
map[10]<map[11];map[13]>map[14];
map[20]>map[21];map[22]>map[23]
unsigned char col[] =
{
0, 0, 2, 0, 2, 0, 0, 0, 0, 0,
0, 0, 0, 1, 0, 0, 1, 0, 0, 1
};
v17 = col[5 * v15];
if ( v17 == 2 )
{
if ( (unsigned __int8)map[5 * v15] < (unsigned __int8)byte_601055[5 * v15] )
return 0;
}
else if ( v17 == 1 && (unsigned __int8)map[5 * v15] > (unsigned __int8)byte_601055[5 * v15] )
{
return 0;
}
v18 = byte_601091[5 * v15];
if ( v18 == 1 )
{
if ( (unsigned __int8)byte_601051[5 * v15] > (unsigned __int8)byte_601056[5 * v15] )
return 0;
}
else if ( v18 == 2 && (unsigned __int8)byte_601051[5 * v15] < (unsigned __int8)byte_601056[5 * v15] )
{
return 0;
}
v19 = byte_601092[5 * v15];
if ( v19 == 2 )
{
if ( (unsigned __int8)byte_601052[5 * v15] < (unsigned __int8)byte_601057[5 * v15] )
return 0;
}
else if ( v19 == 1 && (unsigned __int8)byte_601052[5 * v15] > (unsigned __int8)byte_601057[5 * v15] )
{
return 0;
}
v20 = byte_601093[5 * v15];
if ( v20 == 2 )
{
if ( (unsigned __int8)byte_601053[5 * v15] < (unsigned __int8)byte_601058[5 * v15] )
return 0;
}
else if ( v20 == 1 && (unsigned __int8)byte_601053[5 * v15] > (unsigned __int8)byte_601058[5 * v15] )
{
return 0;
}
v21 = byte_601094[5 * v15];
if ( v21 == 2 )
{
if ( (unsigned __int8)byte_601054[5 * v15] < (unsigned __int8)byte_601059[5 * v15] )
return 0;
}
else if ( v21 == 1 && (unsigned __int8)byte_601054[5 * v15] > (unsigned __int8)byte_601059[5 * v15] )
{
return 0;
}
这里的话,把map数组照样分成五组,连续的五个元素为一组,然后把col作为5个元素为一组(5个元素,分别和对应组相比较,需要比5次),因为input长度为25,所以map也就是25,map分小组可以分为5组,五组之间,对应元素比较,只需要比4次,那么col也就可以分为4组,每组5个元素:
- col第一组的第三个元素为2;第五个元素为2
if ( v19 == 2 )
{
if ( (unsigned __int8)byte_601052[5 * v15] < (unsigned __int8)byte_601057[5 * v15] )
return 0;
}
if ( v21 == 2 )
{
if ( (unsigned __int8)byte_601054[5 * v15] < (unsigned __int8)byte_601059[5 * v15] )
return 0;
}
这是第一组,也就代表了map[2]>map[7];map[4]>map[9]
- col第三组的第四个元素为1;
i else if ( v20 == 1 && (unsigned __int8)byte_601053[5 * v15] > (unsigned __int8)byte_601058[5 * v15] )
{
return 0;
}
这是第三组,也就代表了map[13]<map[18];
- col第4组的第二个元素为1;第五个元素为1
if ( v18 == 1 )
{
if ( (unsigned __int8)byte_601051[5 * v15] > (unsigned __int8)byte_601056[5 * v15] )
return 0;
}
else if ( v21 == 1 && (unsigned __int8)byte_601054[5 * v15] > (unsigned __int8)byte_601059[5 * v15] )
{
return 0;
}
这是第三组,也就代表了map[16]<map[21];map[19]<map[24]
col[]约束总结为:
map[2]>map[7];map[4]>map[9]
map[13]<map[18];
map[16]<map[21];map[19]<map[24]