action deobfuscator improved again

This commit is contained in:
honfika@gmail.com
2015-09-26 22:31:08 +02:00
parent ad3a760da5
commit dba9a8b162
12 changed files with 105 additions and 41 deletions

View File

@@ -321,10 +321,9 @@ public abstract class Action implements GraphSourceItem {
/**
* Gets the length of action converted to bytes
*
* @param version SWF version
* @return Length
*/
public final int getBytesLength(int version) {
public final int getBytesLength() {
return getContentBytesLength() + (actionCode >= 0x80 ? 3 : 1);
}
@@ -334,11 +333,9 @@ public abstract class Action implements GraphSourceItem {
/**
* Updates the action length to the length calculated from action bytes
*
* @param version SWF version
*/
public void updateLength(int version) {
int length = getBytesLength(version);
public void updateLength() {
int length = getBytesLength();
actionLength = length - 1 - (actionCode >= 0x80 ? 2 : 0);
}

View File

@@ -57,11 +57,11 @@ public class ActionList extends ArrayList<Action> {
}
public void removeAction(int index) {
ActionListReader.removeAction(this, index, SWF.DEFAULT_VERSION, true);
ActionListReader.removeAction(this, index, true);
}
public void removeActions(List<Action> actionsToRemove) {
ActionListReader.removeActions(this, actionsToRemove, SWF.DEFAULT_VERSION, true);
ActionListReader.removeActions(this, actionsToRemove, true);
}
public void removeAction(int index, int count) {
@@ -71,20 +71,20 @@ public class ActionList extends ArrayList<Action> {
}
for (int i = 0; i < count; i++) {
ActionListReader.removeAction(this, index, SWF.DEFAULT_VERSION, true);
ActionListReader.removeAction(this, index, true);
}
}
public void addAction(int index, Action action) {
ActionListReader.addAction(this, index, action, SWF.DEFAULT_VERSION, false, false);
ActionListReader.addAction(this, index, action, false, false);
}
public void addActions(int index, List<Action> actions) {
ActionListReader.addActions(this, index, actions, SWF.DEFAULT_VERSION);
ActionListReader.addActions(this, index, actions);
}
public void fixActionList() {
ActionListReader.fixActionList(this, null, SWF.DEFAULT_VERSION);
ActionListReader.fixActionList(this, null);
}
public List<Action> getContainerLastActions(Action action) {

View File

@@ -156,7 +156,7 @@ public class ActionListReader {
nextOffsets.put(endAddress, endAddress + 1);
}
ActionList actions = fixActionList(new ActionList(actionMap.values()), nextOffsets, version);
ActionList actions = fixActionList(new ActionList(actionMap.values()), nextOffsets);
// jump to the entry action when it is diffrent from the first action in the map
if (entryAction != actions.get(0)) {
@@ -166,13 +166,13 @@ public class ActionListReader {
}
if (SWFDecompilerPlugin.fireActionListParsed(actions, sis.getSwf())) {
actions = fixActionList(actions, null, version);
actions = fixActionList(actions, null);
}
if (deobfuscationMode == 0) {
try {
actions = deobfuscateActionListOld(listeners, actions, version, 0, path);
updateActionLengths(actions, version);
updateActionLengths(actions);
} catch (OutOfMemoryError | StackOverflowError | TranslateException ex) {
// keep orignal (not deobfuscated) actions
logger.log(Level.SEVERE, null, ex);
@@ -192,7 +192,7 @@ public class ActionListReader {
return actions;
}
public static ActionList fixActionList(ActionList actions, Map<Long, Long> nextOffsets, int version) {
public static ActionList fixActionList(ActionList actions, Map<Long, Long> nextOffsets) {
Map<Action, List<Action>> containerLastActions = new HashMap<>();
getContainerLastActions(actions, containerLastActions);
@@ -226,7 +226,7 @@ public class ActionListReader {
Map<Action, Action> jumps = new HashMap<>();
getJumps(ret, jumps);
updateActionLengths(ret, version);
updateActionLengths(ret);
updateAddresses(ret, 0);
long endAddress = ret.get(ret.size() - 1).getAddress();
@@ -427,9 +427,9 @@ public class ActionListReader {
return address;
}
private static void updateActionLengths(List<Action> actions, int version) {
private static void updateActionLengths(List<Action> actions) {
for (int i = 0; i < actions.size(); i++) {
actions.get(i).updateLength(version);
actions.get(i).updateLength();
}
}
@@ -537,11 +537,10 @@ public class ActionListReader {
*
* @param actions
* @param index
* @param version
* @param removeWhenLast
* @return
*/
public static boolean removeAction(ActionList actions, int index, int version, boolean removeWhenLast) {
public static boolean removeAction(ActionList actions, int index, boolean removeWhenLast) {
if (index < 0 || actions.size() <= index) {
return false;
@@ -586,7 +585,7 @@ public class ActionListReader {
actions.remove(index);
updateActionLengths(actions, version);
updateActionLengths(actions);
updateAddresses(actions, startIp);
updateJumps(actions, jumps, containerLastActions, endAddress);
updateActionStores(actions, jumps);
@@ -603,11 +602,10 @@ public class ActionListReader {
*
* @param actions
* @param actionsToRemove
* @param version
* @param removeWhenLast
* @return
*/
public static boolean removeActions(ActionList actions, List<Action> actionsToRemove, int version, boolean removeWhenLast) {
public static boolean removeActions(ActionList actions, List<Action> actionsToRemove, boolean removeWhenLast) {
long startIp = actions.get(0).getAddress();
Action lastAction = actions.get(actions.size() - 1);
@@ -651,7 +649,7 @@ public class ActionListReader {
actions.remove(index);
}
updateActionLengths(actions, version);
updateActionLengths(actions);
updateAddresses(actions, startIp);
updateJumps(actions, jumps, containerLastActions, endAddress);
updateActionStores(actions, jumps);
@@ -667,13 +665,12 @@ public class ActionListReader {
* @param actions
* @param index
* @param action
* @param version
* @param addToContainer
* @param replaceJump
* @return
*/
public static boolean addAction(ActionList actions, int index, Action action,
int version, boolean addToContainer, boolean replaceJump) {
boolean addToContainer, boolean replaceJump) {
if (index < 0 || actions.size() < index) {
return false;
@@ -721,7 +718,7 @@ public class ActionListReader {
actions.add(index, action);
updateActionLengths(actions, version);
updateActionLengths(actions);
updateAddresses(actions, startIp);
updateJumps(actions, jumps, containerLastActions, endAddress);
updateActionStores(actions, jumps);
@@ -737,10 +734,9 @@ public class ActionListReader {
* @param actions
* @param index
* @param newActions
* @param version
* @return
*/
public static boolean addActions(ActionList actions, int index, List<Action> newActions, int version) {
public static boolean addActions(ActionList actions, int index, List<Action> newActions) {
if (index < 0 || actions.size() < index) {
return false;
@@ -767,7 +763,7 @@ public class ActionListReader {
actions.addAll(index, newActions);
updateActionLengths(actions, version);
updateActionLengths(actions);
updateAddresses(actions, startIp);
updateJumps(actions, jumps, containerLastActions, endAddress);
updateActionStores(actions, jumps);

View File

@@ -0,0 +1,69 @@
/*
* Copyright (C) 2010-2015 JPEXS, All rights reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3.0 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library.
*/
package com.jpexs.decompiler.flash.action;
import com.jpexs.decompiler.flash.action.swf4.ActionPush;
import java.util.LinkedList;
import java.util.List;
import java.util.ListIterator;
/**
*
* @author JPEXS
*/
public class FastActionList {
private LinkedList<Action> actions;
public FastActionList(List<Action> actions) {
this.actions = new LinkedList<>(actions);
}
public void expandPushes() {
ListIterator<Action> iterator = actions.listIterator();
while (iterator.hasNext()) {
Action action = iterator.next();
if (action instanceof ActionPush) {
ActionPush push = (ActionPush) action;
if (push.values.size() > 1) {
for (int i = 1; i < push.values.size(); i++) {
Object value = push.values.get(i);
ActionPush newPush = new ActionPush(value);
newPush.constantPool = push.constantPool;
iterator.add(newPush);
}
Object obj = push.values.get(0);
push.values.clear();
push.values.add(obj);
}
}
}
}
private void updateActionLengths() {
for (Action action : actions) {
action.updateLength();
}
}
public ActionList toActionList() {
ActionList result = new ActionList(actions);
updateActionLengths();
return result;
}
}

View File

@@ -22,6 +22,7 @@ import com.jpexs.decompiler.flash.abc.types.MethodBody;
import com.jpexs.decompiler.flash.action.Action;
import com.jpexs.decompiler.flash.action.ActionList;
import com.jpexs.decompiler.flash.action.ActionLocalData;
import com.jpexs.decompiler.flash.action.FastActionList;
import com.jpexs.decompiler.flash.action.swf4.ActionAdd;
import com.jpexs.decompiler.flash.action.swf4.ActionAnd;
import com.jpexs.decompiler.flash.action.swf4.ActionAsciiToChar;
@@ -83,6 +84,10 @@ public class ActionDeobfuscatorSimple implements SWFDecompilerListener {
@Override
public void actionListParsed(ActionList actions, SWF swf) throws InterruptedException {
FastActionList fastActions = new FastActionList(actions);
fastActions.expandPushes();
actions.setActions(fastActions.toActionList());
actions.expandPushes();
removeGetTimes(actions);
removeObfuscationIfs(actions);

View File

@@ -424,7 +424,7 @@ public class ASMParser {
throw new ActionParseException("Unknown instruction name :" + instructionName, lexer.yyline());
}
a.updateLength(version);
a.updateLength();
return a;
}

View File

@@ -19,7 +19,6 @@ package com.jpexs.decompiler.flash.action.swf4;
import com.jpexs.decompiler.flash.SWFInputStream;
import com.jpexs.decompiler.flash.SWFOutputStream;
import com.jpexs.decompiler.flash.action.Action;
import com.jpexs.decompiler.flash.action.ActionGraphSource;
import com.jpexs.decompiler.flash.action.ActionList;
import com.jpexs.decompiler.flash.action.parser.ActionParseException;
import com.jpexs.decompiler.flash.action.parser.pcode.FlasmLexer;
@@ -105,8 +104,7 @@ public class ActionJump extends Action {
@Override
public List<Integer> getBranches(GraphSource code) {
List<Integer> ret = super.getBranches(code);
int version = ((ActionGraphSource) code).version;
int length = getBytesLength(version);
int length = getBytesLength();
int ofs = code.adr2pos(getAddress() + length + offset);
if (ofs == -1) {
ofs = code.adr2pos(getAddress() + length);

View File

@@ -18,7 +18,6 @@ package com.jpexs.decompiler.flash.action.swf4;
import com.jpexs.decompiler.flash.BaseLocalData;
import com.jpexs.decompiler.flash.EndOfStreamException;
import com.jpexs.decompiler.flash.SWF;
import com.jpexs.decompiler.flash.SWFInputStream;
import com.jpexs.decompiler.flash.SWFOutputStream;
import com.jpexs.decompiler.flash.action.Action;
@@ -248,7 +247,7 @@ public class ActionPush extends Action {
super(0x96, 0);
this.values = new ArrayList<>();
this.values.add(value);
updateLength(SWF.DEFAULT_VERSION);
updateLength();
}
public ActionPush(FlasmLexer lexer, List<String> constantPool) throws IOException, ActionParseException {

View File

@@ -84,7 +84,7 @@ public class ActionDefineFunction extends Action implements GraphSourceItemConta
@Override
public long getHeaderSize() {
return getBytesLength(version);
return getBytesLength();
}
@Override

View File

@@ -109,7 +109,7 @@ public class ActionWith extends Action implements GraphSourceItemContainer {
@Override
public long getHeaderSize() {
return getBytesLength(version);
return getBytesLength();
}
@Override

View File

@@ -143,7 +143,7 @@ public class ActionDefineFunction2 extends Action implements GraphSourceItemCont
@Override
public long getHeaderSize() {
return getBytesLength(version);
return getBytesLength();
}
@Override

View File

@@ -180,7 +180,7 @@ public class ActionTry extends Action implements GraphSourceItemContainer {
@Override
public long getHeaderSize() {
return getBytesLength(version);
return getBytesLength();
}
public long getTrySize() {