Fix modification of args array being ignored when calling "backup" method
This commit is contained in:
parent
f1c9b21ca7
commit
af4feada27
|
|
@ -44,44 +44,63 @@ public class DexMakerUtils {
|
|||
}
|
||||
}
|
||||
|
||||
public static void autoUnboxIfNecessary(Code code, Local target, Local source) {
|
||||
public static void autoUnboxIfNecessary(Code code, Local target, Local source,
|
||||
Map<TypeId, Local> tmpLocals, boolean castObj) {
|
||||
String unboxMethod;
|
||||
TypeId typeId = target.getType();
|
||||
TypeId<?> boxTypeId;
|
||||
if (typeId.equals(TypeId.BOOLEAN)) {
|
||||
unboxMethod = "booleanValue";
|
||||
boxTypeId = TypeId.get(Boolean.class);
|
||||
code.invokeVirtual(boxTypeId.getMethod(TypeId.BOOLEAN, unboxMethod), target, source);
|
||||
boxTypeId = TypeId.get("Ljava/lang/Boolean;");
|
||||
Local boxTypedLocal = tmpLocals.get(boxTypeId);
|
||||
code.cast(boxTypedLocal, source);
|
||||
code.invokeVirtual(boxTypeId.getMethod(TypeId.BOOLEAN, unboxMethod), target, boxTypedLocal);
|
||||
} else if (typeId.equals(TypeId.BYTE)) {
|
||||
unboxMethod = "byteValue";
|
||||
boxTypeId = TypeId.get(Byte.class);
|
||||
code.invokeVirtual(boxTypeId.getMethod(TypeId.BYTE, unboxMethod), target, source);
|
||||
boxTypeId = TypeId.get("Ljava/lang/Byte;");
|
||||
Local boxTypedLocal = tmpLocals.get(boxTypeId);
|
||||
code.cast(boxTypedLocal, source);
|
||||
code.invokeVirtual(boxTypeId.getMethod(TypeId.BYTE, unboxMethod), target, boxTypedLocal);
|
||||
} else if (typeId.equals(TypeId.CHAR)) {
|
||||
unboxMethod = "charValue";
|
||||
boxTypeId = TypeId.get(Character.class);
|
||||
code.invokeVirtual(boxTypeId.getMethod(TypeId.CHAR, unboxMethod), target, source);
|
||||
boxTypeId = TypeId.get("Ljava/lang/Character;");
|
||||
Local boxTypedLocal = tmpLocals.get(boxTypeId);
|
||||
code.cast(boxTypedLocal, source);
|
||||
code.invokeVirtual(boxTypeId.getMethod(TypeId.CHAR, unboxMethod), target, boxTypedLocal);
|
||||
} else if (typeId.equals(TypeId.DOUBLE)) {
|
||||
unboxMethod = "doubleValue";
|
||||
boxTypeId = TypeId.get(Double.class);
|
||||
code.invokeVirtual(boxTypeId.getMethod(TypeId.DOUBLE, unboxMethod), target, source);
|
||||
boxTypeId = TypeId.get("Ljava/lang/Double;");
|
||||
Local boxTypedLocal = tmpLocals.get(boxTypeId);
|
||||
code.cast(boxTypedLocal, source);
|
||||
code.invokeVirtual(boxTypeId.getMethod(TypeId.DOUBLE, unboxMethod), target, boxTypedLocal);
|
||||
} else if (typeId.equals(TypeId.FLOAT)) {
|
||||
unboxMethod = "floatValue";
|
||||
boxTypeId = TypeId.get(Float.class);
|
||||
code.invokeVirtual(boxTypeId.getMethod(TypeId.FLOAT, unboxMethod), target, source);
|
||||
boxTypeId = TypeId.get("Ljava/lang/Float;");
|
||||
Local boxTypedLocal = tmpLocals.get(boxTypeId);
|
||||
code.cast(boxTypedLocal, source);
|
||||
code.invokeVirtual(boxTypeId.getMethod(TypeId.FLOAT, unboxMethod), target, boxTypedLocal);
|
||||
} else if (typeId.equals(TypeId.INT)) {
|
||||
unboxMethod = "intValue";
|
||||
boxTypeId = TypeId.get(Integer.class);
|
||||
code.invokeVirtual(boxTypeId.getMethod(TypeId.INT, unboxMethod), target, source);
|
||||
boxTypeId = TypeId.get("Ljava/lang/Integer;");
|
||||
Local boxTypedLocal = tmpLocals.get(boxTypeId);
|
||||
code.cast(boxTypedLocal, source);
|
||||
code.invokeVirtual(boxTypeId.getMethod(TypeId.INT, unboxMethod), target, boxTypedLocal);
|
||||
} else if (typeId.equals(TypeId.LONG)) {
|
||||
unboxMethod = "longValue";
|
||||
boxTypeId = TypeId.get(Long.class);
|
||||
code.invokeVirtual(boxTypeId.getMethod(TypeId.LONG, unboxMethod), target, source);
|
||||
boxTypeId = TypeId.get("Ljava/lang/Long;");
|
||||
Local boxTypedLocal = tmpLocals.get(boxTypeId);
|
||||
code.cast(boxTypedLocal, source);
|
||||
code.invokeVirtual(boxTypeId.getMethod(TypeId.LONG, unboxMethod), target, boxTypedLocal);
|
||||
} else if (typeId.equals(TypeId.SHORT)) {
|
||||
unboxMethod = "shortValue";
|
||||
boxTypeId = TypeId.get(Short.class);
|
||||
code.invokeVirtual(boxTypeId.getMethod(TypeId.SHORT, unboxMethod), target, source);
|
||||
boxTypeId = TypeId.get("Ljava/lang/Short;");
|
||||
Local boxTypedLocal = tmpLocals.get(boxTypeId);
|
||||
code.cast(boxTypedLocal, source);
|
||||
code.invokeVirtual(boxTypeId.getMethod(TypeId.SHORT, unboxMethod), target, boxTypedLocal);
|
||||
} else if (typeId.equals(TypeId.VOID)) {
|
||||
code.loadConstant(target, null);
|
||||
} else if (castObj){
|
||||
code.cast(target, source);
|
||||
} else {
|
||||
code.move(target, source);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -311,7 +311,7 @@ public class HookerDexMaker {
|
|||
Local<Object> callbackObj = code.newLocal(TypeId.OBJECT);
|
||||
Local<XC_MethodHook> callback = code.newLocal(callbackTypeId);
|
||||
|
||||
Local<Object> resultObj = code.newLocal(TypeId.OBJECT);
|
||||
Local<Object> resultObj = code.newLocal(TypeId.OBJECT); // as a temp Local
|
||||
Local<Integer> one = code.newLocal(TypeId.INT);
|
||||
Local<Object> nullObj = code.newLocal(TypeId.OBJECT);
|
||||
Local<Throwable> throwable = code.newLocal(throwableTypeId);
|
||||
|
|
@ -435,6 +435,15 @@ public class HookerDexMaker {
|
|||
// try to call backup
|
||||
// try start
|
||||
code.addCatchClause(throwableTypeId, tryOrigCatch);
|
||||
// we have to load args[] to paramLocals
|
||||
// because args[] may be changed in beforeHookedMethod
|
||||
// should consider first param is thisObj if hooked method is not static
|
||||
offset = mIsStatic ? 0 : 1;
|
||||
for (int i = offset; i < allArgsLocals.length; i++) {
|
||||
code.loadConstant(argIndex, i - offset);
|
||||
code.aget(resultObj, args, argIndex);
|
||||
autoUnboxIfNecessary(code, allArgsLocals[i], resultObj, resultLocals, true);
|
||||
}
|
||||
// get pre-created Local with a matching typeId
|
||||
if (mReturnTypeId.equals(TypeId.VOID)) {
|
||||
code.invokeStatic(mBackupMethodId, null, allArgsLocals);
|
||||
|
|
@ -511,7 +520,7 @@ public class HookerDexMaker {
|
|||
code.cast(matchObjLocal, resultObj);
|
||||
// have to use matching typed Object(Integer, Double ...) to do unboxing
|
||||
Local toReturn = resultLocals.get(mReturnTypeId);
|
||||
autoUnboxIfNecessary(code, toReturn, matchObjLocal);
|
||||
autoUnboxIfNecessary(code, toReturn, matchObjLocal, resultLocals, true);
|
||||
// return
|
||||
code.returnValue(toReturn);
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue