medical_app
因为比赛的时候队友已经做了这一题,所以赛后才看这道。(呜呜呜。。比赛一道逆向没做起,我太菜了 )
从这道题我主要是学习了一下如何用模拟器结合IDA动调apk中的so文件。
先说一下如何配置
我用的是夜神模拟器7.0.1.3版本
- 注意:
模拟器要打开USB调试
具体方法如下:打开设置->点击版本号5次进入开发者模式->从开发者选项中找到USB调试勾选上即可
我们首先在模拟器的安装目录下打开cmd,输入下面几行命令
adb connect 127.0.0.1:62001//62001是夜神模拟器的端口,不同模拟器的端口不同,大家可以自行百度)
adb push d:\IDA\dbgsrv\android_x86_server(IDA安装路径) /data/local/tmp/android_x86_server
adb shell
su
cd /data/local/tmp
chmod 777 android_x86_server
./android_x86_server
再开一个cmd
adb forward tcp:23946 tcp:23946
正确操作应如下图所示
这里简单说一下,IDA的dbgsrv目录下有很多版本,其中android_x64_server和android_x86_server是针对于模拟器的,android_server和android_server64是针对于真机的,混着用可能会报错。
然后打开IDA Debugger->Select debugger->Remote linux debugger
这里Hostname:127.0.0.1 Port:23946
设置成功后再模拟器中运行要进行调试的程序,然后进入IDA选择要调试的进程
然后下断点,就可以正常调试了。
下面我们来说一下这道题
这道题是rc4+修改delta的xxtea加密,但是要通过动态调试so文件来获取这两种加密的秘钥key。
比较坑的是在动调的时候,该题目程序在模拟器分辨率设置为宽:1600 长:900 DPI:240才能运行
(静态也可以找到秘钥,主要是通过这道题练一下so文件动调)
选中部分即为秘钥,在xxtea中变为unsigned int类型(注意大小端格式储存)
rc4:0x01, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00
xxtea:0x00000001,0x00000010,0x00000100,0x00001000
其他就是根据IDA修改一下rc4和xxtea的解密模板即可
xxtea部分:
#include<stdio.h>
#include<stdint.h>
#define DELTA 0x9F5776B6
#define MX (((z>>5^y<<2) + (y>>3^z<<4)) ^ ((sum^y) + (key[(p&3)^e] ^ z)))
using namespace std;
unsigned int v38[9] ={1759876926, 3255595879, 2561659931, 4266368482, 27637259, 1027003974, 3687611311, 2688634624, 1982654234};
unsigned int key[4]={0x00000001,0x00000010,0x00000100,0x00001000};
void xxtea(uint32_t *v, int n, uint32_t const key[4])
{
uint32_t y, z, sum;
unsigned p, rounds, e;
if (n < -1) /* Decoding Part */
{
n = -n;
rounds = 6 + 52/n;
sum = rounds*DELTA;
y = v[0];
do
{
e = (sum >> 2) & 3;
for (p=n-1; p>0; p--)
{
z = v[p-1];
y = v[p] -= MX;
}
z = v[n-1];
y = v[0] -= MX;
sum -= DELTA;
}
while (--rounds);
}
}
int main()
{
xxtea(v38, -9, key);
for(int i=0;i<9;i++)
{
//printf("0x%x",v38[i]);
printf("0x%x,0x%x,0x%x,0x%x,",*((char *)&v38[i]+0)&0xff,*((char *)&v38[i]+1)&0xff,*((char *)&v38[i]+2)&0xff,*((char *)&v38[i]+3)&0xff);
}
return 0;
}
rc4部分:
#include<bits/stdc++.h>
using namespace std;
char flag[36]={0x56,0x4,0xb0,0xd4,0x9c,0x63,0x4d,0x30,0x96,0xce,0xc0,0x5,0x93,0xbe,0x3b,0x82,0x52,0x4b,0x16,0xb2,0x8a,0x33,0xb7,0x4d,0x6d,0x7b,0x99,0x50,0xc2,0xb1,0xc,0x12,0xe1,0x84,0xa,0x93};
int key[16]=
{
0x01, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x01,
0x00, 0x00, 0x00, 0x10, 0x00, 0x00
};
int KeyStream[36],num;
int S[256];
char T[256];
int main()
{
int i=0,j=0;
for(i=0;i<256;i++)
{
S[i]=i;
T[i]=key[i&0xF];
}
for(i=0;i<256;i++)
{
j=(j+S[i]+T[i])%256;
swap(S[i],S[j]);
}
i=0,j=0;
for(int k=0;k<36;k++)
{
i=i+1;
j=(j+S[i])%256;
swap(S[i],S[j]);
KeyStream[num++]=S[(S[i]+S[j])%256];
}
for(int k=0;k<36;k++)
{
flag[k]^=KeyStream[k];
cout<<flag[k];
}
return 0;
}
//flag{194836950ae9df840e8a94348b901a}