最近在尝试分析很多手游用的CrackProof壳,记录一下过程:

众所周知,这个壳的一大特色就是所有解密和检测在.init_array段完成,并且只有里面指向的第一个函数是真正的,从第二个开始就会往0x0瞎写东西。

因为这个壳没有用任何libc的东西,并且所有调用都是通过syscall进行的,所以我们几乎看不到可以瞎猜的函数名,于是一路从第一个函数调用点到底,可以看到一个解密字符串的函数,他大概长这样:

int8_t* decrypt_string(int8_t *result, unsigned __int64 len)
{
    unsigned __int8 v2; // [xsp+17h] [xbp-19h]
    unsigned __int64 i; // [xsp+28h] [xbp-8h]

    for ( i = 0LL; i < len; ++i )
    {
        v2 = result[i];
        if ( !v2 )
            break;
        result[i] = ~(((int)v2 >> 3) | (32 * v2)) - (i & 3);
    }
    return result;
}

下面的函数也能猜出来是读取文件的了

读完maps后一行一行处理,找到自己所在的可执行段对应的文件名

接下来打开自己对应的so并parse,找到SHT中type为SHT_LOUSER的一段,读他的偏移+0x23B的数据0x20字节

然后送去解密,解密出来的是一段数据头

__int64 __fastcall decrypt_code_internal(
        uint32_t init,
        char *data,
        unsigned __int64 blocks,
        unsigned __int64 start_off)
{
  int i; // [xsp+3Ch] [xbp-4h]

  for ( i = start_off >> 2; i < (int)(blocks >> 2); ++i )
  {
    *(_DWORD *)&data[4 * i] += (i + 3) * init;
    *(_DWORD *)&data[4 * i] ^= 0xBF20165D * (i + 1);
  }
  return 1LL;
}

根据数据头的定义继续往下读取一段被加密的代码,解密后设置可执行

然后跳转过去执行


2 条评论

DE · 2021年9月24日 上午10:11

期待大佬的后续分析~

ZDemon · 2021年10月15日 下午4:35

大佬啥时候更新研究~~

回复 ZDemon 取消回复

Avatar placeholder

您的电子邮箱地址不会被公开。