XCTFmobile之easy-so write up

拖進模擬器是一個驗證框,我們直接上jeb:

調用本地方法public static native int CheckString(String arg0),若驗證一致返回1,否則返回0.

將apk重命名爲zip後解壓,在lib目錄將.so文件拖進IDA,找到函數CheckString,代碼如下:

_BOOL4 __cdecl Java_com_testjava_jack_pingan2_cyberpeace_CheckString(int a1, int a2, int a3)
{
  const char *v3; // ST1C_4
  size_t v4; // edi
  char *v5; // esi
  size_t v6; // edi
  char v7; // al
  char v8; // al
  size_t v9; // edi
  char v10; // al

  v3 = (const char *)(*(int (__cdecl **)(int, int, _DWORD))(*(_DWORD *)a1 + 676))(a1, a3, 0);
  v4 = strlen(v3);
  v5 = (char *)malloc(v4 + 1);
  memset(&v5[v4], 0, v4 != -1);
  memcpy(v5, v3, v4);
  if ( strlen(v5) >= 2 )
  {
    v6 = 0;
    do
    {
      v7 = v5[v6];
      v5[v6] = v5[v6 + 16];
      v5[v6++ + 16] = v7;
    }
    while ( v6 < strlen(v5) >> 1 );
  }
  v8 = *v5;
  if ( *v5 )
  {
    *v5 = v5[1];
    v5[1] = v8;
    if ( strlen(v5) >= 3 )
    {
      v9 = 2;
      do
      {
        v10 = v5[v9];
        v5[v9] = v5[v9 + 1];
        v5[v9 + 1] = v10;
        v9 += 2;
      }
      while ( v9 < strlen(v5) );
    }
  }
  return strcmp(v5, "f72c5a36569418a20907b55be5bf95ad") == 0;
}

我們大膽推測const char * v3是傳入的字符串,接下來逐個分析代碼邏輯:

v4 = strlen(v3);              //取變量v4=v3的字符串長度,假設v3="abcd",v4=4
v5 = (char *)malloc(v4 + 1);  //爲字符指針v5請求一塊長度爲v4+1的內存空間
memset(&v5[v4], 0, v4 != -1); //將v5擴增一倍並後面擴增的部分初始化爲0,此行代碼結束,v5=----0000
memcpy(v5, v3, v4);           //將v3的內容複製到v5中
if ( strlen(v5) >= 2 )        //若v5的長度大於等於2則執行花括號內的內容
  {
    v6 = 0;             //初始化v6=0
    do                  //執行循環
    {
      v7 = v5[v6];     //從第0個開始讀取v5的每個字符
      v5[v6] = v5[v6 + 16];   //逐個將v5的第v6個字符與第v6+16個字符交換位置
      v5[v6++ + 16] = v7;     //v6自增1
    }
    while ( v6 < strlen(v5) >> 1 );
  }

假設傳入字符串爲abcd,則上述代碼執行完之後的v5爲cdab

繼續分析接下來的代碼:

v8 = *v5;      //指針v8指向v5
  if ( *v5 )      //v5存在,執行花括號內的邏輯
  {   
    *v5 = v5[1];    
    v5[1] = v8;
    if ( strlen(v5) >= 3 ) //v5的長度大於等於3
    {
      v9 = 2;         //初始化v9=2
      do
      {
        v10 = v5[v9];   
        v5[v9] = v5[v9 + 1];
        v5[v9 + 1] = v10;
        v9 += 2;
      }
      while ( v9 < strlen(v5) );
    }
  }

這段代碼很簡單,就是兩兩交換。

根據上述我們直接手動得到flag的code:

1.將f72c5a36569418a20907b55be5bf95ad兩兩交換得到7fc2a5636549812a90705bb55efb59da

2.將7fc2a5636549812a90705bb55efb59da從中間砍斷,頭拼接到尾,得到90705bb55efb59da7fc2a5636549812a

3.加上flag{}就是flag。

 

發佈了112 篇原創文章 · 獲贊 35 · 訪問量 12萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章