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));
            }
        }
Example #2
0
        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");
        }
Example #7
0
 public static void RegisterMethodToHook(MethodToHook toHook)
 {
     toHook.Print();
     methodsToHook.Add(toHook);
 }