Skip to content

Commit

Permalink
Update to current pxb1988 version
Browse files Browse the repository at this point in the history
  • Loading branch information
ThexXTURBOXx committed Aug 31, 2023
2 parents 3bdb743 + d66af7d commit 994ced1
Show file tree
Hide file tree
Showing 34 changed files with 774 additions and 227 deletions.
6 changes: 4 additions & 2 deletions .github/workflows/gradle.yml
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
# This workflow will build a Java project with Gradle
# This workflow will build a Java project with Gradle and cache/restore any dependencies to improve the workflow execution time
# For more information see: https://help.github.com/actions/language-and-framework-guides/building-and-testing-java-with-gradle

name: Java CI with Gradle

on:
push:
branches: [ main ]
pull_request:
branches: [ main ]
workflow_dispatch:

jobs:
Expand Down Expand Up @@ -34,4 +36,4 @@ jobs:
if: success()
with:
name: dex-tools-2.1-SNAPSHOT
path: dex-tools/build/distributions/dex-tools-2.1-SNAPSHOT.zip
path: dex-tools/build/distributions/dex-tools-2.1-SNAPSHOT.zip
Original file line number Diff line number Diff line change
Expand Up @@ -175,8 +175,7 @@ sAnnotationValue
:sSubannotation
|sBaseValue
|sArrayValue
| ( '.iget' | '.iput' | '.sget' | '.sput' ) FIELD_FULL
| ( '.invoke-instance' | '.invoke-static' ) METHOD_FULL
| method_handler
;// field,method,array,subannotation
sBaseValue
:STRING
Expand All @@ -199,6 +198,11 @@ method_handler
| type=('invoke-static'|'invoke-instance'|'invoke-direct'|'invoke-interface'|'invoke-constructor') '@' mtd=METHOD_FULL
;

// FIXME samli syntax only write out method_handler's method field
call_site
: name=sAnnotationKeyName '(' method_name=STRING ',' method_type=METHOD_PROTO (',' sBaseValue)* ')' '@' bsm=METHOD_FULL
;

sInstruction
:fline
|flocal
Expand Down Expand Up @@ -415,9 +419,9 @@ fm45cc : op='invoke-polymorphic' '{' (REGISTER (',' REGISTER)* )? '}' ',' metho
;
fm4rcc : op='invoke-polymorphic/range' '{' (rstart=REGISTER '..' rend=REGISTER)? '}' ',' method=METHOD_FULL ',' proto=METHOD_PROTO
;
fmcustomc : op='invoke-custom' '{' (REGISTER (',' REGISTER)* )? '}' ',' sArrayValue
fmcustomc : op='invoke-custom' '{' (REGISTER (',' REGISTER)* )? '}' ',' call_site
;
fmcustomrc : op='invoke-custom/range' '{' (rstart=REGISTER '..' rend=REGISTER)? '}' ',' sArrayValue
fmcustomrc : op='invoke-custom/range' '{' (rstart=REGISTER '..' rend=REGISTER)? '}' ',' call_site
;
ftrc : op='filled-new-array/range' '{' (rstart=REGISTER '..' rend=REGISTER)? '}' ',' type=(OBJECT_TYPE|ARRAY_TYPE);
f31t: op=('fill-array-data'|'packed-switch'|'sparse-switch') r1=REGISTER ',' label=LABEL;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.googlecode.d2j.smali;

import com.googlecode.d2j.CallSite;
import com.googlecode.d2j.DexConstants;
import com.googlecode.d2j.DexLabel;
import com.googlecode.d2j.DexType;
Expand Down Expand Up @@ -468,6 +469,68 @@ public Object visitFm5c(SmaliParser.Fm5cContext ctx) {
return null;
}

@Override
public Object visitFm4rcc(SmaliParser.Fm4rccContext ctx) {
if (ctx.rstart != null) {
int start = m.pareReg(ctx.rstart.getText());
int end = m.pareReg(ctx.rend.getText());
int size = end - start + 1;
int[] rs = new int[size];
for (int i = 0; i < size; i++) {
rs[i] = start + i;
}
scv.visitMethodStmt(getOp(ctx.op), rs, parseMethodAndUnescape(ctx.method.getText()),
parseProtoAndUnescape(ctx.proto.getText()));
} else {
scv.visitMethodStmt(getOp(ctx.op), new int[0], parseMethodAndUnescape(ctx.method.getText()),
parseProtoAndUnescape(ctx.proto.getText()));
}
return null;
}

@Override
public Object visitFm45cc(SmaliParser.Fm45ccContext ctx) {
Op op = getOp(ctx.op);
List<TerminalNode> ts = ctx.REGISTER();
int[] rs = new int[ts.size()];
for (int i = 0; i < ts.size(); i++) {
rs[i] = m.pareReg(ts.get(i).getSymbol().getText());
}
scv.visitMethodStmt(op, rs, parseMethodAndUnescape(ctx.method.getText()),
parseProtoAndUnescape(ctx.proto.getText()));
return null;
}

@Override
public Object visitFmcustomc(SmaliParser.FmcustomcContext ctx) {
Op op = getOp(ctx.op);

List<TerminalNode> ts = ctx.REGISTER();
int[] rs = new int[ts.size()];
for (int i = 0; i < ts.size(); i++) {
rs[i] = m.pareReg(ts.get(i).getSymbol().getText());
}
scv.visitMethodStmt(op, rs, parseCallSite(ctx.call_site()));
return null;
}

@Override
public Object visitFmcustomrc(SmaliParser.FmcustomrcContext ctx) {
if (ctx.rstart != null) {
int start = m.pareReg(ctx.rstart.getText());
int end = m.pareReg(ctx.rend.getText());
int size = end - start + 1;
int[] rs = new int[size];
for (int i = 0; i < size; i++) {
rs[i] = start + i;
}
scv.visitMethodStmt(getOp(ctx.op), rs, parseCallSite(ctx.call_site()));
} else {
scv.visitMethodStmt(getOp(ctx.op), new int[0], parseCallSite(ctx.call_site()));
}
return null;
}

@Override
public Object visitFmrc(SmaliParser.FmrcContext ctx) {
if (ctx.rstart != null) {
Expand Down Expand Up @@ -593,6 +656,25 @@ public Object visitFepiogue(SmaliParser.FepiogueContext ctx) {
scv.visitEnd();
}

private static CallSite parseCallSite(SmaliParser.Call_siteContext callSiteContext) {

List<SmaliParser.SBaseValueContext> sBaseValueContexts = callSiteContext.sBaseValue();
Object[] args = new Object[sBaseValueContexts.size()];
int i = 0;
for (SmaliParser.SBaseValueContext baseValueContext : sBaseValueContexts) {
args[i] = parseBaseValue(baseValueContext);
i++;
}

return new CallSite(
unEscapeId(callSiteContext.name.getText()),
new MethodHandle(MethodHandle.INVOKE_STATIC, parseMethodAndUnescape(callSiteContext.bsm.getText())),
unescapeStr(callSiteContext.method_name.getText()),
parseProtoAndUnescape(callSiteContext.method_type.getText()),
args
);
}

private static MethodHandle parseMethodHandler(SmaliParser.Method_handlerContext methodHandlerContext) {
MethodHandle value;
switch (methodHandlerContext.type.getText()) {
Expand Down Expand Up @@ -833,6 +915,10 @@ private static void acceptAnnotation(DexAnnotationVisitor dexAnnotationVisitor,
Object value = parseBaseValue(baseValueContext);
dexAnnotationVisitor.visit(name, value);
break;
case SmaliParser.RULE_method_handler:
MethodHandle methodHandle = parseMethodHandler((SmaliParser.Method_handlerContext) t);
dexAnnotationVisitor.visit(name, methodHandle);
break;
default:
break;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
package com.googlecode.d2j.smali;

import com.googlecode.d2j.CallSite;
import com.googlecode.d2j.DexLabel;
import com.googlecode.d2j.Field;
import com.googlecode.d2j.Method;
import com.googlecode.d2j.MethodHandle;
import com.googlecode.d2j.Proto;
import com.googlecode.d2j.node.DexDebugNode;
import com.googlecode.d2j.reader.InstructionFormat;
Expand Down Expand Up @@ -387,15 +387,26 @@ public void visitMethodStmt(Op op, int[] args, Method method, Proto proto) {
}

@Override
public void visitMethodStmt(Op op, int[] args, String name, Proto proto, MethodHandle bsm, Object... bsmArgs) {
public void visitMethodStmt(Op op, int[] args, CallSite callSite) {
StringBuilder sb = new StringBuilder();
sb.append("{ ").append(BaksmaliDumper.escapeValue(bsm)).append(", ")
.append(BaksmaliDumper.escapeValue(name)).append(", ").append(BaksmaliDumper.escapeMethodDesc(proto));
for (Object o : bsmArgs) {
sb.append(", ").append(BaksmaliDumper.escapeValue(o));
Object[] extraArguments = callSite.getExtraArguments();

// invoke-custom/range {v0 .. v5}, call_site_1("runDynamic", (IIIIII)V, 0x378)@L038;->bsm
// (Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;I)
// Ljava/lang/invoke/CallSite;

sb.append(BaksmaliDumper.escapeId(callSite.getName()))
.append('(')
.append(BaksmaliDumper.escapeValue(callSite.getMethodName()))
.append(", ")
.append(BaksmaliDumper.escapeMethodDesc(callSite.getMethodProto()));
if (extraArguments != null && extraArguments.length > 0) {
for (Object o : extraArguments) {
sb.append(", ").append(BaksmaliDumper.escapeValue(o));
}
}
sb.append("}");

// FIXME samli syntax only write out method_handler's method field
sb.append(")@").append(BaksmaliDumper.escapeMethod(callSite.getBootstrapMethodHandler().getMethod()));

if (args.length > 0) {
if (op.format == InstructionFormat.kFmt3rc) { // invoke-x/range
Expand Down
9 changes: 1 addition & 8 deletions d2j-smali/src/test/java/a/SmaliTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -72,14 +72,7 @@ public void test2() throws IOException {

private void doTest(File dexFile) throws IOException {
int dexVersion = new DexFileReader(dexFile).getDexVersion();
Opcodes opcodes;
if (dexVersion >= DexConstants.DEX_039) {
opcodes = Opcodes.forApi(28);
} else if (dexVersion >= DexConstants.DEX_037) {
opcodes = Opcodes.forApi(26);
} else {
opcodes = Opcodes.forApi(0);
}
Opcodes opcodes = Opcodes.forApi(DexConstants.toMiniAndroidApiLevel(dexVersion));
DexBackedDexFile dex;
try {
dex = DexFileFactory.loadDexFile(dexFile, opcodes);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.googlecode.dex2jar.ir.expr;

import com.googlecode.d2j.CallSite;
import com.googlecode.d2j.DexType;
import com.googlecode.d2j.Method;
import com.googlecode.d2j.MethodHandle;
Expand Down Expand Up @@ -190,9 +191,8 @@ public static InvokeExpr nInvokeVirtual(Value[] regs, String owner, String name,
return new InvokeExpr(VT.INVOKE_VIRTUAL, regs, owner, name, argmentTypes, returnType);
}

public static InvokeCustomExpr nInvokeCustom(Value[] regs, String name, Proto proto, MethodHandle handle,
Object[] bsmArgs) {
return new InvokeCustomExpr(VT.INVOKE_CUSTOM, regs, name, proto, handle, bsmArgs);
public static InvokeCustomExpr nInvokeCustom(Value[] regs, CallSite callSite) {
return new InvokeCustomExpr(VT.INVOKE_CUSTOM, regs, callSite);
}

public static InvokePolymorphicExpr nInvokePolymorphic(Value[] regs, Proto proto, Method method) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,50 +1,36 @@
package com.googlecode.dex2jar.ir.expr;

import com.googlecode.d2j.MethodHandle;
import com.googlecode.d2j.CallSite;
import com.googlecode.d2j.Proto;
import com.googlecode.dex2jar.ir.LabelAndLocalMapper;

public class InvokeCustomExpr extends InvokeExpr {

public String name;

public Proto proto;

public MethodHandle handle;

public Object[] bsmArgs;
public CallSite callSite;

@Override
protected void releaseMemory() {
name = null;
proto = null;
handle = null;
bsmArgs = null;
callSite = null;
super.releaseMemory();
}

@Override
public Proto getProto() {
return proto;
return callSite.getMethodProto();
}

public InvokeCustomExpr(VT type, Value[] args, String methodName, Proto proto, MethodHandle handle,
Object[] bsmArgs) {
super(type, args, handle == null ? null : handle.getMethod());
this.proto = proto;
this.name = methodName;
this.handle = handle;
this.bsmArgs = bsmArgs;
public InvokeCustomExpr(VT type, Value[] args, CallSite callSite) {
super(type, args, callSite.getBootstrapMethodHandler().getMethod());
this.callSite = callSite;
}

@Override
public InvokeCustomExpr clone() {
return new InvokeCustomExpr(vt, cloneOps(), name, proto, handle, bsmArgs);
return new InvokeCustomExpr(vt, cloneOps(), callSite);
}

@Override
public InvokeCustomExpr clone(LabelAndLocalMapper mapper) {
return new InvokeCustomExpr(vt, cloneOps(mapper), name, proto, handle, bsmArgs);
return new InvokeCustomExpr(vt, cloneOps(mapper), callSite);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -486,7 +486,7 @@ private static String mergeTypeEx(String a, String b) {
return b;
} else { // as==bs;
String elementTypeA = a.substring(as);
String elementTypeB = a.substring(bs);
String elementTypeB = b.substring(bs);
TypeClass ta = TypeClass.clzOf(elementTypeA);
TypeClass tb = TypeClass.clzOf(elementTypeB);
if (ta.fixed && !tb.fixed) {
Expand Down
38 changes: 38 additions & 0 deletions dex-reader-api/src/main/java/com/googlecode/d2j/CallSite.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package com.googlecode.d2j;

public class CallSite {
private final String name;
private final MethodHandle bootstrapMethodHandler;
private final String methodName;
private final Proto methodProto;
private final Object[] extraArguments;

public CallSite(String name, MethodHandle bootstrapMethodHandler, String methodName, Proto methodProto,
Object... extraArguments) {
this.name = name;
this.bootstrapMethodHandler = bootstrapMethodHandler;
this.methodName = methodName;
this.methodProto = methodProto;
this.extraArguments = extraArguments;
}

public String getName() {
return name;
}

public MethodHandle getBootstrapMethodHandler() {
return bootstrapMethodHandler;
}

public String getMethodName() {
return methodName;
}

public Proto getMethodProto() {
return methodProto;
}

public Object[] getExtraArguments() {
return extraArguments;
}
}
18 changes: 15 additions & 3 deletions dex-reader-api/src/main/java/com/googlecode/d2j/DexConstants.java
Original file line number Diff line number Diff line change
Expand Up @@ -68,14 +68,26 @@ public interface DexConstants {

String ANNOTATION_MEMBER_CLASSES_TYPE = "Ldalvik/annotation/MemberClasses;";

static int toMiniAndroidApiLevel(int dexVersion) {
if (dexVersion <= DEX_035 || dexVersion <= DEX_036) {
return 0;
} else if (dexVersion == DEX_037) {
return 24;
} else if (dexVersion == DEX_038) {
return 26;
} else {
return 28;
}
}

int DEX_035 = 0x00303335;

int DEX_036 = 0x00303336;

// android 7.0, api 24
int DEX_037 = 0x00303337;

// android 8.0, api 26
int DEX_038 = 0x00303338;

// android 9.0, api 28
int DEX_039 = 0x00303339;

int DEX_040 = 0x00303340;
Expand Down
Loading

0 comments on commit 994ced1

Please sign in to comment.