蓝天资源网
当前位置:蓝天资源网 / 汇编逆向 / 正文

某壁纸软件的防护 简单分析

作者:忆笙发布时间:2021-10-10 01:13浏览数量:469次评论数量:0次

应用包名:me.alzz.awsl,版本2.5.3,lsp应该知道这个是什么软件。以前分析过,现在加强了检测。破解成品在mt论坛非常多,开通vip怎么破我就不分析了。不过这软件很便宜,喜欢他的还是支持正版吧。

准备工具

1、ida64

2、as

软件是腾讯加固,网上找个自动脱壳机就能脱掉。通过分析so的防护逻辑,可以获得相应的逆向方法。

脱壳后重签名,发现闪退,查看logcat问题出在libpng.so这里面。现在用ida打开这个文件,然后字符串搜索signatures,定位到sub_D340,先重命名为GetSign。然后查找调用,来到Java_me_alzz_png_N_00024Companion_z。代码如下:

void __fastcall Java_me_alzz_png_N_00024Companion_z(JNIEnv *env, __int64 a2, __int64 a3, __int64 a4, __int64 a5)
{
  newthread[1] = *(_ReadStatusReg(ARM64_SYSREG(3, 3, 13, 0, 2)) + 40);
  v9 = GetSign(env, a3);         //获取签名并转换为字符串
  if ( strcmp(v9, "7CA421B9D92C4C5F40427F28E95C0DE4") )     //对比字符串
    pthread_create(newthread, 0LL, sub_D7D8, env);       //sub_D7D8这个进程会导致程序退出
  v10 = (*env)->FindClass(env, "android/app/ActivityThread");
  v11 = (*env)->GetStaticFieldID(env, v10, "sPackageManager", "Landroid/content/pm/IPackageManager;");
  v12 = (*env)->GetStaticObjectField(env, v10, v11);
  (*env)->DeleteLocalRef(env, v10);
  v13 = (*env)->GetObjectClass(env, v12);
  v14 = (*env)->GetSuperclass(env, v13);
  v15 = (*env)->FindClass(env, "java/lang/reflect/Proxy");    //检测PM代{过}{滤}理
  v16 = (*env)->IsAssignableFrom(env, v14, v15);     //检测结果
  (*env)->DeleteLocalRef(env, v12);
  (*env)->DeleteLocalRef(env, v13);
  (*env)->DeleteLocalRef(env, v14);
  (*env)->DeleteLocalRef(env, v15);
  if ( v16 )    //判断
    pthread_create(newthread, 0LL, sub_D7D8, env);
  byte_32000 = strcmp(v9, "7CA421B9D92C4C5F40427F28E95C0DE4") != 0;   //这里又进行了签名检测
  if ( a4 )
  {
    v17 = -1;
  }
  else
  {
    time(newthread);
    if ( byte_32000 )
      v18 = "7bezRrq/jsREB8GacPGtGjVC1RDUOLGD7AD0UZBQWIB5BDPK1VIWRYL9vn4lSHMx\n";
    else
      v18 = "7bezRrq/jsREB8GacPGtGjVC1rduolgdQAD0uZBQWib5bdpk1VIWryL9vn4lSHMx";   //密文
    if ( byte_32000 )
      v17 = -2;
    else
      v17 = 1;
    a4 = (*env)->NewStringUTF(env, v18);
  }
  v19 = (*env)->FindClass(env, "me/alzz/crypt/AesCrypt");
  v20 = (*env)->GetStaticMethodID(env, v19, "decrypt", "(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;");    //解密
  v21 = GetSign(env, a3);
  v22 = (*env)->NewStringUTF(env, v21);
  v23 = sub_D698(env, v19, v20, a4, v22);
  (*env)->DeleteLocalRef(env, v22);
  if ( v17 == 1 )
    a5 = (*env)->NewStringUTF(env, "https://awsl.1.woaifulishe.com");
  v24 = (*env)->FindClass(env, "cn/leancloud/AVOSCloud");
  v25 = (*env)->GetStaticMethodID(
          env,
          v24,
          "initializeSecurely",
          "(Landroid/content/Context;Ljava/lang/String;Ljava/lang/String;)V");
  sub_D8F4(env, v24, v25, a3, v23, a5);    //加载网络
  (*env)->DeleteLocalRef(env, v24);
  if ( v17 != -1 )
    (*env)->DeleteLocalRef(env, a5);
  (*env)->DeleteLocalRef(env, v23);
  if ( v9 )
    operator delete(v9);
}

不管是重签名,还是一键hookPM(非重定向),都会闪退,因为这里首先进行了签名对比,然后再检测自身是否被hook,如果不通过则会运行到sub_D7D8,它的代码如下:

void __fastcall __noreturn sub_D7D8(JNIEnv *env)
{
  time(timer);
  sleep(timer[0] % 10);
  v2 = (*env)->FindClass(env, "java/lang/ClassNotFoundException");
  (*env)->ThrowNew(env, v2, "me.alzz.Png");
  pthread_exit(0LL);
}

这段代码会导致休眠并退出,所以在hook的情况下可以修改判断逻辑,一般用B或者NOP指令直接跳过闪退的地方。

把这些保护代码剥离后剩下的部分可以用Java回填native:

public final void z(Context context,String str,String str2) {
        String salt = "759D1AB2D2254558393B7821E25506DD";
        String Id = me.alzz.crypt.AesCrypt.decrypt(str, salt);
        String URL = "https://awsl.1.woaifulishe.com";
        cn.leancloud.AVOSCloud.initializeSecurely(context, Id, URL);
    }
.method public final z(Landroid/content/Context;Ljava/lang/String;Ljava/lang/String;)V
    .registers 7

    .prologue
    .line 7
    const-string v2, "759D1AB2D2254558393B7821E25506DD"

    .line 8
    invoke-static {p2, v2}, Lme/alzz/crypt/AesCrypt;->decrypt(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;

    move-result-object v0

    .line 9
    const-string v1, "https://awsl.1.woaifulishe.com"

    .line 10
    invoke-static {p1, v0, v1}, Lcn/leancloud/AVOSCloud;->initializeSecurely(Landroid/content/Context;Ljava/lang/String;Ljava/lang/String;)V

    return-void
.end method

现在重签名后可以进入主界面并正常加载壁纸了,但是点击登录或者排行还是会闪退。根据log发现是libhell.so出现问题,那么继续用ida打开看看是怎么回事。

某壁纸软件的防护 简单分析  第1张

某壁纸软件的防护 简单分析  第2张

如上图,开头会进行代{过}{滤}理检测,然后获取签名,判断签名值是否正确。不过我发现检测代{过}{滤}理的还有sub_ED1C。

sub_EE74检测了libmthook.so和libcloudinject.so,部分代码如下:

if ( !dlopen("libmthook.so", 1) )
  {
    v2 = 1;
    if ( !dlopen("libcloudinject.so", 1) )
    {
      v3 = (*env)->FindClass(env, "android/app/ActivityThread");
      v4 = (*env)->GetStaticMethodID(env, v3, "currentApplication", "()Landroid/app/Application;");
      v5 = sub_FAB8(env, v3, v4);
      (*env)->DeleteLocalRef(env, v3);
      v6 = (*env)->GetObjectClass(env, v5);
      v7 = (*env)->GetMethodID(env, v6, "getApplicationInfo", "()Landroid/content/pm/ApplicationInfo;");
      v8 = sub_FA1C(env, v5, v7);
      v9 = (*env)->GetObjectClass(env, v8);
      v10 = (*env)->GetFieldID(env, v9, "nativeLibraryDir", "Ljava/lang/String;");
      v11 = (*env)->GetObjectField(env, v8, v10);
      v12 = (*env)->GetStringUTFChars(env, v11, 0LL);
      sub_EC70(v21, v12);

很明显的看到这是检测了加强版一键hook和云注入,目的就是为了防止有人使用了MT管理器的加强版hook,以及破解后注入弹窗引流等行为。所以对抗思路可以修改这些so关键字,再改一下判断基本上就能绕过去了。

在dex也有个mthook字符串,并且也获取了签名值,看来mt管理器被很多软件针对了,不过毕竟比较死板,通过修改一些特征就可以逃避检测。

某壁纸软件的防护 简单分析  第3张

除了mt管理器,比较强力的np管理器可以轻松应对这些保护,mt和np使用的过签原理还是有些不一样的,用np管理器的话可以说是一劳永逸。

如果APP用了ollvm混淆或者换了爱加密、36O等加固,安全性会有极大提升。

忆笙

忆笙 主页 联系他吧

人间山河远阔,只想与你同行。

欢迎 发表评论: