不思議迷宮:逆向后的放置play


  1. 前言
  2. 前置准備
  3. 目標分析
  4. 逆向加密邏輯
  5. 定位sign與key
  6. 解密luac
  7. 反編譯luajit的bytecode
  8. 開啟上帝模式
  • 前言

    看了fatezero的《陰陽師:一個非酋的逆向旅程》后,受益匪淺。特別是關於opcode映射關系一節,處理的很精妙。

對手頭上的游戲不思議迷宮,技癢的不行。於是上周周六花了整個下午的時間進行了研究。注意本文中針對安卓版本。

  • 前置准備

    如果讀者也想跟着步驟進行操作,需要准備這些工具:ApkIDE少月版、IDA、python、010editor

 

  • 目標分析

     APKIDE載入之后,首先看一下lib\armeabi\目錄下,發現了libcocos2dlua.so

     

  從字面意思來看,應該是使用cocos2d引擎,並且使用lua腳本,再看assets\src\

   

  發現大量的luac腳本,進一步確認了我們的想法。010editor打開Main.luac,從頭來看,並非luac文件的頭

  

  正常的luaca的頭應該是1B 4C 75 61開頭,如下圖

  

  所以不思議迷宮必然是對luac進行了加密。

  • 逆向加密邏輯

  通過IDA打開libcocos2dlua.so,一般情況下加密會出現cocos2dx_lua_loader->luaL_loadbuffer的某個過程中

  源碼如下:

   

  而在IDA中,luaL_loadbuffer之前出現了srcDecrypt函數,這可是源碼中沒有出現了。

  

  數據的流向是:從文件讀入->v51->v25->luaL_loadbuffer,再分析srcDecrypt函數

  

  當一個文件的頭為11 12 13 的時候,就用charMapList進行替換,而charMapList,通過引用查找

  又是從buildEncrypyMap中初始化的,顯然這是一組“靜態”的置換表,完全可逆而且沒有任何難度。

  

  但是回過頭來看apk中的luac文件,沒有一個的文件頭是11 12 13,文件頭全部是applicationWillEnterForeground

  並沒有給我們帶來任何幫助,只能繼續分析luaLoadBuffer,看到了第二個加密的地方xxtea_decrypt

  

  google,baidu之后,找到非常類似的一段源碼

   

  通過sign對文件進行標記,符合條件用key進行解密,梳理一下luac的整體解密過程

  

  由於沒有使用srcDecrypt的流程,所以實際上只有xxtea_decrypt,只要找到sign和key,問題就解決了。

  • 定位sign與key 

   通過分析,可以確定加密的最終文件格式。文件頭都有固定長度的sign

xxtea_decrypt(buf+decode->m_xxteaSignLen, (xxtea_long)size -(xxtea_long)decode->m_xxteaSignLen, (unsigned char*)decode->m_xxteaKey, (xxtea_long)decode->m_xxteaKeyLen, &len); 

  再次打開另外一個luac文件,二者相同的文件頭如圖,所以sign為applicationWillEnterForeground

  

  在IDA中,我們也找到了這個字符串

  

  查找引用之后,這個字符串在initLuaStack中被調用了。

  

  再通過資料搜索,發現一般使用xxtea算法的,都會使用setXXTEAKeyAndSign來設置sign和key,圖中v3就是setXXTEAKeyAndSign函數

stack->setXXTEAKeyAndSign("123", strlen("123"), "cloud", strlen("cloud"));  

  那么自然key就是:applicationDidEnterBackground

  • 解密luac

  首先pip install xxtea-py,安裝python的xxtea的庫

  編寫腳本如下:

import xxtea
import os
sign = 'applicationWillEnterForeground'
key = 'applicationDidEnterBackground'
def decode(filename):
    luacdata = open(filename,'rb').read()
    decrypt_data = xxtea.decrypt(luacdata[len(sign):],key[:16])
    open(filename.replace('.luac','.luacx'),'wb').write(decrypt_data)

  解密后如下,出現的文件頭為1B 4C 4A 01,也並非luac標准頭,難道還有名堂?

  

  經過一番資料查詢之后,這是luajit編譯的bytecode,並非標准lua。其頭為1B 4C 4A


 

  


 

  • 反編譯luajit的bytecode

  在github上找到用於反編譯luajit的項目:https://github.com/NightNord/ljd

   由於該庫只能在python3上跑起來,而我懶得改腳本,於是直接通過命令執行方式,在kali中(同時存在python2、python3)運行了如下腳本

#coding=utf-8
import os
sign = 'applicationWillEnterForeground'
key = 'applicationDidEnterBackground'
path = os.path.join(os.getcwd(),'src') 
def decode(filename):
    luacdata = open(filename,'rb').read()
    decrypt_data = xxtea.decrypt(luacdata[len(sign):],key[:16])
    open(filename.replace('.luac','.luacx'),'wb').write(decrypt_data)

def decomplie(filename):
    os.system('python3 ./ljdm/main.py '+filename+' > '+filename.replace('.luacx','.luacxs'))

    
for path,d,filelist in os.walk(path):  
    for filename in filelist:
        filename = os.path.join(path, filename)
        if filename.endswith('.luac') and not os.path.isfile(filename.replace('.luac','.luac')):
            print( filename)
            decode(filename)
        if filename.endswith('.luacx') and (not os.path.isfile(filename.replace('.luacx','.luacxs')) or os.path.getsize(filename.replace('.luacx','.luacxs'))==0):
            print(filename)
            decomplie(filename)

  src目錄對應生成的luacxs就是最終反編譯好的lua源代碼了。

  • 開啟上帝模式

  通過大量的分析之后,我發現程序員在代碼中,沒有去掉測試用的上帝模式,只是簡單的隱藏

  我在UIAccountBind.luacxs:380行中加入打開上帝模式的一行代碼openGdUI().

  這樣當我點擊復制賬號id的時候就會彈出上帝模式窗口

    local function onCopyClick(sender, eventType)
        if eventType == ccui.TouchEventType.ended then
            copyToClipBoard(rid, getLocStr("text_copied"))
        end
        openGdUI()
        return 
    end

  以及GDM.luacxs:24中的check_mode,讓其始終返回為true,保證上帝模式功能可正常開啟

function check_mode()
    return true 
end

  然后通過luajit編譯,再進行xxtea加密,打包成APK放入手機。

  最終效果圖為:全自動放置play,程序員已經實現了自動加天賦,自動撿東西,自動打怪,自動進入下一層等等

  


免責聲明!

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



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