public void InjectAfterHookCode(MethodToHook hook, ref int index, bool hasReturnValue) { Instructions.Insert(index++, "new-instance v0, Lcom/xquadplaystatic/MethodHookParam;"); Instructions.Insert(index++, "invoke-direct {v0}, Lcom/xquadplaystatic/MethodHookParam;-><init>()V"); if (hasReturnValue) { Instructions.Insert(index++, "invoke-virtual {v0, v1}, Lcom/xquadplaystatic/MethodHookParam;->setResult(Ljava/lang/Object;)V"); } Instructions.Insert(index++, string.Format("invoke-static {{v0}}, {0}->{1}(Lcom/xquadplaystatic/MethodHookParam;)V", hook.Interceptor.ParentClass.ClassName, hook.Interceptor.MethodName)); if (hasReturnValue) { Instructions.Insert(index++, "invoke-virtual {v0}, Lcom/xquadplaystatic/MethodHookParam;->getResult()Ljava/lang/Object;"); Instructions.Insert(index++, "move-result-object v1"); Instructions.Insert(index++, string.Format("check-cast v1, {0}", ReturnType)); } }
static void ExecuteHook(MethodToHook hook) { Console.WriteLine(" Executing Method Hook: {0}", hook); SmaliClass targetClass; parsedClasses.TryGetValue(hook.TargetClassFormatted, out targetClass); if (targetClass == null) { Console.WriteLine(" Class Not Found! Skipping: {0}", hook.TargetClassFormatted); return; } foreach (var method in targetClass.Methods) { if (hook.IsMethodAdequate(method)) { Console.WriteLine(" Found Adequate Method: {0}", method); if (hook.HookAfter) { method.AddHookAfter(hook); } if (hook.HookBefore) { method.AddHookBefore(hook); } //method.PrintInstructions(); dirtyClasses.Add(targetClass); } } }
public void AddHookAfter(MethodToHook hook) { IsPatched = true; hookAfter = hook; }
public void AddHookBefore(MethodToHook hook) { IsPatched = true; hookBefore = hook; }
public void AddHookAfterOld(MethodToHook hook) { IsPatched = true; for (int n = 0; n < Instructions.Count; ++n) { if (n >= 1 && Instructions[n - 1].StartsWith("#hooked")) { continue; } string instr = Instructions[n]; if (instr.StartsWith("return-void")) { int index = n; InjectAfterHookCode(hook, ref index, false); Instructions.Insert(index++, "#hooked"); } if (instr.StartsWith("return ")) { int index = n; string returnValRegister = instr.Split(' ')[1]; if (returnValRegister != "v1") { Instructions.Insert(index++, string.Format("move v1, {0}", returnValRegister)); PackPrimitiveValue(ref index, ReturnType, "v1"); } InjectAfterHookCode(hook, ref index, true); if (returnValRegister != "v1") { UnpackPrimitiveValue(ref index, ReturnType, "v1"); Instructions.Insert(index++, string.Format("move {0}, v1", returnValRegister)); } Instructions.Insert(index++, "#hooked"); } if (instr.StartsWith("return-object")) { int index = n; string returnValRegister = instr.Split(' ')[1]; if (returnValRegister != "v1") { Instructions.Insert(index++, string.Format("move-object v1, {0}", returnValRegister)); } InjectAfterHookCode(hook, ref index, true); if (returnValRegister != "v1") { Instructions.Insert(index++, string.Format("move-object {0}, v1", returnValRegister)); } Instructions.Insert(index++, "#hooked"); } } }
public void AddHookBeforeOld(MethodToHook hook) { IsPatched = true; int index = 0; Instructions.Insert(index++, "new-instance v0, Lcom/xquadplaystatic/MethodHookParam;"); Instructions.Insert(index++, "invoke-direct {v0}, Lcom/xquadplaystatic/MethodHookParam;-><init>()V"); if (!IsStatic) { Instructions.Insert(index++, "iput-object p0, v0, Lcom/xquadplaystatic/MethodHookParam;->thisObject:Ljava/lang/Object;"); } if (ParameterTypes.Count > 0) { Instructions.Insert(index++, "const v1, 0x" + ParameterTypes.Count.ToString("x")); Instructions.Insert(index++, "new-array v1, v1, [Ljava/lang/Object;"); Instructions.Insert(index++, "iput-object v1, v0, Lcom/xquadplaystatic/MethodHookParam;->args:[Ljava/lang/Object;"); for (int n = 0; n < ParameterTypes.Count; ++n) { string paramType = ParameterTypes[n]; string paramRegister = "p" + (n + (IsStatic ? 0 : 1)); if (!IsObjectTypeTrueObject(paramType)) { PackPrimitiveValue(ref index, paramType, paramRegister); } Instructions.Insert(index++, "iget-object v1, v0, Lcom/xquadplaystatic/MethodHookParam;->args:[Ljava/lang/Object;"); Instructions.Insert(index++, "const v2, 0x" + n.ToString("x")); Instructions.Insert(index++, string.Format("aput-object {0}, v1, v2", paramRegister)); } } Instructions.Insert(index++, string.Format("invoke-static {{v0}}, {0}->{1}(Lcom/xquadplaystatic/MethodHookParam;)V", hook.Interceptor.ParentClass.ClassName, hook.Interceptor.MethodName)); if (ParameterTypes.Count > 0) { for (int n = 0; n < ParameterTypes.Count; ++n) { string paramType = ParameterTypes[n]; string paramRegister = "p" + (n + (IsStatic ? 0 : 1)); Instructions.Insert(index++, "iget-object v1, v0, Lcom/xquadplaystatic/MethodHookParam;->args:[Ljava/lang/Object;"); Instructions.Insert(index++, "const v2, 0x" + n.ToString("x")); Instructions.Insert(index++, string.Format("aget-object {0}, v1, v2", paramRegister)); } AddParameterMirroringCode(ref index); for (int n = 0; n < ParameterTypes.Count; ++n) { string paramType = ParameterTypes[n]; string paramRegister = "p" + (n + (IsStatic ? 0 : 1)); if (!IsObjectTypeTrueObject(paramType)) { UnpackPrimitiveValue(ref index, paramType, paramRegister); } } } Instructions.Insert(index++, "iget-boolean v1, v0, Lcom/xquadplaystatic/MethodHookParam;->returnEarly:Z"); Instructions.Insert(index++, "if-eqz v1, :cond_normal_run"); //if we canceled executing method by calling setResult() if (ReturnType == "V") { Instructions.Insert(index++, "return-void"); } else if (IsObjectTypeTrueObject(ReturnType)) { Instructions.Insert(index++, "invoke-virtual {v0}, Lcom/xquadplaystatic/MethodHookParam;->getResult()Ljava/lang/Object;"); Instructions.Insert(index++, "move-result-object v1"); Instructions.Insert(index++, string.Format("check-cast v1, {0}", ReturnType)); Instructions.Insert(index++, "return-object v1"); } else { Instructions.Insert(index++, "invoke-virtual {v0}, Lcom/xquadplaystatic/MethodHookParam;->getResult()Ljava/lang/Object;"); Instructions.Insert(index++, "move-result-object v1"); UnpackPrimitiveValue(ref index, ReturnType, "v1"); Instructions.Insert(index++, "return v1"); } Instructions.Insert(index++, ":cond_normal_run"); }
public static void RegisterMethodToHook(MethodToHook toHook) { toHook.Print(); methodsToHook.Add(toHook); }