mirror of
https://git.huckle.dev/Huckles-Minecraft-Archive/jpexs-decompiler.git
synced 2026-06-07 21:45:09 +00:00
Issue #939 AS3 Correct deobfuscate pop
AS3 Improved P-code reading - Ignoring jumps in unreachable code
This commit is contained in:
@@ -777,6 +777,8 @@ public class AVM2Code implements Cloneable {
|
||||
Map<Long, AVM2Instruction> codeMap = new TreeMap<>();
|
||||
DumpInfo diParent = ais.dumpInfo;
|
||||
List<Long> addresses = new ArrayList<>();
|
||||
//Do not add new jumps when processing these addresses (unreachable code,etc.)
|
||||
List<Long> unAdresses = new ArrayList<>();
|
||||
//Handle lookupswitches at the end - they can be invalid. Handle other instruction first so we can decide lookupswitch to be invalid based on other instructions inside it
|
||||
//Flashplayer does not check casecount in lookupswitch instruction so the instruction can "be" long and over other instructions
|
||||
List<Long> switchAddresses = new ArrayList<>();
|
||||
@@ -789,14 +791,18 @@ public class AVM2Code implements Cloneable {
|
||||
addresses.add(startPos);
|
||||
|
||||
loopaddr:
|
||||
while (!addresses.isEmpty() || !switchAddresses.isEmpty()) {
|
||||
while (!addresses.isEmpty() || !switchAddresses.isEmpty() || !unAdresses.isEmpty()) {
|
||||
long address;
|
||||
boolean isSwitch = false;
|
||||
boolean handleJumps = true;
|
||||
if (!addresses.isEmpty()) {
|
||||
address = addresses.remove(0);
|
||||
} else {
|
||||
} else if (!switchAddresses.isEmpty()) {
|
||||
address = switchAddresses.remove(0);
|
||||
isSwitch = true;
|
||||
} else {
|
||||
address = unAdresses.remove(0);
|
||||
handleJumps = false;
|
||||
}
|
||||
if (codeMap.containsKey(address) && !(codeMap.get(address).definition instanceof NopIns)) {
|
||||
continue;
|
||||
@@ -805,6 +811,7 @@ public class AVM2Code implements Cloneable {
|
||||
{
|
||||
continue;
|
||||
}
|
||||
boolean afterExit = false;
|
||||
try {
|
||||
ais.seek(address);
|
||||
while (ais.available() > 0) {
|
||||
@@ -847,7 +854,6 @@ public class AVM2Code implements Cloneable {
|
||||
if (afterCasePos > totalBytes) {
|
||||
invalidSwitch = true;
|
||||
}
|
||||
|
||||
if (invalidSwitch) {
|
||||
continue loopaddr;
|
||||
} else {
|
||||
@@ -889,28 +895,33 @@ public class AVM2Code implements Cloneable {
|
||||
|
||||
ais.endDumpLevel(instr.instructionCode);
|
||||
|
||||
if ((instr instanceof IfTypeIns)) {
|
||||
long target = ais.getPosition() + actualOperands[0];
|
||||
addresses.add(target);
|
||||
//addresses.add(ais.getPosition());
|
||||
if (handleJumps) {
|
||||
if ((instr instanceof IfTypeIns)) {
|
||||
long target = ais.getPosition() + actualOperands[0];
|
||||
addresses.add(target);
|
||||
//addresses.add(ais.getPosition());
|
||||
}
|
||||
|
||||
if (instr instanceof JumpIns) {
|
||||
long target = ais.getPosition() + actualOperands[0];
|
||||
addresses.add(target);
|
||||
unAdresses.add(ais.getPosition());
|
||||
continue loopaddr;
|
||||
}
|
||||
|
||||
if (instr.isExitInstruction()) { //do not process jumps if there is return/throw instruction
|
||||
unAdresses.add(ais.getPosition());
|
||||
continue loopaddr;
|
||||
}
|
||||
if (instr instanceof LookupSwitchIns) {
|
||||
addresses.add(beforeSwitchPos + actualOperands[0]);
|
||||
|
||||
for (int c = 2; c < actualOperands.length; c++) {
|
||||
addresses.add(beforeSwitchPos + actualOperands[c]);
|
||||
}
|
||||
continue loopaddr;
|
||||
}
|
||||
}
|
||||
/*if (instr instanceof JumpIns) {
|
||||
long target = ais.getPosition() + actualOperands[0];
|
||||
addresses.add(target);
|
||||
continue loopaddr;
|
||||
}
|
||||
|
||||
if (instr.isExitInstruction()) { //do not process jumps if there is return/throw instruction
|
||||
continue loopaddr;
|
||||
}
|
||||
if (instr instanceof LookupSwitchIns) {
|
||||
addresses.add(beforeSwitchPos + actualOperands[0]);
|
||||
|
||||
for (int c = 2; c < actualOperands.length; c++) {
|
||||
addresses.add(beforeSwitchPos + actualOperands[c]);
|
||||
}
|
||||
continue loopaddr;
|
||||
}*/
|
||||
} else {
|
||||
ais.endDumpLevel();
|
||||
break; // Unknown instructions are ignored (Some of the obfuscators add unknown instructions)
|
||||
|
||||
@@ -367,6 +367,8 @@ public class AVM2DeobfuscatorSimple implements SWFDecompilerListener {
|
||||
long address = action.offset + action.getBytesLength() + action.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);
|
||||
|
||||
if (EcmaScript.toBoolean(res)) {
|
||||
//System.err.println("replacing " + action + " on " + idx + " with jump");
|
||||
@@ -374,13 +376,17 @@ public class AVM2DeobfuscatorSimple implements SWFDecompilerListener {
|
||||
//jumpIns.operands[0] = action.operands[0] /*- action.getBytes().length*/ + jumpIns.getBytes().length;
|
||||
code.replaceInstruction(idx, jumpIns, body);
|
||||
jumpIns.operands[0] = (int) (tarIns.offset - jumpIns.offset - jumpIns.getBytesLength());
|
||||
|
||||
code.insertInstruction(idx, new AVM2Instruction(action.offset, new DeobfuscatePopIns(), new int[]{}), true, body);
|
||||
for (int s = 0; s < stackCount; s++) {
|
||||
code.insertInstruction(idx, new AVM2Instruction(action.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);
|
||||
for (int s = 1 /*first is replaced*/; s < stackCount; s++) {
|
||||
code.insertInstruction(idx, new AVM2Instruction(action.offset, new DeobfuscatePopIns(), new int[]{}), true, body);
|
||||
}
|
||||
//action.definition = new DeobfuscatePopIns();
|
||||
idx++;
|
||||
}
|
||||
|
||||
@@ -93,7 +93,7 @@ public class InstructionDefinition implements Serializable {
|
||||
protected FullMultinameAVM2Item resolveMultiname(TranslateStack stack, AVM2ConstantPool constants, int multinameIndex, AVM2Instruction ins) {
|
||||
GraphTargetItem ns = null;
|
||||
GraphTargetItem name = null;
|
||||
if (multinameIndex < constants.constant_multiname.size()) {
|
||||
if (multinameIndex > 0 && multinameIndex < constants.constant_multiname.size()) {
|
||||
if (constants.getMultiname(multinameIndex).needsName()) {
|
||||
name = stack.pop();
|
||||
}
|
||||
|
||||
@@ -96,7 +96,11 @@ public class FullMultinameAVM2Item extends AVM2Item {
|
||||
} else {
|
||||
AVM2ConstantPool constants = localData.constantsAvm2;
|
||||
List<String> fullyQualifiedNames = localData.fullyQualifiedNames;
|
||||
writer.append(constants.getMultiname(multinameIndex).getName(constants, fullyQualifiedNames, false));
|
||||
if (multinameIndex > 0 && multinameIndex < constants.constant_multiname.size()) {
|
||||
writer.append(constants.getMultiname(multinameIndex).getName(constants, fullyQualifiedNames, false));
|
||||
} else {
|
||||
writer.append("§§unknown_multiname");
|
||||
}
|
||||
}
|
||||
return writer;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user