首页 > 其他分享 >【Android 逆向】【攻防世界】android2.0

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

时间:2023-03-16 19:11:07浏览次数:35  
标签:攻防 str int v5 v6 v7 android2.0 Android ord

这是一道纯算法还原题

1. apk安装到手机,提示输入flag,看来输入就是flag

2. jadx 打开apk查看

        this.button.setOnClickListener(new View.OnClickListener() { // from class: com.example.test.ctf03.MainActivity.1
            @Override // android.view.View.OnClickListener
            public void onClick(View v) {
                String str = MainActivity.this.pwd.getText().toString();
                int result = JNI.getResult(str);
                MainActivity.this.Show(result);
            }
        });

JNI.java

public class JNI {
    public static native int getResult(String str);

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

3. IDA打开 libNative.so 看看

bool __fastcall Java_com_example_test_ctf03_JNI_getResult(JNIEnv *env, jclass a2, jstring str)
{
  int v3; // r4
  const char *str_chars; // r8
  char *v5; // r6
  char *v6; // r4
  char *v7; // r5
  int i; // r0
  int j; // r0

  v3 = 0;
  str_chars = (*env)->GetStringUTFChars(env, str, 0);
  if ( strlen(str_chars) == 15 )
  {
    v5 = (char *)malloc(1u);
    v6 = (char *)malloc(1u);
    v7 = (char *)malloc(1u);
    Init(v5, v6, v7, str_chars, 15);
    if ( !First(v5) )
      return 0;
    for ( i = 0; i != 4; ++i )
      v6[i] ^= v5[i];
    if ( !strcmp(v6, a5) )
    {
      for ( j = 0; j != 4; ++j )
        v7[j] ^= v6[j];
      return strcmp(v7, "AFBo}") == 0;
    }
    else
    {
      return 0;
    }
  }
  return v3;
}

先看一下Init函数在干什么

int __fastcall Init(int result, char *a2, char *a3, const char *str_chars, int len)
{
  int v5; // r5
  int v6; // r10
  int v7; // r6

  if ( len < 1 )
  {
    v6 = 0;
  }
  else
  {
    v5 = 0;
    v6 = 0;
    do
    {
      v7 = v5 % 3;
      if ( v5 % 3 == 2 )
      {
        a3[v5 / 3u] = str_chars[v5];
      }
      else if ( v7 == 1 )
      {
        a2[v5 / 3u] = str_chars[v5];
      }
      else if ( !v7 )
      {
        ++v6;
        *(_BYTE *)(result + v5 / 3u) = str_chars[v5];
      }
      ++v5;
    }
    while ( len != v5 );
  }
  *(_BYTE *)(result + v6) = 0;
  a2[v6] = 0;
  a3[v6] = 0;
  return result;
}

通过分析可知,该函数将字符串分为了三分,第一个字符给a1,第二个给a2,第三个给a3,第四个给a1,这样循环下去

再看First函数
bool __fastcall First(char *a1)
{
  int i; // r1

  for ( i = 0; i != 4; ++i )
    a1[i] = (2 * a1[i]) ^ 0x80;
  return strcmp(a1, "LN^dl") == 0;
}

这里是 拿着a对应的字符做个计算然后取和一个常量比较,这里可以倒推出a1的值,对应python

def first():
    b = "LN^dl"
    a1 = ''
    for i in range(0, 4):
        print(i)
        a1 += (chr(int((ord(b[i])^0x80)/2)))
    a1 += 'l'
    print(a1)

#得到 fgorl

注意这里得到了a1原来的值,但是这里a1已经被改了,值为"LN^dl", 我就在这里被坑到了

first函数过了之后,v6 做了一些计算,然后又和一个常量比较,那么又可以用上面的方法取干活
    for ( i = 0; i != 4; ++i )
      v6[i] ^= v5[i];
    if ( !strcmp(v6, a5) ){
    ......
    }

对应python

def second():
    a5 = [ord(' '),  ord('5'), ord('-'), 0x16, ord('a')]
    # v5 = [ord('f'), ord('g'), ord('o'), ord('r'), ord('l')]
    v5 = [ord('L'), ord('N'), ord('^'), ord('d'), ord('l')]
    v6 = ""
    for i in range(0, 4):
        t = v5[i]^a5[i]
        v6 += (chr(t))
    v6 += 'a'
    print(v6)

# 得到 l{sra

最后v7 也是一个套路,这里就直接给还原的代码了

def third():
    a6 = [ord('A'),  ord('F'), ord('B'), ord('o'), ord('}')]
    v6 = [ord(' '),  ord('5'), ord('-'), 0x16, ord('a')]
    v7 = ''
    for i in range(0, 4):
        t = v6[i]^a6[i]
        v7 += (chr(t))
    v7 += '}'
    print(v7)

# 得到 asoy}

最后把三个值拼起来,也就是最上面分析的那个循环赋值的逻辑,这里是还原算法

s1 = 'fgorl'
s2 = 'l{sra'
s3 = 'asoy}'
flag = ''
for i in range(5):
    flag += s1[i] + s2[i] + s3[i]
print(flag)

# 得到 flag{sosorryla}

标签:攻防,str,int,v5,v6,v7,android2.0,Android,ord
From: https://www.cnblogs.com/gradyblog/p/17223845.html

相关文章