背景
Luajit在遊戲中應用廣泛,在逆向分析遊戲過程中免不了與luajit打交道,那網上有非常多關于luajit反編譯的資料,彙總起來常用的兩種方案:
https://github.com/zzwlpx/ljd和
https://github.com/bobsayshilol/luajit-decomp,第一種方案相對來說可讀性好但相容性差經常出現反編譯異常崩潰。第二種方案反編譯更穩定但可讀性稍差。在實踐中穩定性是優先考慮的,是以這篇文章将深入分析第二種方案并解決開源代碼相關問題。
使用
1.下載下傳
https://github.com/bobsayshilol/luajit-decomp- 确定luajit版本(如何确定不是本文重點), 這裡 下載下傳對應版本
- 編譯luajit然後将生成的luajit.exe、lua51.dll和jit檔案夾覆寫到lua-decomp
- 複制要反編譯的檔案到luajit-decomp
- 将反編譯檔案重命名為test.lua
- 運作decoder_new.exe
- 最終生成test.asm out.lua out2.lua,out2.lua就是我們要的檔案
源碼分析
源碼Decoder.au3編寫采用的是basic語言,具體編譯環境安裝看
,花了些時間熟悉了basic文法然後分析源碼,其流程見下圖:
![](https://img.laitimes.com/img/_0nNw4CM6IyYiwiM6ICdiwiIn5GcuMDM1gjZwYDOlJWMjdzNlFjN4YGZ1EmY4gTOmFzMiZWYvwVbvNmLj5Wat4Wd5lGbh5iY1BXLn1WauU3bop3ZuFGat42YucWbp1iMhRXYvw1LcpDc0RHaiojIsJye.png)
Test.asm->Out.lua->Out2.lua内容變化見下圖:
核心代碼邏輯見下圖:
問題
問題一:decoder.au3編譯報錯,作者隐藏了_ArrayAdd函數的自定義實作。
解決:将_ArrayAdd替換為__ARRAYADD,__ARRAYADD定義如下:
FUNC __ARRAYADD(BYREF $AVARRAY, $VVALUE)
IF NOT ISARRAY($AVARRAY) THEN RETURN SETERROR(0x00000001, 0x00000000, -0x00000001)
IF UBOUND($AVARRAY, 0x00000000) <> 0x00000001 THEN RETURN SETERROR(0x00000002, 0x00000000, -0x00000001)
LOCAL $IUBOUND = UBOUND($AVARRAY)
REDIM $AVARRAY [$IUBOUND + 0x00000001 ]
$AVARRAY [$IUBOUND ]= $VVALUE
RETURN $IUBOUND
ENDFUNC
問題二:實際項目反編譯會崩潰,因為lua的定義函數個數超過了定義數組的大小
解決:将$filo數組擴容
ElseIf $f = "FNEW" Then
If $p1 >= UBound($filo) then
ReDim $filo[UBound($filo)+50]
EndIf
$filo[$p1] = "randomFunction" & $randomFunctionNo
If $c = "" Then
FileWriteLine($out,"local randomFunction" & $randomFunctionNo & " = function() end -- unknown location")
Else
FileWriteLine($out,"local randomFunction" & $randomFunctionNo & " = function() end -- starts at " & $c)
EndIf
$randomFunctionNo = $randomFunctionNo + 1
問題三:可讀性差,筆者曾嘗試在out2.lua基礎上做優化,但發現本質原因是指令翻譯這一步本身就有問題,譬如:if repeat until else end 順序被打亂成 if repeat else until end,Function if end end 殘缺為function if end。如果想解決此問題,還是推倒重新實作吧。