Skip to content

Commit

Permalink
Dump and build dex file markers
Browse files Browse the repository at this point in the history
  • Loading branch information
REAndroid committed Apr 23, 2024
1 parent 39511f9 commit 8d2a0c4
Show file tree
Hide file tree
Showing 12 changed files with 229 additions and 6 deletions.
9 changes: 9 additions & 0 deletions baksmali/src/main/java/org/jf/baksmali/Baksmali.java
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@

import org.jf.baksmali.Adaptors.ClassDefinition;
import org.jf.baksmali.formatter.BaksmaliWriter;
import org.jf.dexlib2.extra.DexMarker;
import org.jf.dexlib2.iface.ClassDef;
import org.jf.dexlib2.iface.DexFile;
import org.jf.util.ClassFileNameHandler;
Expand Down Expand Up @@ -58,6 +59,14 @@ public static boolean disassembleDexFile(DexFile dexFile, File outputDir, int jo
//may still change of course
List<? extends ClassDef> classDefs = ListUtil.sortedCopy(dexFile.getClasses());

if(options.dumpMarkers) {
File markerFile = new File(outputDir, DexMarker.FILE_NAME);
try {
DexMarker.writeMarkers(dexFile.getMarkers(), markerFile);
} catch (IOException ignored) {
}
}

final ClassFileNameHandler fileNameHandler = new ClassFileNameHandler(outputDir, ".smali");

ExecutorService executor = Executors.newFixedThreadPool(jobs);
Expand Down
2 changes: 2 additions & 0 deletions baksmali/src/main/java/org/jf/baksmali/BaksmaliOptions.java
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,8 @@ public class BaksmaliOptions {
public ClassPath classPath = null;
public SyntheticAccessorResolver syntheticAccessorResolver = null;

public boolean dumpMarkers;

public BaksmaliOptions(){
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,10 @@ public class DisassembleCommand extends DexInputCommand {
@ExtendedParameter(argumentNames = "classes")
private List<String> classes = null;

@Parameter(names = {"--dump-markers", "--markers"},
description = "Dump markers to file")
private boolean dumpMarkers = false;

public DisassembleCommand(@Nonnull List<JCommander> commandAncestors) {
super(commandAncestors);
}
Expand Down Expand Up @@ -293,6 +297,8 @@ protected BaksmaliOptions getOptions() {
options.allowOdex = true;
}

options.dumpMarkers = dumpMarkers;

return options;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
import org.jf.dexlib2.dexbacked.reference.*;
import org.jf.dexlib2.dexbacked.util.FixedSizeList;
import org.jf.dexlib2.dexbacked.util.FixedSizeSet;
import org.jf.dexlib2.extra.DexMarker;
import org.jf.dexlib2.iface.DexFile;
import org.jf.dexlib2.iface.reference.Reference;
import org.jf.dexlib2.util.DexUtil;
Expand Down Expand Up @@ -227,7 +228,12 @@ public boolean supportsOptimizedOpcodes() {
return false;
}

@Override
public List<DexMarker> getMarkers(){
return DexMarker.listMarkers(getStringSection().iterator());
}
@Nonnull
@Override
public Set<? extends DexBackedClassDef> getClasses() {
return new FixedSizeSet<DexBackedClassDef>() {
@Nonnull
Expand Down
121 changes: 121 additions & 0 deletions dexlib2/src/main/java/org/jf/dexlib2/extra/DexMarker.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
package org.jf.dexlib2.extra;

import java.io.*;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

public class DexMarker {

private final String marker;

private DexMarker(String marker) {
this.marker = marker;
}

public String getMarker() {
return marker;
}

@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
DexMarker dexMarker = (DexMarker) o;
return marker.equals(dexMarker.marker);
}

@Override
public int hashCode() {
return marker.hashCode();
}

@Override
public String toString() {
return marker;
}

public static List<DexMarker> listMarkers(Iterator<String> iterator) {
List<DexMarker> markerList = new ArrayList<>();
while (iterator.hasNext()){
DexMarker marker = of(iterator.next());
if(marker != null){
markerList.add(marker);
}
}
return markerList;
}
public static void writeMarkers(List<DexMarker> markerList, File file) throws IOException {
StringBuilder builder = new StringBuilder();
boolean append = false;
for(DexMarker marker : markerList){
if(append){
builder.append('\n');
}
builder.append(marker.getMarker());
append = true;
}
byte[] bytes = builder.toString().getBytes(StandardCharsets.UTF_8);
File dir = file.getParentFile();
if(dir != null && !dir.exists()){
dir.mkdirs();
}
FileOutputStream outputStream = new FileOutputStream(file);
outputStream.write(bytes, 0, bytes.length);
outputStream.close();
}
public static List<DexMarker> readMarkers(File file) throws IOException {
return readMarkers(new FileInputStream(file));
}
public static List<DexMarker> readMarkers(InputStream inputStream) throws IOException {
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
byte[] buffer = new byte[1024];
int length;
while ((length = inputStream.read(buffer, 0, buffer.length)) != -1){
outputStream.write(buffer, 0, length);
}
inputStream.close();
outputStream.close();
buffer = outputStream.toByteArray();
String text = new String(buffer, 0, buffer.length, StandardCharsets.UTF_8);
return parseMarkers(text);
}
public static List<DexMarker> parseMarkers(String lineSeparatedMarkers) {
List<DexMarker> markerList = new ArrayList<>();
String[] lines = lineSeparatedMarkers.split("\n");
for(String line : lines){
DexMarker marker = of(line.trim());
if(marker != null){
markerList.add(marker);
}
}
return markerList;
}
public static DexMarker of(String text){
if(isMarker(text)){
return new DexMarker(text);
}
return null;
}
public static boolean isMarker(String text){
if(text == null){
return false;
}
int i = text.length() - 1;
if(i < 5){
return false;
}
if(text.charAt(0) != '~' || text.charAt(i) != '}'){
return false;
}
return text.startsWith(PREFIX_D8) || text.startsWith(PREFIX_R8);
}
public static final String PREFIX_D8 = "~~D8{";
public static final String PREFIX_R8 = "~~R8{";
public static final String FILE_NAME = "markers.txt";
}
10 changes: 8 additions & 2 deletions dexlib2/src/main/java/org/jf/dexlib2/iface/DexFile.java
Original file line number Diff line number Diff line change
Expand Up @@ -32,27 +32,33 @@
package org.jf.dexlib2.iface;

import org.jf.dexlib2.Opcodes;
import org.jf.dexlib2.extra.DexMarker;

import javax.annotation.Nonnull;
import java.util.List;
import java.util.Set;

/**
* This class is a high level representation of a dex file - essentially a set of class definitions.
*/
public interface DexFile {

List<DexMarker> getMarkers();
/**
* Get a set of the classes defined in this dex file.
*
* The classes in the returned set will all have unique types.
*
* @return A set of the classes defined in this dex file
*/
@Nonnull Set<? extends ClassDef> getClasses();
@Nonnull
Set<? extends ClassDef> getClasses();

/**
* Get the Opcodes associated with this dex file
*
* @return The Opcodes instance representing the possible opcodes that can be encountered in this dex file
*/
@Nonnull Opcodes getOpcodes();
@Nonnull
Opcodes getOpcodes();
}
Original file line number Diff line number Diff line change
Expand Up @@ -32,13 +32,16 @@
package org.jf.dexlib2.immutable;

import org.jf.dexlib2.Opcodes;
import org.jf.dexlib2.extra.DexMarker;
import org.jf.dexlib2.iface.ClassDef;
import org.jf.dexlib2.iface.DexFile;
import org.jf.util.ImmutableUtils;

import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Set;

public class ImmutableDexFile implements DexFile {
Expand All @@ -47,6 +50,8 @@ public class ImmutableDexFile implements DexFile {
@Nonnull
private final Opcodes opcodes;

private List<DexMarker> markerList;

public ImmutableDexFile(@Nonnull Opcodes opcodes, @Nullable Collection<? extends ClassDef> classes) {
this.classes = ImmutableClassDef.immutableSetOf(classes);
this.opcodes = opcodes;
Expand All @@ -61,9 +66,22 @@ public static ImmutableDexFile of(DexFile dexFile) {
if (dexFile instanceof ImmutableDexFile) {
return (ImmutableDexFile)dexFile;
}
return new ImmutableDexFile(dexFile.getOpcodes(), dexFile.getClasses());
ImmutableDexFile immutableDexFile = new ImmutableDexFile(dexFile.getOpcodes(), dexFile.getClasses());
immutableDexFile.setMarkerList(dexFile.getMarkers());
return immutableDexFile;
}

public void setMarkerList(List<DexMarker> markerList) {
this.markerList = markerList;
}

@Override
public List<DexMarker> getMarkers() {
if(this.markerList == null){
this.markerList = new ArrayList<>();
}
return markerList;
}
@Nonnull
@Override
public Set<? extends ImmutableClassDef> getClasses() { return classes; }
Expand Down
20 changes: 17 additions & 3 deletions dexlib2/src/main/java/org/jf/dexlib2/rewriter/DexFileRewriter.java
Original file line number Diff line number Diff line change
Expand Up @@ -32,10 +32,13 @@
package org.jf.dexlib2.rewriter;

import org.jf.dexlib2.Opcodes;
import org.jf.dexlib2.extra.DexMarker;
import org.jf.dexlib2.iface.ClassDef;
import org.jf.dexlib2.iface.DexFile;

import javax.annotation.Nonnull;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;

public class DexFileRewriter implements Rewriter<DexFile> {
Expand All @@ -53,17 +56,28 @@ public DexFile rewrite(@Nonnull DexFile value) {
}

protected class RewrittenDexFile implements DexFile {
@Nonnull protected final DexFile dexFile;
@Nonnull
protected final DexFile dexFile;
private final List<DexMarker> markerList;

public RewrittenDexFile(@Nonnull DexFile dexFile) {
this.dexFile = dexFile;
this.markerList = new ArrayList<>(dexFile.getMarkers());
}

@Override @Nonnull public Set<? extends ClassDef> getClasses() {
@Override
public List<DexMarker> getMarkers() {
return markerList;
}
@Nonnull
@Override
public Set<? extends ClassDef> getClasses() {
return RewriterUtils.rewriteSet(rewriters.getClassDefRewriter(), dexFile.getClasses());
}

@Nonnull @Override public Opcodes getOpcodes() {
@Nonnull
@Override
public Opcodes getOpcodes() {
return dexFile.getOpcodes();
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
import org.jf.dexlib2.HiddenApiRestriction;
import org.jf.dexlib2.Opcodes;
import org.jf.dexlib2.ValueType;
import org.jf.dexlib2.extra.DexMarker;
import org.jf.dexlib2.iface.Annotation;
import org.jf.dexlib2.iface.AnnotationElement;
import org.jf.dexlib2.iface.MethodImplementation;
Expand Down Expand Up @@ -71,6 +72,17 @@ public DexBuilder(@Nonnull Opcodes opcodes) {
super(opcodes);
}

public void addMarkers(Iterator<DexMarker> markers){
while (markers.hasNext()){
addMarker(markers.next());
}
}
public void addMarker(DexMarker marker){
if(marker != null){
stringSection.internString(marker.getMarker());
}
}

@Nonnull
@Override
protected SectionProvider getSectionProvider() {
Expand Down
Loading

0 comments on commit 8d2a0c4

Please sign in to comment.