【Android 逆向】【攻防世界】easy-so

android,逆向,攻防,世界,easy,so · 浏览次数 : 23

小编点评

The code you provided is a Java program that checks the validity of an APK file. **Explanation:** 1. **APK Installation and Input:** - The code first installs an APK file onto the phone. - It then inputs a string into an `EditText` control. 2. **Native Method Call:** - The code calls a native method `CheckString()` from the `cyberpeace` library. - The `CheckString()` method takes a string as input and checks if it matches the pattern of a valid APK file. 3. **SO File Inspection:** - The code uses the `LoadLibrary()` function to load the `cyberpeace` library from the system. - It then calls the `Java_com_testjava_jack_pingan2_cyberpeace_CheckString()` native method to perform the APK validation. - The `CheckString()` method takes a Java string as input and returns an integer result. 4. **Key Conversion and Validation:** - The code converts the return value of the `CheckString()` method to an `int` type. - It checks if the value is equal to 1, indicating that the APK is valid. - If it's not valid, an error message is shown. **Code Structure:** ```java public class MainActivity { // ... public native int CheckString(String apkPath); // ... @Override public void onCreate() { // Get the APK path from somewhere. String apkPath = getApkPath(); // Check if the APK is valid. int result = CheckString(apkPath); // Handle the result. if (result == 1) { // APK is valid. // Do something... } else { // APK is invalid. // Show an error message. } } } ``` **Notes:** - The `key` variable in the `main()` method is an array of `char` values representing the APK file. - The `nativeMethod()` function is a method that allows Java to call native code. - The `android.native.lib` package contains the native code for the `CheckString()` method.

正文

1. apk安装到手机,随便输入点内容,提示错误

2. jadx打开apk

        btn.setOnClickListener(new View.OnClickListener() { // from class: com.testjava.jack.pingan2.MainActivity.1
            @Override // android.view.View.OnClickListener
            public void onClick(View v) {
                EditText et1 = (EditText) MainActivity.this.findViewById(R.id.editText);
                String strIn = et1.getText().toString();
                if (cyberpeace.CheckString(strIn) == 1) {
                    Toast.makeText(MainActivity.this, "验证通过!", 1).show();
                } else {
                    Toast.makeText(MainActivity.this, "验证失败!", 1).show();
                }
            }
        });

核心是这一行 cyberpeace.CheckString(strIn)

public class cyberpeace {
    public static native int CheckString(String str);

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

那么算法在so中

3. IDA打开SO看一下

bool __fastcall Java_com_testjava_jack_pingan2_cyberpeace_CheckString(JNIEnv *env, jclass clz, jstring key)
{
  const char *key_chars; // x20
  __int64 key_len; // x0
  signed int t_key_len; // w21
  unsigned __int64 v6; // x22
  _BYTE *v7; // x0
  _BYTE *t_key_chars; // x19
  size_t v9; // w2
  unsigned __int64 v10; // x20
  _BYTE *v11; // x8
  char v12; // w9
  char v13; // w10
  char v14; // w9
  __int64 v15; // x20
  _BYTE *v16; // x8
  char v17; // w10
  unsigned __int64 v18; // x0
  unsigned __int64 v19; // x8

  key_chars = (*env)->GetStringUTFChars(env, key, 0LL);
  key_len = strlen(key_chars);
  t_key_len = key_len;
  v6 = ((key_len << 32) + 0x100000000LL) >> 32;
  v7 = malloc((unsigned __int64)((key_len << 32) + 0x100000000LL) >> 32);
  t_key_chars = v7;
  if ( v6 > t_key_len )
    v9 = v6 - t_key_len;
  else
    v9 = 0;
  memset(&v7[t_key_len], 0, v9);
  memcpy(t_key_chars, key_chars, t_key_len);
  if ( strlen(t_key_chars) >= 2uLL )
  {
    v10 = 0LL;
    do
    {
      v11 = &t_key_chars[v10];
      v12 = t_key_chars[v10 + 16];
      v13 = t_key_chars[v10++];
      *v11 = v12;
      v11[16] = v13;
    }
    while ( (unsigned __int64)strlen(t_key_chars) >> 1 > v10 );
  }
  if ( *t_key_chars )
  {
    v14 = t_key_chars[1];
    t_key_chars[1] = *t_key_chars;
    *t_key_chars = v14;
    if ( strlen(t_key_chars) >= 3uLL )
    {
      v15 = 0LL;
      do
      {
        v16 = &t_key_chars[v15];
        v17 = t_key_chars[v15 + 2];
        v16[2] = t_key_chars[v15 + 3];
        v16[3] = v17;
        v18 = strlen(t_key_chars);
        v19 = v15 + 4;
        v15 += 2LL;
      }
      while ( v18 > v19 );
    }
  }
  return strcmp(t_key_chars, "f72c5a36569418a20907b55be5bf95ad") == 0;
}

有点看不清,整理以下


    i = 0;
    do
    {
      v12 = t_key_chars[i + 16];
      v13 = t_key_chars[i];
      t_key_chars[i] = v12;
      t_key_chars[i+16] = v13;
      i++;
    }
    while ( strlen(t_key_chars) / 2 > i );

  if ( *t_key_chars )
  {
    tmp = t_key_chars[1];
    t_key_chars[1] = t_key_chars[0];
    t_key_chars[0] = tmp;
    if ( strlen(t_key_chars) >= 3uLL )
    {
      i = 0;
      do
      {
        tmp = t_key_chars[i + 2];
        t_key_chars[i+2] = t_key_chars[i + 3];
        t_key_chars[i+3] = tmp;
        v19 = i + 4;
        i += 2;
      }
      while ( strlen(t_key_chars) > v19 );
    }
  }

可以看出,是先把32位字符串前十六位和后十六位换个位置,然后每两位互换位置

4 写出还原算法

key = 'f72c5a36569418a20907b55be5bf95ad'

def main():
    print(key)
    key_list = list(key)
    t_len = len(key)
    i = 0
    v19 = 0
    while v19 < t_len:
        tmp = key_list[i+2]
        key_list[i+2] = key_list[i+3]
        key_list[i+3] = tmp
        v19 = i+4
        i += 2

    tmp = key_list[1]
    key_list[1] = key_list[0]
    key_list[0] = tmp
    print("after ======")
    print(''.join(key_list))

    i = 0
    while i < t_len >> 1:
        tmp = key_list[i+16]
        key_list[i+16] = key_list[i]
        key_list[i] = tmp
        i += 1
    print("after ======")
    print(''.join(key_list))

main()

日志

f72c5a36569418a20907b55be5bf95ad
after ======
7fc2a5636549812a90705bb55efb59da
after ======
90705bb55efb59da7fc2a5636549812a  # flag

成功获得flag

与 【Android 逆向】【攻防世界】easy-so相似的内容:

【Android 逆向】【攻防世界】easy-so

1. apk安装到手机,随便输入点内容,提示错误 2. jadx打开apk btn.setOnClickListener(new View.OnClickListener() { // from class: com.testjava.jack.pingan2.MainActivity.1 @Ove

【Android 逆向】【攻防世界】easy-apk

apk 安装到手机,随便输入点内容,提示错误 2. apk 拖入到jadx中看看 public class MainActivity extends AppCompatActivity { /* JADX INFO: Access modifiers changed from: protected

【Android 逆向】【攻防世界】easy-dex

这一题不easy,不知为何叫这个名字。。。。 1. apk 安装到手机,不知所云,各种亮瞎眼闪光 2. jadx 打开apk,一行java代码都没有,打开AndroidManifest看看

【Android 逆向】【攻防世界】基础android

1. 下载并安装apk,提示要输入密码 2. apk拖入到jadx中看一下 this.login.setOnClickListener(new View.OnClickListener() { // from class: com.example.test.ctf02.MainActivity.1

【Android 逆向】【攻防世界】android2.0

这是一道纯算法还原题 1. apk安装到手机,提示输入flag,看来输入就是flag 2. jadx 打开apk查看 this.button.setOnClickListener(new View.OnClickListener() { // from class: com.example.test

【Android 逆向】【攻防世界】APK逆向

1. apk安装到手机,提示输入flag 2. jadx打开apk 定位到checkSN方法 public boolean checkSN(String userName, String sn) { if (userName != null) { try { if (userName.length(

【Android 逆向】【攻防世界】人民的名义-抓捕赵德汉1-200

1. 这一题下载下来是个jar文件,感觉很android关系不大,但还是放在了mobile这个分类下了 2. 直接java jar运行,提示需要输入密码 # java -jar 169e139f152e45d5ae634223fe53e6be.jar Enter password: 1234 Inc

【Android 逆向】【攻防世界】ill-intentions

1. apk 安装到手机, 啥输入框都没有 2. apk拖入到jadx中看看 public class MainActivity extends Activity { @Override // android.app.Activity public void onCreate(Bundle save

【Android 逆向】【攻防世界】boomshakalaka-3

1. apk 安装到手机,是一个cocos2dx 写的打飞机的游戏 题目描述跟得分有关(题目描述: play the game, get the highest score) 2. jadx 打开apk public class FirstTest extends Cocos2dxActivity

【Android 逆向】【攻防世界】app1

1. apk安装到手机, 老套路了 2. jadx打开 this.btn.setOnClickListener(new View.OnClickListener() { // from class: com.example.yaphetshan.tencentgreat.MainActivity.1