Android reverse 黑客精神

这篇博客详细介绍了安卓应用程序的注册验证机制,通过JEB静态分析MainActivity和MyApp类,揭示了如何检查应用是否已注册。在SO层,分析了initSN和saveSN方法,发现注册码的存储和校验过程,涉及文件操作和异或加密。最终,博主提供了一段脚本来模拟注册码的解密过程,得到了最终的flag。此文章深入探讨了移动应用的安全性和逆向工程。
摘要由CSDN通过智能技术生成

黑客精神
打开界面输入注册码后弹出:
在这里插入图片描述
JEB分析MainActivity:onCreat 函数中出现了刚刚的已注册,通过MyApp.m来判断是否已经注册

    public void onCreate(Bundle arg6) {
        String v2;
        super.onCreate(arg6);
        this.setContentView(0x7F04001A);
        String v1 = "Xman";
        Log.d("com.gdufs.xman m=", v1);
        this.getApplication();
        int v0 = MyApp.m;
        if(v0 == 0) {
            v2 = "未注册";
        }
        else if(v0 == 1) {
            v2 = "已注册";
        }
        else {
            v2 = "已混乱";
        }

        this.setTitle(v1 + v2);
        this.btn1 = this.findViewById(0x7F0B0054);
        this.btn1.setOnClickListener(new View$OnClickListener() {
            public void onClick(View arg5) {
                MainActivity.this.getApplication();
                if(MyApp.m == 0) {
                    MainActivity.this.doRegister();
                }
                else {
                    MainActivity.this.getApplication().work();
                    Toast.makeText(MainActivity.this.getApplicationContext(), MainActivity.workString, 0).show();
                }
            }
        });
    }

MyApp类分析:onCreate函数中调用了initSN()方法

public class MyApp extends Application {
    public static int m;

    static {
        MyApp.m = 0;
        System.loadLibrary("myjni");
    }

    public MyApp() {
        super();
    }

    public native void initSN() {
    }

    public void onCreate() {
        this.initSN();
        Log.d("com.gdufs.xman m=", String.valueOf(MyApp.m));
        super.onCreate();
    }

    public native void saveSN(String arg1) {
    }

    public native void work() {
    }
}

RegActivity类中调用了saveSN方法,并把输入的值传到了本地

          public void onClick(View arg5) {
                String v0 = RegActivity.this.edit_sn.getText().toString().trim();
                if(v0 == null || v0.length() == 0) {
                    Toast.makeText(RegActivity.this, "您的输入为空", 0).show();
                }
                else {
                    RegActivity.this.getApplication().saveSN(v0);
                    new AlertDialog$Builder(RegActivity.this).setTitle("回复").setMessage("您的注册码已保存").setPositiveButton("好吧", new DialogInterface$OnClickListener() {
                        public void onClick(DialogInterface arg2, int arg3) {
                            Process.killProcess(Process.myPid());
                        }
                    }).show();
                }

分析so层代码
找到JNI_OnLoad注册函数
在这里插入图片描述
跟到n1:initSN

 v2 = j_fopen("/sdcard/reg.dat", "r+");  //打开文件夹
  v3 = v2;
  if ( !v2 )   
  {
    v4 = a1;
    return setValue(v4, 0);
  }
  j_fseek(v2, 0, 2);
  v5 = j_ftell(v3);
  v6 = (const char *)j_malloc(v5 + 1);
  if ( !v6 )
  {
    j_fclose(v3);
    v4 = a1;
    return setValue(v4, 0);
  }
  j_fseek(v3, 0, 0);
  j_fread(v6, v5, 1, v3);
  v6[v5] = 0;
  if ( !j_strcmp(v6, "EoPAoY62@ElRD") )  //与字符串EoPAoY62@ElRD进行比较
  {
    v8 = a1;
    v9 = 1;
  }
  else
  {
    v8 = a1;
    v9 = 0;
  }
  setValue(v8, v9);
  return j_fclose(v3);
}

跟到n2:saveSN

v5 = j_fopen("/sdcard/reg.dat", "w+");  //打开文件夹
  if ( !v5 )
    return j___android_log_print(3, "com.gdufs.xman", byte_2E5A);
  strcpy(v13, "W3_arE_whO_we_ARE");
  v7 = (const char *)(*(int (__fastcall **)(int, int, _DWORD))(*(_DWORD *)a1 + 676))(a1, a3, 0);
  v8 = v7;
  v12 = j_strlen(v7);
  v9 = 2016;
  while ( 1 )
  {
    v10 = v8 - v7;
    if ( v8 - v7 >= v12 )
      break;
    if ( v10 % 3 == 1 )
    {
      v9 = (v9 + 5) % 16;
      v11 = v13[v9 + 1];
    }
    else if ( v10 % 3 == 2 )
    {
      v9 = (v9 + 7) % 15;
      v11 = v13[v9 + 2];
    }
    else
    {
      v9 = (v9 + 3) % 13;
      v11 = v13[v9 + 3];
    }
    *v8++ ^= v11;                  //if循环或者异或处理
  }
  j_fputs(v7, v5);
  return j_fclose(v5);
}

写脚本

n1='EoPAoY62@ElRD'
data='W3_arE_whO_we_ARE'
v9=2016
flag=''
for i in range(len(n1)):
    if i % 3 == 1:
        v9 = (v9 +5) % 16
        res = data[v9 + 1]
    elif i % 3 ==2:
        v9 = (v9 + 7) % 15
        res = data[v9 + 2]
    else:
        v9 = (v9 + 3) % 13
        res = data[v9 + 3]
    flag+=chr(ord(n1[i])^ord(res))
print(flag)

运行

201608Am!2333

最终flag{201608Am!2333}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值