作业报告┭┮﹏┭┮(Android反调试)

一:Android反调试

主要是用来防止IDA进行附加的,主要的方法思路就是,判断自身是否有父进程,判断是否端口被监听,然后通过调用so文件中的线程进行监视,这个线程开启一般JNI_OnLoad中进行开启的。但是这个是在这个之前断开的。思路→过反调试的话呢,就要把相关的函数进行NOP掉,直接将这几个字节改为00就可以了。

反编译截图:


我们可以fax1这个软件是不可以调试的,要想调试这个软件,我们有俩个方法。

其一:我们给他增加上:android:debuggable="true"在application的节点中,然后进行编译,签名,安装。

其二:我们有magisk面具,刷入MagiskHideProsp Config模块

调试软件的时候执行以下命令,就可以调试软件了

jsx 复制代码
adb shell
su
magisk resetprop ro.debuggable 1
stop
start

然后打开IDA进行附加:

  1. 常规的运行服务器,转发端口
jsx 复制代码
adb forward tcp:23946 tcp:23946
  1. 然后使用调试模式进行运行:
jsx 复制代码
adb shell am start -D -n com.ctf.mobile/com.ctf.mobile.MainActivity
  1. 查看我们软件的进程,并进行转发
jsx 复制代码
adb shell ps | findstr ctf
adb forward tcp:8700 jdwp:
  1. 运行之后,使用IDA进行附加,附加的时候正常操作,但是进去之后我们需要选择一下:

在调试器的调试器选项中设置:

  1. 然后点击运行,之后就会不动,这个时候我们用jdb绑定端口(ddms需要打开的情况下使用8700端口),使用命令:
jsx 复制代码
jdb -connect com.sun.jdi.SocketAttach:hostname=127.0.0.1,port=8700然后程序就会断下,因为在加载so文件。
  1. 我们一次运行就查看是否是我们的so被载入,我们的so文件名是:libmobile.so

  2. 当被载入的时候,我们就选择在JNI_OnLoad中进行下断点。然后破除反调试

(不会/(ㄒoㄒ)/~~)

参考文章

https://www.cnblogs.com/bmjoker/p/11962585.html

二:java分析

jsx 复制代码
package com.ctf.mobile;

import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;
import androidx.appcompat.app.AppCompatActivity;
import com.ctf.mobile.databinding.ActivityMainBinding;

public class MainActivity extends AppCompatActivity {
    private ActivityMainBinding binding;
    private Button button;
    private EditText flagText;

    public native boolean check(String str);

    static {
        System.loadLibrary("mobile");
    }

    /* access modifiers changed from: protected */
    @Override // androidx.activity.ComponentActivity, androidx.core.app.ComponentActivity, androidx.fragment.app.FragmentActivity
    public void onCreate(Bundle bundle) {
        super.onCreate(bundle);
        ActivityMainBinding inflate = ActivityMainBinding.inflate(getLayoutInflater());
        this.binding = inflate;
        setContentView(inflate.getRoot());
        final op opVar = new op();
        this.button = (Button) findViewById(R.id.button);
        this.flagText = (EditText) findViewById(R.id.editText);
        this.button.setOnClickListener(new View.OnClickListener() {
            /* class com.ctf.mobile.MainActivity.AnonymousClass1 */

            public void onClick(View view) {
                if (MainActivity.this.flagText.getText().toString().trim().length() < 50) {
                    MainActivity mainActivity = MainActivity.this;
                    if (mainActivity.check(mainActivity.flagText.getText().toString().trim())) {
                        Toast.makeText(MainActivity.this, op.flagRight, 0).show();
                        return;
                    }
                }
                Toast.makeText(MainActivity.this, op.flagWrong, 0).show();
            }
        });
    }
}

载入时候的,发现按钮被点击之后,调用了Check这个方法,这是个本地函数,我们在IDA中进行寻找:

看一下IDA给我们的伪代码:

jsx 复制代码
__int64 __fastcall Java_com_ctf_mobile_MainActivity_check(__int64 a1, __int64 a2, __int64 a3)
{
  __int64 v4; // x0

  v4 = (*(__int64 (__fastcall **)(__int64, __int64, _QWORD))(*(_QWORD *)a1 + 1352LL))(a1, a3, 0LL);
  return sub_EF0(a1, v4) & 1;
}

sub_EF0

jsx 复制代码
bool __fastcall sub_EF0(__int64 a1, const char *a2)
{
  __int64 v3; // x25
  __int64 v4; // x0
  __int64 v5; // x24
  __int64 v6; // x0
  __int64 v7; // x8
  __int64 v8; // x26
  __int64 v9; // x25
  unsigned __int8 v10; // w0
  unsigned int v11; // w27
  char v12; // w0
  __int64 v13; // x22
  __int64 v14; // x26
  char v15; // w0
  const char *v16; // x24
  __int64 v17; // x23
  __int64 v18; // x0
  __int64 v19; // x8
  unsigned int v20; // w0
  unsigned int v21; // w0
  int v22; // w25
  bool v23; // cc
  const char *v24; // x8
  __int64 v25; // x25
  __int64 v26; // x0
  __int64 v27; // x21
  __int64 v28; // x23
  __int64 v29; // x26
  __int64 v30; // x25
  unsigned int v31; // w27
  const char *v32; // x24
  __int64 v33; // x0
  unsigned int v34; // w0
  unsigned int v35; // w0
  __int64 v36; // x17
  __int64 v37; // x1
  __int64 v38; // x0
  __int64 i; // x8
  __int64 v40; // x9
  unsigned int v41; // w10
  char v42; // w14
  char v43; // w13
  _BYTE *v44; // x16
  _BYTE *v45; // x15
  char v46; // w11
  int v47; // w22
  _BYTE *v48; // x23
  int v49; // w24
  __int64 v50; // x8
  int v51; // w20
  FILE *v52; // x0
  FILE *v53; // x28
  int v58; // w8
  int v59; // w20
  FILE *v60; // x0
  FILE *v61; // x28
  __int64 v62; // x24
  FILE *v63; // x0
  FILE *v64; // x28
  FILE *v65; // x0
  FILE *v66; // x28
  __int64 v67; // x26
  __int64 v68; // x28
  __int64 v69; // x27
  __int64 v70; // x20
  int v71; // w22
  int v72; // w23
  int v73; // w9
  __int64 v74; // x3
  __int64 v75; // x25
  unsigned __int64 v76; // x24
  _BOOL4 v77; // w21
  FILE *v78; // x0
  FILE *v79; // x23
  _BYTE v81[256]; // [xsp-630h] [xbp-8A0h] BYREF
  __int64 v82; // [xsp-530h] [xbp-7A0h] BYREF
  _BYTE v83[48]; // [xsp-430h] [xbp-6A0h] BYREF
  _BYTE v84[256]; // [xsp-400h] [xbp-670h] BYREF
  _BYTE v85[12]; // [xsp-300h] [xbp-570h] BYREF
  __int128 v86; // [xsp-2F4h] [xbp-564h]
  __int128 v87; // [xsp-2E4h] [xbp-554h]
  __int128 v88; // [xsp-2D4h] [xbp-544h]
  __int128 v89; // [xsp-2C4h] [xbp-534h]
  __int128 v90; // [xsp-2B4h] [xbp-524h]
  __int128 v91; // [xsp-2A4h] [xbp-514h]
  __int128 v92; // [xsp-294h] [xbp-504h]
  __int128 v93; // [xsp-284h] [xbp-4F4h]
  __int128 v94; // [xsp-274h] [xbp-4E4h]
  __int128 v95; // [xsp-264h] [xbp-4D4h]
  __int128 v96; // [xsp-254h] [xbp-4C4h]
  __int128 v97; // [xsp-244h] [xbp-4B4h]
  __int128 v98; // [xsp-234h] [xbp-4A4h]
  __int128 v99; // [xsp-224h] [xbp-494h]
  __int128 v100; // [xsp-214h] [xbp-484h]
  int v101; // [xsp-204h] [xbp-474h]
  _BYTE v102[520]; // [xsp-200h] [xbp-470h] BYREF
  __int64 v103; // [xsp+8h] [xbp-268h]
  __int64 v104; // [xsp+10h] [xbp-260h]
  unsigned __int64 StatusReg; // [xsp+18h] [xbp-258h]
  _BYTE *v106; // [xsp+20h] [xbp-250h]
  _BYTE *v107; // [xsp+28h] [xbp-248h]
  __int64 *v108; // [xsp+30h] [xbp-240h]
  const char *v109; // [xsp+38h] [xbp-238h]
  _BYTE *v110; // [xsp+40h] [xbp-230h]
  __int64 v111; // [xsp+48h] [xbp-228h]
  _BYTE *v112; // [xsp+50h] [xbp-220h]
  const char *v113; // [xsp+58h] [xbp-218h]
  char v114[10]; // [xsp+60h] [xbp-210h] BYREF
  _BYTE v115[6]; // [xsp+6Ah] [xbp-206h] BYREF
  char v116[256]; // [xsp+160h] [xbp-110h] BYREF
  __int64 v117; // [xsp+260h] [xbp-10h]

  v109 = a2;
  StatusReg = _ReadStatusReg(ARM64_SYSREG(3, 3, 13, 0, 2));
  v117 = *(StatusReg + 40);
  if ( y >= 10 && (((x - 1) * x) & 1) != 0 )
    goto LABEL_5;
  while ( 1 )
  {
    v106 = v85;
    v112 = v84;
    v110 = v84;
    v107 = v83;
    v113 = v83;
    v108 = &v82;
    v3 = (*(*a1 + 48LL))(a1, &xmmword_4350);
    v4 = (*(*a1 + 264LL))(a1, v3, &byte_4364, &byte_436C);
    v5 = sub_1B58(a1, v3, v4);
    v6 = (*(*a1 + 264LL))(a1, v3, &byte_4370, &byte_4374);
    v7 = *a1;
    v111 = v6;
    v8 = (*(v7 + 264))(a1, v3, &byte_437C, &byte_4374);
    v9 = (*(*a1 + 264LL))(a1, v3, &byte_4380, &byte_4374);
    v101 = 0;
    memset(v102, 0, 256);
    v100 = 0u;
    v99 = 0u;
    v98 = 0u;
    v97 = 0u;
    v96 = 0u;
    v95 = 0u;
    v94 = 0u;
    v93 = 0u;
    v92 = 0u;
    v91 = 0u;
    v90 = 0u;
    v89 = 0u;
    v88 = 0u;
    v87 = 0u;
    v86 = 0u;
    v10 = sub_1BF4(a1, v5, v8, 20LL, 28LL);
    v11 = v10;
    v85[0] = v10;
    v85[1] = sub_1BF4(a1, v5, v8, v10, 72LL);
    v85[2] = sub_1BF4(a1, v5, v8, v11, 1LL);
    v85[3] = sub_1BF4(a1, v5, v8, v11, 2LL);
    v85[4] = sub_1BF4(a1, v5, v8, v11, 3LL);
    v85[5] = sub_1BF4(a1, v5, v8, v11, 4LL);
    v85[6] = sub_1BF4(a1, v5, v8, v11, 5LL);
    v85[7] = sub_1BF4(a1, v5, v8, v11, 6LL);
    v85[8] = sub_1BF4(a1, v5, v8, v11, 7LL);
    v12 = sub_1BF4(a1, v5, v8, v11, 8LL);
    v13 = v112;
    v85[9] = v12;
    v85[10] = sub_1BF4(a1, v5, v8, v11, 9LL);
    v14 = v5;
    v15 = sub_1BF4(a1, v5, v9, v11, v11);
    v16 = v109;
    v85[11] = v15;
    v17 = v111;
    memset(v84, 0, sizeof(v84));
    v18 = strlen(v109);
    __memcpy_chk(v13, v16, v18 + 1, 256LL);
    v19 = v110;
    *(v110 - 3) = unk_980;
    *(v19 - 32) = unk_990;
    *(v19 - 19) = unk_99D;
    *(v19 - 48) = sub_1BF4(a1, v14, v17, 6LL, 115LL);
    v20 = sub_1BF4(a1, v14, v17, 42LL, 189LL);
    v21 = sub_1BF4(a1, v14, v9, 226LL, v20);
    v22 = sub_1BF4(a1, v14, v17, v21, 331LL);
    v23 = y < 10;
    v24 = v113;
    *(v113 - 16) = 0u;
    *(v24 - 15) = 0u;
    *(v24 - 14) = 0u;
    *(v24 - 13) = 0u;
    *(v24 - 12) = 0u;
    *(v24 - 11) = 0u;
    *(v24 - 10) = 0u;
    *(v24 - 9) = 0u;
    *(v24 - 8) = 0u;
    *(v24 - 7) = 0u;
    *(v24 - 6) = 0u;
    *(v24 - 5) = 0u;
    *(v24 - 4) = 0u;
    *(v24 - 3) = 0u;
    *(v24 - 2) = 0u;
    *(v24 - 1) = 0u;
    if ( v23 || (((x - 1) * x) & 1) == 0 )
      break;
LABEL_5:
    v25 = (*(*a1 + 48LL))(a1, &xmmword_4350);
    v26 = (*(*a1 + 264LL))(a1, v25, &byte_4364, &byte_436C);
    v27 = sub_1B58(a1, v25, v26);
    v28 = (*(*a1 + 264LL))(a1, v25, &byte_4370, &byte_4374);
    v29 = (*(*a1 + 264LL))(a1, v25, &byte_437C, &byte_4374);
    v30 = (*(*a1 + 264LL))(a1, v25, &byte_4380, &byte_4374);
    v31 = sub_1BF4(a1, v27, v29, 20LL, 28LL);
    sub_1BF4(a1, v27, v29, v31, 72LL);
    sub_1BF4(a1, v27, v29, v31, 1LL);
    sub_1BF4(a1, v27, v29, v31, 2LL);
    sub_1BF4(a1, v27, v29, v31, 3LL);
    sub_1BF4(a1, v27, v29, v31, 4LL);
    sub_1BF4(a1, v27, v29, v31, 5LL);
    sub_1BF4(a1, v27, v29, v31, 6LL);
    sub_1BF4(a1, v27, v29, v31, 7LL);
    sub_1BF4(a1, v27, v29, v31, 8LL);
    sub_1BF4(a1, v27, v29, v31, 9LL);
    sub_1BF4(a1, v27, v30, v31, v31);
    memset(v81, 0, sizeof(v81));
    v32 = v109;
    v33 = strlen(v109);
    __memcpy_chk(v81, v32, v33 + 1, 256LL);
    sub_1BF4(a1, v27, v28, 6LL, 115LL);
    v34 = sub_1BF4(a1, v27, v28, 42LL, 189LL);
    v35 = sub_1BF4(a1, v27, v30, 226LL, v34);
    sub_1BF4(a1, v27, v28, v35, 331LL);
  }
  v103 = v14;
  v104 = a1;
  if ( v22 < 1 )
  {
    v36 = v108;
    v37 = 0LL;
    goto LABEL_14;
  }
  v36 = v108;
  v37 = v22;
  if ( v22 == 1 )
  {
    v38 = v106;
    for ( i = 0LL; i != v22; *(v36 + i++) = v46 )
    {
LABEL_13:
      v46 = *(v38 + i % 0x2A);
      v102[i] = i;
    }
    goto LABEL_14;
  }
  v38 = v106;
  v40 = 0LL;
  i = v22 & 0xFFFFFFFE;
  v41 = 1;
  do
  {
    v42 = *(v38 + v40 % 0x2A);
    v43 = *(v38 + v40 + ((-42 * (v41 / 0x2A)) | 1));
    v44 = &v102[v40];
    v44[1] = v40 | 1;
    v45 = (v36 + v40);
    *v44 = v40;
    v40 += 2LL;
    v41 += 2;
    *v45 = v42;
    v45[1] = v43;
  }
  while ( i != v40 );
  if ( i != v22 )
    goto LABEL_13;
LABEL_14:
  v113 = v115;
  if ( v37 )
  {
    v47 = 0;
    v48 = 0LL;
    v110 = v37;
    do
    {
      v49 = v48[v36];
      while ( 1 )
      {
        v51 = v102[v48];
        getpid();
        sub_1C90(v116, 256LL);
        v52 = fopen(v116, &byte_43A0);
        if ( v52 )
        {
          v53 = v52;
          while ( fgets(v114, 256, v53) )
          {
            if ( strstr(v114, &qword_43A8) )
            {
              if ( atoi(v113) )
                __asm { SVC             0x80 }
              break;
            }
          }
          fclose(v53);
        }
        v58 = (v47 + v51 + v49) % v22;
        v23 = y < 10;
        v102[v48] = v102[v58];
        v102[v58] = v51;
        if ( v23 || (((x - 1) * x) & 1) == 0 )
          break;
        v59 = v102[v48];
        getpid();
        sub_1C90(v116, 256LL);
        v60 = fopen(v116, &byte_43A0);
        if ( v60 )
        {
          v61 = v60;
          while ( fgets(v114, 256, v61) )
          {
            if ( strstr(v114, &qword_43A8) )
            {
              if ( atoi(v113) )
                __asm { SVC             0x80 }
              break;
            }
          }
          fclose(v61);
        }
        v50 = (v47 + v59 + v49) % v22;
        v102[v48] = v102[v50];
        v102[v50] = v59;
      }
      v36 = v108;
      ++v48;
      v47 = (v47 + v51 + v49) % v22;
    }
    while ( v48 != v110 );
  }
  v62 = v104;
  while ( 1 )
  {
    getpid();
    sub_1C90(v116, 256LL);
    v63 = fopen(v116, &byte_43A0);
    if ( v63 )
    {
      v64 = v63;
      while ( fgets(v114, 256, v64) )
      {
        if ( strstr(v114, &qword_43A8) )
        {
          if ( atoi(v113) )
            __asm { SVC             0x80 }
          break;
        }
      }
      fclose(v64);
    }
    if ( y < 10 || (((x - 1) * x) & 1) == 0 )
      break;
    getpid();
    sub_1C90(v116, 256LL);
    v65 = fopen(v116, &byte_43A0);
    if ( v65 )
    {
      v66 = v65;
      while ( fgets(v114, 256, v66) )
      {
        if ( strstr(v114, &qword_43A8) )
        {
          if ( atoi(v113) )
            __asm { SVC             0x80 }
          break;
        }
      }
      fclose(v66);
    }
  }
  v68 = v111;
  v67 = v112;
  v69 = v103;
  v70 = 0LL;
  v71 = 0;
  v72 = 0;
  do
  {
    v72 = (v72 + 1) % v22;
    v73 = v102[v72];
    v74 = *(v67 + v70);
    v71 = (v71 + v73) % v22;
    v102[v72] = v102[v71];
    v102[v71] = v73;
    *(v67 + v70++) = sub_1BF4(v62, v69, v68, v74, v102[(v102[v72] + v73) % v22]);
  }
  while ( v70 != 42 );
  v75 = v107;
  v76 = 0LL;
  v77 = 1;
  do
  {
    getpid();
    sub_1C90(v116, 256LL);
    v78 = fopen(v116, &byte_43A0);
    if ( v78 )
    {
      v79 = v78;
      while ( fgets(v114, 256, v79) )
      {
        if ( strstr(v114, &qword_43A8) )
        {
          if ( atoi(v113) )
            __asm { SVC             0x80 }
          break;
        }
      }
      fclose(v79);
    }
    if ( *(v67 + v76) != *(v75 + v76) )
      break;
    _CF = v76++ >= 0x29;
    v77 = !_CF;
  }
  while ( v76 != 42 );
  return !v77;
}

最重要的一部分

我们发现最后返回的是根据V67和V76,V75进行判断的,在java层我们也分析道我们要的就是返回值,看最后的循环语句,可以清楚的发现,其实就是就是一个类似于strcmp的一个函数,每一个字符进行比较,如果有一处不一样,就跳出循环,否则都一样的话呢,返回v77,这个是1,需要获取到值,这个就是注册码,或者试试将这个返回修改一下也是可以的。

然后尝试分析流程图(不会/(ㄒoㄒ)/~~

相关推荐
九河云1 小时前
数字化转型中的网络安全风险与零信任架构实践
运维·科技·安全·web安全·架构
木木子99991 小时前
业务架构、应用架构、数据架构、技术架构
java·开发语言·架构
七七七七073 小时前
【计算机网络】深入理解ARP协议:工作原理、报文格式与安全防护
linux·服务器·网络·计算机网络·安全
qq_5470261793 小时前
Flowable 工作流引擎
java·服务器·前端
鼓掌MVP4 小时前
Java框架的发展历程体现了软件工程思想的持续进化
java·spring·架构
编程爱好者熊浪5 小时前
两次连接池泄露的BUG
java·数据库
lllsure5 小时前
【Spring Cloud】Spring Cloud Config
java·spring·spring cloud
wanhengidc5 小时前
云手机搬砖 尤弥尔传奇自动化操作
运维·服务器·arm开发·安全·智能手机·自动化
鬼火儿5 小时前
SpringBoot】Spring Boot 项目的打包配置
java·后端
NON-JUDGMENTAL5 小时前
Tomcat 新手避坑指南:环境配置 + 启动问题 + 乱码解决全流程
java·tomcat