日系卡牌遊戲都很熱啊,這貨下載量據說有500w+了
而且……日本的工程師似乎寫代碼的時候連類的名字都會取得差不多,非常方便。因此寫篇文章,也許會對以後的或現有的(?)遊戲破解帶來一點靈感。
no bullshit let’s begin XD
JAVA層
dex2jar搞一下,得到一個jar,jd-gui瀏覽jar可以定位加密類位於jp.colopl/util/Crypto.class中,代碼片段如下:
以及
從一個native method返回了SecretKeySpec對象。看來東西都在so里了
native層
IDA靜態分析libcryptograph.so和libgetlockey.so,getlockey里沒有JNI_load入口,跳過;在cryptograph里發現了名為Java_jp_colopl_util_Crypto_getKeySpec的導出@0x00000BD8 。就是它了XD,粘貼如下(沒有arm彙編高亮殘念了- -)
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 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 |
.text:00000BD8 EXPORT Java_jp_colopl_util_Crypto_getKeySpec .text:00000BD8 Java_jp_colopl_util_Crypto_getKeySpec .text:00000BD8 .text:00000BD8 var_28 = -0x28 .text:00000BD8 var_1C = -0x1C .text:00000BD8 .text:00000BD8 PUSH {R4-R7,LR} .text:00000BDA LDR R2, [R0] .text:00000BDC LDR R1, =(unk_21FC - 0xBEA) .text:00000BDE MOVS R3, 0x29C .text:00000BE2 SUB SP, SP, #0x14 .text:00000BE4 LDR R3, [R2,R3] .text:00000BE6 ADD R1, PC .text:00000BE8 MOVS R5, R0 .text:00000BEA BLX R3 .text:00000BEC MOVS R2, R0 .text:00000BEE STR R0, [SP,#0x28+var_1C] .text:00000BF0 CMP R0, #0 .text:00000BF2 BEQ loc_CD8 .text:00000BF4 LDR R2, [R5] .text:00000BF6 MOVS R3, 0x2C0 .text:00000BFA LDR R3, [R2,R3] .text:00000BFC MOVS R0, R5 .text:00000BFE MOVS R1, #0x20 .text:00000C00 BLX R3 .text:00000C02 MOVS R2, R0 .text:00000C04 SUBS R7, R0, #0 .text:00000C06 BEQ loc_CD8 .text:00000C08 LDR R1, [R5] .text:00000C0A MOVS R3, 0x2E0 .text:00000C0E LDR R3, [R1,R3] .text:00000C10 MOVS R0, R5 .text:00000C12 MOVS R1, R2 .text:00000C14 MOVS R2, #0 .text:00000C16 BLX R3 .text:00000C18 SUBS R2, R0, #0 .text:00000C1A BEQ loc_CD8 .text:00000C1C MOVS R3, #0x30 .text:00000C1E STRB R3, [R2] .text:00000C20 MOVS R3, #0x6C .text:00000C22 STRB R3, [R2,#1] .text:00000C24 MOVS R3, #0x71 .text:00000C26 STRB R3, [R2,#2] .text:00000C28 MOVS R1, #0x66 .text:00000C2A MOVS R3, #0x47 .text:00000C2C STRB R3, [R2,#3] .text:00000C2E STRB R1, [R2,#6] .text:00000C30 MOVS R3, #0x54 .text:00000C32 MOVS R1, #0x4B .text:00000C34 STRB R3, [R2,#4] .text:00000C36 STRB R1, [R2,#8] .text:00000C38 MOVS R3, #0x79 .text:00000C3A MOVS R1, #0x39 .text:00000C3C STRB R3, [R2,#5] .text:00000C3E STRB R3, [R2,#7] .text:00000C40 STRB R1, [R2,#9] .text:00000C42 STRB R3, [R2,#0x17] .text:00000C44 MOVS R1, #0x49 .text:00000C46 MOVS R3, #0x77 .text:00000C48 STRB R1, [R2,#0xA] .text:00000C4A STRB R3, [R2,#0x18] .text:00000C4C MOVS R1, #0x32 .text:00000C4E MOVS R3, #0x48 .text:00000C50 STRB R1, [R2,#0xB] .text:00000C52 STRB R3, [R2,#0x19] .text:00000C54 MOVS R1, #0x6B .text:00000C56 MOVS R3, #0x4C .text:00000C58 STRB R1, [R2,#0xC] .text:00000C5A STRB R3, [R2,#0x1A] .text:00000C5C MOVS R1, #0x76 .text:00000C5E MOVS R3, #0x62 .text:00000C60 MOVS R0, #0x35 .text:00000C62 MOVS R4, #0x57 .text:00000C64 STRB R1, [R2,#0xD] .text:00000C66 STRB R0, [R2,#0xE] .text:00000C68 STRB R4, [R2,#0x11] .text:00000C6A STRB R1, [R2,#0x15] .text:00000C6C STRB R3, [R2,#0x1B] .text:00000C6E STRB R3, [R2,#0x1D] .text:00000C70 MOVS R0, #0x2E .text:00000C72 MOVS R4, #0x6E .text:00000C74 MOVS R1, #0x63 .text:00000C76 MOVS R3, #0x7A .text:00000C78 STRB R0, [R2,#0xF] .text:00000C7A STRB R4, [R2,#0x12] .text:00000C7C STRB R1, [R2,#0x16] .text:00000C7E STRB R3, [R2,#0x1E] .text:00000C80 MOVS R0, #0x59 .text:00000C82 MOVS R4, #0x53 .text:00000C84 MOVS R1, #0x5A .text:00000C86 MOVS R3, #0x4A .text:00000C88 STRB R0, [R2,#0x10] .text:00000C8A STRB R0, [R2,#0x14] .text:00000C8C STRB R3, [R2,#0x1F] .text:00000C8E STRB R4, [R2,#0x13] .text:00000C90 STRB R1, [R2,#0x1C] .text:00000C92 LDR R1, [R5] .text:00000C94 MOVS R3, 0x300 .text:00000C98 LDR R4, [R1,R3] .text:00000C9A MOVS R0, R5 .text:00000C9C MOVS R1, R7 .text:00000C9E MOVS R3, #0 .text:00000CA0 BLX R4 .text:00000CA2 LDR R3, [R5] .text:00000CA4 LDR R1, =(aJavaxCryptoSpe - 0xCAE) .text:00000CA6 MOVS R0, R5 .text:00000CA8 LDR R3, [R3,#0x18] .text:00000CAA ADD R1, PC ; "javax/crypto/spec/SecretKeySpec" .text:00000CAC BLX R3 .text:00000CAE LDR R1, [R5] .text:00000CB0 LDR R2, =(aInit - 0xCBE) .text:00000CB2 LDR R3, =(aBljavaLangStri - 0xCC0) .text:00000CB4 MOVS R6, R0 .text:00000CB6 ADDS R1, #8 .text:00000CB8 LDR R4, [R1,#0x7C] .text:00000CBA ADD R2, PC ; "<init>" .text:00000CBC ADD R3, PC ; "([BLjava/lang/String;)V" .text:00000CBE MOVS R1, R6 .text:00000CC0 MOVS R0, R5 .text:00000CC2 BLX R4 .text:00000CC4 LDR R1, [SP,#0x28+var_1C] .text:00000CC6 LDR R3, [R5] .text:00000CC8 MOVS R2, R0 .text:00000CCA STR R1, [SP,#0x28+var_28] .text:00000CCC LDR R4, [R3,#0x70] .text:00000CCE MOVS R0, R5 .text:00000CD0 MOVS R1, R6 .text:00000CD2 MOVS R3, R7 .text:00000CD4 BLX R4 .text:00000CD6 ADDS R2, R0, #0 .text:00000CD8 .text:00000CD8 loc_CD8 ; CODE XREF: Java_jp_colopl_util_Crypto_getKeySpec+1Aj .text:00000CD8 ; Java_jp_colopl_util_Crypto_getKeySpec+2Ej ... .text:00000CD8 ADD SP, SP, #0x14 .text:00000CDA MOVS R0, R2 .text:00000CDC POP {R4-R7,PC} .text:00000CDC ; End of function Java_jp_colopl_util_Crypto_getKeySpec |
掰彎xx王的製作團隊你們好好看看啊,這才像點樣啊好么,把AES密鑰明文存儲在so裡面和沒加密有個毛線差別啊摔!
(╯‵□′)╯︵┻━┻
瀏覽了下這段代碼之後發現,大概是在這裡調用了javax.crypto.spec.SecretKeySpec構造方法返回了SecretKeySpec對象。由於AES密鑰長度只能是16的整數倍,於是找到0x00000C8C 處的
1 |
.text:00000C8C STRB R3, [R2,#0x1F] |
1Fh=32d,想到這可能是生成一個32位key的過程,往上找,應該就是00000C1E到00000C90 這部分的代碼了;主要邏輯是,
1 2 |
.text:00000C24 MOVS R3, #0x71 ;R3賦值asc碼為0x71的字符,即'q' .text:00000C26 STRB R3, [R2,#2] ;'q'放到R2的第三位 |
python腳本多快好省
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
import sys _this = sys.modules[__name__] lines=asm.split('\n') #asm即上面那一坨彙編偽代碼 aeskey=[[]]*32#R2 for l in lines: print l l=l[31:].split(' ') cmd,opt,dst=l[0],l[-2],l[-1] if cmd=='MOVS': setattr(_this,opt,chr(int(dst[3:],16))) if cmd=='STRB': if ',' not in dst: off=0 else: off=dst[1:-1].split(',')[1] off=int(off[1:],16) aeskey[off]=getattr(_this,opt) print ''.join(aeskey) |
得到0lqGTyfyK9I2kv5.YWnSYvcywHLbZbzJ,沒試過,不知道對不對
done
然後……?
試了一下抓包然後解密,但似乎沒有padding,嘛,不管了,反正對這個遊戲不是很感興趣,霓虹語略捉急ww
(不過所有問題的題乾和答案都會在遇到妖怪的時候一起下載好,要做外掛的話應該很方便呢233
PS
java中使用>16字節(>128bit)的AES key會被認為是欠抽的做法,從這裡下載安裝無限密鑰長度策略並覆蓋原JAVA_HOME/lib/security下的文件即可
po主技術逆天啊,彙編完全不懂……敢問po主大學主修?
嘛……通信
順便學習下arm指令集arm
from: 白貓Project/白貓プロジェクト ; 論野生技術&二次元