2018腾讯游戏安全技术竞赛Android 组决赛 第二轮 基础版 第一关

本博客由闲散白帽子胖胖鹏鹏胖胖鹏潜力所写,仅仅作为个人技术交流分享,不得用做商业用途。转载请注明出处,禁止未经许可将本博客内所有内容转载、商用。

“别人吓自己不可怕,可怕的是自己吓自己”

—胖胖鹏鹏胖胖鹏

        已经是决赛的最后一题了,发现是个UE4引擎。还是先打开App看一眼,哟呵还能跑能飞,开始我还以为和上一题一样,是一个能够直接看到Flag的题目,各种飞还是不行,甚至猜他把材质反着贴,把Flag藏在了材质里面。接着又去学习了UE4的开发,蓝图编程、蓝图的编译、菜单的widget等等,看了两天还是没有头绪,心急如焚。正巧赶上项目组的论文要发表了,赶紧过去改论文,就这样本来7天做题时间,花了2天梦游,又花了3天半改论文。剩下2天半要抓紧了,能做出来第一关就很满足了。可还是这个问题,校验的入口在哪里呢?

        无奈还是先解包看看。发现有6个so库。其中libgnustl_shared.so、libOVRPlugin.so、libvrapi.so都是和引擎相关的库,貌似第一关的时候没用上。而libph2.so、libtmgs.so、libUE4.so就和我们比较相关了。libUE4处理用户交互、绘制界面等等一系列的函数。那么剩下的两个库有什么用呢?又是怎么加载进去的呢?为了弄清他们之间的调用关系,我搜搜了libUE4中的dlopen函数,果然有情况。


        果然调用了libtmgs库,并且加载了三个函数null、maln和ths。我觉得maln这个函数特别像单词“main”。于是IDA动态调试,在maln上下断点,输入错误的验证码,点击验证。果然程序断在了这里。


      其中还悄悄调用了null函数,不过我们不关心,调试的时候发现sub_271d8这个函数传入了v7也就是我们输入的验证码。而且这个函数是最后的返回结果,所以确定就是检查验证码的地方。跟进去


        emmmmm没有看出来到底做了啥操作。于是这里卡住了。翻了翻ph2这个库,发现里面充斥着大量的lua字样。回首再看这段代码,难道!这是lua脚本?动态调试了一下,发现v5的头部是“.LuaS”,lua脚本无误。直接dump内存,保存成luac文件。剩下的就是反编译lua字节码,并且拿到真正的检查逻辑了。(上图函数标记的差不多了,动态调试的时候调没了)

        翻了翻看雪的帖子,原来是要找到opmode和opcode,之后修改这个对应的表格,然后编译luadec就可以反编译我们的脚本了。这部分比较吃力,一直在学习lua的各种原理和底层实现,这里花了将近10几个小时。最终定位到了opmode,发现,嗯?没改?紧接着定位到opcode的部分,看了很久发现,嗯?也没改?WTF???感觉自己像个傻子,自己吓住了自己,以为这个题目很难。既然这么简单,直接使用luadec反编译吧!获得Error,size_t不匹配。翻了翻github的issue,了解了这个lua编译的时候是32位机子编译的而我的电脑是64位的,所以会出现这个问题。无奈装上虚拟机,一跑,segmentation fatal......我用各种方法尝试解决这个问题,都无果。这里耽误了4个小时。算了还是生成汇编吧。这里还是蛮顺利的。最后得到了代码。

; Disassembled using luadec 2.2 rev: 895d923 for Lua 5.3 from https://github.com/viruscamp/luadec
; Command line: -dis test.luac 

; Function:        0
; Defined at line: 0
; #Upvalues:       1
; #Parameters:     0
; Is_vararg:       1
; Max Stack Size:  26

    0 [-]: GETTABUP  R0 U0 K0     ; R0 := U0["require"]
    1 [-]: GETTABUP  R1 U0 K1     ; R1 := U0["setmetatable"]
    2 [-]: GETTABUP  R2 U0 K2     ; R2 := U0["string"]
    3 [-]: GETTABLE  R2 R2 K3     ; R2 := R2["char"]
    4 [-]: GETTABUP  R3 U0 K4     ; R3 := U0["table"]
    5 [-]: GETTABLE  R3 R3 K5     ; R3 := R3["concat"]
    6 [-]: LOADNIL   R4 2         ; R4 to R6 := nil
    7 [-]: GETTABUP  R7 U0 K6     ; R7 := U0["jit"]
    8 [-]: TEST      R7 0         ; if R7 then goto 10 else goto 20
    9 [-]: JMP       R0 10        ; PC += 10 (goto 20)
   10 [-]: GETTABUP  R7 U0 K6     ; R7 := U0["jit"]
   11 [-]: GETTABLE  R7 R7 K7     ; R7 := R7["version_num"]
   12 [-]: LT        0 K8 R7      ; if 20000 < R7 then goto 14 else goto 20
   13 [-]: JMP       R0 6         ; PC += 6 (goto 20)
   14 [-]: LOADBOOL  R4 1 0       ; R4 := true
   15 [-]: GETTABUP  R7 U0 K9     ; R7 := U0["bit"]
   16 [-]: GETTABLE  R5 R7 K10    ; R5 := R7["bxor"]
   17 [-]: GETTABUP  R7 U0 K9     ; R7 := U0["bit"]
   18 [-]: GETTABLE  R6 R7 K11    ; R6 := R7["band"]
   19 [-]: JMP       R0 16        ; PC += 16 (goto 36)
   20 [-]: GETTABUP  R7 U0 K12    ; R7 := U0["_VERSION"]
   21 [-]: EQ        0 R7 K13     ; if R7 == "Lua 5.2" then goto 23 else goto 28
   22 [-]: JMP       R0 5         ; PC += 5 (goto 28)
   23 [-]: GETTABUP  R7 U0 K14    ; R7 := U0["bit32"]
   24 [-]: GETTABLE  R5 R7 K10    ; R5 := R7["bxor"]
   25 [-]: GETTABUP  R7 U0 K14    ; R7 := U0["bit32"]
   26 [-]: GETTABLE  R6 R7 K11    ; R6 := R7["band"]
   27 [-]: JMP       R0 8         ; PC += 8 (goto 36)
   28 [-]: MOVE      R7 R0        ; R7 := R0
   29 [-]: LOADK     R8 K9        ; R8 := "bit"
   30 [-]: CALL      R7 2 2       ; R7 := R7(R8)
   31 [-]: SETTABUP  U0 K9 R7     ; U0["bit"] := R7
   32 [-]: GETTABUP  R7 U0 K9     ; R7 := U0["bit"]
   33 [-]: GETTABLE  R5 R7 K10    ; R5 := R7["bxor"]
   34 [-]: GETTABUP  R7 U0 K9     ; R7 := U0["bit"]
   35 [-]: GETTABLE  R6 R7 K11    ; R6 := R7["band"]
   36 [-]: EXTRAARG  5377203      ; 
   37 [-]: LOADNIL   R7 1         ; R7 to R8 := nil
   38 [-]: TEST      R4 0         ; if R4 then goto 40 else goto 63
   39 [-]: JMP       R0 23        ; PC += 23 (goto 63)
   40 [-]: MOVE      R9 R0        ; R9 := R0
   41 [-]: LOADK     R10 K15      ; R10 := "ffi"
   42 [-]: CALL      R9 2 2       ; R9 := R9(R10)
   43 [-]: GETTABLE  R10 R9 K2    ; R10 := R9["string"]
   44 [-]: GETTABLE  R11 R9 K16   ; R11 := R9["copy"]
   45 [-]: GETTABLE  R12 R9 K17   ; R12 := R9["cdef"]
   46 [-]: LOADK     R13 K18      ; R13 := "\t\ttypedef struct { uint8_t v; } idx_t;\n\t"
   47 [-]: CALL      R12 2 1      ;  := R12(R13)
   48 [-]: GETTABLE  R12 R9 K19   ; R12 := R9["typeof"]
   49 [-]: LOADK     R13 K20      ; R13 := "uint8_t[256]"
   50 [-]: CALL      R12 2 2      ; R12 := R12(R13)
   51 [-]: GETTABLE  R13 R9 K19   ; R13 := R9["typeof"]
   52 [-]: LOADK     R14 K21      ; R14 := "idx_t"
   53 [-]: CALL      R13 2 2      ; R13 := R13(R14)
   54 [-]: GETTABLE  R14 R9 K19   ; R14 := R9["typeof"]
   55 [-]: LOADK     R15 K22      ; R15 := "uint8_t[?]"
   56 [-]: CALL      R14 2 2      ; R14 := R14(R15)
   57 [-]: CLOSURE   R15 0        ; R15 := closure(Function #0_0)
   58 [-]: MOVE      R7 R15       ; R7 := R15
   59 [-]: CLOSURE   R15 1        ; R15 := closure(Function #0_1)
   60 [-]: MOVE      R8 R15       ; R8 := R15
   61 [-]: JMP       R10 5        ; PC += 5 (goto 67); close all upvalues in R9 to top
   62 [-]: JMP       R0 4         ; PC += 4 (goto 67)
   63 [-]: CLOSURE   R9 2         ; R9 := closure(Function #0_2)
   64 [-]: MOVE      R7 R9        ; R7 := R9
   65 [-]: CLOSURE   R9 3         ; R9 := closure(Function #0_3)
   66 [-]: MOVE      R8 R9        ; R8 := R9
   67 [-]: CLOSURE   R9 4         ; R9 := closure(Function #0_4)
   68 [-]: GETTABUP  R10 U0 K23   ; R10 := U0["arg"]
   69 [-]: TEST      R10 0        ; if R10 then goto 71 else goto 147
   70 [-]: JMP       R0 76        ; PC += 76 (goto 147)
   71 [-]: GETTABUP  R10 U0 K24   ; R10 := U0["os"]
   72 [-]: GETTABLE  R10 R10 K25  ; R10 := R10["clock"]
   73 [-]: CLOSURE   R11 5        ; R11 := closure(Function #0_5)
   74 [-]: GETTABUP  R12 U0 K26   ; R12 := U0["tonumber"]
   75 [-]: GETTABUP  R13 U0 K23   ; R13 := U0["arg"]
   76 [-]: GETTABLE  R13 R13 K27  ; R13 := R13[1]
   77 [-]: CALL      R12 2 2      ; R12 := R12(R13)
   78 [-]: TEST      R12 1        ; if not R12 then goto 80 else goto 81
   79 [-]: JMP       R0 1         ; PC += 1 (goto 81)
   80 [-]: LOADK     R12 K28      ; R12 := 100000
   81 [-]: LOADK     R13 K29      ; R13 := "Z@\024轌闅\236"
   82 [-]: LOADNIL   R14 0        ; R14 := nil
   83 [-]: EXTRAARG  134246       ; 
   84 [-]: MOVE      R15 R10      ; R15 := R10
   85 [-]: CALL      R15 1 2      ; R15 := R15()
   86 [-]: MOVE      R14 R15      ; R14 := R15
   87 [-]: LOADK     R15 K27      ; R15 := 1
   88 [-]: MOVE      R16 R12      ; R16 := R12
   89 [-]: LOADK     R17 K27      ; R17 := 1
   90 [-]: FORPREP   R15 4        ; R15 -= R17; pc += 4 (goto 95)
   91 [-]: MOVE      R19 R9       ; R19 := R9
   92 [-]: LOADNIL   R20 0        ; R20 := nil
   93 [-]: MOVE      R21 R13      ; R21 := R13
   94 [-]: CALL      R19 3 2      ; R19 := R19(R20 to R21)
   95 [-]: FORLOOP   R15 -5       ; R15 += R17; if R15 <= R16 then R18 := R15; PC += -5 , goto 91 end
   96 [-]: MOVE      R15 R11      ; R15 := R11
   97 [-]: LOADK     R16 K30      ; R16 := "%-16s %8.3f sec (%d times, #key %d)"
   98 [-]: LOADK     R17 K31      ; R17 := "RC4 keygen test"
   99 [-]: MOVE      R18 R10      ; R18 := R10
  100 [-]: CALL      R18 1 2      ; R18 := R18()
  101 [-]: SUB       R18 R18 R14  ; R18 := R18 - R14
  102 [-]: MOVE      R19 R12      ; R19 := R12
  103 [-]: LEN       R20 R13      ; R20 := #R13
  104 [-]: CALL      R15 6 1      ;  := R15(R16 to R20)
  105 [-]: GETTABUP  R15 U0 K32   ; R15 := U0["collectgarbage"]
  106 [-]: CALL      R15 1 1      ;  := R15()
  107 [-]: MOVE      R15 R9       ; R15 := R9
  108 [-]: LOADNIL   R16 0        ; R16 := nil
  109 [-]: MOVE      R17 R13      ; R17 := R13
  110 [-]: CALL      R15 3 2      ; R15 := R15(R16 to R17)
  111 [-]: MOVE      R16 R9       ; R16 := R9
  112 [-]: LOADNIL   R17 0        ; R17 := nil
  113 [-]: MOVE      R18 R13      ; R18 := R13
  114 [-]: CALL      R16 3 2      ; R16 := R16(R17 to R18)
  115 [-]: LOADK     R17 K33      ; R17 := "bS1hjNeePwaj6dY293F7rzmcTFjZVS9O9vAq5l69onIiZTOwZ3LrtuiWLT0Jpr3lZ0XJ11Ajw6RoyLP6Xf66lbFu68edKJK8oyGJLu9xFTQRaFXrsMu9nX4Q5qufETjU0nsN6JZxGXQZfAAcgFyvlik2tJEyovhHsEINhtXnYuj7VpUEZl8ZXAVf2Aa5cbSYVcb1wY3D2ts2kHHXVqUhKpYQ60LKGbWOB1CKkSDFR8JfL9tBmpezS9MWCh1yTUXjfFxSbEq3KV7c8qtwxKGjINoDAMWDQLO0qBGC8IitKyc1zbBUbHBPTvx9TPiGpYObQeX5Ktu7ZtiRpak2o5h9AfEXHCd4tL1F2OsQfpMZghGWnRAez32JeWksXis6X1uJAZgA6mB5Fc7CErLJCiSJVl1TbG4Z7KhypNN0MOfeVV7RY5shwQtYixzA86LNa4w8It2XyjYe6qrcYX3Eq3cKEFFfBPJXZnqwoO3W6MJ52KUrTWcOtqnnfOtWhm9FsLZM"
  116 [-]: MOVE      R18 R10      ; R18 := R10
  117 [-]: CALL      R18 1 2      ; R18 := R18()
  118 [-]: MOVE      R14 R18      ; R14 := R18
  119 [-]: LOADK     R18 K27      ; R18 := 1
  120 [-]: MOVE      R19 R12      ; R19 := R12
  121 [-]: LOADK     R20 K27      ; R20 := 1
  122 [-]: FORPREP   R18 13       ; R18 -= R20; pc += 13 (goto 136)
  123 [-]: MOVE      R22 R15      ; R22 := R15
  124 [-]: MOVE      R23 R17      ; R23 := R17
  125 [-]: CALL      R22 2 2      ; R22 := R22(R23)
  126 [-]: MOVE      R23 R16      ; R23 := R16
  127 [-]: MOVE      R24 R22      ; R24 := R22
  128 [-]: CALL      R23 2 2      ; R23 := R23(R24)
  129 [-]: EXTRAARG  17435774     ; 
  130 [-]: GETTABUP  R24 U0 K34   ; R24 := U0["assert"]
  131 [-]: EQ        1 R17 R23    ; if R17 ~= R23 then goto 133 else goto 134
  132 [-]: JMP       R0 1         ; PC += 1 (goto 134)
  133 [-]: LOADBOOL  R25 0 1      ; R25 := false; goto 135
  134 [-]: LOADBOOL  R25 1 0      ; R25 := true
  135 [-]: CALL      R24 2 1      ;  := R24(R25)
  136 [-]: FORLOOP   R18 -14      ; R18 += R20; if R18 <= R19 then R21 := R18; PC += -14 , goto 123 end
  137 [-]: MOVE      R18 R11      ; R18 := R11
  138 [-]: LOADK     R19 K35      ; R19 := "%-16s %8.3f sec (%d times, #key %d, #input %d)"
  139 [-]: LOADK     R20 K36      ; R20 := "RC4 crypt test"
  140 [-]: MOVE      R21 R10      ; R21 := R10
  141 [-]: CALL      R21 1 2      ; R21 := R21()
  142 [-]: SUB       R21 R21 R14  ; R21 := R21 - R14
  143 [-]: MOVE      R22 R12      ; R22 := R12
  144 [-]: LEN       R23 R13      ; R23 := #R13
  145 [-]: LEN       R24 R17      ; R24 := #R17
  146 [-]: CALL      R18 7 1      ;  := R18(R19 to R24)
  147 [-]: MOVE      R10 R1       ; R10 := R1
  148 [-]: NEWTABLE  R11 0 0      ; R11 := {} (size = 0,0)
  149 [-]: NEWTABLE  R12 0 2      ; R12 := {} (size = 0,2)
  150 [-]: SETTABLE  R12 K38 R9   ; R12["__call"] := R9
  151 [-]: SETTABLE  R12 K39 K40  ; R12["__metatable"] := false
  152 [-]: CALL      R10 3 2      ; R10 := R10(R11 to R12)
  153 [-]: SETTABUP  U0 K37 R10   ; U0["rc4"] := R10
  154 [-]: CLOSURE   R10 6        ; R10 := closure(Function #0_6)
  155 [-]: SETTABUP  U0 K41 R10   ; U0["check"] := R10
  156 [-]: RETURN    R0 1         ; return 


; Function:        0_0
; Defined at line: 66
; #Upvalues:       4
; #Parameters:     1
; Is_vararg:       0
; Max Stack Size:  12

    0 [-]: GETUPVAL  R1 U0        ; R1 := U0
    1 [-]: CALL      R1 1 2       ; R1 := R1()
    2 [-]: LOADK     R2 K0        ; R2 := 0
    3 [-]: LOADK     R3 K1        ; R3 := 255
    4 [-]: LOADK     R4 K2        ; R4 := 1
    5 [-]: FORPREP   R2 1         ; R2 -= R4; pc += 1 (goto 7)
    6 [-]: SETTABLE  R1 R5 R5     ; R1[R5] := R5
    7 [-]: FORLOOP   R2 -2        ; R2 += R4; if R2 <= R3 then R5 := R2; PC += -2 , goto 6 end
    8 [-]: LEN       R2 R0        ; R2 := #R0
    9 [-]: GETUPVAL  R3 U1        ; R3 := U1
   10 [-]: MOVE      R4 R2        ; R4 := R2
   11 [-]: CALL      R3 2 2       ; R3 := R3(R4)
   12 [-]: GETUPVAL  R4 U2        ; R4 := U2
   13 [-]: MOVE      R5 R3        ; R5 := R3
   14 [-]: MOVE      R6 R0        ; R6 := R0
   15 [-]: MOVE      R7 R2        ; R7 := R2
   16 [-]: CALL      R4 4 1       ;  := R4(R5 to R7)
   17 [-]: GETUPVAL  R4 U3        ; R4 := U3
   18 [-]: CALL      R4 1 2       ; R4 := R4()
   19 [-]: LOADK     R5 K0        ; R5 := 0
   20 [-]: LOADK     R6 K1        ; R6 := 255
   21 [-]: LOADK     R7 K2        ; R7 := 1
   22 [-]: FORPREP   R5 14        ; R5 -= R7; pc += 14 (goto 37)
   23 [-]: GETTABLE  R9 R4 K3     ; R9 := R4["v"]
   24 [-]: GETTABLE  R10 R1 R8    ; R10 := R1[R8]
   25 [-]: ADD       R9 R9 R10    ; R9 := R9 + R10
   26 [-]: MOD       R10 R8 R2    ; R10 := R8 % R2
   27 [-]: GETTABLE  R10 R3 R10   ; R10 := R3[R10]
   28 [-]: ADD       R9 R9 R10    ; R9 := R9 + R10
   29 [-]: SETTABLE  R4 K3 R9     ; R4["v"] := R9
   30 [-]: GETTABLE  R9 R4 K3     ; R9 := R4["v"]
   31 [-]: GETTABLE  R10 R4 K3    ; R10 := R4["v"]
   32 [-]: GETTABLE  R10 R1 R10   ; R10 := R1[R10]
   33 [-]: GETTABLE  R11 R1 R8    ; R11 := R1[R8]
   34 [-]: SETTABLE  R1 R9 R11    ; R1[R9] := R11
   35 [-]: SETTABLE  R1 R8 R10    ; R1[R8] := R10
   36 [-]: EXTRAARG  31198292     ; 
   37 [-]: FORLOOP   R5 -15       ; R5 += R7; if R5 <= R6 then R8 := R5; PC += -15 , goto 23 end
   38 [-]: EXTRAARG  15600870     ; 
   39 [-]: NEWTABLE  R5 0 3       ; R5 := {} (size = 0,3)
   40 [-]: GETUPVAL  R6 U3        ; R6 := U3
   41 [-]: CALL      R6 1 2       ; R6 := R6()
   42 [-]: SETTABLE  R5 K4 R6     ; R5["x"] := R6
   43 [-]: GETUPVAL  R6 U3        ; R6 := U3
   44 [-]: CALL      R6 1 2       ; R6 := R6()
   45 [-]: SETTABLE  R5 K5 R6     ; R5["y"] := R6
   46 [-]: SETTABLE  R5 K6 R1     ; R5["st"] := R1
   47 [-]: RETURN    R5 2         ; return R5
   48 [-]: RETURN    R0 1         ; return 


; Function:        0_1
; Defined at line: 85
; #Upvalues:       4
; #Parameters:     2
; Is_vararg:       0
; Max Stack Size:  15

    0 [-]: GETTABLE  R2 R0 K0     ; R2 := R0["x"]
    1 [-]: GETTABLE  R3 R0 K1     ; R3 := R0["y"]
    2 [-]: GETTABLE  R4 R0 K2     ; R4 := R0["st"]
    3 [-]: EXTRAARG  6294676      ; 
    4 [-]: LEN       R5 R1        ; R5 := #R1
    5 [-]: GETUPVAL  R6 U0        ; R6 := U0
    6 [-]: MOVE      R7 R5        ; R7 := R5
    7 [-]: CALL      R6 2 2       ; R6 := R6(R7)
    8 [-]: GETUPVAL  R7 U1        ; R7 := U1
    9 [-]: MOVE      R8 R6        ; R8 := R6
   10 [-]: MOVE      R9 R1        ; R9 := R1
   11 [-]: MOVE      R10 R5       ; R10 := R5
   12 [-]: CALL      R7 4 1       ;  := R7(R8 to R10)
   13 [-]: LOADK     R7 K3        ; R7 := 0
   14 [-]: SUB       R8 R5 K4     ; R8 := R5 - 1
   15 [-]: LOADK     R9 K4        ; R9 := 1
   16 [-]: FORPREP   R7 28        ; R7 -= R9; pc += 28 (goto 45)
   17 [-]: GETTABLE  R11 R2 K5    ; R11 := R2["v"]
   18 [-]: ADD       R11 R11 K4   ; R11 := R11 + 1
   19 [-]: SETTABLE  R2 K5 R11    ; R2["v"] := R11
   20 [-]: GETTABLE  R11 R3 K5    ; R11 := R3["v"]
   21 [-]: GETTABLE  R12 R2 K5    ; R12 := R2["v"]
   22 [-]: GETTABLE  R12 R4 R12   ; R12 := R4[R12]
   23 [-]: ADD       R11 R11 R12  ; R11 := R11 + R12
   24 [-]: SETTABLE  R3 K5 R11    ; R3["v"] := R11
   25 [-]: GETTABLE  R11 R2 K5    ; R11 := R2["v"]
   26 [-]: GETTABLE  R12 R3 K5    ; R12 := R3["v"]
   27 [-]: GETTABLE  R13 R3 K5    ; R13 := R3["v"]
   28 [-]: GETTABLE  R13 R4 R13   ; R13 := R4[R13]
   29 [-]: GETTABLE  R14 R2 K5    ; R14 := R2["v"]
   30 [-]: GETTABLE  R14 R4 R14   ; R14 := R4[R14]
   31 [-]: SETTABLE  R4 R12 R14   ; R4[R12] := R14
   32 [-]: SETTABLE  R4 R11 R13   ; R4[R11] := R13
   33 [-]: GETUPVAL  R11 U2       ; R11 := U2
   34 [-]: GETTABLE  R12 R6 R10   ; R12 := R6[R10]
   35 [-]: GETTABLE  R13 R2 K5    ; R13 := R2["v"]
   36 [-]: GETTABLE  R13 R4 R13   ; R13 := R4[R13]
   37 [-]: GETTABLE  R14 R3 K5    ; R14 := R3["v"]
   38 [-]: GETTABLE  R14 R4 R14   ; R14 := R4[R14]
   39 [-]: ADD       R13 R13 R14  ; R13 := R13 + R14
   40 [-]: MOD       R13 R13 K6   ; R13 := R13 % 256
   41 [-]: GETTABLE  R13 R4 R13   ; R13 := R4[R13]
   42 [-]: CALL      R11 3 2      ; R11 := R11(R12 to R13)
   43 [-]: SETTABLE  R6 R10 R11   ; R6[R10] := R11
   44 [-]: EXTRAARG  4983888      ; 
   45 [-]: FORLOOP   R7 -29       ; R7 += R9; if R7 <= R8 then R10 := R7; PC += -29 , goto 17 end
   46 [-]: GETUPVAL  R7 U3        ; R7 := U3
   47 [-]: MOVE      R8 R6        ; R8 := R6
   48 [-]: MOVE      R9 R5        ; R9 := R5
   49 [-]: TAILCALL  R7 3 0       ; R7 to top := R7(R8 to R9)
   50 [-]: RETURN    R7 0         ; return R7 to top
   51 [-]: RETURN    R0 1         ; return 


; Function:        0_2
; Defined at line: 105
; #Upvalues:       0
; #Parameters:     1
; Is_vararg:       0
; Max Stack Size:  12

    0 [-]: NEWTABLE  R1 0 0       ; R1 := {} (size = 0,0)
    1 [-]: LOADK     R2 K0        ; R2 := 0
    2 [-]: LOADK     R3 K1        ; R3 := 255
    3 [-]: LOADK     R4 K2        ; R4 := 1
    4 [-]: FORPREP   R2 1         ; R2 -= R4; pc += 1 (goto 6)
    5 [-]: SETTABLE  R1 R5 R5     ; R1[R5] := R5
    6 [-]: FORLOOP   R2 -2        ; R2 += R4; if R2 <= R3 then R5 := R2; PC += -2 , goto 5 end
    7 [-]: LEN       R2 R0        ; R2 := #R0
    8 [-]: LOADK     R3 K0        ; R3 := 0
    9 [-]: LOADK     R4 K0        ; R4 := 0
   10 [-]: LOADK     R5 K1        ; R5 := 255
   11 [-]: LOADK     R6 K2        ; R6 := 1
   12 [-]: FORPREP   R4 13        ; R4 -= R6; pc += 13 (goto 26)
   13 [-]: GETTABLE  R8 R1 R7     ; R8 := R1[R7]
   14 [-]: ADD       R8 R3 R8     ; R8 := R3 + R8
   15 [-]: SELF      R9 R0 K3     ; R10 := R0; R9 := R0["byte"]
   16 [-]: MOD       R11 R7 R2    ; R11 := R7 % R2
   17 [-]: ADD       R11 R11 K2   ; R11 := R11 + 1
   18 [-]: CALL      R9 3 2       ; R9 := R9(R10 to R11)
   19 [-]: ADD       R8 R8 R9     ; R8 := R8 + R9
   20 [-]: MOD       R3 R8 K4     ; R3 := R8 % 256
   21 [-]: GETTABLE  R8 R1 R3     ; R8 := R1[R3]
   22 [-]: GETTABLE  R9 R1 R7     ; R9 := R1[R7]
   23 [-]: SETTABLE  R1 R3 R9     ; R1[R3] := R9
   24 [-]: SETTABLE  R1 R7 R8     ; R1[R7] := R8
   25 [-]: EXTRAARG  15338701     ; 
   26 [-]: FORLOOP   R4 -14       ; R4 += R6; if R4 <= R5 then R7 := R4; PC += -14 , goto 13 end
   27 [-]: EXTRAARG  21892159     ; 
   28 [-]: NEWTABLE  R4 0 3       ; R4 := {} (size = 0,3)
   29 [-]: SETTABLE  R4 K5 K0     ; R4["x"] := 0
   30 [-]: SETTABLE  R4 K6 K0     ; R4["y"] := 0
   31 [-]: SETTABLE  R4 K7 R1     ; R4["st"] := R1
   32 [-]: RETURN    R4 2         ; return R4
   33 [-]: RETURN    R0 1         ; return 


; Function:        0_3
; Defined at line: 121
; #Upvalues:       3
; #Parameters:     2
; Is_vararg:       0
; Max Stack Size:  15

    0 [-]: GETTABLE  R2 R0 K0     ; R2 := R0["x"]
    1 [-]: GETTABLE  R3 R0 K1     ; R3 := R0["y"]
    2 [-]: GETTABLE  R4 R0 K2     ; R4 := R0["st"]
    3 [-]: NEWTABLE  R5 0 0       ; R5 := {} (size = 0,0)
    4 [-]: LOADK     R6 K3        ; R6 := 1
    5 [-]: LEN       R7 R1        ; R7 := #R1
    6 [-]: LOADK     R8 K3        ; R8 := 1
    7 [-]: FORPREP   R6 23        ; R6 -= R8; pc += 23 (goto 31)
    8 [-]: EXTRAARG  7212269      ; 
    9 [-]: ADD       R10 R2 K3    ; R10 := R2 + 1
   10 [-]: MOD       R2 R10 K4    ; R2 := R10 % 256
   11 [-]: GETTABLE  R10 R4 R2    ; R10 := R4[R2]
   12 [-]: ADD       R10 R3 R10   ; R10 := R3 + R10
   13 [-]: MOD       R3 R10 K4    ; R3 := R10 % 256
   14 [-]: GETTABLE  R10 R4 R3    ; R10 := R4[R3]
   15 [-]: GETTABLE  R11 R4 R2    ; R11 := R4[R2]
   16 [-]: SETTABLE  R4 R3 R11    ; R4[R3] := R11
   17 [-]: SETTABLE  R4 R2 R10    ; R4[R2] := R10
   18 [-]: GETUPVAL  R10 U0       ; R10 := U0
   19 [-]: GETUPVAL  R11 U1       ; R11 := U1
   20 [-]: SELF      R12 R1 K5    ; R13 := R1; R12 := R1["byte"]
   21 [-]: MOVE      R14 R9       ; R14 := R9
   22 [-]: CALL      R12 3 2      ; R12 := R12(R13 to R14)
   23 [-]: GETTABLE  R13 R4 R2    ; R13 := R4[R2]
   24 [-]: GETTABLE  R14 R4 R3    ; R14 := R4[R3]
   25 [-]: ADD       R13 R13 R14  ; R13 := R13 + R14
   26 [-]: MOD       R13 R13 K4   ; R13 := R13 % 256
   27 [-]: GETTABLE  R13 R4 R13   ; R13 := R4[R13]
   28 [-]: CALL      R11 3 0      ; R11 to top := R11(R12 to R13)
   29 [-]: CALL      R10 0 2      ; R10 := R10(R11 to top)
   30 [-]: SETTABLE  R5 R9 R10    ; R5[R9] := R10
   31 [-]: FORLOOP   R6 -24       ; R6 += R8; if R6 <= R7 then R9 := R6; PC += -24 , goto 8 end
   32 [-]: EXTRAARG  26348548     ; 
   33 [-]: MOVE      R6 R2        ; R6 := R2
   34 [-]: SETTABLE  R0 K1 R3     ; R0["y"] := R3
   35 [-]: SETTABLE  R0 K0 R6     ; R0["x"] := R6
   36 [-]: GETUPVAL  R6 U2        ; R6 := U2
   37 [-]: MOVE      R7 R5        ; R7 := R5
   38 [-]: TAILCALL  R6 2 0       ; R6 to top := R6(R7)
   39 [-]: RETURN    R6 0         ; return R6 to top
   40 [-]: RETURN    R0 1         ; return 


; Function:        0_4
; Defined at line: 138
; #Upvalues:       3
; #Parameters:     2
; Is_vararg:       0
; Max Stack Size:  7

    0 [-]: GETUPVAL  R2 U0        ; R2 := U0
    1 [-]: MOVE      R3 R1        ; R3 := R1
    2 [-]: CALL      R2 2 2       ; R2 := R2(R3)
    3 [-]: GETUPVAL  R3 U1        ; R3 := U1
    4 [-]: MOVE      R4 R2        ; R4 := R2
    5 [-]: NEWTABLE  R5 0 2       ; R5 := {} (size = 0,2)
    6 [-]: GETUPVAL  R6 U2        ; R6 := U2
    7 [-]: SETTABLE  R5 K0 R6     ; R5["__call"] := R6
    8 [-]: SETTABLE  R5 K1 K2     ; R5["__metatable"] := false
    9 [-]: TAILCALL  R3 3 0       ; R3 to top := R3(R4 to R5)
   10 [-]: RETURN    R3 0         ; return R3 to top
   11 [-]: RETURN    R0 1         ; return 


; Function:        0_5
; Defined at line: 146
; #Upvalues:       0
; #Parameters:     1
; Is_vararg:       1
; Max Stack Size:  2

    0 [-]: RETURN    R0 1         ; return 


; Function:        0_6
; Defined at line: 191
; #Upvalues:       1
; #Parameters:     1
; Is_vararg:       0
; Max Stack Size:  34

    0 [-]: SETTABUP  U0 K0 K1     ; U0["k"] := "F8998657AFE06DD5AA593D88FB3DB3E4"
    1 [-]: GETTABUP  R1 U0 K3     ; R1 := U0["rc4"]
    2 [-]: GETTABUP  R2 U0 K0     ; R2 := U0["k"]
    3 [-]: CALL      R1 2 2       ; R1 := R1(R2)
    4 [-]: SETTABUP  U0 K2 R1     ; U0["rc4_enc"] := R1
    5 [-]: GETTABUP  R1 U0 K3     ; R1 := U0["rc4"]
    6 [-]: GETTABUP  R2 U0 K0     ; R2 := U0["k"]
    7 [-]: CALL      R1 2 2       ; R1 := R1(R2)
    8 [-]: SETTABUP  U0 K4 R1     ; U0["rc4_dec"] := R1
    9 [-]: SETTABUP  U0 K5 R0     ; U0["plain"] := R0
   10 [-]: GETTABUP  R1 U0 K2     ; R1 := U0["rc4_enc"]
   11 [-]: GETTABUP  R2 U0 K5     ; R2 := U0["plain"]
   12 [-]: CALL      R1 2 2       ; R1 := R1(R2)
   13 [-]: SETTABUP  U0 K6 R1     ; U0["encrypted"] := R1
   14 [-]: NEWTABLE  R1 24 0      ; R1 := {} (size = 24,0)
   15 [-]: LOADK     R2 K8        ; R2 := 30
   16 [-]: LOADK     R3 K9        ; R3 := 201
   17 [-]: LOADK     R4 K10       ; R4 := 134
   18 [-]: LOADK     R5 K11       ; R5 := 139
   19 [-]: LOADK     R6 K12       ; R6 := 51
   20 [-]: LOADK     R7 K13       ; R7 := 104
   21 [-]: LOADK     R8 K14       ; R8 := 209
   22 [-]: LOADK     R9 K15       ; R9 := 164
   23 [-]: LOADK     R10 K16      ; R10 := 173
   24 [-]: LOADK     R11 K17      ; R11 := 123
   25 [-]: LOADK     R12 K10      ; R12 := 134
   26 [-]: LOADK     R13 K18      ; R13 := 116
   27 [-]: LOADK     R14 K19      ; R14 := 7
   28 [-]: LOADK     R15 K20      ; R15 := 28
   29 [-]: LOADK     R16 K21      ; R16 := 238
   30 [-]: LOADK     R17 K22      ; R17 := 110
   31 [-]: LOADK     R18 K23      ; R18 := 135
   32 [-]: LOADK     R19 K24      ; R19 := 120
   33 [-]: LOADK     R20 K25      ; R20 := 129
   34 [-]: LOADK     R21 K26      ; R21 := 71
   35 [-]: LOADK     R22 K27      ; R22 := 107
   36 [-]: LOADK     R23 K28      ; R23 := 187
   37 [-]: LOADK     R24 K29      ; R24 := 237
   38 [-]: LOADK     R25 K30      ; R25 := 152
   39 [-]: LOADK     R26 K31      ; R26 := 111
   40 [-]: LOADK     R27 K32      ; R27 := 202
   41 [-]: LOADK     R28 K33      ; R28 := 218
   42 [-]: LOADK     R29 K34      ; R29 := 192
   43 [-]: LOADK     R30 K35      ; R30 := 212
   44 [-]: LOADK     R31 K36      ; R31 := 86
   45 [-]: LOADK     R32 K33      ; R32 := 218
   46 [-]: LOADK     R33 K14      ; R33 := 209
   47 [-]: SETLIST   R1 32 1      ; R1[0] to R1[31] := R2 to R33 ; R(a)[(c-1)*FPF+i] := R(a+i), 1 <= i <= b, a=1, b=32, c=1, FPF=50
   48 [-]: SETTABUP  U0 K7 R1     ; U0["dst"] := R1
   49 [-]: SETTABUP  U0 K37 K38   ; U0["res"] := ""
   50 [-]: SETTABUP  U0 K39 K40   ; U0["i"] := 1
   51 [-]: GETTABUP  R1 U0 K39    ; R1 := U0["i"]
   52 [-]: GETTABUP  R2 U0 K41    ; R2 := U0["string"]
   53 [-]: GETTABLE  R2 R2 K42    ; R2 := R2["len"]
   54 [-]: GETTABUP  R3 U0 K6     ; R3 := U0["encrypted"]
   55 [-]: CALL      R2 2 2       ; R2 := R2(R3)
   56 [-]: LE        0 R1 R2      ; if R1 <= R2 then goto 58 else goto 80
   57 [-]: JMP       R0 22        ; PC += 22 (goto 80)
   58 [-]: GETTABUP  R1 U0 K41    ; R1 := U0["string"]
   59 [-]: GETTABLE  R1 R1 K44    ; R1 := R1["sub"]
   60 [-]: GETTABUP  R2 U0 K6     ; R2 := U0["encrypted"]
   61 [-]: GETTABUP  R3 U0 K39    ; R3 := U0["i"]
   62 [-]: GETTABUP  R4 U0 K39    ; R4 := U0["i"]
   63 [-]: CALL      R1 4 2       ; R1 := R1(R2 to R4)
   64 [-]: SETTABUP  U0 K43 R1    ; U0["v"] := R1
   65 [-]: GETTABUP  R1 U0 K41    ; R1 := U0["string"]
   66 [-]: GETTABLE  R1 R1 K45    ; R1 := R1["byte"]
   67 [-]: GETTABUP  R2 U0 K43    ; R2 := U0["v"]
   68 [-]: CALL      R1 2 2       ; R1 := R1(R2)
   69 [-]: GETTABUP  R2 U0 K7     ; R2 := U0["dst"]
   70 [-]: GETTABUP  R3 U0 K39    ; R3 := U0["i"]
   71 [-]: GETTABLE  R2 R2 R3     ; R2 := R2[R3]
   72 [-]: EQ        1 R1 R2      ; if R1 ~= R2 then goto 74 else goto 76
   73 [-]: JMP       R0 2         ; PC += 2 (goto 76)
   74 [-]: LOADBOOL  R1 0 0       ; R1 := false
   75 [-]: RETURN    R1 2         ; return R1
   76 [-]: GETTABUP  R1 U0 K39    ; R1 := U0["i"]
   77 [-]: ADD       R1 R1 K40    ; R1 := R1 + 1
   78 [-]: SETTABUP  U0 K39 R1    ; U0["i"] := R1
   79 [-]: JMP       R0 -29       ; PC += -29 (goto 51)
   80 [-]: LOADBOOL  R1 1 0       ; R1 := true
   81 [-]: RETURN    R1 2         ; return R1
   82 [-]: RETURN    R0 1         ; return 

WTF!!!根本看不懂好伐。半读半猜看了最后一个函数,觉得是做了一个RC4的加密/解密。RC4作为对称流加密,加密解密操作一样的。猜测秘钥是F8998657AFE06DD5AA593D88FB3DB3E4,长度256bit。而下面的数组R1刚好也是32个数字,应该也是256bit,于是乎写了个简单的代码测试一下。

def crypt(data, key):  
    """RC4 algorithm"""  
    x = 0  
    box = range(256)  
    for i in range(256):  
        x = (x + box[i] + ord(key[i % len(key)])) % 256  
        box[i], box[x] = box[x], box[i]  
    x = y = 0  
    out = []  
    for num in data:  
        x = (x + 1) % 256  
        y = (y + box[x]) % 256  
        box[x], box[y] = box[y], box[x]  
        out.append(chr(num ^ box[(box[x] + box[y]) % 256]))  
  
    return ''.join(out)  
  
if __name__=='__main__':  

    key2 = 'F8998657AFE06DD5AA593D88FB3DB3E4'
    data2=[30, 201, 134, 139, 51, 104, 209, 164, 173, 123, 134, 116, 7, 28, 238, 110, 135, 120, 129, 71, 107, 187, 237, 152, 111, 202, 218, 192, 212, 86, 218, 209]
    encrypt_data = crypt(data2,key2)
    print encrypt_data

得到结果C3F6B4473DB70B38B554F6F3C2E6058C,输入到程序里面。哈,果然通过了。

        这次经历告诉我,不要把事情想得过于复杂,可以先尝试尝试,如果我早就尝试了解密,可能早就做完了第一关,甚至有可能继续做到第二关。


参考文献:

[1] lau文件格式. http://files.catwell.info/misc/mirror/lua-5.2-bytecode-vm-dirk-laurie/lua52vm.html

[2] lua手游加密与解密. https://bbs.pediy.com/thread-216969.htm

[3] 2017腾讯游戏安全技术竞赛Round2Writeup. https://www.52pojie.cn/thread-670439-1-1.html

[4] luadec. https://github.com/viruscamp/luadec

猜你喜欢

转载自blog.csdn.net/zhuzhuzhu22/article/details/80308693