mirror of
https://git.huckle.dev/Huckles-Minecraft-Archive/jpexs-decompiler.git
synced 2026-09-25 12:11:11 +00:00
AS3 allow exception start/end to not match instruction boundary
This commit is contained in:
@@ -894,8 +894,7 @@ public class AVM2Code implements Cloneable {
|
||||
addresses.add(startPos);
|
||||
if (body != null) {
|
||||
for (ABCException e : body.exceptions) {
|
||||
addresses.add((long) e.start);
|
||||
addresses.add((long) e.end);
|
||||
//do not process e.start and e.end - they can be not on an instruction boundary
|
||||
addresses.add((long) e.target);
|
||||
}
|
||||
}
|
||||
@@ -1263,13 +1262,14 @@ public class AVM2Code implements Cloneable {
|
||||
ABCException exception = body.exceptions[e];
|
||||
writer.appendNoHilight("try");
|
||||
|
||||
//Note: start and end address can be not on instruction boundary - call adr2pos( nearest=true) to make them legal
|
||||
writer.appendNoHilight(" from ");
|
||||
writer.appendNoHilight("ofs");
|
||||
writer.appendNoHilight(Helper.formatAddress(exception.start));
|
||||
writer.appendNoHilight(Helper.formatAddress(pos2adr(adr2pos(exception.start, true))));
|
||||
|
||||
writer.appendNoHilight(" to ");
|
||||
writer.appendNoHilight("ofs");
|
||||
writer.appendNoHilight(Helper.formatAddress(exception.end));
|
||||
writer.appendNoHilight(Helper.formatAddress(pos2adr(adr2pos(exception.end, true))));
|
||||
|
||||
writer.appendNoHilight(" target ");
|
||||
writer.appendNoHilight("ofs");
|
||||
@@ -1353,9 +1353,9 @@ public class AVM2Code implements Cloneable {
|
||||
Set<Long> ret = new HashSet<>();
|
||||
if (body != null) {
|
||||
for (ABCException exception : body.exceptions) {
|
||||
ret.add((long) exception.start);
|
||||
ret.add((long) pos2adr(adr2pos(exception.start, true)));
|
||||
if (tryEnds) {
|
||||
ret.add((long) exception.end);
|
||||
ret.add((long) pos2adr(adr2pos(exception.end, true)));
|
||||
}
|
||||
ret.add((long) exception.target);
|
||||
}
|
||||
@@ -2451,7 +2451,6 @@ public class AVM2Code implements Cloneable {
|
||||
return null;
|
||||
}
|
||||
int scopePos = -1;
|
||||
int prevStart = 0;
|
||||
for (int e = 0; e < body.exceptions.length; e++) {
|
||||
ABCException ex = body.exceptions[e];
|
||||
try {
|
||||
@@ -2475,28 +2474,10 @@ public class AVM2Code implements Cloneable {
|
||||
}
|
||||
}
|
||||
scopePos = stats.instructionStats[maxIp].scopepos_after;
|
||||
int stackPos = stats.instructionStats[maxIp].stackpos_after;
|
||||
int nextIp = maxIp + 1;
|
||||
if (code.get(maxIp).definition instanceof JumpIns) {
|
||||
nextIp = adr2pos(pos2adr(nextIp) + code.get(maxIp).operands[0]);
|
||||
}
|
||||
/*if (nextIp < stats.instructionStats.length) {
|
||||
InstructionStats nextIpStat = stats.instructionStats[nextIp];
|
||||
int origScopePos = nextIpStat.scopepos;
|
||||
int origStackPos = nextIpStat.stackpos;
|
||||
|
||||
if (prevStart == ex.start && ex.isFinally() && !code.get(nextIp).isExit() && nextIpStat.seen) {
|
||||
for (int i = 0; i < stats.instructionStats.length; i++) {
|
||||
stats.instructionStats[i].seen = false;
|
||||
}
|
||||
// Rerun rest with new scopePos, stackPos
|
||||
if (!walkCode(stats, nextIp, origStackPos + 1, scopePos - 1, abc, autoFill)) {
|
||||
return null;
|
||||
}
|
||||
scopePos--;
|
||||
}
|
||||
}*/
|
||||
prevStart = ex.start;
|
||||
} catch (ConvertException ex1) {
|
||||
// ignore
|
||||
}
|
||||
@@ -2593,14 +2574,9 @@ public class AVM2Code implements Cloneable {
|
||||
refs.put(i, new ArrayList<>());
|
||||
}
|
||||
visitCode(0, 0, refs);
|
||||
int pos = 0;
|
||||
for (ABCException e : body.exceptions) {
|
||||
pos++;
|
||||
try {
|
||||
visitCode(adr2pos(e.start, true), adr2pos(e.start, true) - 1, refs);
|
||||
visitCode(adr2pos(e.start, true), -1, refs);
|
||||
visitCode(adr2pos(e.target), adr2pos(e.end, true), refs);
|
||||
visitCode(adr2pos(e.end, true), -pos, refs);
|
||||
visitCode(adr2pos(e.target), -1, refs);
|
||||
} catch (ConvertException ex) {
|
||||
logger.log(Level.SEVERE, "Visitcode error", ex);
|
||||
}
|
||||
|
||||
+7
-1
@@ -12,7 +12,8 @@
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library.␍ */
|
||||
* License along with this library.
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.abc.avm2.deobfuscation;
|
||||
|
||||
import com.jpexs.decompiler.flash.BaseLocalData;
|
||||
@@ -303,6 +304,11 @@ public class AVM2DeobfuscatorRegisters extends AVM2DeobfuscatorSimple {
|
||||
return code.pos2adr(pos);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int adr2pos(long adr, boolean nearest) {
|
||||
return code.adr2pos(adr, nearest);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<Long> getImportantAddresses() {
|
||||
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
|
||||
|
||||
+7
-6
@@ -187,7 +187,7 @@ public class AVM2DeobfuscatorRegistersOld extends AVM2DeobfuscatorSimpleOld {
|
||||
|
||||
Map<Integer, List<ExceptionTargetIpPair>> exceptionStartToTargets = new HashMap<>();
|
||||
for (ABCException ex : body.exceptions) {
|
||||
int startIp = code.adr2pos(ex.start);
|
||||
int startIp = code.adr2pos(ex.start, true);
|
||||
int targetIp = code.adr2pos(ex.target);
|
||||
if (!exceptionStartToTargets.containsKey(startIp)) {
|
||||
exceptionStartToTargets.put(startIp, new ArrayList<>());
|
||||
@@ -230,11 +230,6 @@ public class AVM2DeobfuscatorRegistersOld extends AVM2DeobfuscatorSimpleOld {
|
||||
toVisitStacks.add(targetStack);
|
||||
}
|
||||
}
|
||||
for (ABCException ex : body.exceptions) {
|
||||
if (code.pos2adr(idx) == ex.start) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
AVM2Instruction ins = code.code.get(idx);
|
||||
InstructionDefinition def = ins.definition;
|
||||
@@ -317,6 +312,12 @@ public class AVM2DeobfuscatorRegistersOld extends AVM2DeobfuscatorSimpleOld {
|
||||
return code.pos2adr(pos);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int adr2pos(long adr, boolean nearest) {
|
||||
return code.adr2pos(adr, nearest);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Set<Long> getImportantAddresses() {
|
||||
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
|
||||
|
||||
@@ -36,6 +36,9 @@ import com.jpexs.decompiler.flash.abc.avm2.instructions.localregs.SetLocalTypeIn
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.other.HasNext2Ins;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.other.LabelIns;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.other.NopIns;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.other.ReturnValueIns;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.other.ReturnVoidIns;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.other.ThrowIns;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.other2.DecLocalPIns;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.other2.IncLocalPIns;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.stack.PopIns;
|
||||
@@ -280,7 +283,7 @@ public class AVM2Graph extends Graph {
|
||||
}
|
||||
}
|
||||
|
||||
int finEndIp = avm2code.adr2pos(ex.end);
|
||||
int finEndIp = avm2code.adr2pos(ex.end, true);
|
||||
GraphPart finallyEndPart = searchPart(finEndIp, allParts);
|
||||
List<GraphPart> refs = getRealRefs(finallyEndPart);
|
||||
|
||||
@@ -315,7 +318,7 @@ public class AVM2Graph extends Graph {
|
||||
}
|
||||
} else if (finallyKind == FINALLY_KIND_REGISTER_BASED) {
|
||||
switchPart = findLookupSwitchWithGetLocal(switchedReg, finallyPart);
|
||||
int startIp = code.adr2pos(ex.start);
|
||||
int startIp = code.adr2pos(ex.start, true);
|
||||
GraphPart tryPart = null;
|
||||
for (GraphPart p : allParts) {
|
||||
if (startIp >= p.start && startIp <= p.end) {
|
||||
@@ -724,18 +727,21 @@ public class AVM2Graph extends Graph {
|
||||
List<Integer> finnalysIndicesToBe = new ArrayList<>();
|
||||
int realIp = -1;
|
||||
for (int e = 0; e < body.exceptions.length; e++) {
|
||||
if (addr == avm2code.getAddrThroughJumpAndDebugLine(body.exceptions[e].start)) {
|
||||
long fixedExStart = avm2code.pos2adr(avm2code.adr2pos(body.exceptions[e].start, true));
|
||||
long fixedExEnd = avm2code.pos2adr(avm2code.adr2pos(body.exceptions[e].end, true));
|
||||
|
||||
if (addr == avm2code.getAddrThroughJumpAndDebugLine(fixedExStart)) {
|
||||
ABCException ex = body.exceptions[e];
|
||||
if (!parsedExceptions.contains(ex)) {
|
||||
if (ex.isFinally()) {
|
||||
finnalysIndicesToBe.add(e);
|
||||
} else {
|
||||
long endAddr = avm2code.getAddrThroughJumpAndDebugLine(body.exceptions[e].end);
|
||||
long endAddr = avm2code.getAddrThroughJumpAndDebugLine(fixedExEnd);
|
||||
if (endAddr > maxEndAddr) {
|
||||
catchedExceptions.clear();
|
||||
maxEndAddr = avm2code.getAddrThroughJumpAndDebugLine(body.exceptions[e].end);
|
||||
maxEndAddr = avm2code.getAddrThroughJumpAndDebugLine(fixedExEnd);
|
||||
endIp = avm2code.adr2pos(maxEndAddr);
|
||||
realIp = avm2code.adr2pos(body.exceptions[e].end);
|
||||
realIp = avm2code.adr2pos(fixedExEnd);
|
||||
catchedExceptions.add(body.exceptions[e]);
|
||||
} else if (endAddr == maxEndAddr) {
|
||||
catchedExceptions.add(body.exceptions[e]);
|
||||
@@ -757,7 +763,7 @@ public class AVM2Graph extends Graph {
|
||||
finallyException = finallyExceptionToBe;
|
||||
break;
|
||||
}
|
||||
int finEndIp = avm2code.getIpThroughJumpAndDebugLine(avm2code.adr2pos(finallyExceptionToBe.end));
|
||||
int finEndIp = avm2code.getIpThroughJumpAndDebugLine(avm2code.adr2pos(finallyExceptionToBe.end, true));
|
||||
if (finEndIp == endIp) {
|
||||
finallyIndex = e;
|
||||
finallyException = finallyExceptionToBe;
|
||||
@@ -800,18 +806,58 @@ public class AVM2Graph extends Graph {
|
||||
GraphPart afterPart = null;
|
||||
|
||||
GraphPart endIpPart = searchPart(endIp, allParts);
|
||||
if (endIpPart != null && getRealRefs(endIpPart).isEmpty()) { //swftools - there is jump on previous ip
|
||||
if (avm2code.code.get(endIpPart.start - 1).definition instanceof JumpIns) {
|
||||
GraphPart prevPart = searchPart(endIpPart.start - 1, allParts);
|
||||
endIpPart = prevPart.nextParts.get(0);
|
||||
if (endIpPart != null && getRealRefs(endIpPart).isEmpty()) {
|
||||
int pos = endIpPart.start - 1;
|
||||
if (avm2code.code.get(pos).definition instanceof DebugLineIns) {
|
||||
pos--;
|
||||
}
|
||||
if (avm2code.code.get(pos).definition instanceof JumpIns) {
|
||||
GraphPart prevPart = searchPart(pos, allParts);
|
||||
if (prevPart.nextParts.get(0).start >= realIp) {
|
||||
endIpPart = prevPart.nextParts.get(0);
|
||||
} else {
|
||||
endIpPart = null;
|
||||
}
|
||||
}
|
||||
else if (avm2code.code.get(pos).definition instanceof ReturnVoidIns) {
|
||||
endIpPart = null;
|
||||
}
|
||||
else if (avm2code.code.get(pos).definition instanceof ReturnValueIns) {
|
||||
endIpPart = null;
|
||||
}
|
||||
else if (avm2code.code.get(pos).definition instanceof ThrowIns) {
|
||||
endIpPart = null;
|
||||
}
|
||||
}
|
||||
|
||||
GraphPart realEndIpPart = searchPart(realIp, allParts);
|
||||
if (realEndIpPart != null && getRealRefs(realEndIpPart).isEmpty()) { //swftools - there is jump on previous ip
|
||||
if (avm2code.code.get(realEndIpPart.start - 1).definition instanceof JumpIns) {
|
||||
GraphPart prevPart = searchPart(realEndIpPart.start - 1, allParts);
|
||||
realEndIpPart = prevPart.nextParts.get(0);
|
||||
if (realEndIpPart != null && getRealRefs(realEndIpPart).isEmpty()) {
|
||||
int pos = realEndIpPart.start - 1;
|
||||
if (avm2code.code.get(pos).definition instanceof DebugLineIns) {
|
||||
pos--;
|
||||
}
|
||||
if (avm2code.code.get(pos).definition instanceof JumpIns) {
|
||||
GraphPart prevPart = searchPart(pos, allParts);
|
||||
|
||||
if (prevPart.nextParts.get(0).start >= realIp) {
|
||||
realEndIpPart = prevPart.nextParts.get(0);
|
||||
endIpPart = prevPart.nextParts.get(0);
|
||||
} else {
|
||||
realEndIpPart = null;
|
||||
endIpPart = null;
|
||||
}
|
||||
}
|
||||
else if (avm2code.code.get(pos).definition instanceof ReturnVoidIns) {
|
||||
realEndIpPart = null;
|
||||
endIpPart = null;
|
||||
}
|
||||
else if (avm2code.code.get(pos).definition instanceof ReturnValueIns) {
|
||||
realEndIpPart = null;
|
||||
endIpPart = null;
|
||||
}
|
||||
else if (avm2code.code.get(pos).definition instanceof ThrowIns) {
|
||||
realEndIpPart = null;
|
||||
endIpPart = null;
|
||||
}
|
||||
}
|
||||
afterPart = realEndIpPart;
|
||||
@@ -1284,15 +1330,15 @@ public class AVM2Graph extends Graph {
|
||||
if (spt.object instanceof LocalRegAVM2Item) {
|
||||
getLocalObjectIp = avm2code.adr2pos(spt.object.getSrc().getAddress());
|
||||
regIndex = ((LocalRegAVM2Item) spt.object).regIndex;
|
||||
expr = ift.expression.getNotCoerced();
|
||||
if (withCommands.size() > 1) {
|
||||
withCommands.remove(withCommands.size() - 1);
|
||||
withCommands.add(expr);
|
||||
expr = new CommaExpressionItem(null, localData.lineStartInstruction, withCommands);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
expr = ift.expression.getNotCoerced();
|
||||
if (withCommands.size() > 1) {
|
||||
withCommands.remove(withCommands.size() - 1);
|
||||
withCommands.add(expr);
|
||||
expr = new CommaExpressionItem(null, localData.lineStartInstruction, withCommands);
|
||||
}
|
||||
} else {
|
||||
//There is no if - this means there was something that
|
||||
// can be evaluated on compiletime and compiler removed the whole if
|
||||
|
||||
@@ -12,7 +12,8 @@
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library.␍ */
|
||||
* License along with this library.
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.abc.avm2.graph;
|
||||
|
||||
import com.jpexs.decompiler.flash.BaseLocalData;
|
||||
@@ -133,4 +134,9 @@ public class AVM2GraphSource extends GraphSource {
|
||||
public long pos2adr(int pos) {
|
||||
return code.pos2adr(pos);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int adr2pos(long adr, boolean nearest) {
|
||||
return code.adr2pos(adr, true);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,7 +12,8 @@
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library.␍ */
|
||||
* License along with this library.
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.action;
|
||||
|
||||
import com.jpexs.decompiler.flash.BaseLocalData;
|
||||
@@ -154,37 +155,11 @@ public class ActionGraphSource extends GraphSource {
|
||||
if (!posCache.isEmpty() && (adr > posCache.get(posCache.size() - 1))) {
|
||||
return size();
|
||||
}
|
||||
//ret = adr2posInside(adr);
|
||||
if (ret == -1) {
|
||||
Logger.getLogger(ActionGraphSource.class.getName()).log(Level.SEVERE, "{0} - address loc{1} not found", new Object[]{path, Helper.formatAddress(adr)});
|
||||
/*System.err.println("Addr loc"+Helper.formatAddress(adr)+" not found");
|
||||
int pos=0;
|
||||
for(long l:posCache){
|
||||
System.err.println("ip "+pos+" action "+get(pos).toString()+" loc"+Helper.formatAddress(l));
|
||||
pos++;
|
||||
}*/
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
/*int pos = 0;
|
||||
long lastAddr = 0;
|
||||
for (Action a : actions) {
|
||||
lastAddr = a.getAddress();
|
||||
System.err.println("ip "+pos+" addr "+Helper.formatAddress(lastAddr));
|
||||
if (lastAddr == adr) {
|
||||
return pos;
|
||||
}
|
||||
|
||||
pos++;
|
||||
}
|
||||
if (adr > lastAddr) {
|
||||
return actions.size();
|
||||
}
|
||||
if (adr == 0) {
|
||||
return 0;
|
||||
}
|
||||
//throw new RuntimeException("Address "+Helper.formatAddress(adr)+" not found");
|
||||
return -1;*/
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -195,4 +170,29 @@ public class ActionGraphSource extends GraphSource {
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int adr2pos(long adr, boolean nearest) {
|
||||
if (posCache == null) {
|
||||
rebuildCache();
|
||||
}
|
||||
if (adr == 0) {
|
||||
return 0;
|
||||
}
|
||||
int ret = posCache.indexOf((Long) adr);
|
||||
if (ret == -1) {
|
||||
if (!posCache.isEmpty() && (adr > posCache.get(posCache.size() - 1))) {
|
||||
return size();
|
||||
}
|
||||
for (int i = 0; i < posCache.size(); i++) {
|
||||
Long a = posCache.get(i);
|
||||
if (a > adr) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return size();
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -12,7 +12,8 @@
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library.␍ */
|
||||
* License along with this library.
|
||||
*/
|
||||
package com.jpexs.decompiler.graph;
|
||||
|
||||
import com.jpexs.decompiler.flash.BaseLocalData;
|
||||
@@ -112,6 +113,8 @@ public abstract class GraphSource implements Serializable {
|
||||
|
||||
public abstract int adr2pos(long adr);
|
||||
|
||||
public abstract int adr2pos(long adr, boolean nearest);
|
||||
|
||||
public abstract long pos2adr(int pos);
|
||||
|
||||
public long getAddressAfterCode() {
|
||||
|
||||
Reference in New Issue
Block a user