我正在通过Android中的Xposed框架。特别是阅读博客 - http://d3adend.org/blog/?p=589了解潜在的对策,并对这些问题提出了几个问题。
因此,当我们使用Xposed挂钩方法时,框架将该方法设置为本机并执行它想要挂钩的代码。那么如何在stacktrace原始方法中调用它?
com.example.hookdetection.DoStuff->getSecret //This one
de.robv.android.xposed.XposedBridge->invokeOriginalMethodNative
de.robv.android.xposed.XposedBridge->handleHookedMethod
com.example.hookdetection.DoStuff->getSecret //This one again
com.example.hookdetection.MainActivity->onCreate
android.app.Activity->performCreate
android.app.Instrumentation->callActivityOnCreate
android.app.ActivityThread->performLaunchActivity
android.app.ActivityThread->handleLaunchActivity
android.app.ActivityThread->access$800
android.app.ActivityThread$H->handleMessage
android.os.Handler->dispatchMessage
android.os.Looper->loop
android.app.ActivityThread->main
java.lang.reflect.Method->invokeNative
java.lang.reflect.Method->invoke
com.android.internal.os.ZygoteInit$MethodAndArgsCaller->run
com.android.internal.os.ZygoteInit->main
de.robv.android.xposed.XposedBridge->main
dalvik.system.NativeStart->main
为什么它会在堆栈跟踪中出现两次。我想了解它们的执行顺序。
实际方法是否运行?由于钩子方法代码执行,因此理想情况下不会执行原始方法代码。那么我们怎样才能在相同的方法中添加一个stracktrace检测机制,知道它将被替换。
答案 0 :(得分:10)
如果您对低级代码和Android内核感到不舒服,则不容易理解Xposed内部工作原理。简而言之,当您在Android设备上打开应用程序时,会有一个名为Zygote的主进程将其作为子进程生成。
Xposed的目的是能够控制Zygote并检测每当一个进程即将产生时,以便有人能够在对方法进行任何调用之前替换它们的定义来挂钩方法。
你可以通过使用Xposed进行大量控制,你可以替换整个方法体,因此原始代码永远不会被调用,或者你可以使用beforeCall和afterCall钩子,这基本上是蹦床技术的一种用法(下面是一个C ++示例) )
正如你所看到的那样,当一个方法被调用时,它不会直接转到原始代码,而是转移到一个注入的代码块,在那里有人可以做任何他想做的事情(转储,更改参数等)然后它会跳回到真正的代码。您也可以在正版代码之后执行此操作,以便获得方法输出。 Xposed通过使用 beforeHookedMethod 和 afterHookedMethod 来实现此目的。
添加堆栈跟踪检测机制根本无济于事。您将调用Java方法来获取实际的堆栈跟踪。通过挂钩getStacktrace方法,保存有效的真正堆栈跟踪,然后在调用getStackTrace并包含Xposed方法时,可以轻松地将其丢失,返回先前保存的真正堆栈跟踪。
您最好的选择是依靠Native代码来检测它,但即便如此,任何具有完全设备控制权的已确定且经过实验的黑客都可能最终将其击败。
答案 1 :(得分:1)
要在致电XposedHelpers.findAndHookMethod
时添加上述积分,回调可以是 -
beforeHookedMethod(XC_MethodHook.MethodHookParam)
和/或afterHookedMethod(XC_MethodHook.MethodHookParam)
。 第一个只提供了在原始方法之前和之后执行方法的钩子,其中第二个完全替换它。例如 - Xposed example on github
我写的几篇帖子 -