use of com.googlecode.d2j.visitors.DexCodeVisitor in project dex2jar by pxb1988.
the class BaksmaliDumper method baksmaliCode.
public void baksmaliCode(DexMethodNode methodNode, DexCodeNode codeNode, Out out) {
final List<DexLabel> allLabel = new ArrayList<>();
final Set<DexLabel> usedLabel = new HashSet<>();
codeNode.accept(new DexCodeVisitor() {
@Override
public void visitJumpStmt(Op op, int a, int b, DexLabel label) {
usedLabel.add(label);
}
@Override
public void visitPackedSwitchStmt(Op op, int aA, int first_case, DexLabel[] labels) {
usedLabel.addAll(Arrays.asList(labels));
}
@Override
public void visitTryCatch(DexLabel start, DexLabel end, DexLabel[] handler, String[] type) {
usedLabel.add(start);
usedLabel.add(end);
usedLabel.addAll(Arrays.asList(handler));
}
@Override
public void visitLabel(DexLabel label) {
allLabel.add(label);
}
@Override
public void visitSparseSwitchStmt(Op op, int ra, int[] cases, DexLabel[] labels) {
usedLabel.addAll(Arrays.asList(labels));
}
});
Map<DexLabel, List<DexDebugNode.DexDebugOpNode>> debugLabelMap = new HashMap<>();
if (codeNode.debugNode != null) {
DexDebugNode debugNode = codeNode.debugNode;
for (DexDebugNode.DexDebugOpNode opNode : debugNode.debugNodes) {
List<DexDebugNode.DexDebugOpNode> list = debugLabelMap.get(opNode.label);
if (list == null) {
list = new ArrayList<>(3);
debugLabelMap.put(opNode.label, list);
}
list.add(opNode);
}
}
int nextLabelNumber = 0;
for (DexLabel label : allLabel) {
if (usedLabel.contains(label)) {
label.displayName = "L" + nextLabelNumber++;
}
}
int inRegs = Utils.methodIns(methodNode.method, (methodNode.access & ACC_STATIC) != 0);
DexCodeVisitor dexCodeVisitor = new BaksmaliCodeDumper(out, useParameterRegisters, useLocals, nextLabelNumber, codeNode.totalRegister - inRegs, usedLabel, debugLabelMap);
accept(out, codeNode, dexCodeVisitor);
dexCodeVisitor.visitEnd();
}
use of com.googlecode.d2j.visitors.DexCodeVisitor in project dex2jar by pxb1988.
the class SmaliCodeVisitor method visitF31tStmt.
/* package */
void visitF31tStmt(final Op op, final int reg, final DexLabel label) {
add(new DexStmtNode(op) {
@Override
public void accept(DexCodeVisitor cv) {
int labelIndex = findLabelIndex(label);
if (labelIndex < 0 || labelIndex >= needCareStmts.size()) {
throw new RuntimeException("can't find label for " + op + " " + label);
}
switch(op) {
case PACKED_SWITCH:
PackedSwitchStmt packedSwitchStmt = (PackedSwitchStmt) needCareStmts.get(labelIndex + 1);
cv.visitPackedSwitchStmt(op, reg, packedSwitchStmt.firstCase, packedSwitchStmt.labels);
break;
case SPARSE_SWITCH:
SparseSwitchStmt sparseSwitchStmt = (SparseSwitchStmt) needCareStmts.get(labelIndex + 1);
cv.visitSparseSwitchStmt(op, reg, sparseSwitchStmt.cases, sparseSwitchStmt.labels);
break;
case FILL_ARRAY_DATA:
ArrayDataStmt arrayDataStmt = (ArrayDataStmt) needCareStmts.get(labelIndex + 1);
Object v;
byte[] vs = arrayDataStmt.objs;
switch(arrayDataStmt.length) {
case 1:
{
v = vs;
}
break;
case 2:
{
short[] vs1 = new short[vs.length / 2];
for (int i = 0; i < vs1.length; i++) {
vs1[i] = (short) ((vs[i * 2] & 0xFF) | ((vs[i * 2 + 1] & 0xFF) << 8));
}
v = vs1;
}
break;
case 4:
{
int[] vs1 = new int[vs.length / 4];
for (int i = 0; i < vs1.length; i++) {
int base = i * 4;
vs1[i] = (vs[base + 0] & 0xFF) | ((vs[base + 1] & 0xFF) << 8) | ((vs[base + 2] & 0xFF) << 16) | ((vs[base + 3] & 0xFF) << 24);
}
v = vs1;
}
break;
case 8:
{
long[] vs1 = new long[vs.length / 8];
for (int i = 0; i < vs1.length; i++) {
int base = i * 8;
int a = ((vs[base + 0] & 0xFF) << 0) | ((vs[base + 1] & 0xFF) << 8) | ((vs[base + 2] & 0xFF) << 16) | ((vs[base + 3] & 0xFF) << 24);
int b = ((vs[base + 4] & 0xFF) << 0) | ((vs[base + 5] & 0xFF) << 8) | ((vs[base + 6] & 0xFF) << 16) | ((vs[base + 7] & 0xFF) << 24);
vs1[i] = (((long) b) << 32) | a;
}
v = vs1;
}
break;
default:
throw new RuntimeException();
}
cv.visitFillArrayDataStmt(Op.FILL_ARRAY_DATA, reg, v);
break;
default:
throw new RuntimeException();
}
}
});
}
use of com.googlecode.d2j.visitors.DexCodeVisitor in project dex2jar by pxb1988.
the class DexWeaver method buildInvocationClz.
public String buildInvocationClz(DexFileVisitor dfv) {
String typeName = getCurrentInvocationName();
String typeNameDesc = "L" + typeName + ";";
DexClassVisitor dcv = dfv.visit(DexConstants.ACC_PUBLIC, typeNameDesc, "Ljava/lang/Object;", new String[] { invocationInterfaceDesc });
dcv.visitField(DexConstants.ACC_PRIVATE | DexConstants.ACC_FINAL, new Field(typeNameDesc, "thiz", "Ljava/lang/Object;"), null).visitEnd();
dcv.visitField(DexConstants.ACC_PRIVATE | DexConstants.ACC_FINAL, new Field(typeNameDesc, "args", "[Ljava/lang/Object;"), null).visitEnd();
dcv.visitField(DexConstants.ACC_PRIVATE | DexConstants.ACC_FINAL, new Field(typeNameDesc, "idx", "I"), null).visitEnd();
{
DexMethodVisitor mv = dcv.visitMethod(DexConstants.ACC_PUBLIC | DexConstants.ACC_CONSTRUCTOR, new Method(typeNameDesc, "<init>", new String[] { "Ljava/lang/Object;", "[Ljava/lang/Object;", "I" }, "V"));
DexCodeVisitor codeVisitor = mv.visitCode();
codeVisitor.visitRegister(4);
codeVisitor.visitFieldStmt(Op.IPUT_OBJECT, 1, 0, new Field(typeNameDesc, "thiz", "Ljava/lang/Object;"));
codeVisitor.visitFieldStmt(Op.IPUT_OBJECT, 2, 0, new Field(typeNameDesc, "args", "[Ljava/lang/Object;"));
codeVisitor.visitFieldStmt(Op.IPUT, 3, 0, new Field(typeNameDesc, "idx", "I"));
codeVisitor.visitStmt0R(Op.RETURN_VOID);
codeVisitor.visitEnd();
mv.visitEnd();
}
{
genSwitchMethod(dcv, typeNameDesc, "getMethodOwner", new CB() {
@Override
public String getKey(Method mtd) {
return toInternal(mtd.getOwner());
}
});
genSwitchMethod(dcv, typeNameDesc, "getMethodName", new CB() {
@Override
public String getKey(Method mtd) {
return mtd.getName();
}
});
genSwitchMethod(dcv, typeNameDesc, "getMethodDesc", new CB() {
@Override
public String getKey(Method mtd) {
return mtd.getDesc();
}
});
}
{
DexMethodVisitor mv = dcv.visitMethod(DexConstants.ACC_PUBLIC, new Method(typeNameDesc, "getArguments", new String[0], "[Ljava/lang/Object;"));
DexCodeVisitor code = mv.visitCode();
code.visitRegister(2);
code.visitFieldStmt(Op.IGET, 0, 1, new Field(typeNameDesc, "args", "[Ljava/lang/Object;"));
code.visitStmt1R(Op.RETURN_OBJECT, 0);
code.visitEnd();
mv.visitEnd();
}
{
DexMethodVisitor mv = dcv.visitMethod(DexConstants.ACC_PUBLIC, new Method(typeNameDesc, "getThis", new String[0], "Ljava/lang/Object;"));
DexCodeVisitor code = mv.visitCode();
code.visitRegister(2);
code.visitFieldStmt(Op.IGET, 0, 1, new Field(typeNameDesc, "thiz", "Ljava/lang/Object;"));
code.visitStmt1R(Op.RETURN_OBJECT, 0);
code.visitEnd();
mv.visitEnd();
}
{
DexMethodVisitor mv = dcv.visitMethod(DexConstants.ACC_PUBLIC, new Method(typeNameDesc, "proceed", new String[0], "Ljava/lang/Object;"));
DexCodeVisitor code = mv.visitCode();
code.visitRegister(4);
code.visitFieldStmt(Op.IGET, 0, 3, new Field(typeNameDesc, "thiz", "Ljava/lang/Object;"));
code.visitFieldStmt(Op.IGET, 1, 3, new Field(typeNameDesc, "args", "[Ljava/lang/Object;"));
code.visitFieldStmt(Op.IGET, 2, 3, new Field(typeNameDesc, "idx", "I"));
DexLabel[] labels = new DexLabel[callbacks.size()];
for (int i = 0; i < labels.length; i++) {
labels[i] = new DexLabel();
}
code.visitPackedSwitchStmt(Op.PACKED_SWITCH, 2, 0, labels);
code.visitTypeStmt(Op.NEW_INSTANCE, 0, 0, "Ljava/lang/RuntimeException;");
code.visitConstStmt(Op.CONST_STRING, 1, "invalid idx");
code.visitMethodStmt(Op.INVOKE_DIRECT, new int[] { 0, 1 }, new Method("Ljava/lang/RuntimeException;", "<init>", new String[] { "Ljava/lang/String;" }, "V"));
code.visitStmt1R(Op.THROW, 0);
for (int i = 0; i < labels.length; i++) {
code.visitLabel(labels[i]);
Callback callback = callbacks.get(i);
Method mCallback = (Method) callback.callback;
if (callback.isStatic) {
code.visitMethodStmt(Op.INVOKE_STATIC, new int[] { 1 }, mCallback);
} else if (callback.isSpecial) {
code.visitTypeStmt(Op.CHECK_CAST, 0, -1, mCallback.getOwner());
code.visitMethodStmt(Op.INVOKE_VIRTUAL, new int[] { 0, 1 }, mCallback);
} else {
code.visitMethodStmt(Op.INVOKE_STATIC, new int[] { 0, 1 }, mCallback);
}
code.visitStmt1R(Op.MOVE_RESULT_OBJECT, 0);
code.visitStmt1R(Op.RETURN_OBJECT, 0);
}
code.visitEnd();
mv.visitEnd();
}
dcv.visitEnd();
return typeName;
}
use of com.googlecode.d2j.visitors.DexCodeVisitor in project dex2jar by pxb1988.
the class AsmfierTest method test.
@Test
public void test() {
ASMifierFileV fv = new ASMifierFileV(new File("target/asmftest").toPath(), "a.b");
DexClassVisitor cv = fv.visit(ACC_PUBLIC, "La/f;", "Ljava/lang/Object;", null);
DexFieldVisitor f2v = cv.visitField(ACC_PUBLIC, new Field("La/f;", "abc", "I"), null);
f2v.visitEnd();
DexMethodVisitor mv = cv.visitMethod(ACC_PUBLIC | ACC_STATIC, new Method("La/f;", "zz", new String[0], "I"));
DexAnnotationAble pv = mv.visitParameterAnnotation(2);
DexAnnotationVisitor dav = pv.visitAnnotation("Leeeff;", Visibility.BUILD);
dav.visitEnd();
DexCodeVisitor dcv = mv.visitCode();
dcv.visitConstStmt(Op.FILL_ARRAY_DATA, 0, new int[] { 1, 2, 3 });
dcv.visitStmt0R(Op.RETURN_VOID);
dcv.visitEnd();
mv.visitEnd();
cv.visitEnd();
fv.visitEnd();
}
use of com.googlecode.d2j.visitors.DexCodeVisitor in project dex2jar by pxb1988.
the class DexWeaverCmd method doCommandLine.
@Override
protected void doCommandLine() throws Exception {
if (remainingArgs.length == 0) {
throw new HelpException("no odex");
}
final Map<String, Method> map = new HashMap<>();
for (String ln : Files.readAllLines(config, StandardCharsets.UTF_8)) {
if (ln.startsWith("#") || ln.length() == 0) {
continue;
}
String[] x = ln.split("=");
map.put(x[0], parseMethod(x[1]));
}
DexFileWriter out = new DexFileWriter();
DexFileVisitor fv = new DexFileVisitor(out) {
@Override
public DexClassVisitor visit(int access_flags, String className, String superClass, String[] interfaceNames) {
DexClassVisitor dcv = super.visit(access_flags, className, superClass, interfaceNames);
if (dcv != null) {
return new DexClassVisitor(dcv) {
@Override
public DexMethodVisitor visitMethod(int accessFlags, Method method) {
DexMethodVisitor dmv = super.visitMethod(accessFlags, method);
if (dmv != null) {
return new DexMethodVisitor(dmv) {
@Override
public DexCodeVisitor visitCode() {
DexCodeVisitor code = super.visitCode();
if (code != null) {
return new DexCodeVisitor(code) {
@Override
public void visitMethodStmt(Op op, int[] args, Method method) {
Method replaceTo = map.get(method.toString());
if (replaceTo != null) {
switch(op) {
case INVOKE_DIRECT:
case INVOKE_INTERFACE:
case INVOKE_STATIC:
case INVOKE_SUPER:
case INVOKE_VIRTUAL:
super.visitMethodStmt(Op.INVOKE_STATIC, args, replaceTo);
break;
case INVOKE_DIRECT_RANGE:
case INVOKE_INTERFACE_RANGE:
case INVOKE_STATIC_RANGE:
case INVOKE_SUPER_RANGE:
case INVOKE_VIRTUAL_RANGE:
super.visitMethodStmt(Op.INVOKE_STATIC_RANGE, args, replaceTo);
break;
default:
}
} else {
super.visitMethodStmt(op, args, method);
}
}
};
}
return code;
}
};
}
return dmv;
}
};
}
return dcv;
}
@Override
public void visitEnd() {
}
};
for (String f : remainingArgs) {
byte[] data = ZipUtil.readDex(new File(f).toPath());
DexFileReader r = new DexFileReader(data);
r.accept(fv);
}
if (stub != null) {
byte[] data = ZipUtil.readDex(stub);
DexFileReader r = new DexFileReader(data);
r.accept(new DexFileVisitor(out) {
@Override
public void visitEnd() {
}
});
}
out.visitEnd();
byte[] data = out.toByteArray();
Files.write(output, data);
}
Aggregations