首页
社区
课程
招聘
[原创]挑战赛解题思路
发表于: 2015-1-26 18:17 3763

[原创]挑战赛解题思路

2015-1-26 18:17
3763
第一题:
解法一:反编译后,在MainActivity里找到如下代码:
        String str1 = localEditText.getText().toString();
        String str2 = MainActivity.this.getTableFromPic();
        String str3 = MainActivity.this.getPwdFromPic();
        Log.i("lil", "table:" + str2);
        Log.i("lil", "pw:" + str3);
        String str4 = "";
        try
        {
          str4 = MainActivity.bytesToAliSmsCode(str2, str1.getBytes("utf-8"));
          Log.i("lil", "enPassword:" + str4);
          if ((str3 != null) && (!str3.equals("")) && (str3.equals(str4)))
          {
            MainActivity.this.showDialog();
            return;
          }

可知有四个字符串,str1为输入,str2从getTableFromPic()得到,str3从getPwdFromPic()得到,str4由bytesToAliSmsCode(str2, str1.getBytes("utf-8"))得到,如果str3与str4相同,则验证通过。通过逆向以上三个方法得知,str2从assets文件夹中的logo.png图片的0x15d81位置处获取0x300字节数据,作为字符串返回,str3从0x16481地址处获取0x12字节数据,作为字符串返回,bytesToAliSmsCode将str2作为表,str1每字符的ASCII值作为下标,取表中由str1映射的字符出来,组成新的字符串返回,与str4比较。因此可根据str4编写解密器,调用indexof方法在str2表中寻找str4每一个字符,记录其下标,将下标作为ASCII码转换成字符串返回,即为flag。这个解密方法在题目中已提供:
  
private static byte[] aliCodeToBytes(String paramString1, String paramString2)
  {
    byte[] arrayOfByte = new byte[paramString2.length()];
    for (int i = 0; ; i++)
    {
      if (i >= paramString2.length())
        return arrayOfByte;
      arrayOfByte[i] = ((byte)paramString1.indexOf(paramString2.charAt(i)));
    }
  }


解法二:
不逆向上述三个方法,观察到如下代码:
        Log.i("lil", "table:" + str2);
        Log.i("lil", "pw:" + str3);
        Log.i("lil", "enPassword:" + str4);

可知str2、str3与str4已用logcat打印出来,因此可以考虑用黑盒法猜测str1。
logcat打印str3结果如下:
pw:义弓么丸广之
根据题目描述,猜测答案是由数字组成,因此输入"0123456789",得到如下打印:
enPassword:丸么广亡门义之尸弓己
观察到pw打印的每一个字在enPassword里都存在,因此考虑数字与打印结果有一一对应关系,根据打印结果的排列,猜测答案为581026。
输入后得知破解成功。

第二题:
反编译看到如下:
 String str = MainActivity.this.inputCode.getText().toString();
        if (MainActivity.this.securityCheck(str))
        {
          Intent localIntent = new Intent(MainActivity.this, ResultActivity.class);
          MainActivity.this.startActivity(localIntent);
          return;
        }
        Toast.makeText(MainActivity.this.getApplicationContext(), "验证码校验失败", 0).show();
      }

得知调用securityCheck方法对输入的字符串进行校验,返回true则校验成功,该方法在libcrackme.so里,因此用ida对其逆向。
在逆向过程中发现了该方法,部分关键代码如下:
.text:000012A8 loc_12A8                                ; CODE XREF: Java_com_yaotong_crackme_MainActivity_securityCheck+120j
.text:000012A8                 LDRB    R3, [R2]
.text:000012AC                 LDRB    R1, [R0]
.text:000012B0                 CMP     R3, R1
.text:000012B4                 BNE     loc_12D0
.text:000012B8                 ADD     R2, R2, #1
.text:000012BC                 ADD     R0, R0, #1
.text:000012C0                 MOV     R1, #1
.text:000012C4                 CMP     R3, #0
.text:000012C8                 BNE     loc_12A8
.text:000012CC                 B       loc_12D4
.text:000012D0 ; ---------------------------------------------------------------------------
.text:000012D0
.text:000012D0 loc_12D0                                ; CODE XREF: Java_com_yaotong_crackme_MainActivity_securityCheck+10Cj
.text:000012D0                 MOV     R1, #0
.text:000012D4
.text:000012D4 loc_12D4                                ; CODE XREF: Java_com_yaotong_crackme_MainActivity_securityCheck+124j
.text:000012D4                 MOV     R0, R1
.text:000012D8                 ADD     SP, SP, #8
.text:000012DC                 LDMFD   SP!, {R4-R7,R11,PC}

可知程序用一个循环比较输入字符串与一个特定的字符串,如果相同则返回1,不相同则返回0。
逆向得知此字符串偏移量如下:
.data:0000628C off_628C        DCD aWojiushidaan

尝试输入wojiushidaan后破解失败,考虑可能程序在运行时动态修改了值,因此必须调试查看。
但程序存在Anti-code,开了一个线程用以检测本程序是否正在被调试,因此将其susppend,即可继续调试。
在调试过程中,找到此字符串为:
aiyou,bucuoo
输入后即破解成功。

[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)

收藏
免费 0
支持
分享
最新回复 (1)
雪    币: 163
活跃值: (1623)
能力值: ( LV5,RANK:60 )
在线值:
发帖
回帖
粉丝
2
但程序存在Anti-code,开了一个线程用以检测本程序是否正在被调试,因此将其susppend,即可继续调试。

如何挂起线程,IDA一附加,应用就退出了。
2015-2-4 14:46
0
游客
登录 | 注册 方可回帖
返回
//