2017年陕西省网络空间安全技术大赛·Mobile T1

0x00拯救鲁班七号

CM下载网址:链接: https://pan.baidu.com/s/10EPc2KCWqcaT9wLw5eyxWw 密码: swkn

界面流程:一个输入框,一个按钮。


0x01JAVA层分析

  1. 反汇编代码逻辑分析
    加载了humen.so文件,说明这是写在native层的加密方法。说明已在代码注释中,不再重复。

      static
      {
        System.loadLibrary("humen");
      }
      
      public void checkPass(String paramString)
      {
        String str = CheckUtil.checkPass(paramString);   //②来到CheckUtil.checkPass进行判断,返回对应状态赋给str
        if ((paramString == null) || (paramString.equals("")))
        {
          Toast.makeText(getApplicationContext(), getString(2131034114), 1).show();
          return;
        }
        if (str.equals("a"))
        {
          startActivity(new Intent(this, WindowActivity.class));
          return;
        }
        Toast.makeText(getApplicationContext(), getString(2131034115), 1).show();
      }
      
      protected void onCreate(Bundle paramBundle)
      {
        super.onCreate(paramBundle);
        setContentView(2130903040);
        ((Button)findViewById(2131165184)).setOnClickListener(new View.OnClickListener()
        {
          public void onClick(View paramAnonymousView)
          {
            paramAnonymousView = (TextView)MainActivity.this.findViewById(2131165185);
            MainActivity.this.checkPass(paramAnonymousView.getText().toString().trim());   //①传入提交的String
          }
        });
      }
    public class CheckUtil
    {
      public static native String checkPass(String paramString);    //③看到这是JNI方法,固需要分析native层的checkPass方法
    }

0x02Native层分析

  1. 找到反汇编目录下的humen.so文件,用32位IDA载入
    64位IDA好像分析不了,但是这里会有两个,这里我选择x86中的so文件,因为另一个经我测试分析不到checkPass方法。

  2. 双击该方法后在右侧汇编代码部分F5查看伪C语言代码

    贴上反汇编有部分错误的CheckPass方法的全部代码:
    int __usercall Java_com_humen_crackme010_CheckUtil_checkPass@<eax>(int a1@<ebx>, int *a2, int a3, int a4)
    {
      int v4; // ebx@1
      const char *v5; // edi@1
      signed __int32 v6; // ebp@1
      char v7; // dl@3
      signed int v8; // eax@3
      char *v9; // edx@5
      char *v10; // eax@5
      char v11; // si@5
      int v12; // esi@8
      int v13; // eax@9
      char *v14; // edx@10
      int v15; // eax@10
      char v16; // cl@11
      bool v17; // sf@12
      unsigned __int8 v18; // of@12
      int v19; // eax@12
      int result; // eax@13
      signed int i; // [sp+14h] [bp-28h]@4
      signed __int32 v22; // [sp+14h] [bp-28h]@7
      signed __int32 v23; // [sp+18h] [bp-24h]@1
    
      sub_82B();
      v4 = a1 + 9207;
      v5 = (const char *)getStringUnicodeChars(a2, a4, &aUtf8[v4 - 12208]);
      v23 = 0;
      v6 = strlen(v5);
      while ( 1 )
      {
        v23 += 2;
        if ( v6 <= v23 )
          break;
        v7 = v5[v23 - 2];
        v5[v23 - 2] = v5[v23 - 1];
        v8 = 0;
        v5[v23 - 1] = v7;
        if ( v6 > 4 )
        {
          for ( i = 4; ; i += 4 )
          {
            v10 = (char *)&v5[v8];
            v9 = v10;
            v11 = *v10;
            v10 += 4;
            *v9 = *v10;
            *v10 = v11;
            v8 = i;
            if ( v6 <= i + 4 )
              break;
          }
        }
      }
      v22 = strlen(v5);
      if ( v22 > 0 )
      {
        v12 = 0;
        do
        {
          v13 = v5[v12++];
          __android_log_print(4, &aHumen[v4 - 12208], &aC[v4 - 12208], v13);
        }
        while ( v22 != v12 );
      }
      printf(&aS[v4 - 12208], v5);
      v14 = (&t_ptr)[v4 - 12208];
      v15 = 0;
      if ( *v5 == *v14 )
      {
        do
          v16 = v14[v15++ + 1];
        while ( v5[v15] == v16 );
      }
      v18 = __OFSUB__(v6, v15);
      v17 = v6 - v15 < 0;
      v19 = *a2;
      if ( v17 ^ v18 )
        result = (*(int (__cdecl **)(int *, char *))(v19 + 668))(a2, &aA[v4 - 12208]);
      else
        result = (*(int (__cdecl **)(int *, char *))(v19 + 668))(a2, &aB[v4 - 12208]);
      return result;
    }
  3. 分析主要逻辑
    理一下这么多的v..变量,可以发现v5是传入的string字符串,v6是通过strlen取得的v5的长度。
    于是上面的代码加密逻辑整理为下面的。
    v23 = 0;
    length = strlen(input);
      while ( 1 )
      {
        v23 += 2;
        if ( length <= v23 )              //字符串长度不够2、4、6..就退出while循环
          break;
        v7 = input[v23 - 2];              //v7 = input[0]
        input[v23 - 2] = input[v23 - 1];  //input[0] = input[1]
        v8 = 0;                           
        input[v23 - 1] = v7;              //input[1] = v7       <!--所以上面是每两位(0和1、2和3...)替换一次-->
        if ( length > 4 )
        {
          for ( i = 4; ; i += 4 )
          {
            v10 = (char *)&input[v8];     //v10 = &input[0];
            v9 = v10;                     
            v11 = *v10;                   //v11 = input[0];
            v10 += 4;                     //v10 = input[4]; 
            *v9 = *v10;                   //input[0] = input[4];
            *v10 = v11;                   //input[4] = input[0];
            v8 = i;                       //v8 = 4;
            if ( length <= i + 4 )        //当length=16时,当i=12时就退出。此时交换了(0和4,i=4,v8=0)、(4和8,i=8,v8=4)、(8和12,i=12,v8=8,break;)
              break;
          }
        }
      }
     v14 = (&t_ptr)[v4 - 12208];        //v14是比对的字符串,双击t_ptr进入,其值为"S!@#@1FD23154A34"
      v15 = 0;
      if ( *input == *v14 )
      {
        do
          v16 = v14[v15++ + 1];         //这里v15和v16会影响后面判断的返回值,固当input经过上述流程后等于v14,则成功,我们需要做的是还原算法,倒着走。
        while ( input[v15] == v16 );
      }

0x03 C语言代码还原算法

Part I:

#include <stdio.h>
#include <stdlib.h>
void swap(char *p,char *q){
	char temp = *p;
	*p = *q;
	*q = temp;
}
int getLength(char *p){
	int len = 0;
	while((*p) != '\0'){
		len++;
		p++;
	}
	return len;
}
int main(){
	char str[] = "S!@#@1FD23154A34";
	int length = getLength(str);
	for(int j=14; j>0;j=j-2){                  //最外层需要总循环次数,倒着来,即14、13...
		if(length>4){
			for(int i=12;i>1;i=i-4){   //内层循环交换,12和8、8和4、4和0
				swap(&str[i-4],&str[i]);
			}
		}
		swap(&str[j-1],&str[j-2]);
	}

	printf("%s\n",str);
	system("pause");
}
跑出真码{!@#@ASDF34511234}

Part II:测试成功截图


0x04总结

在native层保护加密的代码,能起到一定的保护。用IDA分析伪代码可以为我们提供算法的逻辑,以此可以构造还原的算法。

安卓逆向,我在路上!2018年3月11日 21:18:39

参考网址:http://blog.csdn.net/Magic1an/article/details/77418294
              https://www.52pojie.cn/thread-602744-1-1.html

猜你喜欢

转载自blog.csdn.net/guchenjun789/article/details/79519358