mirror of
https://git.huckle.dev/Huckles-Minecraft-Archive/jpexs-decompiler.git
synced 2026-07-11 06:58:30 +00:00
actions => instructions in AVM2 deobfuscator
added some thread interrupt checks
This commit is contained in:
@@ -1072,7 +1072,7 @@ public class SWFInputStream implements AutoCloseable {
|
||||
* @throws java.lang.InterruptedException
|
||||
*/
|
||||
public List<Tag> readTagList(Timelined timelined, int level, boolean parallel, boolean skipUnusualTags, boolean parseTags, boolean lazy) throws IOException, InterruptedException {
|
||||
if (Thread.currentThread().interrupted()) {
|
||||
if (Thread.currentThread().isInterrupted()) {
|
||||
throw new InterruptedException();
|
||||
}
|
||||
|
||||
|
||||
@@ -50,7 +50,7 @@ public class AVM2DeobfuscatorJumps extends AVM2DeobfuscatorSimple {
|
||||
public void deobfuscate(String path, int classIndex, boolean isStatic, int scriptIndex, ABC abc, AVM2ConstantPool cpool, Trait trait, MethodInfo minfo, MethodBody body) throws InterruptedException {
|
||||
|
||||
//body.getCode().markMappedOffsets();
|
||||
//removeUnreachableActions(body.getCode(), cpool, trait, minfo, body);
|
||||
//removeUnreachableInstructions(body.getCode(), cpool, trait, minfo, body);
|
||||
AVM2Code code = body.getCode();
|
||||
|
||||
boolean found;
|
||||
@@ -81,7 +81,7 @@ public class AVM2DeobfuscatorJumps extends AVM2DeobfuscatorSimple {
|
||||
}
|
||||
}
|
||||
}
|
||||
removeUnreachableActions(body.getCode(), cpool, trait, minfo, body);
|
||||
removeUnreachableInstructions(body.getCode(), cpool, trait, minfo, body);
|
||||
} while (found);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -46,7 +46,6 @@ import com.jpexs.decompiler.graph.TranslateException;
|
||||
import com.jpexs.decompiler.graph.TranslateStack;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
@@ -72,15 +71,10 @@ public class AVM2DeobfuscatorRegisters extends AVM2DeobfuscatorSimple {
|
||||
public void deobfuscate(String path, int classIndex, boolean isStatic, int scriptIndex, ABC abc, AVM2ConstantPool cpool, Trait trait, MethodInfo minfo, MethodBody abody) throws InterruptedException {
|
||||
//System.err.println("regdeo:" + path);
|
||||
|
||||
removeUnreachableActions(abody.getCode(), cpool, trait, minfo, abody);
|
||||
/*for (AVM2Instruction ins : abody.getCode().code) {
|
||||
System.err.println("" + ins.offset + ": " + ins);
|
||||
}*/
|
||||
removeUnreachableInstructions(abody.getCode(), cpool, trait, minfo, abody);
|
||||
Set<Integer> ignoredRegs = new HashSet<>();
|
||||
|
||||
MethodBody body = abody;
|
||||
|
||||
body = abody.clone();
|
||||
MethodBody body = abody.clone();
|
||||
Reference<AVM2Instruction> assignment = new Reference<>(null);
|
||||
ignoredRegs.clear();
|
||||
for (int i = 0; i < body.getLocalReservedCount(); i++) {
|
||||
@@ -100,6 +94,7 @@ public class AVM2DeobfuscatorRegisters extends AVM2DeobfuscatorSimple {
|
||||
if (setReg < 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
//if there is second assignment
|
||||
if (listedRegs.contains(setReg)) {
|
||||
//System.err.println("second assignment of loc" + setReg + ", ignoring");
|
||||
@@ -118,23 +113,29 @@ public class AVM2DeobfuscatorRegisters extends AVM2DeobfuscatorSimple {
|
||||
if ((assignment.getVal().definition instanceof SetLocalTypeIns) || (assignment.getVal().definition instanceof GetLocalTypeIns /*First usage -> value undefined*/)) {
|
||||
super.removeObfuscationIfs(classIndex, isStatic, scriptIndex, abc, cpool, trait, minfo, body, Arrays.asList(assignment.getVal()));
|
||||
}
|
||||
|
||||
if (assignment.getVal().definition instanceof GetLocalTypeIns) {
|
||||
ignoredRegGets.add(setReg);
|
||||
}
|
||||
|
||||
listedRegs.add(setReg);
|
||||
listedLastBodies.add(bodybefore);
|
||||
}
|
||||
|
||||
abody.exceptions = body.exceptions;
|
||||
abody.setCode(body.getCode());
|
||||
removeUnreachableActions(body.getCode(), cpool, trait, minfo, body);
|
||||
removeUnreachableInstructions(body.getCode(), cpool, trait, minfo, body);
|
||||
//System.err.println("/deo");
|
||||
}
|
||||
|
||||
private void replaceSingleUseRegisters(Map<Integer, GraphTargetItem> singleRegisters, List<AVM2Instruction> setInss, int classIndex, boolean isStatic, int scriptIndex, ABC abc, AVM2ConstantPool cpool, Trait trait, MethodInfo minfo, MethodBody body) {
|
||||
private void replaceSingleUseRegisters(Map<Integer, GraphTargetItem> singleRegisters, List<AVM2Instruction> setInss, int classIndex, boolean isStatic, int scriptIndex, ABC abc, AVM2ConstantPool cpool, Trait trait, MethodInfo minfo, MethodBody body) throws InterruptedException {
|
||||
AVM2Code code = body.getCode();
|
||||
|
||||
for (int i = 0; i < code.code.size(); i++) {
|
||||
if (Thread.currentThread().isInterrupted()) {
|
||||
throw new InterruptedException();
|
||||
}
|
||||
|
||||
AVM2Instruction ins = code.code.get(i);
|
||||
if (((setInss == null) || setInss.contains(ins)) && (ins.definition instanceof SetLocalTypeIns)) {
|
||||
SetLocalTypeIns slt = (SetLocalTypeIns) ins.definition;
|
||||
@@ -143,6 +144,7 @@ public class AVM2DeobfuscatorRegisters extends AVM2DeobfuscatorSimple {
|
||||
code.replaceInstruction(i, new AVM2Instruction(ins.offset, new DeobfuscatePopIns(), new int[]{}), body);
|
||||
}
|
||||
}
|
||||
|
||||
if (ins.definition instanceof GetLocalTypeIns) {
|
||||
GetLocalTypeIns glt = (GetLocalTypeIns) ins.definition;
|
||||
int regId = glt.getRegisterId(ins);
|
||||
@@ -155,7 +157,6 @@ public class AVM2DeobfuscatorRegisters extends AVM2DeobfuscatorSimple {
|
||||
|
||||
private int getFirstRegisterSetter(Reference<AVM2Instruction> assignment, int classIndex, boolean isStatic, int scriptIndex, ABC abc, AVM2ConstantPool cpool, Trait trait, MethodInfo minfo, MethodBody body, Set<Integer> ignoredRegisters, Set<Integer> ignoredGets) throws InterruptedException {
|
||||
AVM2Code code = body.getCode();
|
||||
Map<Integer, GraphTargetItem> ret = new HashMap<>();
|
||||
|
||||
if (code.code.isEmpty()) {
|
||||
return -1;
|
||||
@@ -187,32 +188,32 @@ public class AVM2DeobfuscatorRegisters extends AVM2DeobfuscatorSimple {
|
||||
}
|
||||
visited.add(idx);
|
||||
|
||||
AVM2Instruction action = code.code.get(idx);
|
||||
InstructionDefinition def = action.definition;
|
||||
//System.err.println("" + idx + ": " + action + " stack:" + stack.size());
|
||||
AVM2Instruction ins = code.code.get(idx);
|
||||
InstructionDefinition def = ins.definition;
|
||||
//System.err.println("" + idx + ": " + ins + " stack:" + stack.size());
|
||||
|
||||
action.translate(localData, stack, output, Graph.SOP_USE_STATIC, "");
|
||||
ins.translate(localData, stack, output, Graph.SOP_USE_STATIC, "");
|
||||
|
||||
//if (!(def instanceof KillIns))
|
||||
if (def instanceof SetLocalTypeIns) {
|
||||
int regId = ((SetLocalTypeIns) def).getRegisterId(action);
|
||||
int regId = ((SetLocalTypeIns) def).getRegisterId(ins);
|
||||
if (!ignored.contains(regId)) {
|
||||
assignment.setVal(action);
|
||||
assignment.setVal(ins);
|
||||
return regId;
|
||||
}
|
||||
} else if (def instanceof GetLocalTypeIns) {
|
||||
int regId = ((GetLocalTypeIns) def).getRegisterId(action);
|
||||
int regId = ((GetLocalTypeIns) def).getRegisterId(ins);
|
||||
if (!ignored.contains(regId) && !ignoredGets.contains(regId)) {
|
||||
assignment.setVal(action);
|
||||
assignment.setVal(ins);
|
||||
return regId;
|
||||
}
|
||||
} else {
|
||||
for (int p = 0; p < action.definition.operands.length; p++) {
|
||||
int op = action.definition.operands[p];
|
||||
for (int p = 0; p < ins.definition.operands.length; p++) {
|
||||
int op = ins.definition.operands[p];
|
||||
if (op == AVM2Code.DAT_REGISTER_INDEX) {
|
||||
int regId = action.operands[p];
|
||||
int regId = ins.operands[p];
|
||||
if (!ignored.contains(regId)) {
|
||||
assignment.setVal(action);
|
||||
assignment.setVal(ins);
|
||||
return regId;
|
||||
}
|
||||
}
|
||||
@@ -221,17 +222,17 @@ public class AVM2DeobfuscatorRegisters extends AVM2DeobfuscatorSimple {
|
||||
|
||||
idx++;
|
||||
|
||||
if (action.definition instanceof JumpIns) {
|
||||
if (ins.definition instanceof JumpIns) {
|
||||
|
||||
long address = action.offset + action.getBytesLength() + action.operands[0];
|
||||
long address = ins.offset + ins.getBytesLength() + ins.operands[0];
|
||||
idx = code.adr2pos(address);//code.indexOf(code.getByAddress(address));
|
||||
if (idx == -1) {
|
||||
throw new TranslateException("Jump target not found: " + address);
|
||||
}
|
||||
}
|
||||
|
||||
if (action.isBranch()) {
|
||||
List<Integer> branches = action.getBranches(new GraphSource() {
|
||||
if (ins.isBranch()) {
|
||||
List<Integer> branches = ins.getBranches(new GraphSource() {
|
||||
|
||||
@Override
|
||||
public int size() {
|
||||
@@ -274,8 +275,8 @@ public class AVM2DeobfuscatorRegisters extends AVM2DeobfuscatorSimple {
|
||||
toVisitStacks.add((TranslateStack) stack.clone());
|
||||
}
|
||||
}
|
||||
/*if (action.definition instanceof IfTypeIns) {
|
||||
long address = action.offset + action.getBytes().length + action.operands[0];
|
||||
/*if (ins.definition instanceof IfTypeIns) {
|
||||
long address = ins.offset + ins.getBytes().length + ins.operands[0];
|
||||
int newIdx = code.adr2pos(address);
|
||||
if (newIdx == -1) {
|
||||
throw new TranslateException("If target not found: " + address);
|
||||
@@ -283,15 +284,15 @@ public class AVM2DeobfuscatorRegisters extends AVM2DeobfuscatorSimple {
|
||||
visitCode(visited, (TranslateStack) stack.clone(), classIndex, isStatic, body, scriptIndex, abc, code, newIdx, endIdx, result);
|
||||
}*/
|
||||
|
||||
if (action.definition instanceof ReturnValueIns) {
|
||||
if (ins.definition instanceof ReturnValueIns) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (action.definition instanceof ThrowIns) {
|
||||
if (ins.definition instanceof ThrowIns) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (action.definition instanceof ReturnVoidIns) {
|
||||
if (ins.definition instanceof ReturnVoidIns) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -170,24 +170,28 @@ public class AVM2DeobfuscatorSimple implements SWFDecompilerListener {
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < code.code.size(); i++) {
|
||||
if (Thread.currentThread().isInterrupted()) {
|
||||
throw new InterruptedException();
|
||||
}
|
||||
|
||||
ExecutionResult result = new ExecutionResult();
|
||||
executeActions(staticRegs, classIndex, isStatic, body, scriptIndex, abc, code, i, code.code.size() - 1, result, inlineIns);
|
||||
executeInstructions(staticRegs, classIndex, isStatic, body, scriptIndex, abc, code, i, code.code.size() - 1, result, inlineIns);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
protected void removeUnreachableActions(AVM2Code code, AVM2ConstantPool cpool, Trait trait, MethodInfo minfo, MethodBody body) throws InterruptedException {
|
||||
protected void removeUnreachableInstructions(AVM2Code code, AVM2ConstantPool cpool, Trait trait, MethodInfo minfo, MethodBody body) throws InterruptedException {
|
||||
code.removeDeadCode(body);
|
||||
}
|
||||
|
||||
protected boolean removeZeroJumps(AVM2Code actions, MethodBody body) {
|
||||
protected boolean removeZeroJumps(AVM2Code code, MethodBody body) {
|
||||
boolean result = false;
|
||||
for (int i = 0; i < actions.code.size(); i++) {
|
||||
AVM2Instruction action = actions.code.get(i);
|
||||
if (action.definition instanceof JumpIns) {
|
||||
if (action.operands[0] == 0) {
|
||||
actions.removeInstruction(i, body);
|
||||
for (int i = 0; i < code.code.size(); i++) {
|
||||
AVM2Instruction ins = code.code.get(i);
|
||||
if (ins.definition instanceof JumpIns) {
|
||||
if (ins.operands[0] == 0) {
|
||||
code.removeInstruction(i, body);
|
||||
i--;
|
||||
result = true;
|
||||
}
|
||||
@@ -226,7 +230,7 @@ public class AVM2DeobfuscatorSimple implements SWFDecompilerListener {
|
||||
return localData;
|
||||
}
|
||||
|
||||
private void executeActions(Map<Integer, GraphTargetItem> staticRegs, int classIndex, boolean isStatic, MethodBody body, int scriptIndex, ABC abc, AVM2Code code, int idx, int endIdx, ExecutionResult result, List<AVM2Instruction> inlineIns) throws InterruptedException {
|
||||
private void executeInstructions(Map<Integer, GraphTargetItem> staticRegs, int classIndex, boolean isStatic, MethodBody body, int scriptIndex, ABC abc, AVM2Code code, int idx, int endIdx, ExecutionResult result, List<AVM2Instruction> inlineIns) throws InterruptedException {
|
||||
List<GraphTargetItem> output = new ArrayList<>();
|
||||
AVM2LocalData localData = newLocalData(scriptIndex, abc, abc.constants, body, isStatic, classIndex);
|
||||
|
||||
@@ -243,8 +247,8 @@ public class AVM2DeobfuscatorSimple implements SWFDecompilerListener {
|
||||
break;
|
||||
}
|
||||
|
||||
AVM2Instruction action = code.code.get(idx);
|
||||
if (action.definition instanceof NewFunctionIns) {
|
||||
AVM2Instruction ins = code.code.get(idx);
|
||||
if (ins.definition instanceof NewFunctionIns) {
|
||||
if (idx + 1 < code.code.size()) {
|
||||
if (code.code.get(idx + 1).definition instanceof PopIns) {
|
||||
code.removeInstruction(idx + 1, body);
|
||||
@@ -253,27 +257,27 @@ public class AVM2DeobfuscatorSimple implements SWFDecompilerListener {
|
||||
}
|
||||
}
|
||||
} else {
|
||||
action.translate(localData, stack, output, Graph.SOP_USE_STATIC, "");
|
||||
ins.translate(localData, stack, output, Graph.SOP_USE_STATIC, "");
|
||||
}
|
||||
|
||||
InstructionDefinition def = action.definition;
|
||||
InstructionDefinition def = ins.definition;
|
||||
|
||||
if (inlineIns.contains(action)) {
|
||||
if (inlineIns.contains(ins)) {
|
||||
if (def instanceof SetLocalTypeIns) {
|
||||
int regId = ((SetLocalTypeIns) def).getRegisterId(action);
|
||||
int regId = ((SetLocalTypeIns) def).getRegisterId(ins);
|
||||
staticRegs.put(regId, localData.localRegs.get(regId).getNotCoerced());
|
||||
code.replaceInstruction(idx, new AVM2Instruction(0, new DeobfuscatePopIns(), new int[]{}), body);
|
||||
}
|
||||
}
|
||||
if (def instanceof GetLocalTypeIns) {
|
||||
int regId = ((GetLocalTypeIns) def).getRegisterId(action);
|
||||
int regId = ((GetLocalTypeIns) def).getRegisterId(ins);
|
||||
if (staticRegs.containsKey(regId)) {
|
||||
stack.pop();
|
||||
AVM2Instruction pushins = makePush(abc.constants, staticRegs.get(regId));
|
||||
code.replaceInstruction(idx, pushins, body);
|
||||
stack.push(staticRegs.get(regId));
|
||||
action = pushins;
|
||||
def = action.definition;
|
||||
ins = pushins;
|
||||
def = ins.definition;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -329,7 +333,7 @@ public class AVM2DeobfuscatorSimple implements SWFDecompilerListener {
|
||||
}
|
||||
|
||||
if (def instanceof GetLocalTypeIns) {
|
||||
int regId = ((GetLocalTypeIns) def).getRegisterId(action);
|
||||
int regId = ((GetLocalTypeIns) def).getRegisterId(ins);
|
||||
if (staticRegs.containsKey(regId)) {
|
||||
stack.pop();
|
||||
stack.push(staticRegs.get(regId));
|
||||
@@ -340,41 +344,40 @@ public class AVM2DeobfuscatorSimple implements SWFDecompilerListener {
|
||||
|
||||
boolean ifed = false;
|
||||
if (def instanceof JumpIns) {
|
||||
//ActionJump jump = (ActionJump) action;
|
||||
long address = action.offset + action.getBytesLength() + action.operands[0];
|
||||
long address = ins.offset + ins.getBytesLength() + ins.operands[0];
|
||||
idx = code.adr2pos(address);
|
||||
|
||||
if (idx == -1) {
|
||||
throw new TranslateException("Jump target not found: " + address);
|
||||
}
|
||||
} else if (def instanceof IfTypeIns) {
|
||||
//ActionIf aif = (ActionIf) action;
|
||||
GraphTargetItem top = stack.pop();
|
||||
Object res = top.getResult();
|
||||
long address = action.offset + action.getBytesLength() + action.operands[0];
|
||||
long address = ins.offset + ins.getBytesLength() + ins.operands[0];
|
||||
int nidx = code.adr2pos(address);//code.indexOf(code.getByAddress(address));
|
||||
AVM2Instruction tarIns = code.code.get(nidx);
|
||||
|
||||
//Some IfType instructions need more than 1 operand, we must pop out all of them
|
||||
int stackCount = -action.definition.getStackDelta(action, abc);
|
||||
int stackCount = -ins.definition.getStackDelta(ins, abc);
|
||||
|
||||
if (EcmaScript.toBoolean(res)) {
|
||||
//System.err.println("replacing " + action + " on " + idx + " with jump");
|
||||
//System.err.println("replacing " + ins + " on " + idx + " with jump");
|
||||
AVM2Instruction jumpIns = new AVM2Instruction(0, new JumpIns(), new int[]{0});
|
||||
//jumpIns.operands[0] = action.operands[0] /*- action.getBytes().length*/ + jumpIns.getBytes().length;
|
||||
//jumpIns.operands[0] = ins.operands[0] /*- ins.getBytes().length*/ + jumpIns.getBytes().length;
|
||||
code.replaceInstruction(idx, jumpIns, body);
|
||||
jumpIns.operands[0] = (int) (tarIns.offset - jumpIns.offset - jumpIns.getBytesLength());
|
||||
for (int s = 0; s < stackCount; s++) {
|
||||
code.insertInstruction(idx, new AVM2Instruction(action.offset, new DeobfuscatePopIns(), new int[]{}), true, body);
|
||||
code.insertInstruction(idx, new AVM2Instruction(ins.offset, new DeobfuscatePopIns(), new int[]{}), true, body);
|
||||
}
|
||||
|
||||
idx = code.adr2pos(jumpIns.offset + jumpIns.getBytesLength() + jumpIns.operands[0]);
|
||||
} else {
|
||||
//System.err.println("replacing " + action + " on " + idx + " with pop");
|
||||
code.replaceInstruction(idx, new AVM2Instruction(action.offset, new DeobfuscatePopIns(), new int[]{}), body);
|
||||
//System.err.println("replacing " + ins + " on " + idx + " with pop");
|
||||
code.replaceInstruction(idx, new AVM2Instruction(ins.offset, new DeobfuscatePopIns(), new int[]{}), body);
|
||||
for (int s = 1 /*first is replaced*/; s < stackCount; s++) {
|
||||
code.insertInstruction(idx, new AVM2Instruction(action.offset, new DeobfuscatePopIns(), new int[]{}), true, body);
|
||||
code.insertInstruction(idx, new AVM2Instruction(ins.offset, new DeobfuscatePopIns(), new int[]{}), true, body);
|
||||
}
|
||||
//action.definition = new DeobfuscatePopIns();
|
||||
//ins.definition = new DeobfuscatePopIns();
|
||||
idx++;
|
||||
}
|
||||
ifed = true;
|
||||
@@ -422,7 +425,7 @@ public class AVM2DeobfuscatorSimple implements SWFDecompilerListener {
|
||||
|
||||
public void deobfuscate(String path, int classIndex, boolean isStatic, int scriptIndex, ABC abc, AVM2ConstantPool cpool, Trait trait, MethodInfo minfo, MethodBody body) throws InterruptedException {
|
||||
AVM2Code code = body.getCode();
|
||||
removeUnreachableActions(code, cpool, trait, minfo, body);
|
||||
removeUnreachableInstructions(code, cpool, trait, minfo, body);
|
||||
removeObfuscationIfs(classIndex, isStatic, scriptIndex, abc, cpool, trait, minfo, body, new ArrayList<>());
|
||||
removeZeroJumps(code, body);
|
||||
}
|
||||
|
||||
@@ -44,7 +44,7 @@ public class NewObjectIns extends InstructionDefinition {
|
||||
List<NameValuePair> args = new ArrayList<>(argCount);
|
||||
for (int a = 0; a < argCount; a++) {
|
||||
if (Thread.currentThread().isInterrupted()) {
|
||||
// int obfuscated method argCount can be 16M
|
||||
// in obfuscated method argCount can be 16M
|
||||
throw new InterruptedException();
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user