qintangtao

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::

1、直接运行起来,再用OD附加

 在此处luajit加载并调用main函数

004021C7    E8 64FE0000     call CrackMe.00412030                    ; luaL_newstate
004021CC    8BF0            mov esi,eax
004021CE    56              push esi
004021CF    E8 9C000100     call CrackMe.00412270                    ; luaL_openlibs(lua_State *L)
004021D4    53              push ebx
004021D5    68 75020000     push 0x275
004021DA    8D4424 3C       lea eax,dword ptr ss:[esp+0x3C]
004021DE    50              push eax
004021DF    56              push esi
004021E0    E8 5B040100     call CrackMe.00412640                    ; int luaL_loadbuffer(lua_State*L,const char*buff,size_t size,const char*name
004021E5    53              push ebx
004021E6    56              push esi
004021E7    E8 C41B0100     call CrackMe.00413DB0
004021EC    68 883E4800     push CrackMe.00483E88                    ; ASCII "main"
004021F1    68 EED8FFFF     push -0x2712
004021F6    56              push esi
004021F7    E8 84130100     call CrackMe.00413580                    ; void  (lua_getfield) (lua_State *L, int idx, const char *k);
004021FC    57              push edi
004021FD    56              push esi
004021FE    E8 DD0E0100     call CrackMe.004130E0                    ; lua_pushstring
00402203    6A 01           push 0x1
00402205    56              push esi
00402206    E8 A51B0100     call CrackMe.00413DB0                    ; lua_call

2、在luaL_loadbuffer出下断开dump下luajit的bytecode

 使用luajit-decomp进行反编译,注意:可以此处是LuaJIT-2.1.0-beta3,需编译替换luajit-decomp中对应的文件

    在IDA中字符串列表中搜索lua可以知道lua和luajit的版本。注意:由于有反调试,先运行程序在用OD附加然后dump

Address        Length   Type String                                       
-------        ------   ---- ------                                       
.text:00471CFC 0000002E C    PANIC: unprotected error in call to Lua API (
.text:00473EA0 00000028 C    'module' not called from a Lua function      
.text:00473F40 00000026 C    .\\?.lua;!\\lua\\?.lua;!\\lua\\?\\init.lua;  
.text:00472097 00000016 C    Lua function expected                        
.text:00473378 00000013 C    LuaJIT 2.1.0-beta3                           
.text:00473D1C 0000000D C    luaJIT_BC_%s                                 
.text:00473590 0000000C C    lua_debug>                                   
.text:00473D2C 0000000B C    luaopen_%s                                   
.text:00473F34 0000000A C    LUA_CPATH                                    
.text:00473F74 0000000A C    LUA_NOENV                                    
.text:00473F68 00000009 C    LUA_PATH                                     
.text:00474240 00000008 C    Lua 5.1                                      

dump下luajit的bytecode:

-- BYTECODE -- lua.bytes:0-0
function someFunc0()
var_0_4 = INPUT_VAR_0_
var_0_5 = INPUT_VAR_1_
var_0_6 = INPUT_VAR_1_
var_0_3 = string.sub(var_0_4, var_0_5, var_0_6) --var_0_3 REPLACE-REPLACE
string.byte(var_0_3)
end

-- BYTECODE -- lua.bytes:0-0
function someFunc1()
var_1_2 = INPUT_VAR_0_
var_1_1 = string.len(var_1_2)
if var_1_1 ~= 0 then
--jump to 0009 (if previous if statement is false) --0009 JMP-JMP
var_1_1 = 0 --var_1_1 NUMBER-NUMBER
return var_1_1
--location 0009--0009 LOCATION-LOCATION
var_1_3 = INPUT_VAR_0_
var_1_4 = 1 --var_1_4 NUMBER-NUMBER
var_1_2 = by(var_1_3, var_1_4)
var_1_3 = 112 --var_1_3 NUMBER-NUMBER
var_1_1 = bit.bxor(var_1_2, var_1_3)
var_1_4 = INPUT_VAR_0_
var_1_5 = 2 --var_1_5 NUMBER-NUMBER
var_1_3 = by(var_1_4, var_1_5)
var_1_4 = 101 --var_1_4 NUMBER-NUMBER
var_1_2 = bit.bxor(var_1_3, var_1_4)
var_1_5 = INPUT_VAR_0_
var_1_6 = 3 --var_1_6 NUMBER-NUMBER
var_1_4 = by(var_1_5, var_1_6)
var_1_5 = 100 --var_1_5 NUMBER-NUMBER
var_1_3 = bit.bxor(var_1_4, var_1_5)
var_1_6 = INPUT_VAR_0_
var_1_7 = 4 --var_1_7 NUMBER-NUMBER
var_1_5 = by(var_1_6, var_1_7)
var_1_6 = 105 --var_1_6 NUMBER-NUMBER
var_1_4 = bit.bxor(var_1_5, var_1_6)
var_1_7 = INPUT_VAR_0_
var_1_8 = 5 --var_1_8 NUMBER-NUMBER
var_1_6 = by(var_1_7, var_1_8)
var_1_7 = 121 --var_1_7 NUMBER-NUMBER
var_1_5 = bit.bxor(var_1_6, var_1_7)
var_1_8 = INPUT_VAR_0_
var_1_9 = 6 --var_1_9 NUMBER-NUMBER
var_1_7 = by(var_1_8, var_1_9)
var_1_8 = 49 --var_1_8 NUMBER-NUMBER
var_1_6 = bit.bxor(var_1_7, var_1_8)
var_1_9 = INPUT_VAR_0_
var_1_10 = 7 --var_1_10 NUMBER-NUMBER
var_1_8 = by(var_1_9, var_1_10)
var_1_9 = 50 --var_1_9 NUMBER-NUMBER
var_1_7 = bit.bxor(var_1_8, var_1_9)
var_1_10 = INPUT_VAR_0_
var_1_11 = 8 --var_1_11 NUMBER-NUMBER
var_1_9 = by(var_1_10, var_1_11)
var_1_10 = 51 --var_1_10 NUMBER-NUMBER
var_1_8 = bit.bxor(var_1_9, var_1_10)
var_1_11 = INPUT_VAR_0_
var_1_12 = 9 --var_1_12 NUMBER-NUMBER
var_1_10 = by(var_1_11, var_1_12)
var_1_11 = 52 --var_1_11 NUMBER-NUMBER
var_1_9 = bit.bxor(var_1_10, var_1_11)
var_1_12 = INPUT_VAR_0_
var_1_13 = 10 --var_1_13 NUMBER-NUMBER
var_1_11 = by(var_1_12, var_1_13)
var_1_12 = 53 --var_1_12 NUMBER-NUMBER
var_1_10 = bit.bxor(var_1_11, var_1_12)
var_1_13 = INPUT_VAR_0_
var_1_14 = 11 --var_1_14 NUMBER-NUMBER
var_1_12 = by(var_1_13, var_1_14)
var_1_13 = 54 --var_1_13 NUMBER-NUMBER
var_1_11 = bit.bxor(var_1_12, var_1_13)
var_1_14 = INPUT_VAR_0_
var_1_15 = 12 --var_1_15 NUMBER-NUMBER
var_1_13 = by(var_1_14, var_1_15)
var_1_14 = 55 --var_1_14 NUMBER-NUMBER
var_1_12 = bit.bxor(var_1_13, var_1_14)
var_1_13 = var_1_1
var_1_14 = var_1_2
var_1_15 = var_1_3
var_1_16 = var_1_4
var_1_17 = var_1_5
var_1_18 = var_1_6
var_1_19 = var_1_7
var_1_20 = var_1_8
var_1_21 = var_1_9
var_1_22 = var_1_10
var_1_23 = var_1_11
var_1_24 = var_1_12
return var_1_13, var_1_14, var_1_15, var_1_16, var_1_17, var_1_18, var_1_19, var_1_20, var_1_21, var_1_22, var_1_23, var_1_24
end

-- BYTECODE -- lua.bytes:0-0
function someFunc2()
var_2_1 = "bit" --var_2_1 STRING-STRING
require(var_2_1)
local randomFunction0 = function() end -- starts at  lua.bytes:0
by = randomFunction0
local randomFunction1 = function() end -- starts at  lua.bytes:0
main = randomFunction1
return
end

可以看出

  someFunc0函数截取字符串指定位置的字符 并转换成byte

    someFunc1函数对字符串调用someFunc0函数每个字符截取 并 xor 

       someFunc2中可以看出 by = randomFunction0 应该就是 by = someFunc0,  main = randomFunction1 应该就是 main = someFunc1

3、调用完lua中的main函数后,从lua栈中依次取出每个字符加密后的byte, 然后再次进行 xor

0040222C    55              push ebp
0040222D    6A F4           push -0xC
0040222F    56              push esi
00402230    E8 AB0A0100     call CrackMe.00412CE0                    ; lua_Integer lua_tointegerx (lua_State *L, int idx, int *isnum);
00402235    8BF8            mov edi,eax
00402237    6A F5           push -0xB
00402239    56              push esi
0040223A    83F7 05         xor edi,0x5
0040223D    E8 9E0A0100     call CrackMe.00412CE0
00402242    8BD8            mov ebx,eax
00402244    6A F6           push -0xA
00402246    56              push esi
00402247    83F3 12         xor ebx,0x12
0040224A    E8 910A0100     call CrackMe.00412CE0
0040224F    8BE8            mov ebp,eax
00402251    6A F7           push -0x9
00402253    56              push esi
00402254    83F5 0A         xor ebp,0xA
00402257    E8 840A0100     call CrackMe.00412CE0
0040225C    83F0 29         xor eax,0x29
0040225F    6A F8           push -0x8
00402261    56              push esi
00402262    894424 58       mov dword ptr ss:[esp+0x58],eax
00402266    E8 750A0100     call CrackMe.00412CE0
0040226B    83F0 42         xor eax,0x42
0040226E    6A F9           push -0x7
00402270    56              push esi
00402271    894424 48       mov dword ptr ss:[esp+0x48],eax
00402275    E8 660A0100     call CrackMe.00412CE0
0040227A    83F0 41         xor eax,0x41
0040227D    6A FA           push -0x6
0040227F    56              push esi
00402280    894424 60       mov dword ptr ss:[esp+0x60],eax
00402284    E8 570A0100     call CrackMe.00412CE0
00402289    83F0 75         xor eax,0x75
0040228C    6A FB           push -0x5
0040228E    56              push esi
0040228F    894424 60       mov dword ptr ss:[esp+0x60],eax
00402293    E8 480A0100     call CrackMe.00412CE0
00402298    83C4 40         add esp,0x40
0040229B    83F0 61         xor eax,0x61
0040229E    6A FC           push -0x4
004022A0    56              push esi
004022A1    894424 18       mov dword ptr ss:[esp+0x18],eax
004022A5    E8 360A0100     call CrackMe.00412CE0
004022AA    83F0 35         xor eax,0x35
004022AD    6A FD           push -0x3
004022AF    56              push esi
004022B0    894424 24       mov dword ptr ss:[esp+0x24],eax
004022B4    E8 270A0100     call CrackMe.00412CE0
004022B9    35 83000000     xor eax,0x83
004022BE    6A FE           push -0x2
004022C0    56              push esi
004022C1    894424 34       mov dword ptr ss:[esp+0x34],eax
004022C5    E8 160A0100     call CrackMe.00412CE0
004022CA    83F0 55         xor eax,0x55
004022CD    6A FF           push -0x1
004022CF    56              push esi
004022D0    894424 44       mov dword ptr ss:[esp+0x44],eax
004022D4    E8 070A0100     call CrackMe.00412CE0
004022D9    35 94000000     xor eax,0x94
004022DE    6A F3           push -0xD
004022E0    56              push esi
004022E1    894424 54       mov dword ptr ss:[esp+0x54],eax
004022E5    E8 26050100     call CrackMe.00412810
004022EA    56              push esi
004022EB    E8 80200100     call CrackMe.00414370                    ; lua_close

4、最后每个byte和固定的值进行比较

004022F3    83FF 18         cmp edi,0x18
004022F6    75 54           jnz short CrackMe.0040234C
004022F8    83FB 16         cmp ebx,0x16
004022FB    75 4F           jnz short CrackMe.0040234C
004022FD    83FD 1E         cmp ebp,0x1E
00402300    75 4A           jnz short CrackMe.0040234C
00402302    837C24 30 2F    cmp dword ptr ss:[esp+0x30],0x2F
00402307    75 43           jnz short CrackMe.0040234C
00402309    837C24 18 48    cmp dword ptr ss:[esp+0x18],0x48
0040230E    75 3C           jnz short CrackMe.0040234C
00402310    837C24 28 11    cmp dword ptr ss:[esp+0x28],0x11
00402315    75 35           jnz short CrackMe.0040234C
00402317    837C24 20 21    cmp dword ptr ss:[esp+0x20],0x21
0040231C    75 2E           jnz short CrackMe.0040234C
0040231E    837C24 10 37    cmp dword ptr ss:[esp+0x10],0x37
00402323    75 27           jnz short CrackMe.0040234C
00402325    837C24 14 33    cmp dword ptr ss:[esp+0x14],0x33
0040232A    75 20           jnz short CrackMe.0040234C
0040232C    817C24 1C 86000>cmp dword ptr ss:[esp+0x1C],0x86
00402334    75 16           jnz short CrackMe.0040234C
00402336    837C24 24 52    cmp dword ptr ss:[esp+0x24],0x52
0040233B    75 0F           jnz short CrackMe.0040234C
0040233D    817C24 2C 94000>cmp dword ptr ss:[esp+0x2C],0x94
00402345    75 05           jnz short CrackMe.0040234C

5、可以提取3处xor的值

   lua中main函数对每个字符xor的值

    [112,101,100,105,121,49,50,51,52,53,54,55]

   0040222C   处对lua输出的每个值进行异或

    [0x5,0x12,0xa,0x29,0x42,0x41,0x75,0x61,0x35,0x83,0x55,0x94]

   004022F3    处对上面两次异或后的结果和下面的值进行比较

    [0x18,0x16,0x1e,0x2f,0x48,0x11,0x21,0x37,0x33,0x86,0x52,0x94]

 

6、用python进行解码

result = [0x18,0x16,0x1E,0x2F,0x48,0x11,0x21,0x37,0x33,0x86,0x52,0x94]
luaxor = [112,101,100,105,121,49,50,51,52,53,54,55]
codexor = [0x5,0x12,0xa,0x29,0x42,0x41,0x75,0x61,0x35,0x83,0x55,0x94]

code = ''
for i in range(len(result)):
    code += chr(result[i]^luaxor[i]^codexor[i])

print code

结果:maposafe2017

posted on 2017-07-04 14:14  qintangtao  阅读(376)  评论(0编辑  收藏  举报