記一個手游app數據文件的破解


出於一些非常猥瑣的須要,同一時候自己也想做一些新奇的嘗試,周末用了大半天時間破解了某款手游的數據文件。

過程比我預想的要順利,主要原因還是我們開發者的懈怠。咳咳。

步驟例如以下:

  • 下載安裝包,解壓,發現幾個XXX.db文件,最感興趣的是一個50多M的XXX.db
  • 用UltraEdit打開XXX.DB文件,沒有不論什么線索。僅僅發現這幾個文件有同樣的文件頭
  • 搜索.DB文件可能是什么文件。發現了開源庫sqlite,這是一個輕量級的數據庫組件,IOS就用了這個,頓時眼前一亮
  • 下載sqlite的命令行工具。發現打不開.DB文件
  • 自己存了一個sqlite的數據庫文件做測試,發現根本就是明文存儲的
  • 是時候祭出神器IDA pro了。反匯編libXXX.so,發現大量sqlite3_XXX函數,.db文件應該是sqlite數據庫文件沒錯
  • 搜索sqlite加密的相關信息。官方的加密實現是須要授權的,但有一個wxsqlite的開源實現。私下猜測該app用了wxsqlite
  • wxsqlite是AES算法加密的。必須找到密匙,否則無法解密,心里涼了半截
  • 繼續看反匯編,找到keySqlite函數,發現key就明文寫在代碼里,是一串1....。額
  • 下載wxsqlite。寫了幾行代碼進行測試,發現依舊打不開。

    自己創建了一個加密數據庫文件。發現跟app的db文件區別非常大。

  • 閱讀wxsqlite的代碼。發現加密算法是在sqlite3Codec函數中調用的。在匯編中找到sqlite3Codec,發現它調用了一個My_Encrypt_Func(呵呵)
  • 閱讀My_Encrypt_Func的匯編代碼,發現就是按字節取反(呵呵呵)
  • 寫個小程序。將db文件按字節取反。再用UltraEdit打開。看到了熟悉的明文信息
  • 這回數據文件能夠用sqlite命令行打開了,dump成txt文件。得到表結構和全部的數據
  • 最后是那個50多M的db文件。

    打印出表結構發現是一個字符串name和一個二進制對象。

    寫個小程序,遍歷全部表項,將二進制對象存成png文件。任務完畢


收獲:
  • 假設是用wxsqlite加密實現,而且密匙是通過網絡獲取的。那就得先想辦法在執行時hook api截獲密匙。破解難度會上升一大截...
  • 加密函數的arm匯編看上去效率非常低....讓我好生奇怪。寫了一段相同的代碼自己編了一下,發現該lib是debug的。這....
  • 加密相關的函數名暴露在動態庫中是非常危急的,給函數聲明加上static。export符號表中沒有了。我們就僅僅能看到一個地址跳轉啦

反匯編出來的加密函數,跟自己寫的並用debug編譯出來是一樣的
.text:002C46E0                 EXPORT My_Encrypt_Func
.text:002C46E0 My_Encrypt_Func                         ; CODE XREF: sqlite3Codec+11Cp
.text:002C46E0                                         ; sqlite3Codec+190p
.text:002C46E0
.text:002C46E0 var_3C          = -0x3C
.text:002C46E0 var_38          = -0x38
.text:002C46E0 var_34          = -0x34
.text:002C46E0 var_30          = -0x30
.text:002C46E0 var_28          = -0x28
.text:002C46E0 var_20          = -0x20
.text:002C46E0 var_4           = -4
.text:002C46E0
.text:002C46E0                 STR     R11, [SP,#var_4]!
.text:002C46E4                 ADD     R11, SP, #4+var_4
.text:002C46E8                 SUB     SP, SP, #0x1C
.text:002C46EC                 STR     R0, [R11,#0x20+var_30]
.text:002C46F0                 STR     R1, [R11,#0x20+var_34]
.text:002C46F4                 STR     R2, [R11,#0x20+var_38]
.text:002C46F8                 STR     R3, [R11,#0x20+var_3C]
.text:002C46FC                 MOV     R3, #0
.text:002C4700                 STR     R3, [R11,#0x20+var_28]
.text:002C4704                 B       loc_2C473C
.text:002C4708 ; ---------------------------------------------------------------------------
.text:002C4708
.text:002C4708 loc_2C4708                              ; CODE XREF: My_Encrypt_Func+68j
.text:002C4708                 LDR     R3, [R11,#-0x10]
.text:002C470C                 LDRB    R3, [R3]
.text:002C4710                 MVN     R3, R3
.text:002C4714                 STRB    R3, [R11,#-9]
.text:002C4718                 LDR     R3, [R11,#-0x10]
.text:002C471C                 LDRB    R2, [R11,#-9]
.text:002C4720                 STRB    R2, [R3]
.text:002C4724                 LDR     R3, [R11,#-0x10]
.text:002C4728                 ADD     R3, R3, #1
.text:002C472C                 STR     R3, [R11,#-0x10]
.text:002C4730                 LDR     R3, [R11,#-8]
.text:002C4734                 ADD     R3, R3, #1
.text:002C4738                 STR     R3, [R11,#-8]
.text:002C473C
.text:002C473C loc_2C473C                              ; CODE XREF: My_Encrypt_Func+24j
.text:002C473C                 LDR     R2, [R11,#-8]
.text:002C4740                 LDR     R3, [R11,#-0x14]
.text:002C4744                 CMP     R2, R3
.text:002C4748                 BCC     loc_2C4708
.text:002C474C                 MOV     R3, #0
.text:002C4750                 MOV     R0, R3
.text:002C4754                 SUB     SP, R11, #0
.text:002C4758                 LDR     R11, [SP+0x20+var_20],#4
.text:002C475C                 BX      LR
.text:002C475C ; End of function My_Encrypt_Func

用release編譯的,執行效率怎么也得差幾十倍

.text:00001D88 ; My_Encrypt_Func(unsigned char *, unsigned int, unsigned char *, unsigned int)
.text:00001D88                 EXPORT _Z15My_Encrypt_FuncPhjS_j
.text:00001D88 _Z15My_Encrypt_FuncPhjS_j
.text:00001D88                 MOVS    R3, #0
.text:00001D8A                 B       loc_1D94
.text:00001D8C ; ---------------------------------------------------------------------------
.text:00001D8C
.text:00001D8C loc_1D8C                                ; CODE XREF: My_Encrypt_Func(uchar *,uint,uchar *,uint)+Ej
.text:00001D8C                 LDRB    R2, [R0,R3]
.text:00001D8E                 MVNS    R2, R2
.text:00001D90                 STRB    R2, [R0,R3]
.text:00001D92                 ADDS    R3, #1
.text:00001D94
.text:00001D94 loc_1D94                                ; CODE XREF: My_Encrypt_Func(uchar *,uint,uchar *,uint)+2j
.text:00001D94                 CMP     R3, R1
.text:00001D96                 BNE     loc_1D8C
.text:00001D98                 MOVS    R0, #0
.text:00001D9A                 BX      LR
.text:00001D9A ; End of function My_Encrypt_Func(uchar *,uint,uchar *,uint)



免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM