use of org.jf.dexlib2.writer.builder.DexBuilder in project smali by JesusFreke.
the class Smali method assemble.
/**
* Assemble the specified files, using the given options
*
* @param options a SmaliOptions object with the options to run smali with
* @param input The files/directories to process
* @return true if assembly completed with no errors, or false if errors were encountered
*/
public static boolean assemble(final SmaliOptions options, List<String> input) throws IOException {
LinkedHashSet<File> filesToProcessSet = new LinkedHashSet<File>();
for (String fileToProcess : input) {
File argFile = new File(fileToProcess);
if (!argFile.exists()) {
throw new IllegalArgumentException("Cannot find file or directory \"" + fileToProcess + "\"");
}
if (argFile.isDirectory()) {
getSmaliFilesInDir(argFile, filesToProcessSet);
} else if (argFile.isFile()) {
filesToProcessSet.add(argFile);
}
}
boolean errors = false;
final DexBuilder dexBuilder = new DexBuilder(Opcodes.forApi(options.apiLevel));
ExecutorService executor = Executors.newFixedThreadPool(options.jobs);
List<Future<Boolean>> tasks = Lists.newArrayList();
for (final File file : filesToProcessSet) {
tasks.add(executor.submit(new Callable<Boolean>() {
@Override
public Boolean call() throws Exception {
return assembleSmaliFile(file, dexBuilder, options);
}
}));
}
for (Future<Boolean> task : tasks) {
while (true) {
try {
try {
if (!task.get()) {
errors = true;
}
} catch (ExecutionException ex) {
throw new RuntimeException(ex);
}
} catch (InterruptedException ex) {
continue;
}
break;
}
}
executor.shutdown();
if (errors) {
return false;
}
dexBuilder.writeTo(new FileDataStore(new File(options.outputDexFile)));
return true;
}
use of org.jf.dexlib2.writer.builder.DexBuilder in project smali by JesusFreke.
the class JumboStringConversionTest method testJumboStringConversion_NonMethodBuilder.
@Test
public void testJumboStringConversion_NonMethodBuilder() throws IOException {
DexBuilder dexBuilder = new DexBuilder(Opcodes.getDefault());
final List<Instruction> instructions = Lists.newArrayList();
for (int i = 0; i < 66000; i++) {
final StringReference ref = dexBuilder.internStringReference(String.format("%08d", i));
instructions.add(new Instruction21c() {
@Override
public int getRegisterA() {
return 0;
}
@Nonnull
@Override
public Reference getReference() {
return ref;
}
@Override
public int getReferenceType() {
return ReferenceType.STRING;
}
@Override
public Opcode getOpcode() {
return Opcode.CONST_STRING;
}
@Override
public int getCodeUnits() {
return getOpcode().format.size / 2;
}
});
}
instructions.add(new ImmutableInstruction10x(Opcode.RETURN_VOID));
MethodImplementation methodImpl = new MethodImplementation() {
@Override
public int getRegisterCount() {
return 1;
}
@Nonnull
@Override
public Iterable<? extends Instruction> getInstructions() {
return instructions;
}
@Nonnull
@Override
public List<? extends TryBlock<? extends ExceptionHandler>> getTryBlocks() {
return ImmutableList.of();
}
@Nonnull
@Override
public Iterable<? extends DebugItem> getDebugItems() {
return ImmutableList.of();
}
};
dexBuilder.internClassDef("Ltest;", 0, "Ljava/lang/Object;", null, null, ImmutableSet.<Annotation>of(), null, ImmutableList.of(dexBuilder.internMethod("Ltest;", "test", null, "V", 0, ImmutableSet.<Annotation>of(), methodImpl)));
MemoryDataStore dexStore = new MemoryDataStore();
dexBuilder.writeTo(dexStore);
DexBackedDexFile dexFile = new DexBackedDexFile(Opcodes.getDefault(), dexStore.getData());
ClassDef classDef = Iterables.getFirst(dexFile.getClasses(), null);
Assert.assertNotNull(classDef);
Method method = Iterables.getFirst(classDef.getMethods(), null);
Assert.assertNotNull(method);
MethodImplementation impl = method.getImplementation();
Assert.assertNotNull(impl);
List<? extends Instruction> actualInstructions = Lists.newArrayList(impl.getInstructions());
Assert.assertEquals(66001, actualInstructions.size());
for (int i = 0; i < 65536; i++) {
Assert.assertEquals(Opcode.CONST_STRING, actualInstructions.get(i).getOpcode());
Assert.assertEquals(String.format("%08d", i), ((StringReference) ((ReferenceInstruction) actualInstructions.get(i)).getReference()).getString());
}
for (int i = 65536; i < 66000; i++) {
Assert.assertEquals(Opcode.CONST_STRING_JUMBO, actualInstructions.get(i).getOpcode());
Assert.assertEquals(String.format("%08d", i), ((StringReference) ((ReferenceInstruction) actualInstructions.get(i)).getReference()).getString());
}
Assert.assertEquals(Opcode.RETURN_VOID, actualInstructions.get(66000).getOpcode());
}
use of org.jf.dexlib2.writer.builder.DexBuilder in project smali by JesusFreke.
the class JumboStringConversionTest method testJumboStringConversion.
@Test
public void testJumboStringConversion() throws IOException {
DexBuilder dexBuilder = new DexBuilder(Opcodes.getDefault());
MethodImplementationBuilder methodBuilder = new MethodImplementationBuilder(1);
for (int i = 0; i < 66000; i++) {
methodBuilder.addInstruction(new BuilderInstruction21c(Opcode.CONST_STRING, 0, dexBuilder.internStringReference(String.format("%08d", i))));
}
methodBuilder.addInstruction(new BuilderInstruction10x(Opcode.RETURN_VOID));
dexBuilder.internClassDef("Ltest;", 0, "Ljava/lang/Object;", null, null, ImmutableSet.<Annotation>of(), null, ImmutableList.of(dexBuilder.internMethod("Ltest;", "test", null, "V", 0, ImmutableSet.<Annotation>of(), methodBuilder.getMethodImplementation())));
MemoryDataStore dexStore = new MemoryDataStore();
dexBuilder.writeTo(dexStore);
DexBackedDexFile dexFile = new DexBackedDexFile(Opcodes.getDefault(), dexStore.getData());
ClassDef classDef = Iterables.getFirst(dexFile.getClasses(), null);
Assert.assertNotNull(classDef);
Method method = Iterables.getFirst(classDef.getMethods(), null);
Assert.assertNotNull(method);
MethodImplementation impl = method.getImplementation();
Assert.assertNotNull(impl);
List<? extends Instruction> instructions = Lists.newArrayList(impl.getInstructions());
Assert.assertEquals(66001, instructions.size());
for (int i = 0; i < 65536; i++) {
Assert.assertEquals(Opcode.CONST_STRING, instructions.get(i).getOpcode());
Assert.assertEquals(String.format("%08d", i), ((StringReference) ((ReferenceInstruction) instructions.get(i)).getReference()).getString());
}
for (int i = 65536; i < 66000; i++) {
Assert.assertEquals(Opcode.CONST_STRING_JUMBO, instructions.get(i).getOpcode());
Assert.assertEquals(String.format("%08d", i), ((StringReference) ((ReferenceInstruction) instructions.get(i)).getReference()).getString());
}
Assert.assertEquals(Opcode.RETURN_VOID, instructions.get(66000).getOpcode());
}
use of org.jf.dexlib2.writer.builder.DexBuilder in project Apktool by iBotPeaches.
the class SmaliBuilder method build.
private void build() throws AndrolibException {
try {
DexBuilder dexBuilder;
if (mApiLevel > 0) {
dexBuilder = DexBuilder.makeDexBuilder(Opcodes.forApi(mApiLevel));
} else {
dexBuilder = DexBuilder.makeDexBuilder();
}
for (String fileName : mSmaliDir.getDirectory().getFiles(true)) {
buildFile(fileName, dexBuilder);
}
dexBuilder.writeTo(new FileDataStore(new File(mDexFile.getAbsolutePath())));
} catch (IOException | DirectoryException ex) {
throw new AndrolibException(ex);
}
}
use of org.jf.dexlib2.writer.builder.DexBuilder in project atlas by alibaba.
the class SmaliUtils method assembleSmaliFile.
/**
* 将smali文件夹转换为dex文件
* @param smaliFolder
* @param outDexFile
* @return
*/
public static boolean assembleSmaliFile(File smaliFolder, File outDexFile) throws IOException, RecognitionException {
Collection<File> smaliFiles = FileUtils.listFiles(smaliFolder, new String[] { "smali" }, true);
if (null != smaliFiles && smaliFiles.size() > 0) {
DexBuilder dexBuilder = DexBuilder.makeDexBuilder();
for (File smaliFile : smaliFiles) {
SmaliMod.assembleSmaliFile(smaliFile, dexBuilder, true, true);
}
dexBuilder.writeTo(new FileDataStore(outDexFile));
return true;
} else {
return false;
}
}
Aggregations