Skip to content

Commit 8d75e4a

Browse files
committed
Should avoid the error when there is a closure without move or getupval defined
1 parent 9c07b83 commit 8d75e4a

File tree

3 files changed

+81
-65
lines changed

3 files changed

+81
-65
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
.idea
12
/target
23
/temp
34
/build
Lines changed: 69 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -1,71 +1,71 @@
11
use lua_deserializer::enums::opcode_type::OpcodeType;
22

3-
pub fn get_opcode_string(opcode: &OpcodeType) -> String {
3+
pub fn get_opcode_string(opcode: &OpcodeType, opcode_list: &Vec<OpcodeType>) -> String {
44
match opcode {
5-
OpcodeType::OpMove => "memory[inst[$A_REGISTER$]] = memory[inst[$B_REGISTER$]]",
6-
OpcodeType::OpLoadConst => "memory[inst[$A_REGISTER$]] = inst[$CONSTANT$]",
5+
OpcodeType::OpMove => "memory[inst[$A_REGISTER$]] = memory[inst[$B_REGISTER$]]".to_string(),
6+
OpcodeType::OpLoadConst => "memory[inst[$A_REGISTER$]] = inst[$CONSTANT$]".to_string(),
77
OpcodeType::OpLoadBool => {
88
"memory[inst[$A_REGISTER$]] = inst[$B_REGISTER$] ~= 0
99
10-
if inst[$C_REGISTER$] ~= 0 then pc = pc + 1 end"
10+
if inst[$C_REGISTER$] ~= 0 then pc = pc + 1 end".to_string()
1111
}
12-
OpcodeType::OpLoadNil => "for i = inst[$A_REGISTER$], inst[$B_REGISTER$] do memory[i] = nil end",
12+
OpcodeType::OpLoadNil => "for i = inst[$A_REGISTER$], inst[$B_REGISTER$] do memory[i] = nil end".to_string(),
1313
OpcodeType::OpGetUpval => {
1414
"local uv = upvals[inst[$B_REGISTER$]]
1515
16-
memory[inst[$A_REGISTER$]] = uv[2][uv[1]]"
16+
memory[inst[$A_REGISTER$]] = uv[2][uv[1]]".to_string()
1717
}
18-
OpcodeType::OpGetGlobal => "memory[inst[$A_REGISTER$]] = env[inst[$CONSTANT$]]",
19-
OpcodeType::OpGetTable => "memory[inst[$A_REGISTER$]] = memory[inst[$B_REGISTER$]][constantC(inst)]",
20-
OpcodeType::OpSetGlobal => "env[inst[$CONSTANT$]] = memory[inst[$A_REGISTER$]]",
18+
OpcodeType::OpGetGlobal => "memory[inst[$A_REGISTER$]] = env[inst[$CONSTANT$]]".to_string(),
19+
OpcodeType::OpGetTable => "memory[inst[$A_REGISTER$]] = memory[inst[$B_REGISTER$]][constantC(inst)]".to_string(),
20+
OpcodeType::OpSetGlobal => "env[inst[$CONSTANT$]] = memory[inst[$A_REGISTER$]]".to_string(),
2121
OpcodeType::OpSetUpval => {
2222
"local uv = upvals[inst[$B_REGISTER$]]
2323
24-
uv[2][uv[1]] = memory[inst[$A_REGISTER$]]"
24+
uv[2][uv[1]] = memory[inst[$A_REGISTER$]]".to_string()
2525
}
26-
OpcodeType::OpSetTable => "memory[inst[$A_REGISTER$]][constantB(inst)] = constantC(inst)",
27-
OpcodeType::OpNewTable => "memory[inst[$A_REGISTER$]] = {}",
26+
OpcodeType::OpSetTable => "memory[inst[$A_REGISTER$]][constantB(inst)] = constantC(inst)".to_string(),
27+
OpcodeType::OpNewTable => "memory[inst[$A_REGISTER$]] = {}".to_string(),
2828
OpcodeType::OpSelf => {
2929
"memory[inst[$A_REGISTER$] + 1] = memory[inst[$B_REGISTER$]]
30-
memory[inst[$A_REGISTER$]] = memory[inst[$B_REGISTER$]][constantC(inst)]"
30+
memory[inst[$A_REGISTER$]] = memory[inst[$B_REGISTER$]][constantC(inst)]".to_string()
3131
}
32-
OpcodeType::OpAdd => "memory[inst[$A_REGISTER$]] = constantB(inst) + constantC(inst)",
33-
OpcodeType::OpSub => "memory[inst[$A_REGISTER$]] = constantB(inst) - constantC(inst)",
34-
OpcodeType::OpMul => "memory[inst[$A_REGISTER$]] = constantB(inst) * constantC(inst)",
35-
OpcodeType::OpDiv => "memory[inst[$A_REGISTER$]] = constantB(inst) / constantC(inst)",
36-
OpcodeType::OpMod => "memory[inst[$A_REGISTER$]] = constantB(inst) % constantC(inst)",
37-
OpcodeType::OpPow => "memory[inst[$A_REGISTER$]] = constantB(inst) ^ constantC(inst)",
38-
OpcodeType::OpUnm => "memory[inst[$A_REGISTER$]] = -memory[inst[$B_REGISTER$]]",
39-
OpcodeType::OpNot => "memory[inst[$A_REGISTER$]] = not memory[inst[$B_REGISTER$]]",
40-
OpcodeType::OpLen => "memory[inst[$A_REGISTER$]] = #memory[inst[$B_REGISTER$]]",
32+
OpcodeType::OpAdd => "memory[inst[$A_REGISTER$]] = constantB(inst) + constantC(inst)".to_string(),
33+
OpcodeType::OpSub => "memory[inst[$A_REGISTER$]] = constantB(inst) - constantC(inst)".to_string(),
34+
OpcodeType::OpMul => "memory[inst[$A_REGISTER$]] = constantB(inst) * constantC(inst)".to_string(),
35+
OpcodeType::OpDiv => "memory[inst[$A_REGISTER$]] = constantB(inst) / constantC(inst)".to_string(),
36+
OpcodeType::OpMod => "memory[inst[$A_REGISTER$]] = constantB(inst) % constantC(inst)".to_string(),
37+
OpcodeType::OpPow => "memory[inst[$A_REGISTER$]] = constantB(inst) ^ constantC(inst)".to_string(),
38+
OpcodeType::OpUnm => "memory[inst[$A_REGISTER$]] = -memory[inst[$B_REGISTER$]]".to_string(),
39+
OpcodeType::OpNot => "memory[inst[$A_REGISTER$]] = not memory[inst[$B_REGISTER$]]".to_string(),
40+
OpcodeType::OpLen => "memory[inst[$A_REGISTER$]] = #memory[inst[$B_REGISTER$]]".to_string(),
4141
OpcodeType::OpConcat => {
4242
"local B = inst[$B_REGISTER$]
4343
local str = memory[B]
4444
4545
for i = B + 1, inst[$C_REGISTER$] do str = str .. memory[i] end
4646
47-
memory[inst[$A_REGISTER$]] = str"
47+
memory[inst[$A_REGISTER$]] = str".to_string()
4848
}
49-
OpcodeType::OpJmp => "pc = pc + inst[$B_REGISTER$]",
49+
OpcodeType::OpJmp => "pc = pc + inst[$B_REGISTER$]".to_string(),
5050
OpcodeType::OpEq => "if (constantB(inst) == constantC(inst)) == (inst[$A_REGISTER$] ~= 0) then pc = pc + code[pc][$B_REGISTER$] end
5151
52-
pc = pc + 1",
52+
pc = pc + 1".to_string(),
5353
OpcodeType::OpLt => "if (constantB(inst) < constantC(inst)) == (inst[$A_REGISTER$] ~= 0) then pc = pc + code[pc][$B_REGISTER$] end
5454
55-
pc = pc + 1",
55+
pc = pc + 1".to_string(),
5656
OpcodeType::OpLe => "if (constantB(inst) <= constantC(inst)) == (inst[$A_REGISTER$] ~= 0) then pc = pc + code[pc][$B_REGISTER$] end
5757
58-
pc = pc + 1",
58+
pc = pc + 1".to_string(),
5959
OpcodeType::OpTest => "if (not memory[inst[$A_REGISTER$]]) ~= (inst[$C_REGISTER$] ~= 0) then pc = pc + code[pc][$B_REGISTER$] end
60-
pc = pc + 1",
60+
pc = pc + 1".to_string(),
6161
OpcodeType::OpTestSet => "local A = inst[$A_REGISTER$]
6262
local B = inst[$B_REGISTER$]
6363
6464
if (not memory[B]) ~= (inst[$C_REGISTER$] ~= 0) then
6565
memory[A] = memory[B]
6666
pc = pc + code[pc][$B_REGISTER$]
6767
end
68-
pc = pc + 1",
68+
pc = pc + 1".to_string(),
6969
OpcodeType::OpCall => "local A = inst[$A_REGISTER$]
7070
local B = inst[$B_REGISTER$]
7171
local C = inst[$C_REGISTER$]
@@ -86,7 +86,7 @@ pub fn get_opcode_string(opcode: &OpcodeType) -> String {
8686
ret_num = C - 1
8787
end
8888
89-
TableMove(ret_list, 1, ret_num, A, memory)",
89+
TableMove(ret_list, 1, ret_num, A, memory)".to_string(),
9090
OpcodeType::OpTailCall => "local A = inst[$A_REGISTER$]
9191
local B = inst[$B_REGISTER$]
9292
local params
@@ -99,7 +99,7 @@ pub fn get_opcode_string(opcode: &OpcodeType) -> String {
9999
100100
close_lua_upvalues(open_list, 0)
101101
102-
return memory[A](TableUnpack(memory, A + 1, A + params))",
102+
return memory[A](TableUnpack(memory, A + 1, A + params))".to_string(),
103103
OpcodeType::OpReturn => "local A = inst[$A_REGISTER$]
104104
local B = inst[$B_REGISTER$]
105105
local len
@@ -112,7 +112,7 @@ pub fn get_opcode_string(opcode: &OpcodeType) -> String {
112112
113113
close_lua_upvalues(open_list, 0)
114114
115-
return TableUnpack(memory, A, A + len - 1)",
115+
return TableUnpack(memory, A, A + len - 1)".to_string(),
116116
OpcodeType::OpForLoop => "local A = inst[$A_REGISTER$]
117117
local step = memory[A + 2]
118118
local index = memory[A] + step
@@ -129,7 +129,7 @@ pub fn get_opcode_string(opcode: &OpcodeType) -> String {
129129
memory[A] = index
130130
memory[A + 3] = index
131131
pc = pc + inst[$B_REGISTER$]
132-
end",
132+
end".to_string(),
133133
OpcodeType::OpForPrep => "local A = inst[$A_REGISTER$]
134134
-- local init, limit, step
135135
@@ -146,7 +146,7 @@ pub fn get_opcode_string(opcode: &OpcodeType) -> String {
146146
memory[A + 1] = limit
147147
memory[A + 2] = step
148148
149-
pc = pc + inst[$B_REGISTER$]",
149+
pc = pc + inst[$B_REGISTER$]".to_string(),
150150
OpcodeType::OpTForLoop => "local A = inst[$A_REGISTER$]
151151
local base = A + 3
152152
@@ -159,7 +159,7 @@ pub fn get_opcode_string(opcode: &OpcodeType) -> String {
159159
pc = pc + code[pc][3]
160160
end
161161
162-
pc = pc + 1",
162+
pc = pc + 1".to_string(),
163163
OpcodeType::OpSetList => "local A = inst[$A_REGISTER$]
164164
local C = inst[$C_REGISTER$]
165165
local len = inst[$B_REGISTER$]
@@ -175,29 +175,42 @@ pub fn get_opcode_string(opcode: &OpcodeType) -> String {
175175
176176
offset = (C - 1) * 50 --FIELDS_PER_FLUSH
177177
178-
TableMove(memory, A + 1, A + len, offset + 1, tab)",
179-
OpcodeType::OpClose => "close_lua_upvalues(open_list, inst[$A_REGISTER$])",
180-
OpcodeType::OpClosure => "local sub = subs[inst[$B_REGISTER$] + 1] -- offset for 1 based index
178+
TableMove(memory, A + 1, A + len, offset + 1, tab)".to_string(),
179+
OpcodeType::OpClose => "close_lua_upvalues(open_list, inst[$A_REGISTER$])".to_string(),
180+
OpcodeType::OpClosure => {
181+
let mut opcode_string = "local sub = subs[inst[$B_REGISTER$] + 1] -- offset for 1 based index
181182
local nups = sub[$UPVALUE_COUNT$]
182183
local uvlist
183184
184185
if nups ~= 0 then
185-
uvlist = {}
186-
187-
for i = 1, nups do
188-
local pseudo = code[pc + i - 1]
189-
190-
if pseudo[$OPCODE$] == $MOVE_OPCODE$ then -- @MOVE
191-
uvlist[i - 1] = open_lua_upvalue(open_list, pseudo[$B_REGISTER$], memory)
192-
elseif pseudo[$OPCODE$] == $GETUPVAL_OPCODE$ then -- @GETUPVAL
193-
uvlist[i - 1] = upvals[pseudo[$B_REGISTER$]]
194-
end
195-
end
196-
197-
pc = pc + nups
198-
end
199-
200-
memory[inst[$A_REGISTER$]] = lua_wrap_state(sub, env, uvlist)",
186+
uvlist = {}".to_string();
187+
188+
if opcode_list.contains(&OpcodeType::OpMove) || opcode_list.contains(&OpcodeType::OpGetUpval) {
189+
opcode_string += "for i = 1, nups do
190+
local pseudo = code[pc + i - 1]";
191+
192+
if opcode_list.contains(&OpcodeType::OpMove) {
193+
opcode_string += "if pseudo[$OPCODE$] == $MOVE_OPCODE$ then -- @MOVE
194+
uvlist[i - 1] = open_lua_upvalue(open_list, pseudo[$B_REGISTER$], memory)
195+
end";
196+
}
197+
198+
if opcode_list.contains(&OpcodeType::OpGetUpval) {
199+
opcode_string += "if pseudo[$OPCODE$] == $GETUPVAL_OPCODE$ then -- @GETUPVAL
200+
uvlist[i - 1] = upvals[pseudo[$B_REGISTER$]]
201+
end";
202+
}
203+
204+
opcode_string += " end
205+
206+
pc = pc + nups";
207+
}
208+
209+
210+
211+
opcode_string += " end; memory[inst[$A_REGISTER$]] = lua_wrap_state(sub, env, uvlist)";
212+
213+
opcode_string},
201214
OpcodeType::OpVarArg => "local A = inst[$A_REGISTER$]
202215
local len = inst[$B_REGISTER$]
203216
@@ -206,7 +219,7 @@ pub fn get_opcode_string(opcode: &OpcodeType) -> String {
206219
top_index = A + len - 1
207220
end
208221
209-
TableMove(vararg.list, 1, len, A, memory)",
222+
TableMove(vararg.list, 1, len, A, memory)".to_string(),
210223
}
211-
.to_string()
224+
212225
}

src/obfuscator/vm_generator.rs

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -218,7 +218,7 @@ impl VMGenerator {
218218
for (i, opcode) in obfuscation_context.opcode_map.iter().enumerate() {
219219
vm_string += if i == 0 { "if " } else { " elseif " };
220220
vm_string += &format!("op == {} then --[[{:#?}]] ", i, opcode);
221-
vm_string += &opcode_strings::get_opcode_string(opcode);
221+
vm_string += &opcode_strings::get_opcode_string(opcode, &opcode_list);
222222
}
223223

224224
vm_string += " end";
@@ -316,17 +316,19 @@ impl VMGenerator {
316316
vm_string = vm_string.replace(&format!("${}$", *rename), &(i + 1).to_string());
317317
}
318318

319-
let move_opcode = opcode_list
320-
.iter()
321-
.position(|&r| r == OpcodeType::OpMove)
322-
.expect("Move Opcode index cannot be found");
319+
let move_opcode = opcode_list.iter().position(|&r| r == OpcodeType::OpMove);
323320
let getupval_opcode = opcode_list
324321
.iter()
325-
.position(|&r| r == OpcodeType::OpGetUpval)
326-
.expect("Get Upval Opcode index cannot be found");
322+
.position(|&r| r == OpcodeType::OpGetUpval);
323+
324+
if move_opcode != None {
325+
vm_string = vm_string.replace("$MOVE_OPCODE$", &move_opcode.unwrap().to_string());
326+
}
327327

328-
vm_string = vm_string.replace("$MOVE_OPCODE$", &move_opcode.to_string());
329-
vm_string = vm_string.replace("$GETUPVAL_OPCODE$", &getupval_opcode.to_string());
328+
if getupval_opcode != None {
329+
vm_string =
330+
vm_string.replace("$GETUPVAL_OPCODE$", &getupval_opcode.unwrap().to_string());
331+
}
330332

331333
vm_string
332334
}

0 commit comments

Comments
 (0)