mirror of
https://git.huckle.dev/Huckles-Minecraft-Archive/jpexs-decompiler.git
synced 2026-06-08 04:35:05 +00:00
Merge origin/master
This commit is contained in:
@@ -659,6 +659,7 @@ public final class SWF implements SWFContainerItem, Timelined {
|
||||
if (hasEndTag) {
|
||||
sos.writeUI16(0);
|
||||
}
|
||||
|
||||
sos.close();
|
||||
os.write(Utf8Helper.getBytes(getHeaderBytes(compression, gfx)));
|
||||
os.write(version);
|
||||
@@ -711,6 +712,7 @@ public final class SWF implements SWFContainerItem, Timelined {
|
||||
} else if (compression == SWFCompression.ZLIB) {
|
||||
os = new DeflaterOutputStream(os);
|
||||
}
|
||||
|
||||
os.write(data);
|
||||
} finally {
|
||||
if (os != null) {
|
||||
@@ -2028,11 +2030,13 @@ public final class SWF implements SWFContainerItem, Timelined {
|
||||
ret++;
|
||||
}
|
||||
}
|
||||
|
||||
for (ASMSource src : actionsMap.keySet()) {
|
||||
actionsMap.get(src).removeNops();
|
||||
src.setActions(actionsMap.get(src));
|
||||
src.setModified();
|
||||
}
|
||||
|
||||
deobfuscation.deobfuscateInstanceNames(false, deobfuscated, renameType, tags, selected);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -17,7 +17,6 @@
|
||||
package com.jpexs.decompiler.flash;
|
||||
|
||||
import com.jpexs.decompiler.flash.action.Action;
|
||||
import com.jpexs.decompiler.flash.action.model.ConstantPool;
|
||||
import com.jpexs.decompiler.flash.action.special.ActionEnd;
|
||||
import com.jpexs.decompiler.flash.action.special.ActionNop;
|
||||
import com.jpexs.decompiler.flash.action.swf3.ActionGetURL;
|
||||
@@ -1565,11 +1564,10 @@ public class SWFInputStream implements AutoCloseable {
|
||||
/**
|
||||
* Reads one Action from the stream
|
||||
*
|
||||
* @param cpool
|
||||
* @return Action or null when ActionEndFlag or end of the stream
|
||||
* @throws IOException
|
||||
*/
|
||||
public Action readAction(ConstantPool cpool) throws IOException {
|
||||
public Action readAction() throws IOException {
|
||||
int actionCode = -1;
|
||||
|
||||
try {
|
||||
@@ -1603,7 +1601,7 @@ public class SWFInputStream implements AutoCloseable {
|
||||
case 0x09:
|
||||
return new ActionStopSounds();
|
||||
case 0x8A:
|
||||
return new ActionWaitForFrame(actionLength, this, cpool);
|
||||
return new ActionWaitForFrame(actionLength, this);
|
||||
case 0x8B:
|
||||
return new ActionSetTarget(actionLength, this, swf.version);
|
||||
case 0x8C:
|
||||
@@ -1684,7 +1682,7 @@ public class SWFInputStream implements AutoCloseable {
|
||||
case 0x28:
|
||||
return new ActionEndDrag();
|
||||
case 0x8D:
|
||||
return new ActionWaitForFrame2(actionLength, this, cpool);
|
||||
return new ActionWaitForFrame2(actionLength, this);
|
||||
case 0x26:
|
||||
return new ActionTrace();
|
||||
case 0x34:
|
||||
|
||||
@@ -153,11 +153,15 @@ public class SWFOutputStream extends OutputStream {
|
||||
/**
|
||||
* Writes UI8 (Unsigned 8bit integer) value to the stream
|
||||
*
|
||||
* @param val UI8 value to write
|
||||
* @param value UI8 value to write
|
||||
* @throws IOException
|
||||
*/
|
||||
public void writeUI8(int val) throws IOException {
|
||||
write(val);
|
||||
public void writeUI8(int value) throws IOException {
|
||||
if (value > 0xff) {
|
||||
throw new Error("Value is too large for UI8: " + value);
|
||||
}
|
||||
|
||||
write(value);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -167,7 +171,14 @@ public class SWFOutputStream extends OutputStream {
|
||||
* @throws IOException
|
||||
*/
|
||||
public void writeString(String value) throws IOException {
|
||||
write(Utf8Helper.getBytes(value));
|
||||
byte[] data = Utf8Helper.getBytes(value);
|
||||
for (int i = 0; i < data.length; i++) {
|
||||
if (data[i] == 0) {
|
||||
throw new IOException("String should not contain null character.");
|
||||
}
|
||||
}
|
||||
|
||||
write(data);
|
||||
write(0);
|
||||
}
|
||||
|
||||
@@ -178,6 +189,10 @@ public class SWFOutputStream extends OutputStream {
|
||||
* @throws IOException
|
||||
*/
|
||||
public void writeUI32(long value) throws IOException {
|
||||
if (value > 0xffffffffL) {
|
||||
throw new Error("Value is too large for UI32: " + value);
|
||||
}
|
||||
|
||||
write((int) (value & 0xff));
|
||||
write((int) ((value >> 8) & 0xff));
|
||||
write((int) ((value >> 16) & 0xff));
|
||||
@@ -191,6 +206,10 @@ public class SWFOutputStream extends OutputStream {
|
||||
* @throws IOException
|
||||
*/
|
||||
public void writeUI16(int value) throws IOException {
|
||||
if (value > 0xffff) {
|
||||
throw new Error("Value is too large for UI16: " + value);
|
||||
}
|
||||
|
||||
write((int) (value & 0xff));
|
||||
write((int) ((value >> 8) & 0xff));
|
||||
}
|
||||
@@ -202,6 +221,10 @@ public class SWFOutputStream extends OutputStream {
|
||||
* @throws IOException
|
||||
*/
|
||||
public void writeSI32(long value) throws IOException {
|
||||
if (value > 0x7fffffffL) {
|
||||
throw new Error("Value is too large for SI32: " + value);
|
||||
}
|
||||
|
||||
writeUI32(value);
|
||||
}
|
||||
|
||||
@@ -212,6 +235,10 @@ public class SWFOutputStream extends OutputStream {
|
||||
* @throws IOException
|
||||
*/
|
||||
public void writeSI16(int value) throws IOException {
|
||||
if (value > 0x7fff) {
|
||||
throw new Error("Value is too large for SI16: " + value);
|
||||
}
|
||||
|
||||
writeUI16(value);
|
||||
}
|
||||
|
||||
@@ -222,6 +249,10 @@ public class SWFOutputStream extends OutputStream {
|
||||
* @throws IOException
|
||||
*/
|
||||
public void writeSI8(int value) throws IOException {
|
||||
if (value > 0x7ff) {
|
||||
throw new Error("Value is too large for SI8: " + value);
|
||||
}
|
||||
|
||||
writeUI8(value);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,16 +1,16 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
@@ -131,13 +131,11 @@ public class ActionListReader {
|
||||
* @throws java.lang.InterruptedException
|
||||
*/
|
||||
public static ActionList readActionList(List<DisassemblyListener> listeners, SWFInputStream sis, int version, int ip, int endIp, String path, int deobfuscationMode) throws IOException, InterruptedException {
|
||||
ConstantPool cpool = new ConstantPool();
|
||||
|
||||
// Map of the actions. Use TreeMap to sort the keys in ascending order
|
||||
// actionMap and nextOffsets should contain exaclty the same keys
|
||||
Map<Long, Action> actionMap = new TreeMap<>();
|
||||
Map<Long, Long> nextOffsets = new HashMap<>();
|
||||
Action entryAction = readActionListAtPos(listeners, cpool,
|
||||
Action entryAction = readActionListAtPos(listeners, null,
|
||||
sis, actionMap, nextOffsets,
|
||||
ip, 0, endIp, path, false, new ArrayList<Long>());
|
||||
|
||||
@@ -238,12 +236,10 @@ public class ActionListReader {
|
||||
}
|
||||
|
||||
public static List<Action> getOriginalActions(SWFInputStream sis, int startIp, int endIp) throws IOException, InterruptedException {
|
||||
ConstantPool cpool = new ConstantPool();
|
||||
|
||||
// Map of the actions. Use TreeMap to sort the keys in ascending order
|
||||
Map<Long, Action> actionMap = new TreeMap<>();
|
||||
Map<Long, Long> nextOffsets = new HashMap<>();
|
||||
readActionListAtPos(new ArrayList<DisassemblyListener>(), cpool,
|
||||
readActionListAtPos(new ArrayList<DisassemblyListener>(), null,
|
||||
sis, actionMap, nextOffsets,
|
||||
startIp, startIp, endIp + 1, "", false, new ArrayList<Long>());
|
||||
|
||||
@@ -690,7 +686,7 @@ public class ActionListReader {
|
||||
sis.seek((int) ip);
|
||||
|
||||
Action a;
|
||||
if ((a = sis.readAction(cpool)) == null) {
|
||||
if ((a = sis.readAction()) == null) {
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -729,10 +725,7 @@ public class ActionListReader {
|
||||
if (a instanceof ActionPush && cpool != null) {
|
||||
((ActionPush) a).constantPool = cpool.constants;
|
||||
} else if (a instanceof ActionConstantPool) {
|
||||
if (cpool == null) {
|
||||
cpool = new ConstantPool();
|
||||
}
|
||||
cpool.setNew(((ActionConstantPool) a).constantPool);
|
||||
cpool = new ConstantPool(((ActionConstantPool) a).constantPool);
|
||||
} else if (a instanceof ActionIf) {
|
||||
ActionIf aIf = (ActionIf) a;
|
||||
long nIp = ip + actionLengthWithHeader + aIf.getJumpOffset();
|
||||
|
||||
@@ -1,18 +1,19 @@
|
||||
/*
|
||||
* 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.
|
||||
* License along with this library.
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.action.parser.pcode;
|
||||
|
||||
import com.jpexs.decompiler.flash.action.Action;
|
||||
@@ -128,14 +129,16 @@ import com.jpexs.helpers.Helper;
|
||||
import java.io.IOException;
|
||||
import java.io.StringReader;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Stack;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
public class ASMParser {
|
||||
|
||||
|
||||
public static ActionList parse(boolean ignoreNops, List<Label> labels, Map<Action, Integer> lineMap, long address, FlasmLexer lexer, List<String> constantPool, int version) throws IOException, ActionParseException {
|
||||
ActionList list = new ActionList();
|
||||
Stack<GraphSourceItemContainer> containers = new Stack<>();
|
||||
|
||||
@@ -192,6 +195,7 @@ public class ASMParser {
|
||||
}
|
||||
if (a != null) {
|
||||
list.add(a);
|
||||
lineMap.put(a, lexer.yyline());
|
||||
}
|
||||
} else if (symb.type == ASMParsedSymbol.TYPE_EOL) {
|
||||
} else if ((symb.type == ASMParsedSymbol.TYPE_BLOCK_END) || (symb.type == ASMParsedSymbol.TYPE_EOF)) {
|
||||
@@ -464,7 +468,8 @@ public class ASMParser {
|
||||
|
||||
lexer = new FlasmLexer(new StringReader(source));
|
||||
List<Label> labels = new ArrayList<>();
|
||||
List<Label> labels = new ArrayList<>();
|
||||
Map<Action, Integer> lineMap = new HashMap<>();
|
||||
ActionList ret = parse(ignoreNops, labels, lineMap, address, lexer, constantPool, version);
|
||||
//Action.setActionsAddresses(ret, address, version);
|
||||
for (Action link : ret) {
|
||||
if (!(link instanceof ActionIf || link instanceof ActionJump)) {
|
||||
@@ -480,7 +485,22 @@ public class ASMParser {
|
||||
ActionJump actionJump = (ActionJump) link;
|
||||
|
||||
if (actionJump.identifier.equals(label.name)) {
|
||||
if (actionJump.identifier.equals(label.name)) {
|
||||
int offset = (int) (label.address - (actionJump.getAddress() + actionJump.getTotalActionLength()));
|
||||
if (offset < -0x8000 || offset > 0x7fff) {
|
||||
String message = "Jump offset is too large:" + offset + " addr: ofs" + Helper.formatAddress(link.getAddress());
|
||||
if (throwOnError) {
|
||||
Integer line = lineMap.get(link);
|
||||
if (line == null) {
|
||||
line = -1;
|
||||
}
|
||||
|
||||
throw new ActionParseException(message, line);
|
||||
} else {
|
||||
Logger.getLogger(ASMParser.class.getName()).log(Level.SEVERE, message);
|
||||
}
|
||||
}
|
||||
|
||||
actionJump.setJumpOffset(offset);
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
@@ -491,7 +511,22 @@ public class ASMParser {
|
||||
|
||||
for (Label label : labels) {
|
||||
if (actionIf.identifier.equals(label.name)) {
|
||||
if (actionIf.identifier.equals(label.name)) {
|
||||
int offset = (int) (label.address - (actionIf.getAddress() + actionIf.getTotalActionLength()));
|
||||
if (offset < -0x8000 || offset > 0x7fff) {
|
||||
String message = "If offset is too large:" + offset + " addr: ofs" + Helper.formatAddress(link.getAddress());
|
||||
if (throwOnError) {
|
||||
Integer line = lineMap.get(link);
|
||||
if (line == null) {
|
||||
line = -1;
|
||||
}
|
||||
|
||||
throw new ActionParseException(message, line);
|
||||
} else {
|
||||
Logger.getLogger(ASMParser.class.getName()).log(Level.SEVERE, message);
|
||||
}
|
||||
}
|
||||
|
||||
actionIf.setJumpOffset(offset);
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
@@ -499,13 +534,20 @@ public class ASMParser {
|
||||
}
|
||||
|
||||
if (!found) {
|
||||
String message = "TARGET NOT FOUND - identifier:" + identifier + " addr: ofs" + Helper.formatAddress(link.getAddress());
|
||||
if (throwOnError) {
|
||||
if (throwOnError) {
|
||||
Integer line = lineMap.get(link);
|
||||
if (line == null) {
|
||||
line = -1;
|
||||
}
|
||||
|
||||
throw new ActionParseException(message, line);
|
||||
} else {
|
||||
} else {
|
||||
Logger.getLogger(ASMParser.class.getName()).log(Level.SEVERE, message);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,7 +22,6 @@ import com.jpexs.decompiler.flash.SWFOutputStream;
|
||||
import com.jpexs.decompiler.flash.action.Action;
|
||||
import com.jpexs.decompiler.flash.action.ActionGraph;
|
||||
import com.jpexs.decompiler.flash.action.ActionList;
|
||||
import com.jpexs.decompiler.flash.action.model.ConstantPool;
|
||||
import com.jpexs.decompiler.flash.action.model.DirectValueActionItem;
|
||||
import com.jpexs.decompiler.flash.action.model.clauses.IfFrameLoadedActionItem;
|
||||
import com.jpexs.decompiler.flash.action.parser.ActionParseException;
|
||||
@@ -46,7 +45,7 @@ public class ActionWaitForFrame extends Action implements ActionStore {
|
||||
|
||||
public List<Action> skipped;
|
||||
|
||||
public ActionWaitForFrame(int actionLength, SWFInputStream sis, ConstantPool cpool) throws IOException {
|
||||
public ActionWaitForFrame(int actionLength, SWFInputStream sis) throws IOException {
|
||||
super(0x8A, actionLength);
|
||||
frame = sis.readUI16("frame");
|
||||
skipCount = sis.readUI8("skipCount");
|
||||
|
||||
@@ -22,7 +22,6 @@ import com.jpexs.decompiler.flash.SWFOutputStream;
|
||||
import com.jpexs.decompiler.flash.action.Action;
|
||||
import com.jpexs.decompiler.flash.action.ActionGraph;
|
||||
import com.jpexs.decompiler.flash.action.ActionList;
|
||||
import com.jpexs.decompiler.flash.action.model.ConstantPool;
|
||||
import com.jpexs.decompiler.flash.action.model.clauses.IfFrameLoadedActionItem;
|
||||
import com.jpexs.decompiler.flash.action.parser.ActionParseException;
|
||||
import com.jpexs.decompiler.flash.action.parser.pcode.FlasmLexer;
|
||||
@@ -60,7 +59,7 @@ public class ActionWaitForFrame2 extends Action implements ActionStore {
|
||||
skipCount = store.size();
|
||||
}
|
||||
|
||||
public ActionWaitForFrame2(int actionLength, SWFInputStream sis, ConstantPool cpool) throws IOException {
|
||||
public ActionWaitForFrame2(int actionLength, SWFInputStream sis) throws IOException {
|
||||
super(0x8D, actionLength);
|
||||
skipCount = sis.readUI8("skipCount");
|
||||
skipped = new ArrayList<>();
|
||||
|
||||
@@ -46,6 +46,7 @@ public class ConstantIndex implements Serializable {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return "constant" + index;
|
||||
}
|
||||
|
||||
@@ -58,6 +59,7 @@ public class ConstantIndex implements Serializable {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return "constant" + index;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -196,6 +196,7 @@ public class DefineButtonTag extends ButtonTag implements ASMSource {
|
||||
if (prevLength != 0) {
|
||||
rri.seek(prevLength);
|
||||
}
|
||||
|
||||
ActionList list = ActionListReader.readActionListTimeout(listeners, rri, getVersion(), prevLength, prevLength + actionBytes.getLength(), toString()/*FIXME?*/);
|
||||
return list;
|
||||
} catch (InterruptedException ex) {
|
||||
|
||||
@@ -282,6 +282,14 @@ public class DefineSpriteTag extends CharacterTag implements DrawableTag, Timeli
|
||||
super.setModified(value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void createOriginalData() {
|
||||
super.createOriginalData();
|
||||
for (Tag subTag : subTags) {
|
||||
subTag.createOriginalData();
|
||||
}
|
||||
}
|
||||
|
||||
public static void clearCache() {
|
||||
rectCache.clear();
|
||||
}
|
||||
|
||||
@@ -131,6 +131,7 @@ public class DoActionTag extends Tag implements ASMSource {
|
||||
if (prevLength != 0) {
|
||||
rri.seek(prevLength);
|
||||
}
|
||||
|
||||
ActionList list = ActionListReader.readActionListTimeout(listeners, rri, getVersion(), prevLength, prevLength + actionBytes.getLength(), toString()/*FIXME?*/);
|
||||
return list;
|
||||
} catch (InterruptedException ex) {
|
||||
|
||||
@@ -138,6 +138,7 @@ public class DoInitActionTag extends Tag implements CharacterIdTag, ASMSource {
|
||||
if (prevLength != 0) {
|
||||
rri.seek(prevLength);
|
||||
}
|
||||
|
||||
ActionList list = ActionListReader.readActionListTimeout(listeners, rri, getVersion(), prevLength, prevLength + actionBytes.getLength(), toString()/*FIXME?*/);
|
||||
return list;
|
||||
} catch (InterruptedException ex) {
|
||||
|
||||
@@ -205,6 +205,7 @@ public class BUTTONCONDACTION implements ASMSource, Serializable {
|
||||
if (prevLength != 0) {
|
||||
rri.seek(prevLength);
|
||||
}
|
||||
|
||||
ActionList list = ActionListReader.readActionListTimeout(listeners, rri, swf.version, prevLength, prevLength + actionBytes.getLength(), toString()/*FIXME?*/);
|
||||
return list;
|
||||
|
||||
|
||||
@@ -199,6 +199,7 @@ public class CLIPACTIONRECORD implements ASMSource, Serializable {
|
||||
if (prevLength != 0) {
|
||||
rri.seek(prevLength);
|
||||
}
|
||||
|
||||
ActionList list = ActionListReader.readActionListTimeout(listeners, rri, swf.version, prevLength, prevLength + actionBytes.getLength(), toString()/*FIXME?*/);
|
||||
return list;
|
||||
} catch (InterruptedException ex) {
|
||||
|
||||
Reference in New Issue
Block a user