Reverse 
Rustdroid 
Java层智能看到调用了Native层的Check
看看SO,是个Rust,大体看一下是 RC4
这里先判断flag长度是否为43,和是否以WMCTF{}包裹
这里是rc4的S盒,可以动调或者直接模拟拿到S盒,fun@eZ是RC4的key
这里是单字节位移加密,同时还有给RC4加了一个异或
异或的值
单字节位移加密逻辑如下
1 2 3 4 5 6 7 8 9 10 def  ROR (value, shift, bits=8  ):    return  ((value >> shift) | (value << (bits - shift))) & ((1  << bits) - 1 ) def  rotate_enc (x ):    x = ROR(x, 1 ) ^ 0xef        x = ROR(x, 2 ) ^ 0xbe        x = ROR(x, 3 ) ^ 0xad        x = ROR(x, 4 ) ^ 0xde        x = ROR(x, 5 )             return  x 
这里再记录一下SO的调试方法
先 adb 连接一下模拟器
需要先把ida服务push到模拟器
1 adb push D:\CTF\RE\IDA_Pro_7.7\dbgsrv\android_server64(ida安装路径) /data/local/tmp/android_server64 
然后连接
1 2 3 4 5 adb shell su cd /data/tmp/local chmod 777 android_server64 ./android_server64 
再开个命令行转发一下端口
1 adb forward tcp:23946 tcp:23946 
选择Remote Android debugger
然后Debugger里选择Attach to process,找到对应的包名进行附加
exp 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 from  struct import  packdef  ROR (value, shift, bits=8  ):    return  ((value >> shift) | (value << (bits - shift))) & ((1  << bits) - 1 ) def  rotate_enc (x ):    x = ROR(x, 1 ) ^ 0xef        x = ROR(x, 2 ) ^ 0xbe        x = ROR(x, 3 ) ^ 0xad        x = ROR(x, 4 ) ^ 0xde        x = ROR(x, 5 )             return  x data = [0x4E4FCE594215BA1F , 0xC745BAE69BFD994 , 0x87081E9C7F8AFCC0 , 0x2BB08F87F5646BF5 ] enc = [] for  i in  data:    enc += list (pack("<Q" , i)) enc += list (pack("<I" ,0x29FF53E2 )) key = [0x66 , 0x75 , 0x6E , 0x40 , 0x65 , 0x5A ] xor_table = [0x77 , 0x88 , 0x99 , 0x66 ] def  rc4 (key, data ):    key_length = len (key)     s = list (range (256 ))     j = 0      for  i in  range (256 ):         j = (j + s[i] + key[i % key_length]) % 256          s[i], s[j] = s[j], s[i]     res = []     i = j = 0      for  index, val in  enumerate (data):         i = (i + 1 ) % 256          j = (j + s[i]) % 256          s[i], s[j] = s[j], s[i]         k = s[(s[i] + s[j]) % 256 ]         res.append(val ^ k ^ xor_table[index % 4 ])     return  res decrypted_data = rc4(key, enc) flag = "WMCTF{"  for  i in  range (36 ):    for  j in  range (30 , 128 ):         if  rotate_enc(j) == decrypted_data[i]:             flag += chr (j)             break  flag += "}"  print (flag)
re1 
先Jadx看看,应该是有Hook
看看so
这里对几个函数memcmp、strlen、printf、strftime、scanf、fgetws进行了Hook
checkYourFlag是假逻辑
在JNI_Onload可以找到真正的加密逻辑
真正的在sub_F430
进入sub_F430就可以动调跟踪被Hook的函数
strlen对输入进行了异或
printf、scanf、strftime、fgetws实现了xtea
密文
exp 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 #include  <stdio.h>  #include  <stdint.h>  void  decipher (unsigned  int  num_rounds, uint32_t  v[2 ], uint32_t  const  key[4 ])      unsigned  int  i;     uint32_t  v0 = v[0 ], v1 = v[1 ], delta = 0xfa11010d , sum = delta * num_rounds;     for  (i = 0 ; i < num_rounds; i++) {         v1 -= (((v0 << 6 ) ^ (v0 >> 6 )) + v0) ^ (sum + key[(unsigned  char )sum >> 6 ]);         sum -= delta;         v0 -= (((v1 << 6 ) ^ (v1 >> 6 )) + v1) ^ (sum + key[sum & 3 ]);     }     v[0 ] = v0; v[1 ] = v1; } int  main ()      uint32_t  enc[] = { 0xEFC05FD2 , 0x9378625E , 0x841F41A0  , 0x6D05F4A  , 0xDC898F9A  ,0x21AA7CFC  ,0x4229FB0B  ,0x31E52B8B  };     uint32_t  key[4 ] = { 0xffffffff , 0xaaaaaaaa , 0x11111111 , 0x11111111  };     for (int  i=0 ; i<8 ; i+=2 ){         decipher (66 , &enc[i], key);     }     for  (int  i = 0 ; i < 32 ; i++) {         printf ("%c" , (*((char *)enc + i) ^ 0x5A  ^ i));     } } #WMCTF{b86d69bbeedeccb9257782534}