2021 巅峰极客 RE medical_app(结合IDA动调so文件)

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}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值