UC安卓逆向面试第二题——ARM逆向练手

原程分析链接:https://blog.csdn.net/qq1084283172/article/details/52133172 

样本下载地址:https://pan.baidu.com/s/10DuffiXUWCrCNoeH9pWw-Q      提取码: f4b9

为了更加熟练的掌握ARM逆向,找了几个程序来练手,这个就是其中一个。

 

1. 拿到apk就直接用 jdx 加载看吧,首先看 AndroidManifest.xml 

UC安卓逆向面试第二题——ARM逆向练手_第1张图片

很清楚可以看到,程序没有加壳处理

包名叫: com.ucweb.crackme140522 

入口Activity为: com.ucweb.crackme140522.MainActivity

 

2. 既然没有加壳,直接去 com.ucweb.crackme140522.MainActivity 看java代码吧

UC安卓逆向面试第二题——ARM逆向练手_第2张图片

这里的 java 代码比较简单,取了手机imei,用户输入的userName,注册码sn 就通过 JNI 调用 so 函数 clacSnFuntion

3. 既然如此,那么开始用 IDA 打开 UCcrackme2/lib/armeabi/libclacSn.so ,然后进行分析 Java_com_ucweb_crackme140522_MainActivity_clacSnFuntion 函数

UC安卓逆向面试第二题——ARM逆向练手_第3张图片

函数大概意思如下:

bool Java_com_ucweb_crackme140522_MainActivity_clacSnFuntion(
    JNIEnv *env, 
    jobject clazz, 
    jobject imei, 
    jobject userName, 
    jobject sn)
{
    bool check_result = false;
    if (imei == NULL || userName == NULL || sn == NULL)
    {
        return check_result;
    }
    char* szimei = (char*)jstringTostring(env, imei);
    char* szuserName = (char*)jstringTostring(env, userName);
    char* szsn = (char*)jstringTostring(env, sn);
    check_result = check_sn(szimei, szuserName, szsn);
    free(szimei);
    free(szuserName);
    free(szsn);
    return check_result;
}

4. 发现校验函数在 check_sn 函数里面,但是双击进去,嗯哼?这是什么鬼

UC安卓逆向面试第二题——ARM逆向练手_第4张图片

5. 这么多红红的,这个函数肯定是不对的。so 在加载的时候还会调用初始化函数。(Linux so加载流程: https://www.cnblogs.com/vendanner/p/4979177.html)

所以按 Shift+F7 打开程序段

UC安卓逆向面试第二题——ARM逆向练手_第5张图片

双击进入 .init_array 段

UC安卓逆向面试第二题——ARM逆向练手_第6张图片

发现 init 段 直接就 -1,没有其他函数,所以修改函数不是在 init 里面处理的 

6.  除了so加载的机制外,在Android中加载so,加载以后会主动调用 JNI_OnLoad 函数(Android加载so流程: https://shuwoom.com/?p=351)

UC安卓逆向面试第二题——ARM逆向练手_第7张图片

函数比较复杂,粗略的看了下,就是在 JNI_OnLoad 函数里面做的手脚

7. 这个可以慢慢跟踪看看,为了方便大家跟踪,我把整个 JNI_OnLoad 函数逆向回C语言表述,流程跟汇编流程是一样的(F5插件出来流程上下关系会乱一点)

直接贴代码吧,还原各位对着C代码都跟踪下 JNI_OnLoad。特别是解密字符串部分,跟踪完一定会有收获的,加油

// so中加密的函数数组存储 
unsigned char __data_start[0x414] = {
    0xA5, 0x1A, 0x78, 0xBC, 0x4D, 0xD1, 0xCA, 0xB0, 0x4D, 0x61, 0xCA, 0xB0, 0x2C, 0x8A, 0x18, 0xB7, 
    0x5D, 0xD5, 0xDA, 0xB5, 0x55, 0x65, 0xD8, 0xB0, 0x56, 0x65, 0xCD, 0xB2, 0x4D, 0x35, 0xD8, 0xB7, 
    0x55, 0x15, 0xF5, 0xB6, 0x55, 0xB5, 0xC6, 0xB0, 0x59, 0x65, 0xD3, 0xB7, 0x51, 0x15, 0xD6, 0xB1, 
    0x65, 0x05, 0xD8, 0xB7, 0x59, 0x95, 0xD0, 0xB7, 0x51, 0x15, 0xD6, 0xB1, 0x51, 0x15, 0xD9, 0xB1, 
    0x55, 0x15, 0xD6, 0xB0, 0xB5, 0x66, 0xCA, 0xB0, 0x51, 0x15, 0xD9, 0xB1, 0x55, 0x15, 0xD9, 0xB0, 
    0x8D, 0x96, 0xCA, 0xB0, 0x49, 0x65, 0xD8, 0xB0, 0x54, 0x61, 0xD6, 0xB7, 0x56, 0x63, 0x16, 0xB7, 
    0x61, 0x95, 0xD8, 0xB0, 0x74, 0x6B, 0x16, 0xB7, 0x91, 0x96, 0xCA, 0xB0, 0x75, 0x65, 0xD8, 0xB0, 
    0x94, 0x60, 0xD6, 0xB7, 0xA7, 0x69, 0xD6, 0xB7, 0x6D, 0x95, 0xD8, 0xB0, 0x71, 0x65, 0xD8, 0xB0, 
    0xBA, 0x92, 0xD9, 0xB7, 0xF9, 0x66, 0xCA, 0xB0, 0x96, 0x9E, 0xD9, 0xB7, 0x57, 0x99, 0xD9, 0xB7, 
    0x69, 0x95, 0xD8, 0xB0, 0x7D, 0x65, 0xD8, 0xB0, 0xC9, 0x96, 0xCA, 0xB0, 0xC9, 0x66, 0xCA, 0xB0, 
    0xC9, 0xE6, 0xCA, 0xB0, 0xC9, 0xC6, 0xCA, 0xB0, 0x01, 0x25, 0xD8, 0xB7, 0x51, 0x25, 0xD8, 0xB0, 
    0x5D, 0x55, 0xD8, 0xB0, 0x54, 0xF5, 0xF5, 0xB4, 0x59, 0x75, 0xD8, 0xB0, 0x51, 0x45, 0xF5, 0xB4, 
    0x54, 0x79, 0xF5, 0xB6, 0x52, 0x55, 0xF5, 0xB4, 0x52, 0x28, 0xD8, 0xB7, 0x89, 0xB4, 0xD8, 0xB0, 
    0x15, 0x95, 0xD8, 0xB0, 0x1D, 0x65, 0xD8, 0xB0, 0x65, 0xE5, 0xD8, 0xB0, 0x4D, 0xC5, 0xD8, 0xB0, 
    0x19, 0x15, 0xD8, 0xB0, 0x2A, 0xAE, 0xAA, 0xBE, 0x51, 0x65, 0xD2, 0xB7, 0x51, 0x15, 0xD6, 0xB1, 
    0x51, 0x15, 0xD6, 0xB1, 0x51, 0x15, 0xD6, 0xB1, 0x55, 0x15, 0xD6, 0xB0, 0x5D, 0x55, 0xC8, 0xB0, 
    0x95, 0x14, 0xD8, 0xB0, 0xD6, 0xAE, 0xAA, 0xBE, 0x41, 0x55, 0xD8, 0xB0, 0x5F, 0x55, 0xF5, 0xB4, 
    0xD5, 0xAE, 0xAA, 0xBE, 0x45, 0x55, 0xD8, 0xB0, 0x54, 0x55, 0x55, 0xBF, 0x51, 0xE5, 0xC0, 0xB2, 
    0x51, 0xC5, 0xC3, 0xB2, 0x5E, 0xC5, 0xDC, 0xB5, 0x51, 0xC5, 0xD0, 0xB2, 0x51, 0x15, 0xD1, 0xB7, 
    0x4D, 0x55, 0x01, 0xB6, 0xAD, 0xAA, 0xAA, 0x4F, 0x59, 0x66, 0xCA, 0xB0, 0x50, 0x55, 0xF5, 0xB4, 
    0x55, 0x45, 0xF5, 0xB6, 0x1D, 0x65, 0xD8, 0xB0, 0x01, 0xAE, 0xAA, 0xBE, 0x55, 0x15, 0x05, 0xB7, 
    0x55, 0x55, 0xB5, 0x56, 0x58, 0x55, 0x55, 0x5F, 0x1D, 0x45, 0xD8, 0xB7, 0x0E, 0xAE, 0xAA, 0xBE, 
    0x05, 0xC5, 0xD8, 0xB7, 0x55, 0xE5, 0xF5, 0xB4, 0x51, 0x55, 0xF5, 0xB4, 0x6A, 0xAE, 0xAA, 0xBE, 
    0x5C, 0x55, 0xF5, 0xB4, 0x6E, 0xAA, 0x7A, 0xB4, 0x59, 0x55, 0xC8, 0xB0, 0x30, 0xAE, 0xAA, 0xBE, 
    0x45, 0x55, 0x05, 0xB6, 0x05, 0x65, 0xC8, 0xB0, 0x5D, 0x55, 0x55, 0x5F, 0x55, 0x55, 0xF5, 0xB6, 
    0x55, 0x45, 0xC8, 0xB0, 0x89, 0x74, 0xC8, 0xB0, 0x54, 0x65, 0xCD, 0xB2, 0x55, 0x65, 0xC6, 0xB0, 
    0x56, 0x55, 0x07, 0xB4, 0xC8, 0x55, 0x55, 0x4F, 0x2C, 0x8A, 0xD8, 0xB7, 0xA5, 0xDA, 0xE8, 0xBD, 
    0xCD, 0x77, 0xCA, 0xB0, 0x41, 0x95, 0xC8, 0xB0, 0x45, 0x15, 0xC8, 0xB0, 0xC7, 0xB6, 0xD4, 0xB5, 
    0x54, 0x05, 0xD9, 0xB7, 0x74, 0x47, 0xF5, 0xB4, 0x50, 0x55, 0xF5, 0xB4, 0x59, 0x55, 0x01, 0xB4, 
    0x59, 0x15, 0xF5, 0xF4, 0x45, 0x45, 0xD8, 0xB0, 0x4B, 0xAE, 0xAA, 0xBE, 0x50, 0x75, 0xF5, 0xB4, 
    0x55, 0x45, 0xF5, 0xB6, 0x55, 0x35, 0xF5, 0xB4, 0x6B, 0xAE, 0xAA, 0xBE, 0x5C, 0x55, 0xF5, 0xB4, 
    0x6E, 0xAA, 0x7A, 0xB4, 0x05, 0x75, 0xC8, 0xB0, 0x01, 0x47, 0xCA, 0xB0, 0x55, 0x95, 0xC3, 0xB0, 
    0x97, 0x5A, 0xF5, 0xB4, 0xC4, 0xB7, 0x96, 0xB5, 0x45, 0x75, 0xC8, 0xB0, 0x96, 0x64, 0x35, 0xB5, 
    0x5D, 0x45, 0xC8, 0xB0, 0x57, 0x65, 0x76, 0xB5, 0x56, 0x65, 0x79, 0xB5, 0x53, 0x55, 0xF5, 0xB4, 
    0x55, 0x65, 0xD3, 0xB0, 0xA3, 0xAF, 0xAA, 0xBE, 0x55, 0x55, 0x01, 0xB6, 0x52, 0x55, 0x55, 0x8F, 
    0x55, 0x65, 0xF5, 0xB6, 0x56, 0x75, 0x83, 0xB2, 0x56, 0x45, 0x8F, 0xB2, 0x57, 0x75, 0x74, 0xB5, 
    0x56, 0x75, 0x93, 0xB2, 0x54, 0x65, 0xD6, 0xB7, 0x51, 0x55, 0x06, 0xB4, 0xAD, 0xAA, 0xAA, 0x4F, 
    0x5C, 0x55, 0xF5, 0xB4, 0x6E, 0xAA, 0x7A, 0xB4, 0x05, 0x65, 0xC8, 0xB0, 0xA5, 0x54, 0xCA, 0xB0, 
    0x3E, 0x1A, 0xD8, 0xB7, 0x96, 0x7A, 0xF5, 0xB4, 0xC5, 0x96, 0x94, 0xB5, 0x55, 0x55, 0xC3, 0xB0, 
    0x94, 0x74, 0x37, 0xB5, 0x45, 0x45, 0xC8, 0xB0, 0x55, 0x65, 0xF5, 0xB6, 0x51, 0x95, 0xD1, 0xB7, 
    0x51, 0x65, 0xD9, 0xB1, 0x51, 0x65, 0xD9, 0xB1, 0x54, 0xB5, 0x77, 0xB5, 0x5B, 0xB5, 0x75, 0xB5, 
    0x51, 0x65, 0xD9, 0xB1, 0x55, 0xB5, 0xD3, 0xB0, 0x55, 0x65, 0xD9, 0xB0, 0xE1, 0x94, 0xCA, 0xB0, 
    0x00, 0x0A, 0xD8, 0xB7, 0x41, 0x75, 0xC8, 0xB0, 0x01, 0x94, 0xD8, 0xB0, 0x77, 0x96, 0xD9, 0xB7, 
    0x77, 0x92, 0xD9, 0xB7, 0x77, 0x9E, 0xD9, 0xB7, 0xDD, 0x95, 0xD9, 0xB7, 0x0D, 0x94, 0xD8, 0xB0, 
    0xC1, 0x94, 0xCA, 0xB0, 0x50, 0x55, 0xF5, 0xB4, 0x53, 0x45, 0xF5, 0xB4, 0x09, 0x94, 0xD8, 0xB0, 
    0xDD, 0x94, 0xCA, 0xB0, 0x20, 0xFA, 0xD8, 0xB7, 0x31, 0x64, 0xD8, 0xB0, 0x35, 0x94, 0xD8, 0xB0, 
    0xF9, 0x64, 0xD8, 0xB0, 0x3D, 0x64, 0xD8, 0xB0, 0xE0, 0xA8, 0xAA, 0xBE, 0x5F, 0x55, 0xF5, 0xB4, 
    0x45, 0x45, 0xD0, 0xB7, 0x5D, 0x75, 0xF5, 0xB6, 0xB9, 0xA8, 0xAA, 0xBE, 0x31, 0x74, 0xC8, 0xB0, 
    0x09, 0x64, 0xCA, 0xB0, 0x50, 0x55, 0xF5, 0xB4, 0xF7, 0x74, 0xF5, 0xB4, 0x6A, 0x75, 0x57, 0xB7, 
    0x56, 0x65, 0xDA, 0xB5, 0x62, 0x55, 0x07, 0xB6, 0xAA, 0x6B, 0x16, 0xB7, 0x5D, 0x45, 0x16, 0xB7, 
    0x6D, 0x75, 0x37, 0xC7, 0x2D, 0x75, 0x37, 0xD7, 0xF0, 0xA8, 0xAA, 0xBE, 0x50, 0x55, 0xF5, 0xB4, 
    0x5F, 0x45, 0xF5, 0xB4, 0x5D, 0x75, 0xF5, 0xB6, 0xF4, 0xA8, 0xAA, 0xBE, 0x45, 0x75, 0xF5, 0xB6, 
    0x51, 0x55, 0xF5, 0xB4, 0x50, 0x45, 0xF5, 0xB4, 0x8D, 0xA8, 0xAA, 0xBE, 0x0D, 0x75, 0xD0, 0xB7, 
    0x55, 0x65, 0xF5, 0xB6, 0x54, 0x65, 0x90, 0xB1, 0x57, 0x55, 0x00, 0xB4, 0xA9, 0xAA, 0xAA, 0x4F, 
    0x45, 0x75, 0xF5, 0xB6, 0x55, 0x65, 0xF5, 0xB6, 0x56, 0x55, 0x81, 0xB2, 0x54, 0x45, 0xD7, 0xB7, 
    0x55, 0x75, 0x77, 0xB5, 0x56, 0x75, 0x92, 0xB2, 0x54, 0x65, 0xD6, 0xB7, 0x45, 0x55, 0x06, 0xB6, 
    0xAA, 0x75, 0x54, 0xB7, 0xA2, 0xAA, 0xAA, 0x4F, 0x55, 0x55, 0xF5, 0xB4, 0x81, 0xF5, 0xCA, 0xB0, 
    0x51, 0x05, 0xC8, 0xB0, 0x55, 0x15, 0xF5, 0xB6, 0x5F, 0xF5, 0xDA, 0xB5, 0x51, 0x75, 0x82, 0xB2, 
    0x45, 0x65, 0xD1, 0xB7, 0x50, 0x55, 0xF5, 0xB4, 0x54, 0x15, 0xD1, 0xB7, 0x56, 0x75, 0x77, 0xB5, 
    0x5F, 0x45, 0xF5, 0xB4, 0x81, 0xAF, 0xAA, 0xBE, 0x45, 0x55, 0x01, 0xB6, 0x57, 0x05, 0xD0, 0xB7, 
    0xA0, 0xAA, 0xAA, 0x4F, 0x5C, 0x55, 0xF5, 0xB4, 0x6E, 0xAA, 0x7A, 0xB4, 0x05, 0x45, 0xC8, 0xB0, 
    0x29, 0x55, 0xCA, 0xB0, 0x45, 0x95, 0xC8, 0xB0, 0x94, 0x6A, 0xF5, 0xB4, 0xC5, 0x24, 0x97, 0xB5, 
    0x53, 0x55, 0xF5, 0xB4, 0x97, 0x64, 0x36, 0xB5, 0x01, 0x75, 0xC8, 0xB0, 0x56, 0x65, 0x79, 0xB5, 
    0x56, 0x65, 0x77, 0xB5, 0x01, 0x65, 0xD8, 0xB0, 0x99, 0xAF, 0xAA, 0xBE, 0x51, 0x55, 0xC8, 0xB0, 
    0x59, 0x45, 0xC8, 0xB0, 0x51, 0x75, 0xF5, 0xB4, 0xF8, 0xAF, 0xAA, 0xBE, 0x55, 0x55, 0x05, 0xB6, 
    0x08, 0xAA, 0xAA, 0x4F
};

// 加密函数解密代码的函数代码数组 
unsigned char func_start[0x24] = {
    0x00, 0x00, 0x51, 0xE3, 0x1E, 0xFF, 0x2F, 0xD1, 0x01, 0x10, 0x80, 0xE0, 0x00, 0x30, 0xD0, 0xE5, 
    0x55, 0x30, 0x23, 0xE2, 0x01, 0x30, 0xC0, 0xE4, 0x01, 0x00, 0x50, 0xE1, 0xFA, 0xFF, 0xFF, 0x1A, 
    0x1E, 0xFF, 0x2F, 0xE1
};

// 替换后的函数,用于解码真实函数 
void sub20140522(char* buf, int len)
{
    if (len <= 0)
    {
        return;
    }
    char* end_point = buf+len;
    do 
    {
        *buf = *buf^0x55;
    } while (buf != end_point);
    
}

bool check_sn(char* imei, char* username, char* sn)
{
    // 这个函数懒得逆了,大概意思就是这样 
    // 由于有随机数在,算不出注册码 
    if (strlen(sn) != 16)
    {
        return false;
    }

    uint32 ntime = time()>>31;
    *((int*)imei) ^= ntime^time();
    int imei_len = strlen(imei);
    for (int i=0; i>31);
    char* str = md5(imei);
    
    char real_sn[34] = {0};
    for (int i=0; i<16; i++)
    {
        sprintf(real_sn+i*2, "%02X", str[i]);
    }
    *((int*)real_sn) = ntime^(time()>>31);
    if (strcmp(real_sn, sn) == 0)
    {
        return true;
    }
    return false;
}

jint JNICALL JNI_OnLoad(JavaVM* vm, void* reserved)
{
    jint ret_val = 0;
    char buf[0x20] = {0};
    int pid = getpid();
    if (pid < 0)
    {
        snprintf(buf, 0x20, "/proc/self/maps");
    }
    else
    {
        snprintf(buf, 0x20, "/proc/%d/maps", pid);
    }

    // 搜索libclacSn加载基址 
    int base_addr = 0;
    char lib_string[0x400] = {0};
    FILE* fp = fopen(buf, "r");
    if (fp != 0)
    {
        do 
        {
            if( !fgets(lib_string, 0x400, fp) )
            {
                base_addr = 0;
                break;
            }
            if(strstr(lib_string, "libclacSn.so") == NULL)
                continue;

            // 找到 libclacSn 模块 
            // f421e000-f4222000 r-xp 00000000 103:0d 294502    /data/app/com.ucweb.crackme140522-1/lib/arm/libclacSn.so
            // f4222000-f4224000 rw-p 00003000 103:0d 294502    /data/app/com.ucweb.crackme140522-1/lib/arm/libclacSn.so
            char* start_addr = strtok(lib_string, "-");  // 获取so的基址 
            base_addr = strtoul(start_addr, NULL, 16);
            if (base_addr == 0x8000)
            {
                base_addr = 0;
                break;
            }
        } while (1);
        fclose(fp);
    }

    // 设置libclacSn模块内存可读可写可执行  
    mprotect(base_addr, 0x3000, PROT_READ|PROT_WRITE|PROT_EXEC);
    // 直接拷贝机器码替换函数 
    /*
    .rodata:00003BA0 00 00 51 E3                 CMP     R1, #0
    .rodata:00003BA4 1E FF 2F D1                 BXLE    LR
    .rodata:00003BA8 01 10 80 E0                 ADD     R1, R0, R1
    .rodata:00003BAC
    .rodata:00003BAC             loc_3BAC  
    .rodata:00003BAC 00 30 D0 E5                 LDRB    R3, [R0]                      
    .rodata:00003BB0 55 30 23 E2                 EOR     R3, R3, #0x55
    .rodata:00003BB4 01 30 C0 E4                 STRB    R3, [R0],#1
    .rodata:00003BB8 01 00 50 E1                 CMP     R0, R1
    .rodata:00003BBC FA FF FF 1A                 BNE     loc_3BAC
    .rodata:00003BC0 1E FF 2F E1                 BX      LR
    */
    memcpy(sub20140522, func_start, 0x24); // 00003BA0 地址的函数复制过去了 

    // 解码字符串  /system/lib/libc.so 
    uint32 encrypt_str[5] = {0};
    uint32 decode_key[5] = {0};
    // 加密过的字符串 
    encrypt_str[1] = 0x103C2233;
    encrypt_str[2] = 0xF61283B;
    encrypt_str[3] = encrypt_str[2]+0x3BC0000+0x30C00+0x200;
    encrypt_str[4] = 0x5E2120;
    encrypt_str[0] = 0x40081311;
    // 解密秘钥 
    decode_key[0] = 0x3371601E;
    decode_key[1] = 0x1F314341;
    decode_key[2] = decode_key[1]+0x1000000-0x300000-0x210;
    decode_key[3] = decode_key[2]+0x30400000+0xF200;
    decode_key[4] = 0x11520E;
    // 解密 
    for (int i=0; i<5; i++)
    {
        encrypt_str[i] = encrypt_str[i]+decode_key[i];
    }

    do 
    {
        // 反调试 
        void* libc = dlopen((char*)encrypt_str, 0);
        if (libc == 0)
        {
            ret_val = -1;
            break;
        }

        long (*f_ptrace)(int, int, int, int);
        // 设置函数名 ptrace
        uint32 func_name[8] = {0};
        func_name[0] = 0x61727470;  // 'artp' 
        func_name[1] = 0x6563;   // 'ec' 
        f_ptrace = dlsym(libc, (char*)func_name);
        dlclose(libc);

        f_ptrace(PTRACE_TRACEME, 0, 0, 0);

        // 这里从全局变量取两个uint32数据,然后在check_sn函数中进行搜索 
        // 00 00 A0 E1      nop
        // 01 00 A0 E3      mov R0, #1
        // 最终搜索到文件偏移为 0x000025CC 的地方 
        char* find_func = (char*)&check_sn;
        char* find_addr = 0;
        do 
        {
            find_addr = memcmp(find_func, "\x00\x00\xA0\xE1\x01\x00\xA0\xE3", 8);
            find_func += 2;
        } while (find_addr == 0);
        sub20140522(__data_start, find_addr-(char*)&check_sn); // 把data段的真实函数机器码解码出来
        memcpy(check_sn, __data_start, find_addr-(char*)&check_sn);  // 解码出来的函数 复制到check_sn函数中,大小为函数头到搜索到的 "\x00\x00\xA0\xE1\x01\x00\xA0\xE3" 为止 
        ret_val = JNI_VERSION_1_4;
    } while (0);

    return ret_val;
}

bool Java_com_ucweb_crackme140522_MainActivity_clacSnFuntion(
    JNIEnv *env, 
    jobject clazz, 
    jobject imei, 
    jobject userName, 
    jobject sn)
{
    bool check_result = false;
    if (imei == NULL || userName == NULL || sn == NULL)
    {
        return check_result;
    }
    char* szimei = (char*)jstringTostring(env, imei);
    char* szuserName = (char*)jstringTostring(env, userName);
    char* szsn = (char*)jstringTostring(env, sn);
    check_result = check_sn(szimei, szuserName, szsn);
    free(szimei);
    free(szuserName);
    free(szsn);
    return check_result;
}

 

根据 解密逆向出来的算法,可以静态解密 check_sn 函数

IDA 中按 shift + F2 ,执行如下脚本即可 ,然后进入原来的 check_sn 函数位置,函数能够正常看到了

auto start_addr = 0x4F44;
auto patch_addr = 0x21B4;
auto lenth = 0x414;
auto i=0;
for(i=0;i

F5 效果如下:

UC安卓逆向面试第二题——ARM逆向练手_第8张图片

 

 

关于动态调试: 

1. 命令行调试启动安卓程序

adb shell am start -D -n com.ucweb.crackme140522/com.ucweb.crackme140522.MainActivity 

2. 将 android_server  push 到手机,然后用root 运行之

D:\>adb push D:\Crack_Tools\Static_Analysis\IDA_Pro_v7.0_Portable\dbgsrv\android_server /data/local/tmp/
D:\Crack_Tools\Static_Analysis\IDA_Pro...hed. 1.3 MB/s (589588 bytes in 0.446s)

D:\>adb shell su
root@bullhead:/ # cd /data/local/tmp
cd /data/local/tmp
root@bullhead:/data/local/tmp # chmod 755 android_server
chmod 755 android_server
root@bullhead:/data/local/tmp # ./android_server
./android_server
IDA Android 32-bit remote debug server(ST) v1.22. Hex-Rays (c) 2004-2017
Listening on 0.0.0.0:23946...

3. 设置adb端口转发  adb forward tcp:23946 tcp:23946

adb forward tcp:23946 tcp:23946

4. 打开IDA进行挂接 Debugger --> attach --> Remote ARMLinux/Android debugger 默认就好,直接点ok

UC安卓逆向面试第二题——ARM逆向练手_第9张图片

5. 进程列表中选择 com.ucweb.crackme140522

UC安卓逆向面试第二题——ARM逆向练手_第10张图片

6. 挂接上以后,程序会停住,这时候设置下IDA : Debugger --> Debugger options 勾上以下一个位置,然后点确定,F9把程序运行起来

UC安卓逆向面试第二题——ARM逆向练手_第11张图片

7. 用 ApkTool 工具反编译 UCcrackme2, 然后用 Android Studio 加载 UCcrackme2,加载完以后用 AS 附加 com.ucweb.crackme140522 进程 (AS调试方法 请看 https://blog.csdn.net/jha334201553/article/details/104494732 )

 

8. IDA会中断于 linker.so 某个位置,不用管,直接按 Ctrl + S 找 libclacSn.so 是否加载起来,加载起来就 在静态分析的地址 + 当前加载的地址进行设置断点。如果没找到则按F9继续执行,等待下一次断点通知 

UC安卓逆向面试第二题——ARM逆向练手_第12张图片

ps: 这里有可能 linker.so 断不来下,可能原因是用 IDA64 挂载了 Android 32 位程序,具体查看Android程序是32位还是64位,使用:

root@bullhead:/ # ps | grep com.ucweb.crackme140522
u0_a84    8767  513   920360 36248 ptrace_sto 00f7283cb8 t com.ucweb.crackme140522
root@bullhead:/ # cat /proc/8767/maps|grep /system/lib

cat /proc/8767/maps|grep /system/lib
e916e000-e9172000 r-xp 00000000 103:09 1412                              /system/lib/libwebviewchromium_loader.so
e9172000-e9173000 r--p 00003000 103:09 1412                              /system/lib/libwebviewchromium_loader.so
e9173000-e9174000 rw-p 00004000 103:09 1412                              /system/lib/libwebviewchromium_loader.so
e9212000-e9215000 r-xp 00000000 103:09 1289                              /system/lib/libjnigraphics.so
e9215000-e9216000 r--p 00002000 103:09 1289                              /system/lib/libjnigraphics.so
e9216000-e9217000 rw-p 00003000 103:09 1289                              /system/lib/libjnigraphics.so
e9217000-e921f000 r-xp 00000000 103:09 1253                              /system/lib/libcompiler_rt.so
e921f000-e9220000 r--p 00007000 103:09 1253                              /system/lib/libcompiler_rt.so
e9220000-e9221000 rw-p 00008000 103:09 1253                              /system/lib/libcompiler_rt.so
e9221000-e922f000 r-xp 00000000 103:09 1218                              /system/lib/libandroid.so
e922f000-e9231000 r--p 0000d000 103:09 1218                              /system/lib/libandroid.so
.....

上面会显示很多加载的 /system/lib/xx.so 说明是32位程序,如果加载的是 /system/lib64/xxx.so 说明是 64 位程序

 

9. 设置好断点,F9继续运行,到达断点处就可以慢慢调试啦 

 

你可能感兴趣的:(安卓,arm,逆向,汇编,新手练习)