安卓註冊機

2016Tencent初賽Android移動端

1.java層

java層沒有什麼特殊的地方,so層返回一個參數爲0,或1,執行Toast
進入libCheckRegister.so

2.so層

在這裏插入圖片描述
在這裏插入圖片描述
分析發現so層是將name進行加密,並和pass非標準的base64解密後的結果進行比較,table爲

private static byte[] table = {
	0x2B, 0x04, 0x7E, 0xBA, 0x77, 0xD6, 0x26, 0xE1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0C, 0x7D, 0x40,
	0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,
	0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,
	0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x3E, 0x40, 0x40, 0x40, 0x3F, 0x34,
	0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,
	0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
	0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,
	0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29,
	0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, 0x30, 0x31, 0x32, 0x33, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,
	0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,
	0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,
	0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,
	0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,
	0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,
	0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,
	0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,
	0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x41,
	0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x50, 0x51,
	0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
	0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,
	0x78, 0x79, 0x7A, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x2B, 0x2F, 0x00
};

通過

while ( (unsigned __int8)encodeTable[(unsigned __int8)*(pPass - 1)] <= 0x3Fu );

取出表中的有用的值,然後進行如下的變換

finalPass[4]+finalName[0]==finalPass[2]
finalName[0]+finalName[1]==finalPass[4]
finalName[2]+finalPass[3]==finalPass[0]
finalName[2]+finalName[3]==finalPass[3]
finalName[4]+finalPass[1]-3finalName[2]<=0
由finalName–>finalPass
finalPass[4]==finalName[0]+finalName[1]
finalPass[2]==finalName[0]+finalPass[4]
finalPass[3]==finalName[4]+finalName[3]
finalPass[0]==finalName[2]+finalPass[3]
finalPass[1]<=3
finalName[2]-finalName[4]
finalPass由pass經過base64decode得到
finalName ->某種變換

3.根據上述分析編寫腳本

最後編寫解密腳本
ctfdecrypt.java

import java.util.Scanner;

public class ctfdecrypt {
   private static byte[] name = null;
   private String code = null;
   private static int[] nameCrypt1 = null;
   private static int[] nameCrypt2 = null;
   private static int[]  codeCrypt1 = null;
   private static byte[] codeCrypt2 = null;
   private byte[] resByte = null;

   private static byte[] table = {0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x3E,0x40,0x40,0x40,0x3F,0x34,0x35,0x36,0x37,0x38,0x39,0x3A,0x3B,0x3C,0x3D,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0,1,2,3,4,5,6,7,8,9,0xA,0xB,0xC,0xD,0xE,0xF,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x40,0x40,0x40,0x40,0x40,0x40,0x1A,0x1B,0x1C,0x1D,0x1E,0x1F,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2A,0x2B,0x2C,0x2D,0x2E,0x2F,0x30,0x31,0x32,0x33,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40};

   public ctfdecrypt(String n) throws Exception{
       this.name = n.getBytes();

       if (this.name.length < 6 || this.name.length > 20) {
       	System.out.println("請輸入6-20的長度");
           throw new Exception();
       }

       nameCrypt1 = new int[23];
       nameCrypt2 = new int[5];
        codeCrypt1 = new int[5];
       resByte = new byte[50];
       codeCrypt2 = new byte[30];
   }

   public static void namedecode() {
       int tmp = 0;

       int i = 0, j = 0;
       for (; i < 16; i++, j = i % name.length) {
       	nameCrypt1[i] = ((name[j] * (0x1339e7e + i) * name.length) + tmp) & 0x0ff;
           tmp = (((name[j] * (0x1339e7e + i) * name.length) + tmp) >> 0x8) & 0x00ffffff;
       }

       nameCrypt1[i++] = tmp & 0x0ff;
       nameCrypt1[i++] = (tmp & 0x0ff00) >> 8;
       nameCrypt1[i++] = (tmp & 0x0ff0000) >> 16;

       for (i = 0; i < 5; i++) {
           nameCrypt2[i] = nameCrypt1[i * 4 + 3];
           nameCrypt2[i] = nameCrypt2[i] << 8 | nameCrypt1[i * 4 + 2];
           nameCrypt2[i] = nameCrypt2[i] << 8 | nameCrypt1[i * 4 + 1];
           nameCrypt2[i] = nameCrypt2[i] << 8 |nameCrypt1[i * 4];
       }

       for (i = 0; i < 5; i++) {
           nameCrypt2[i] = nameCrypt2[i] / 10;
       }
   }

   public static String getCode() {
       StringBuilder sb = new StringBuilder();

        codeCrypt1[3] = nameCrypt2[2] + nameCrypt2[3];
        codeCrypt1[0] =  codeCrypt1[3] + nameCrypt2[2];

        codeCrypt1[1] = 3 * nameCrypt2[2] - nameCrypt2[4];

        codeCrypt1[4] = nameCrypt2[0] + nameCrypt2[1];
        codeCrypt1[2] =  codeCrypt1[4] + nameCrypt2[0];


       for (int i = 0; i < 5; i++) {
            codeCrypt2[i * 4] = (byte) ( codeCrypt1[i] & 0x0ff);
           codeCrypt2[i * 4 + 1] = (byte) (( codeCrypt1[i] >> 8) & 0x0ff);
           codeCrypt2[i * 4 + 2] = (byte) (( codeCrypt1[i] >> 16) & 0x0ff);
           codeCrypt2[i * 4 + 3] = (byte) (( codeCrypt1[i] >> 24) & 0x0ff);
       }

       for (int i = 0; i <= 6; i++) {
           byte tmp = 0;

           if (i == 6) {
               tmp = (byte) ((codeCrypt2[i * 3] & 0x0ff) >> 2);
               sb.append((char)  SearchTable(tmp));
               tmp = (byte) (((codeCrypt2[i * 3] & 0x03) << 4) | ((codeCrypt2[i * 3 + 1] >> 4)) & 0x0f);
               sb.append((char)  SearchTable(tmp));
               tmp = (byte) (((codeCrypt2[i * 3 + 1] & 0xf) << 2) | ((codeCrypt2[i * 3 + 2] & 0x0ff) >> 6));
               sb.append((char)  SearchTable(tmp));
           } else {
               tmp = (byte) ((codeCrypt2[i * 3] & 0x0ff) >> 2);
               sb.append((char) SearchTable(tmp));
               tmp = (byte) (((codeCrypt2[i * 3] & 0x03) << 4) | ((codeCrypt2[i * 3 + 1] >> 4)) & 0x0f);
               sb.append((char)  SearchTable(tmp));
               tmp = (byte) (((codeCrypt2[i * 3 + 1] & 0xf) << 2) | ((codeCrypt2[i * 3 + 2] & 0x0ff) >> 6));
               sb.append((char)  SearchTable(tmp));
               tmp = (byte) (codeCrypt2[i * 3 + 2] & 0x3f);
               sb.append((char)  SearchTable(tmp));
           }
       }
       return sb.toString();
   }

   private static int SearchTable(byte content) {
       for (int i = 0; i < 256; i++) {
           if (table[i] == content) {
               return i;
           } else {
               continue;
           }
       }

       return -1;
   }
   


}

Main.java

import java.util.Scanner;

public class Main {
   public static void main(String[] args) throws Exception {
   	
   	Scanner scanner =new Scanner(System.in);
   	System.out.println("請輸入姓名:");
   	String name=scanner.next();
   	ctfdecrypt c=new ctfdecrypt(name);
   	c.namedecode();
   	System.out.println("那麼密碼爲:"+c.getCode());
   	
   	
   }
}
![在這裏插入圖片描述](https://img-blog.csdnimg.cn/20191218131204553.png)

這裏的腳本採用的是java,最開始打算使用C++來編寫的,但是無奈太菜,日後有時間在補上

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章