2019ISCC Mobile

0x01 Mobile1

用Android killer載入找到入口函數(shù)

package com.iscc.crackme;

import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;

public class MainActivity
  extends AppCompatActivity
{
  static
  {
    System.loadLibrary("native-lib");
  }
  
  private boolean checkFirst(String paramString)
  {
    if (paramString.length() != 16) {
      return false;
    }
    int i = 0;
    while (i < paramString.length()) {
      if (paramString.charAt(i) <= '8')
      {
        if (paramString.charAt(i) < '1') {
          return false;
        }
        i += 1;
      }
      else
      {
        return false;
      }
    }
    return true;
  }
  
  public native boolean checkSecond(String paramString);
  
  protected void onCreate(final Bundle paramBundle)
  {
    super.onCreate(paramBundle);
    setContentView(2131296284);
    paramBundle = (EditText)findViewById(2131165240);
    ((Button)findViewById(2131165218)).setOnClickListener(new View.OnClickListener()
    {
      public void onClick(View paramAnonymousView)
      {
        paramAnonymousView = paramBundle.getText().toString().trim();
        if ((MainActivity.this.checkFirst(paramAnonymousView)) && (MainActivity.this.checkSecond(paramAnonymousView)))
        {
          Toast.makeText(MainActivity.this, "注冊(cè)成功!", 0).show();
          return;
        }
        Toast.makeText(MainActivity.this, "注冊(cè)失敗!", 0).show();
      }
    });
  }
}

代碼非常簡(jiǎn)單,對(duì)注冊(cè)碼進(jìn)行兩次check毁嗦,第一次check是

  private boolean checkFirst(String paramString)
  {
    if (paramString.length() != 16) {
      return false;
    }
    int i = 0;
    while (i < paramString.length()) {
      if (paramString.charAt(i) <= '8')
      {
        if (paramString.charAt(i) < '1') {
          return false;
        }
        i += 1;
      }
      else
      {
        return false;
      }
    }
    return true;
  }
  

功能是check注冊(cè)碼是否為16位,以及注冊(cè)碼是否為1~8的數(shù)字組合
第二個(gè)check函數(shù)在native層,分析so文件

 public native boolean checkSecond(String paramString);

用ida64載入64位的so文件,觀察入口函數(shù)偽代碼

char __fastcall Java_com_iscc_crackme_MainActivity_checkSecond(__int64 a1, __int64 a2, __int64 a3)
{
  char result; // al
  char v4; // [rsp+6h] [rbp-8Ah]
  char v5; // [rsp+13h] [rbp-7Dh]
  char v6; // [rsp+40h] [rbp-50h]
  char v7; // [rsp+58h] [rbp-38h]
  char v8; // [rsp+70h] [rbp-20h]
  unsigned __int64 v9; // [rsp+88h] [rbp-8h]

  v9 = __readfsqword(0x28u);
  jstring2str(&v8, a1, a3);
  v5 = 0;
  std::__ndk1::basic_string<char,std::__ndk1::char_traits<char>,std::__ndk1::allocator<char>>::basic_string(&v7, &v8);
  v4 = 0;
  if ( checkfirst((__int64)&v7) & 1 )
  {
    std::__ndk1::basic_string<char,std::__ndk1::char_traits<char>,std::__ndk1::allocator<char>>::basic_string(&v6, &v8);
    v5 = 1;
    v4 = checkAgain(&v6);
  }
  if ( v5 & 1 )
    std::__ndk1::basic_string<char,std::__ndk1::char_traits<char>,std::__ndk1::allocator<char>>::~basic_string(&v6);
  std::__ndk1::basic_string<char,std::__ndk1::char_traits<char>,std::__ndk1::allocator<char>>::~basic_string(&v7);
  std::__ndk1::basic_string<char,std::__ndk1::char_traits<char>,std::__ndk1::allocator<char>>::~basic_string(&v8);
  result = v4 & 1;
  if ( __readfsqword(0x28u) == v9 )
    result = v4 & 1;
  return result;
}

發(fā)現(xiàn)也進(jìn)行了兩次check分別是checkfirst 以及 checkAgain,所以只要過了這兩個(gè)check就完事了
值得注意的是jstring2str函數(shù)是將輸入轉(zhuǎn)換為字節(jié)數(shù)組
觀察checkfirst函數(shù)

__int64 __fastcall checkfirst(__int64 a1)
{
  signed __int64 v2; // [rsp+0h] [rbp-118h]
  signed __int64 v3; // [rsp+18h] [rbp-100h]
  signed int i; // [rsp+30h] [rbp-E8h]
  char v5; // [rsp+37h] [rbp-E1h]

  for ( i = 1; i < 8; ++i )
  {
    if ( *(_BYTE *)a1 & 1 )
      v3 = *(_QWORD *)(a1 + 16);
    else
      v3 = a1 + 1;
    if ( *(_BYTE *)a1 & 1 )
      v2 = *(_QWORD *)(a1 + 16);
    else
      v2 = a1 + 1;
    if ( *(char *)(v3 + i) <= *(char *)(v2 + i - 1) )// 升序
    {
      v5 = 0;
      return v5 & 1;
    }
  }
  v5 = 1;
  return v5 & 1;
}

關(guān)鍵代碼是

 if ( *(char *)(v3 + i) <= *(char *)(v2 + i - 1) )// 升序

由于輸入只有16位姥宝,由此我們可以大膽猜測(cè)*(_BYTE *)a1 & 1的值為0

check first
*flag&1==0 && *(flag+i) > *f(lag+i-1) (1<=i<=7) 即前八位為 1 2 3 4 5 6 7 8 

故可以得到注冊(cè)碼前八位是升序的又因注冊(cè)碼是1~8所以可以得到注冊(cè)碼為
12345678********
進(jìn)入checkAgain函數(shù)

char __fastcall checkAgain(__int64 a1)
{
  char result; // al
  signed __int64 v2; // [rsp+10h] [rbp-170h]
  signed __int64 v3; // [rsp+20h] [rbp-160h]
  signed int l; // [rsp+3Ch] [rbp-144h]
  signed int k; // [rsp+40h] [rbp-140h]
  int j; // [rsp+44h] [rbp-13Ch]
  signed int i; // [rsp+48h] [rbp-138h]
  char v8; // [rsp+4Fh] [rbp-131h]
  int v9; // [rsp+130h] [rbp-50h]
  int v10; // [rsp+134h] [rbp-4Ch]
  int v11; // [rsp+148h] [rbp-38h]
  int v12; // [rsp+14Ch] [rbp-34h]
  int v13[10]; // [rsp+150h] [rbp-30h]
  unsigned __int64 v14; // [rsp+178h] [rbp-8h]

  v14 = __readfsqword(0x28u);
  for ( i = 0; i < 8; ++i )
  {
    if ( *(_BYTE *)a1 & 1 )
      v3 = *(_QWORD *)(a1 + 16);
    else
      v3 = a1 + 1;
    v13[i] = *(char *)(v3 + i) - 49;
  }
  for ( j = 0; j < 8; ++j )
  {
    if ( *(_BYTE *)a1 & 1 )
      v2 = *(_QWORD *)(a1 + 16);
    else
      v2 = a1 + 1;
    *(&v9 + j) = *(char *)(v2 + j + 8) - 49;
  }
  if ( v12 + v9 == 5 )
  {
    if ( v11 + v10 == 12 )
    {
      if ( v9 < v12 )
      {
        for ( k = 1; k < 8; ++k )
        {
          for ( l = 0; l < k; ++l )
          {
            if ( v13[l] == v13[k] )
            {
              v8 = 0;
              goto LABEL_34;
            }
            if ( *(&v9 + l) == *(&v9 + k) )
            {
              v8 = 0;
              goto LABEL_34;
            }
            if ( v13[k] - v13[l] == *(&v9 + k) - *(&v9 + l) )
            {
              v8 = 0;
              goto LABEL_34;
            }
            if ( v13[k] - v13[l] == *(&v9 + l) - *(&v9 + k) )
            {
              v8 = 0;
              goto LABEL_34;
            }
          }
        }
        v8 = 1;
      }
      else
      {
        v8 = 0;
      }
    }
    else
    {
      v8 = 0;
    }
  }
  else
  {
    v8 = 0;
  }
LABEL_34:
  result = v8;
  if ( __readfsqword(0x28u) == v14 )
    result = v8 & 1;
  return result;
}

代碼頗長翅萤,逐步分析
check主要進(jìn)行以下功能

check again
i -> range(0,8)
(int)v13[i] = *(flag+i) - 49  
(int)v9[i] = *(flag+i) - 49
v9[7] + v9[0] == 5 && v9[6] + v9[1] == 12 && v9[0] < v9[7]
for k in range(1,8)
    for l in range(0,k)
        v13[l] != v13[k]
        v9[l] != v9[k]
        v13[k] - v13[l] != abs(v9[k] - v9[l])

易得注冊(cè)碼后八位也是不相同的
對(duì)v9[7] + v9[0] == 5 && v9[6] + v9[1] == 12 && v9[0] < v9[7]結(jié)合
v13[k] - v13[l] != abs(v9[k] - v9[l])可以約束求解注冊(cè)碼后八位
最終解得注冊(cè)碼為 1234567836275184

Screenshot_2019-05-09-19-46-51.png

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子套么,更是在濱河造成了極大的恐慌培己,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,509評(píng)論 6 504
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件胚泌,死亡現(xiàn)場(chǎng)離奇詭異省咨,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)玷室,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,806評(píng)論 3 394
  • 文/潘曉璐 我一進(jìn)店門零蓉,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人穷缤,你說我怎么就攤上這事敌蜂。” “怎么了津肛?”我有些...
    開封第一講書人閱讀 163,875評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵章喉,是天一觀的道長。 經(jīng)常有香客問我身坐,道長秸脱,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,441評(píng)論 1 293
  • 正文 為了忘掉前任部蛇,我火速辦了婚禮摊唇,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘搪花。我一直安慰自己遏片,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,488評(píng)論 6 392
  • 文/花漫 我一把揭開白布撮竿。 她就那樣靜靜地躺著吮便,像睡著了一般。 火紅的嫁衣襯著肌膚如雪幢踏。 梳的紋絲不亂的頭發(fā)上髓需,一...
    開封第一講書人閱讀 51,365評(píng)論 1 302
  • 那天,我揣著相機(jī)與錄音房蝉,去河邊找鬼僚匆。 笑死,一個(gè)胖子當(dāng)著我的面吹牛搭幻,可吹牛的內(nèi)容都是我干的咧擂。 我是一名探鬼主播,決...
    沈念sama閱讀 40,190評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼檀蹋,長吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼松申!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,062評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤贸桶,失蹤者是張志新(化名)和其女友劉穎舅逸,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體皇筛,經(jīng)...
    沈念sama閱讀 45,500評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡琉历,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,706評(píng)論 3 335
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了水醋。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片旗笔。...
    茶點(diǎn)故事閱讀 39,834評(píng)論 1 347
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖离例,靈堂內(nèi)的尸體忽然破棺而出换团,到底是詐尸還是另有隱情,我是刑警寧澤宫蛆,帶...
    沈念sama閱讀 35,559評(píng)論 5 345
  • 正文 年R本政府宣布艘包,位于F島的核電站,受9級(jí)特大地震影響耀盗,放射性物質(zhì)發(fā)生泄漏想虎。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,167評(píng)論 3 328
  • 文/蒙蒙 一叛拷、第九天 我趴在偏房一處隱蔽的房頂上張望舌厨。 院中可真熱鬧,春花似錦忿薇、人聲如沸裙椭。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,779評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽揉燃。三九已至,卻和暖如春筋栋,著一層夾襖步出監(jiān)牢的瞬間炊汤,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,912評(píng)論 1 269
  • 我被黑心中介騙來泰國打工弊攘, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留抢腐,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 47,958評(píng)論 2 370
  • 正文 我出身青樓襟交,卻偏偏與公主長得像迈倍,于是被迫代替她去往敵國和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子捣域,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,779評(píng)論 2 354

推薦閱讀更多精彩內(nèi)容