Action reading fixes/enhancements

This commit is contained in:
honfika
2014-08-19 12:01:16 +02:00
parent 7d4fbe5075
commit 005d8544d4
7 changed files with 60 additions and 37 deletions

View File

@@ -313,6 +313,16 @@ public class Action implements GraphSourceItem {
return surroundWithAction(new byte[0], version);
}
/**
* Gets the length of action converted to bytes
*
* @param version SWF version
* @return Length
*/
public int getBytesLength(int version) {
return getBytes(version).length;
}
/**
* Surrounds byte array with Action header
*
@@ -370,7 +380,7 @@ public class Action implements GraphSourceItem {
long offset = baseAddress;
for (Action a : list) {
a.setAddress(offset);
offset += a.getBytes(version).length;
offset += a.getBytesLength(version);
}
}
@@ -455,6 +465,7 @@ public class Action implements GraphSourceItem {
if (containers.containsKey(offset)) {
for (int i = 0; i < containers.get(offset).size(); i++) {
writer.appendNoHilight("}").newLine();
lastPush = false;
GraphSourceItemContainer cnt = containers.get(offset).get(i);
int cntPos = containersPos.get(cnt);
writer.appendNoHilight(cnt.getASMSourceBetween(cntPos));
@@ -482,7 +493,7 @@ public class Action implements GraphSourceItem {
if (pos + 1 < list.size()) {
len = (int) (((Action) (list.get(pos + 1))).getAddress() - a.getAddress());
} else {
len = a.getBytes(version).length;
len = a.getBytesLength(version);
}
if (!(a instanceof ActionEnd)) {
for (int i = 0; i < len; i++) {
@@ -527,7 +538,7 @@ public class Action implements GraphSourceItem {
writer.appendNoHilight("FFDec_DeobfuscatePop").newLine();
if (fixBranch == 0) { //jump
writer.appendNoHilight("Jump loc");
writer.appendNoHilight(Helper.formatAddress(a.getAddress() + a.getBytes(version).length + ((ActionIf) a).getJumpOffset()));
writer.appendNoHilight(Helper.formatAddress(a.getAddress() + a.getBytesLength(version) + ((ActionIf) a).getJumpOffset()));
} else {
//nojump, ignore
}
@@ -636,7 +647,7 @@ public class Action implements GraphSourceItem {
if (actions.isEmpty()) {
return 0;
}
return actions.get(actions.size() - 1).getAddress() + actions.get(actions.size() - 1).getBytes(version).length;
return actions.get(actions.size() - 1).getAddress() + actions.get(actions.size() - 1).getBytesLength(version);
}
if (ip == -1) {
return 0;
@@ -659,7 +670,7 @@ public class Action implements GraphSourceItem {
}
}
if (actions.size() > 0) {
long outpos = actions.get(actions.size() - 1).getAddress() + actions.get(actions.size() - 1).getBytes(version).length;
long outpos = actions.get(actions.size() - 1).getAddress() + actions.get(actions.size() - 1).getBytesLength(version);
if (addr == outpos) {
return actions.size();
}

View File

@@ -194,8 +194,8 @@ public class ActionListReader {
updateJumps(actions, jumps, containerLastActions, endAddress);
updateActionStores(actions, jumps);
updateContainerSizes(actions, containerLastActions);
updateActionLengths(actions, version);
updateContainerSizes(actions, containerLastActions);
if (SWFDecompilerPlugin.listener != null) {
try {
@@ -204,8 +204,8 @@ public class ActionListReader {
updateAddresses(actions, 0, version);
updateJumps(actions, jumps, containerLastActions, endAddress);
updateActionStores(actions, jumps);
updateContainerSizes(actions, containerLastActions);
updateActionLengths(actions, version);
updateContainerSizes(actions, containerLastActions);
} catch (Throwable e) {
View.showMessageDialog(null, "Failed to call plugin method actionListParsed. Exception: " + e.getMessage());
}
@@ -407,7 +407,7 @@ public class ActionListReader {
for (int i = 0; i < actions.size(); i++) {
Action a = actions.get(i);
a.setAddress(address);
int length = a.getBytes(version).length;
int length = a.getBytesLength(version);
if ((i != actions.size() - 1) && (a instanceof ActionEnd)) {
// placeholder for jump action
length = new ActionDeobfuscateJump(0).getTotalActionLength();
@@ -420,7 +420,7 @@ public class ActionListReader {
private static void updateActionLengths(List<Action> actions, int version) {
for (int i = 0; i < actions.size(); i++) {
Action a = actions.get(i);
int length = a.getBytes(version).length;
int length = a.getBytesLength(version);
a.actionLength = length - 1 - ((a.actionCode >= 0x80) ? 2 : 0);
}
}
@@ -599,8 +599,8 @@ public class ActionListReader {
updateAddresses(actions, startIp, version);
updateJumps(actions, jumps, containerLastActions, endAddress);
updateActionStores(actions, jumps);
updateContainerSizes(actions, containerLastActions);
updateActionLengths(actions, version);
updateContainerSizes(actions, containerLastActions);
return true;
}
@@ -691,10 +691,10 @@ public class ActionListReader {
for (long size : cnt.getContainerSizes()) {
if (size != 0) {
long ip2 = ip + actionLengthWithHeader;
//long endIp2 = ip + actionLengthWithHeader + size;
long endIp2 = ip + actionLengthWithHeader + size;
readActionListAtPos(listeners, cpool,
sis, actions, nextOffsets,
ip2, startIp, endIp, newPath, indeterminate, visitedContainers);
ip2, startIp, endIp2, newPath, indeterminate, visitedContainers);
actionLengthWithHeader += size;
}
}

View File

@@ -141,7 +141,7 @@ public class ASMParser {
ActionConstantPool cpool = new ActionConstantPool(constantPool);
cpool.setAddress(address);
address += cpool.getBytes(version).length;
address += cpool.getBytesLength(version);
list.add(cpool);
while (true) {
@@ -185,7 +185,7 @@ public class ASMParser {
address += 1;
} else if (a != null) {
a.setAddress(address);
address += a.getBytes(version).length;
address += a.getBytesLength(version);
}
if (a instanceof GraphSourceItemContainer) {
containers.push((GraphSourceItemContainer) a);
@@ -475,7 +475,7 @@ public class ASMParser {
for (Label label : labels) {
if (((ActionJump) link).identifier.equals(label.name)) {
((ActionJump) link).setJumpOffset((int) (label.address - (((ActionJump) link).getAddress() + ((ActionJump) link).getBytes(version).length)));
((ActionJump) link).setJumpOffset((int) (label.address - (((ActionJump) link).getAddress() + ((ActionJump) link).getBytesLength(version))));
found = true;
break;
}
@@ -485,7 +485,7 @@ public class ASMParser {
for (Label label : labels) {
if (((ActionIf) link).identifier.equals(label.name)) {
((ActionIf) link).setJumpOffset((int) (label.address - (((ActionIf) link).getAddress() + ((ActionIf) link).getBytes(version).length)));
((ActionIf) link).setJumpOffset((int) (label.address - (((ActionIf) link).getAddress() + ((ActionIf) link).getBytesLength(version))));
found = true;
break;
}

View File

@@ -157,7 +157,7 @@ public class ActionSourceGenerator implements SourceGenerator {
|| (((ActionJump) onTrue.get(onTrue.size() - 1)).isBreak)))) {
ajmp = new ActionJump(0);
ret.add(ajmp);
onTrueLen += ajmp.getBytes(SWF.DEFAULT_VERSION).length;
onTrueLen += ajmp.getBytesLength(SWF.DEFAULT_VERSION);
}
ifaif.setJumpOffset(onTrueLen);
byte[] onFalseBytes = Action.actionsToBytes(onFalse, false, SWF.DEFAULT_VERSION);
@@ -182,7 +182,7 @@ public class ActionSourceGenerator implements SourceGenerator {
private void fixLoop(List<Action> code, int breakOffset, int continueOffset) {
int pos = 0;
for (Action a : code) {
pos += a.getBytes(SWF.DEFAULT_VERSION).length;
pos += a.getBytesLength(SWF.DEFAULT_VERSION);
if (a instanceof ActionJump) {
ActionJump aj = (ActionJump) a;
if (aj.isContinue && (continueOffset != Integer.MAX_VALUE)) {
@@ -248,8 +248,9 @@ public class ActionSourceGenerator implements SourceGenerator {
ret.addAll(doExpr);
ActionIf doif = new ActionIf(0);
ret.add(doif);
doif.setJumpOffset(-doBodyLen - doExprLen - doif.getBytes(SWF.DEFAULT_VERSION).length);
fixLoop(doBody, doBodyLen + doExprLen + doif.getBytes(SWF.DEFAULT_VERSION).length, doBodyLen);
int offset = doBodyLen + doExprLen + doif.getBytesLength(SWF.DEFAULT_VERSION);
doif.setJumpOffset(-offset);
fixLoop(doBody, offset, doBodyLen);
return ret;
}
@@ -264,7 +265,7 @@ public class ActionSourceGenerator implements SourceGenerator {
ActionIf foraif = new ActionIf(0);
forExpr.add(foraif);
ActionJump forajmp = new ActionJump(0);
int forajmpLen = forajmp.getBytes(SWF.DEFAULT_VERSION).length;
int forajmpLen = forajmp.getBytesLength(SWF.DEFAULT_VERSION);
int forExprLen = Action.actionsToBytes(forExpr, false, SWF.DEFAULT_VERSION).length;
int forBodyLen = Action.actionsToBytes(forBody, false, SWF.DEFAULT_VERSION).length;
int forFinalLen = Action.actionsToBytes(forFinalCommands, false, SWF.DEFAULT_VERSION).length;
@@ -278,6 +279,7 @@ public class ActionSourceGenerator implements SourceGenerator {
fixLoop(forBody, forBodyLen + forFinalLen + forajmpLen, forBodyLen);
return ret;
}
private long uniqLast = 0;
public String uniqId() {
@@ -371,7 +373,7 @@ public class ActionSourceGenerator implements SourceGenerator {
jmpPos += exprLengths.get(k).get(m);
}
}
jmpPos += defJump.getBytes(SWF.DEFAULT_VERSION).length;
jmpPos += defJump.getBytesLength(SWF.DEFAULT_VERSION);
for (int n = 0; n < i; n++) {
jmpPos += caseLengths.get(n);
}

View File

@@ -76,7 +76,7 @@ public class ActionIf extends Action {
@Override
public String getASMSource(List<? extends GraphSourceItem> container, List<Long> knownAddreses, List<String> constantPool, int version, ScriptExportMode exportMode) {
String ofsStr = Helper.formatAddress(getAddress() + getBytes(version).length + offset);
String ofsStr = Helper.formatAddress(getAddress() + getBytesLength(version) + offset);
return "If loc" + ofsStr + (!jumpUsed ? " ;compileTimeIgnore" : (!ignoreUsed ? " ;compileTimeJump" : ""));
}
@@ -98,10 +98,12 @@ public class ActionIf extends Action {
@Override
public List<Integer> getBranches(GraphSource code) {
List<Integer> ret = super.getBranches(code);
int jmp = code.adr2pos(getAddress() + getBytes(((ActionGraphSource) code).version).length + offset);
int after = code.adr2pos(getAddress() + getBytes(((ActionGraphSource) code).version).length);
int version = ((ActionGraphSource) code).version;
int length = getBytesLength(version);
int jmp = code.adr2pos(getAddress() + length + offset);
int after = code.adr2pos(getAddress() + length);
if (jmp == -1) {
Logger.getLogger(ActionIf.class.getName()).log(Level.SEVERE, "Invalid IF jump to ofs" + Helper.formatAddress(getAddress() + getBytes(((ActionGraphSource) code).version).length + offset));
Logger.getLogger(ActionIf.class.getName()).log(Level.SEVERE, "Invalid IF jump to ofs" + Helper.formatAddress(getAddress() + length + offset));
ret.add(after);
} else {
ret.add(jmp);

View File

@@ -76,12 +76,12 @@ public class ActionJump extends Action {
@Override
public String getASMSource(List<? extends GraphSourceItem> container, List<Long> knownAddreses, List<String> constantPool, int version, ScriptExportMode exportMode) {
String ofsStr = Helper.formatAddress(getAddress() + getBytes(version).length + offset);
String ofsStr = Helper.formatAddress(getAddress() + getBytesLength(version) + offset);
return "Jump loc" + ofsStr;
}
public ActionJump(FlasmLexer lexer) throws IOException, ParseException {
super(0x99, 0);
super(0x99, 2);
identifier = lexIdentifier(lexer);
}
@@ -98,11 +98,12 @@ public class ActionJump extends Action {
@Override
public List<Integer> getBranches(GraphSource code) {
List<Integer> ret = super.getBranches(code);
int ofs = code.adr2pos(getAddress() + getBytes(((ActionGraphSource) code).version).length + offset);
int version = ((ActionGraphSource) code).version;
int length = getBytesLength(version);
int ofs = code.adr2pos(getAddress() + length + offset);
if (ofs == -1) {
ofs = code.adr2pos(getAddress() + getBytes(((ActionGraphSource) code).version).length);
new Exception().printStackTrace();
Logger.getLogger(ActionJump.class.getName()).log(Level.SEVERE, "Invalid jump to ofs" + Helper.formatAddress(getAddress() + getBytes(((ActionGraphSource) code).version).length + offset) + " from ofs" + Helper.formatAddress(getAddress()));
ofs = code.adr2pos(getAddress() + length);
Logger.getLogger(ActionJump.class.getName()).log(Level.SEVERE, "Invalid jump to ofs" + Helper.formatAddress(getAddress() + length + offset) + " from ofs" + Helper.formatAddress(getAddress()));
}
ret.add(ofs);
return ret;

View File

@@ -46,6 +46,7 @@ public class ActionScript2ModificationTest extends ActionStript2TestBase {
public void init() throws IOException, InterruptedException {
Main.initLogging(false);
Configuration.autoDeobfuscate.set(false);
Configuration.pluginPath.set(null);
swf = new SWF(new BufferedInputStream(new FileInputStream("testdata/as2/as2.swf")), false);
}
@@ -69,15 +70,21 @@ public class ActionScript2ModificationTest extends ActionStript2TestBase {
public void testRemoveAction() {
String actionsString =
"ConstantPool\n" +
"Push 1\n" +
"Jump l1\n" +
"l1:Push 2";
"DefineFunction \"test\" 1 \"p1\" {\n" +
"Push 1\n" +
"}\n" +
"Push 2\n" +
"Jump label1\n" +
"label1:Push 3";
String expectedResult =
"ConstantPool\n" +
"Push 1 2\n";
"DefineFunction \"test\" 1 \"p1\" {\n" +
"Push 1\n" +
"}\n" +
"Push 2 3";
try {
ActionList actions = ASMParser.parse(0, true, actionsString, swf.version, false);
actions.removeAction(2);
actions.removeAction(4); // jump
DoActionTag doa = getFirstActionTag();
doa.setActionBytes(Action.actionsToBytes(actions, true, swf.version));