This commit is contained in:
Connor Tumbleson 2013-06-24 11:46:26 -05:00
parent b0cee3c500
commit ca67c00f83
3 changed files with 105 additions and 114 deletions

View File

@ -20,7 +20,7 @@ import java.io.*;
import org.antlr.runtime.*; import org.antlr.runtime.*;
import org.antlr.runtime.tree.CommonTree; import org.antlr.runtime.tree.CommonTree;
import org.antlr.runtime.tree.CommonTreeNodeStream; import org.antlr.runtime.tree.CommonTreeNodeStream;
import org.jf.dexlib.DexFile; import org.jf.dexlib2.writer.builder.DexBuilder;
import org.jf.smali.*; import org.jf.smali.*;
/** /**
@ -28,58 +28,53 @@ import org.jf.smali.*;
*/ */
public class SmaliMod { public class SmaliMod {
public static boolean assembleSmaliFile(InputStream smaliStream, public static boolean assembleSmaliFile(File smaliFile,DexBuilder dexBuilder, boolean verboseErrors,
String name, DexFile dexFile, boolean verboseErrors, boolean printTokens) throws IOException,
boolean oldLexer, boolean printTokens) throws IOException, RecognitionException {
RecognitionException {
CommonTokenStream tokens;
boolean lexerErrors = false; CommonTokenStream tokens;
LexerErrorInterface lexer; LexerErrorInterface lexer;
InputStreamReader reader = new InputStreamReader(smaliStream, "UTF-8"); FileInputStream fis = new FileInputStream(smaliFile.getAbsolutePath());
InputStreamReader reader = new InputStreamReader(fis, "UTF-8");
lexer = new smaliFlexLexer(reader); lexer = new smaliFlexLexer(reader);
tokens = new CommonTokenStream((TokenSource) lexer); ((smaliFlexLexer)lexer).setSourceFile(smaliFile);
tokens = new CommonTokenStream((TokenSource) lexer);
if (printTokens) { if (printTokens) {
tokens.getTokens(); tokens.getTokens();
for (int i = 0; i < tokens.size(); i++) { for (int i=0; i<tokens.size(); i++) {
Token token = tokens.get(i); Token token = tokens.get(i);
if (token.getChannel() == BaseRecognizer.HIDDEN) { if (token.getChannel() == smaliParser.HIDDEN) {
continue; continue;
} }
System.out.println(smaliParser.tokenNames[token.getType()] System.out.println(smaliParser.tokenNames[token.getType()] + ": " + token.getText());
+ ": " + token.getText()); }
} }
}
smaliParser parser = new smaliParser(tokens); smaliParser parser = new smaliParser(tokens);
parser.setVerboseErrors(verboseErrors); parser.setVerboseErrors(verboseErrors);
smaliParser.smali_file_return result = parser.smali_file(); smaliParser.smali_file_return result = parser.smali_file();
if (parser.getNumberOfSyntaxErrors() > 0 if (parser.getNumberOfSyntaxErrors() > 0 || lexer.getNumberOfSyntaxErrors() > 0) {
|| lexer.getNumberOfSyntaxErrors() > 0) { return false;
return false; }
}
CommonTree t = (CommonTree) result.getTree(); CommonTree t = (CommonTree) result.getTree();
CommonTreeNodeStream treeStream = new CommonTreeNodeStream(t); CommonTreeNodeStream treeStream = new CommonTreeNodeStream(t);
treeStream.setTokenStream(tokens); treeStream.setTokenStream(tokens);
smaliTreeWalker dexGen = new smaliTreeWalker(treeStream); smaliTreeWalker dexGen = new smaliTreeWalker(treeStream);
dexGen.dexFile = dexFile; dexGen.setVerboseErrors(verboseErrors);
dexGen.smali_file(); dexGen.setDexBuilder(dexBuilder);
dexGen.smali_file();
if (dexGen.getNumberOfSyntaxErrors() > 0) { return dexGen.getNumberOfSyntaxErrors() == 0;
return false; }
}
return true;
}
} }

View File

@ -16,69 +16,58 @@
package brut.androlib.src; package brut.androlib.src;
import brut.androlib.AndrolibException;
import brut.androlib.mod.SmaliMod;
import java.io.*;
import org.antlr.runtime.RecognitionException;
import org.jf.dexlib.CodeItem;
import org.jf.dexlib.DexFile;
import org.jf.dexlib.Util.ByteArrayAnnotatedOutput;
/** /**
* @author Ryszard Wiśniewski <brut.alll@gmail.com> * @author Ryszard Wiśniewski <brut.alll@gmail.com>
*/ */
public class DexFileBuilder { public class DexFileBuilder {
public void addSmaliFile(File smaliFile) throws AndrolibException { // public void addSmaliFile(File smaliFile, DexBuilder dexBuilder) throws AndrolibException {
try { // try {
addSmaliFile(new FileInputStream(smaliFile), // addSmaliFile(new FileInputStream(smaliFile), smaliFile, smaliFile.getAbsolutePath(), dexBuilder);
smaliFile.getAbsolutePath()); // } catch (FileNotFoundException ex) {
} catch (FileNotFoundException ex) { // throw new AndrolibException(ex);
throw new AndrolibException(ex); // }
} // }
} //
// public void addSmaliFile(InputStream smaliStream,File smaliFile, String name, DexBuilder dexBuilder)
public void addSmaliFile(InputStream smaliStream, String name) // throws AndrolibException {
throws AndrolibException { // try {
try { // if (!SmaliMod.assembleSmaliFile(smaliStream, smaliFile, name, dexBuilder, false, false)) {
if (!SmaliMod.assembleSmaliFile(smaliStream, name, mDexFile, false, // throw new AndrolibException("Could not smali file: " + name);
false, false)) { // }
throw new AndrolibException("Could not smali file: " + name); // } catch (IOException ex) {
} // throw new AndrolibException(ex);
} catch (IOException ex) { // } catch (RecognitionException ex) {
throw new AndrolibException(ex); // throw new AndrolibException(ex);
} catch (RecognitionException ex) { // }
throw new AndrolibException(ex); // }
} //
} // public void writeTo(File dexFile) throws AndrolibException {
// try {
public void writeTo(File dexFile) throws AndrolibException { // OutputStream out = new FileOutputStream(dexFile);
try { // out.write(getAsByteArray());
OutputStream out = new FileOutputStream(dexFile); // out.close();
out.write(getAsByteArray()); // } catch (IOException ex) {
out.close(); // throw new AndrolibException("Could not write dex to file: "
} catch (IOException ex) { // + dexFile, ex);
throw new AndrolibException("Could not write dex to file: " // }
+ dexFile, ex); // }
} //
} // public byte[] getAsByteArray() {
// mDexFile.place();
public byte[] getAsByteArray() { // for (CodeItem codeItem : mDexFile.CodeItemsSection.getItems()) {
mDexFile.place(); // codeItem.fixInstructions(true, true);
for (CodeItem codeItem : mDexFile.CodeItemsSection.getItems()) { // }
codeItem.fixInstructions(true, true); //
} // mDexFile.place();
//
mDexFile.place(); // ByteArrayAnnotatedOutput out = new ByteArrayAnnotatedOutput();
// mDexFile.writeTo(out);
ByteArrayAnnotatedOutput out = new ByteArrayAnnotatedOutput(); // byte[] bytes = out.toByteArray();
mDexFile.writeTo(out); //
byte[] bytes = out.toByteArray(); // DexFile.calcSignature(bytes);
// DexFile.calcChecksum(bytes);
DexFile.calcSignature(bytes); //
DexFile.calcChecksum(bytes); // return bytes;
// }
return bytes;
}
private final DexFile mDexFile = new DexFile();
} }

View File

@ -17,6 +17,7 @@
package brut.androlib.src; package brut.androlib.src;
import brut.androlib.AndrolibException; import brut.androlib.AndrolibException;
import brut.androlib.mod.SmaliMod;
import brut.androlib.res.util.ExtFile; import brut.androlib.res.util.ExtFile;
import brut.directory.DirectoryException; import brut.directory.DirectoryException;
import java.io.*; import java.io.*;
@ -24,7 +25,10 @@ import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.ListIterator; import java.util.ListIterator;
import java.util.logging.Logger; import java.util.logging.Logger;
import org.antlr.runtime.RecognitionException;
import org.apache.commons.io.IOUtils; import org.apache.commons.io.IOUtils;
import org.jf.dexlib2.writer.builder.DexBuilder;
/** /**
* @author Ryszard Wiśniewski <brut.alll@gmail.com> * @author Ryszard Wiśniewski <brut.alll@gmail.com>
@ -45,25 +49,30 @@ public class SmaliBuilder {
private void build() throws AndrolibException { private void build() throws AndrolibException {
try { try {
mDexBuilder = new DexFileBuilder(); DexBuilder dexBuilder = DexBuilder.makeDexBuilder();
for (String fileName : mSmaliDir.getDirectory().getFiles(true)) {
buildFile(fileName); for (String fileName : mSmaliDir.getDirectory().getFiles(true)) {
buildFile(fileName, dexBuilder);
} }
mDexBuilder.writeTo(mDexFile); dexBuilder.writeTo(mDexFile.getAbsolutePath());
} catch (IOException ex) { } catch (IOException | DirectoryException ex) {
throw new AndrolibException(ex);
} catch (DirectoryException ex) {
throw new AndrolibException(ex); throw new AndrolibException(ex);
} }
} }
private void buildFile(String fileName) throws AndrolibException, private void buildFile(String fileName, DexBuilder dexBuilder) throws AndrolibException,
IOException { IOException {
File inFile = new File(mSmaliDir, fileName); File inFile = new File(mSmaliDir, fileName);
InputStream inStream = new FileInputStream(inFile); InputStream inStream = new FileInputStream(inFile);
if (fileName.endsWith(".smali")) { if (fileName.endsWith(".smali")) {
mDexBuilder.addSmaliFile(inFile); try {
if (!SmaliMod.assembleSmaliFile(inFile,dexBuilder, false, false)) {
throw new AndrolibException("Could not smali file: " + fileName);
}
} catch (IOException | RecognitionException ex) {
throw new AndrolibException(ex);
}
return; return;
} }
if (!fileName.endsWith(".java")) { if (!fileName.endsWith(".java")) {
@ -99,16 +108,14 @@ public class SmaliBuilder {
out.append(line).append('\n'); out.append(line).append('\n');
} }
} }
mDexBuilder.addSmaliFile(IOUtils.toInputStream(out.toString()), //mDexBuilder.addSmaliFile(IOUtils.toInputStream(out.toString()),
fileName); //fileName);
} }
private final ExtFile mSmaliDir; private final ExtFile mSmaliDir;
private final File mDexFile; private final File mDexFile;
private final HashMap<String, Boolean> mFlags; private final HashMap<String, Boolean> mFlags;
private DexFileBuilder mDexBuilder;
private final static Logger LOGGER = Logger.getLogger(SmaliBuilder.class private final static Logger LOGGER = Logger.getLogger(SmaliBuilder.class
.getName()); .getName());
} }