AS3: Editing exceptions

This commit is contained in:
Jindra Pet��k
2010-09-19 13:58:21 +02:00
parent 86f602ff80
commit c2194031db
34 changed files with 4322 additions and 1202 deletions
@@ -337,8 +337,12 @@ public class AVM2Code {
return null;
}
public String toASMSource(ConstantPool constants) {
public String toASMSource(ConstantPool constants,MethodBody body) {
String ret = "";
for(int e=0;e<body.exceptions.length;e++){
ret+="exception "+e+" m["+body.exceptions[e].name_index+"]\""+Helper.escapeString(body.exceptions[e].getVarName(constants))+"\" "+
"m["+body.exceptions[e].type_index+"]\""+Helper.escapeString(body.exceptions[e].getTypeName(constants))+"\"\n";
}
List<Long> offsets = new ArrayList<Long>();
for (AVM2Instruction ins : code) {
offsets.addAll(ins.getOffsets());
@@ -348,6 +352,17 @@ public class AVM2Code {
if (offsets.contains(ofs)) {
ret += "ofs" + Helper.formatAddress(ofs) + ":";
}
for(int e=0;e<body.exceptions.length;e++){
if(body.exceptions[e].start==ofs){
ret+="exceptionstart "+e+":";
}
if(body.exceptions[e].end==ofs){
ret+="exceptionend "+e+":";
}
if(body.exceptions[e].target==ofs){
ret+="exceptiontarget "+e+":";
}
}
ret += ins.toStringNoAddress(constants) + "\n";
ofs += ins.getBytes().length;
}
@@ -22,6 +22,8 @@ import com.jpexs.asdec.abc.avm2.AVM2Code;
import com.jpexs.asdec.abc.avm2.ConstantPool;
import com.jpexs.asdec.abc.avm2.instructions.AVM2Instruction;
import com.jpexs.asdec.abc.avm2.instructions.InstructionDefinition;
import com.jpexs.asdec.abc.types.ABCException;
import com.jpexs.asdec.abc.types.MethodBody;
import java.io.IOException;
import java.io.InputStream;
@@ -62,15 +64,17 @@ public class ASM3Parser {
}
}
public static AVM2Code parse(InputStream is, ConstantPool constants) throws IOException, ParseException {
return parse(is, constants, null);
public static AVM2Code parse(InputStream is, ConstantPool constants,MethodBody body) throws IOException, ParseException {
return parse(is, constants, null,body);
}
public static AVM2Code parse(InputStream is, ConstantPool constants, MissingSymbolHandler missingHandler) throws IOException, ParseException {
public static AVM2Code parse(InputStream is, ConstantPool constants, MissingSymbolHandler missingHandler,MethodBody body) throws IOException, ParseException {
AVM2Code code = new AVM2Code();
List<OffsetItem> offsetItems = new ArrayList<OffsetItem>();
List<LabelItem> labelItems = new ArrayList<LabelItem>();
List<ABCException> exceptions=new ArrayList<ABCException>();
List<Integer> exceptionIndices=new ArrayList<Integer>();
int offset = 0;
Flasm3Lexer lexer = new Flasm3Lexer(is);
@@ -79,6 +83,33 @@ public class ASM3Parser {
AVM2Instruction lastIns = null;
do {
symb = lexer.yylex();
if (symb.type == ParsedSymbol.TYPE_EXCEPTION_START){
int exIndex=(Integer)symb.value;
int listIndex=exceptionIndices.indexOf(exIndex);
if(listIndex==-1){
throw new ParseException("Undefinex exception index", lexer.yyline());
}
exceptions.get(listIndex).start=offset;
continue;
}
if (symb.type == ParsedSymbol.TYPE_EXCEPTION_END){
int exIndex=(Integer)symb.value;
int listIndex=exceptionIndices.indexOf(exIndex);
if(listIndex==-1){
throw new ParseException("Undefinex exception index", lexer.yyline());
}
exceptions.get(listIndex).end=offset;
continue;
}
if (symb.type == ParsedSymbol.TYPE_EXCEPTION_TARGET){
int exIndex=(Integer)symb.value;
int listIndex=exceptionIndices.indexOf(exIndex);
if(listIndex==-1){
throw new ParseException("Undefinex exception index", lexer.yyline());
}
exceptions.get(listIndex).target=offset;
continue;
}
if (symb.type == ParsedSymbol.TYPE_EOF) break;
if (symb.type == ParsedSymbol.TYPE_COMMENT) {
if (lastIns != null) {
@@ -87,6 +118,26 @@ public class ASM3Parser {
continue;
}
if (symb.type == ParsedSymbol.TYPE_INSTRUCTION_NAME) {
if(((String)symb.value).toLowerCase().equals("exception")){
ParsedSymbol exIndex = lexer.yylex();
if (exIndex.type != ParsedSymbol.TYPE_INTEGER) {
throw new ParseException("Index expected", lexer.yyline());
}
ParsedSymbol exName = lexer.yylex();
if (exName.type != ParsedSymbol.TYPE_MULTINAME) {
throw new ParseException("Multiname expected", lexer.yyline());
}
ParsedSymbol exType = lexer.yylex();
if (exType.type != ParsedSymbol.TYPE_MULTINAME) {
throw new ParseException("Multiname expected", lexer.yyline());
}
ABCException ex=new ABCException();
ex.name_index=(int) (long) (Long)exName.value;
ex.type_index=(int) (long) (Long)exType.value;
exceptions.add(ex);
exceptionIndices.add((int)(long)(Long)exIndex.value);
continue;
}
boolean insFound = false;
for (InstructionDefinition def : AVM2Code.instructionSet) {
if (def.instructionName.equals((String) symb.value)) {
@@ -251,207 +302,10 @@ public class ASM3Parser {
}
}
}
/* BufferedReader br = new BufferedReader(new InputStreamReader(is));
String s = "";
Pattern patInsName = Pattern.compile("^([a-z0-9_]+) ");
Pattern patLabelName = Pattern.compile("^([a-zA-Z_0-9]+): ");
Pattern patInt = Pattern.compile("^([+-]?[0-9]+) ");
Pattern patDouble = Pattern.compile("^([+-]?[0-9e.]+) ");
Pattern patMultiname = Pattern.compile("^m\\[([0-9]+)\\]\"[^\"]*\" ");
Pattern patString = Pattern.compile("\"([^\"]*)\" ");
Pattern patofs = Pattern.compile("^([a-zA-Z_0-9]+) ");
long line = 0;
while ((s = br.readLine()) != null) {
line++;
s += " ";
Matcher m = patInsName.matcher(s);
if (m.find()) {
String insName = m.group(1);
boolean insFound = false;
for (InstructionDefinition def : AVM2Code.instructionSet) {
if (def.instructionName.equals(insName)) {
insFound = true;
s = s.substring(insName.length() + 1);
List<Integer> operandsList = new ArrayList<Integer>();
for (int i = 0; i < def.operands.length; i++) {
switch (def.operands[i]) {
case AVM2Code.DAT_MULTINAME_INDEX:
m = patMultiname.matcher(s);
if (m.find()) {
operandsList.add(Integer.parseInt(m.group(1)));
s = s.substring(m.group(0).length());
} else {
throw new ParseException("Invalid multiname", line);
}
break;
case AVM2Code.DAT_STRING_INDEX:
m = patString.matcher(s);
if (m.find()) {
String str = m.group(1);
int sid = constants.getStringId(str);
if (sid == 0) {
if((missingHandler!=null)&&(missingHandler.missingString(str))){
sid=constants.addString(str);
}else{
throw new ParseException("Unknown String", line);
}
}
operandsList.add(sid);
s = s.substring(m.group(0).length());
} else {
throw new ParseException("Invalid String", line);
}
break;
case AVM2Code.DAT_INT_INDEX:
m = patInt.matcher(s);
if (m.find()) {
long intVal=Integer.parseInt(m.group(1));
int iid = constants.getIntId(intVal);
if (iid == 0) {
if((missingHandler!=null)&&(missingHandler.missingInt(intVal))){
iid=constants.addInt(intVal);
}else{
throw new ParseException("Unknown int", line);
}
}
operandsList.add(iid);
s = s.substring(m.group(0).length());
} else {
throw new ParseException("Invalid int value", line);
}
break;
case AVM2Code.DAT_UINT_INDEX:
m = patInt.matcher(s);
if (m.find()) {
long intVal=Integer.parseInt(m.group(1));
int iid = constants.getUIntId(intVal);
if (iid == 0) {
if((missingHandler!=null)&&(missingHandler.missingUInt(intVal))){
iid=constants.addUInt(intVal);
}else{
throw new ParseException("Unknown uint", line);
}
}
operandsList.add(iid);
s = s.substring(m.group(0).length());
} else {
throw new ParseException("Invalid uint value", line);
}
break;
case AVM2Code.DAT_DOUBLE_INDEX:
m = patDouble.matcher(s);
if (m.find()) {
double doubleVal=Double.parseDouble(m.group(1));
int did = constants.getDoubleId(doubleVal);
if (did == 0) {
if((missingHandler!=null)&&(missingHandler.missingDouble(doubleVal))){
did=constants.addDouble(doubleVal);
}else{
throw new ParseException("Unknown double", line);
}
}
operandsList.add(did);
s = s.substring(m.group(0).length());
} else {
throw new ParseException("Invalid double value", line);
}
break;
case AVM2Code.DAT_OFFSET:
m = patofs.matcher(s);
if (m.find()) {
offsetItems.add(new OffsetItem(m.group(1), code.code.size(), i));
operandsList.add(0);
s = s.substring(m.group(0).length());
} else {
throw new ParseException("Invalid offset value", line);
}
break;
case AVM2Code.DAT_CASE_BASEOFFSET:
m = patofs.matcher(s);
if (m.find()) {
offsetItems.add(new CaseOffsetItem(m.group(1), code.code.size(), i));
operandsList.add(0);
s = s.substring(m.group(0).length());
} else {
throw new ParseException("Invalid offset value", line);
}
break;
case AVM2Code.OPT_CASE_OFFSETS:
m = patInt.matcher(s);
if (m.find()) {
int patCount = Integer.parseInt(m.group(1));
operandsList.add(patCount);
s = s.substring(m.group(0).length());
m = patofs.matcher(s);
int k = 1;
for (int c = 0; c <= patCount; c++) {
if (m.find()) {
offsetItems.add(new CaseOffsetItem(m.group(1), code.code.size(), i + k));
operandsList.add(0);
s = s.substring(m.group(0).length());
m = patofs.matcher(s);
k++;
} else {
throw new ParseException("Invalid case count", line);
}
}
} else {
throw new ParseException("Invalid case count", line);
}
break;
default:
m = patInt.matcher(s);
if (m.find()) {
operandsList.add(Integer.parseInt(m.group(1)));
s = s.substring(m.group(0).length());
} else {
throw new ParseException("Invalid value", line);
}
}
}
int operands[] = new int[operandsList.size()];
for (int i = 0; i < operandsList.size(); i++) {
operands[i] = operandsList.get(i);
}
AVM2Instruction ins = new AVM2Instruction(offset, def, operands, new byte[0]);
code.code.add(ins);
offset += ins.getBytes().length;
break;
}
}
if (!insFound) {
throw new ParseException("Invalid instruction name:" + insName, line);
}
} else {
m = patLabelName.matcher(s);
if (m.find()) {
labelItems.add(new LabelItem(m.group(1), offset));
} else {
throw new ParseException("Invalid instruction name", line);
}
}
body.exceptions=new ABCException[exceptions.size()];
for(int e=0;e<exceptions.size();e++){
body.exceptions[e]=exceptions.get(e);
}
for (OffsetItem oi : offsetItems) {
for (LabelItem li : labelItems) {
if (oi.label.equals(li.label)) {
AVM2Instruction ins = code.code.get((int) oi.insPosition);
int relOffset = 0;
if (oi instanceof CaseOffsetItem) {
relOffset = li.offset - (int) ins.offset;
} else {
relOffset = li.offset - ((int) ins.offset + ins.getBytes().length);
}
ins.operands[oi.insOperandIndex] = relOffset;
}
}
}*/
return code;
}
}
File diff suppressed because it is too large Load Diff
@@ -32,6 +32,9 @@ public class ParsedSymbol {
public static final int TYPE_EOF = 7;
public static final int TYPE_LABEL = 8;
public static final int TYPE_COMMENT = 9;
public static final int TYPE_EXCEPTION_START=10;
public static final int TYPE_EXCEPTION_END=11;
public static final int TYPE_EXCEPTION_TARGET=12;
public ParsedSymbol(int type, Object value) {
this.type = type;
@@ -61,6 +61,8 @@ Label = {Identifier}:
/* integer literals */
NumberLiteral = 0 | -?[1-9][0-9]*
PositiveNumberLiteral = 0 | [1-9][0-9]*
/* floating point literals */
FloatLiteral = -?({FLit1}|{FLit2}|{FLit3}) {Exponent}?
@@ -75,6 +77,10 @@ OctDigit = [0-7]
/* string and character literals */
StringCharacter = [^\r\n\"\\]
ExceptionStart = "exceptionstart "{PositiveNumberLiteral}":"
ExceptionEnd = "exceptionend "{PositiveNumberLiteral}":"
ExceptionTarget = "exceptiontarget "{PositiveNumberLiteral}":"
%state STRING,PARAMETERS
%%
@@ -85,6 +91,18 @@ StringCharacter = [^\r\n\"\\]
/* whitespace */
{WhiteSpace} { }
{ExceptionStart} {
String s=yytext();
return new ParsedSymbol(ParsedSymbol.TYPE_EXCEPTION_START,Integer.parseInt(s.substring(15,s.length()-1)));
}
{ExceptionEnd} {
String s=yytext();
return new ParsedSymbol(ParsedSymbol.TYPE_EXCEPTION_END,Integer.parseInt(s.substring(13,s.length()-1)));
}
{ExceptionTarget} {
String s=yytext();
return new ParsedSymbol(ParsedSymbol.TYPE_EXCEPTION_TARGET,Integer.parseInt(s.substring(16,s.length()-1)));
}
{Label} {
String s=yytext();
return new ParsedSymbol(ParsedSymbol.TYPE_LABEL,s.substring(0,s.length()-1));
@@ -44,7 +44,7 @@ public class ASMSourceEditorPane extends JEditorPane {
public void setBodyIndex(int bodyIndex, ABC abc) {
this.bodyIndex = bodyIndex;
this.abc = abc;
setText(abc.bodies[bodyIndex].code.toASMSource(abc.constants));
setText(abc.bodies[bodyIndex].code.toASMSource(abc.constants,abc.bodies[bodyIndex]));
}
public void graph(){
@@ -53,7 +53,7 @@ public class ASMSourceEditorPane extends JEditorPane {
public void save(ConstantPool constants) {
try {
AVM2Code acode = ASM3Parser.parse(new ByteArrayInputStream(getText().getBytes()), constants, new DialogMissingSymbolHandler());
AVM2Code acode = ASM3Parser.parse(new ByteArrayInputStream(getText().getBytes()), constants, new DialogMissingSymbolHandler(),abc.bodies[bodyIndex]);
abc.bodies[bodyIndex].code = acode;
Main.abcMainFrame.decompiledTextArea.reloadClass();
Main.abcMainFrame.decompiledTextArea.gotoLastTrait();
@@ -68,14 +68,13 @@ public class ASMSourceEditorPane extends JEditorPane {
public void verify(ConstantPool constants, ABC abc) {
try {
AVM2Code acode = ASM3Parser.parse(new ByteArrayInputStream(getText().getBytes()), constants, new DialogMissingSymbolHandler());
acode.clearSecureSWF(abc.constants, abc.bodies[bodyIndex]);
setText(acode.toASMSource(constants));
AVM2Code acode = ASM3Parser.parse(new ByteArrayInputStream(getText().getBytes()), constants, new DialogMissingSymbolHandler(),abc.bodies[bodyIndex]);
//acode.clearSecureSWF(abc.constants, abc.bodies[bodyIndex]);
setText(acode.toASMSource(constants,abc.bodies[bodyIndex]));
//Main.mainFrame.decompiledTextArea.setBody(mb, abc);
} catch (IOException ex) {
} catch (ConvertException ex) {
} catch (ParseException ex) {
JOptionPane.showMessageDialog(this, (ex.text + " on line " + ex.line));
selectLine((int) ex.line);