承接上文 http://blog.youkuaiyun.com/yzzst/article/details/47829657
之前我们看过了app_main.cpp源码,知道了在其中,启动了XposedBridge.jar方法。那么,其中还做了些什么事情呢?
之前我们也看到了在app_main.cpp还有几处新增的逻辑。xposed::initialize和onVmCreated回调。下面我在仔细的阅读以下源码。
xposed::initialize初始化
对于xposed::initalize的初始化工作,我们能够在xposed.cpp中看到其具体的逻辑实现。
<code class="hljs cs has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-comment" style="color:#8800;box-sizing: border-box;">/**
* 初始化xposed
*/</span>
<span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">bool</span> initialize(<span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">bool</span> zygote, <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">bool</span> startSystemServer, <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">const</span> <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">char</span>* className, <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">int</span> argc, <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">char</span>* <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">const</span> argv[]) {
<span class="hljs-preprocessor" style="color:#444444;box-sizing: border-box;">#<span class="hljs-keyword" style="color:#444444;box-sizing: border-box;">if</span> !defined(XPOSED_ENABLE_FOR_TOOLS)</span>
<span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">if</span> (!zygote)
<span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">return</span> <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">false</span>;
<span class="hljs-preprocessor" style="color:#444444;box-sizing: border-box;">#<span class="hljs-keyword" style="color:#444444;box-sizing: border-box;">endif</span></span>
xposed->zygote = zygote;
xposed->startSystemServer = startSystemServer;
xposed->startClassName = className;
xposed->xposedVersionInt = xposedVersionInt;
<span class="hljs-preprocessor" style="color:#444444;box-sizing: border-box;">#<span class="hljs-keyword" style="color:#444444;box-sizing: border-box;">if</span> XPOSED_WITH_SELINUX</span>
xposed->isSELinuxEnabled = is_selinux_enabled() == <span class="hljs-number" style="color:#06666;box-sizing: border-box;">1</span>;
xposed->isSELinuxEnforcing = xposed->isSELinuxEnabled && security_getenforce() == <span class="hljs-number" style="color:#06666;box-sizing: border-box;">1</span>;
<span class="hljs-preprocessor" style="color:#444444;box-sizing: border-box;">#<span class="hljs-keyword" style="color:#444444;box-sizing: border-box;">else</span></span>
xposed->isSELinuxEnabled = <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">false</span>;
xposed->isSELinuxEnforcing = <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">false</span>;
<span class="hljs-preprocessor" style="color:#444444;box-sizing: border-box;">#<span class="hljs-keyword" style="color:#444444;box-sizing: border-box;">endif</span> // XPOSED_WITH_SELINUX</span>
<span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">if</span> (startSystemServer) {
xposed::logcat::start();
} <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">else</span> <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">if</span> (zygote) {
<span class="hljs-comment" style="color:#8800;box-sizing: border-box;">// TODO Find a better solution for this</span>
<span class="hljs-comment" style="color:#8800;box-sizing: border-box;">// Give the primary Zygote process a little time to start first.</span>
<span class="hljs-comment" style="color:#8800;box-sizing: border-box;">// This also makes the log easier to read, as logs for the two Zygotes are not mixed up.</span>
sleep(<span class="hljs-number" style="color:#06666;box-sizing: border-box;">10</span>);
}
<span class="hljs-comment" style="color:#8800;box-sizing: border-box;">// 打印rom信息</span>
printRomInfo();
<span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">if</span> (startSystemServer) {
<span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">if</span> (!xposed::service::startAll())
<span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">return</span> <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">false</span>;
<span class="hljs-preprocessor" style="color:#444444;box-sizing: border-box;">#<span class="hljs-keyword" style="color:#444444;box-sizing: border-box;">if</span> XPOSED_WITH_SELINUX</span>
} <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">else</span> <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">if</span> (xposed->isSELinuxEnabled) {
<span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">if</span> (!xposed::service::startMembased())
<span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">return</span> <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">false</span>;
<span class="hljs-preprocessor" style="color:#444444;box-sizing: border-box;">#<span class="hljs-keyword" style="color:#444444;box-sizing: border-box;">endif</span> // XPOSED_WITH_SELINUX</span>
}
<span class="hljs-comment" style="color:#8800;box-sizing: border-box;">// FIXME Zygote has no access to input devices, this would need to be check in system_server context</span>
<span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">if</span> (zygote && !isSafemodeDisabled() && detectSafemodeTrigger(shouldSkipSafemodeDelay()))
disableXposed();
<span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">if</span> (isDisabled() || (!zygote && shouldIgnoreCommand(argc, argv)))
<span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">return</span> <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">false</span>;
<span class="hljs-comment" style="color:#8800;box-sizing: border-box;">// 将XposedBridge.jar的路径添加到环境变量classpath中</span>
<span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">return</span> addJarToClasspath();
}</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li><li style="box-sizing: border-box; padding: 0px 5px;">21</li><li style="box-sizing: border-box; padding: 0px 5px;">22</li><li style="box-sizing: border-box; padding: 0px 5px;">23</li><li style="box-sizing: border-box; padding: 0px 5px;">24</li><li style="box-sizing: border-box; padding: 0px 5px;">25</li><li style="box-sizing: border-box; padding: 0px 5px;">26</li><li style="box-sizing: border-box; padding: 0px 5px;">27</li><li style="box-sizing: border-box; padding: 0px 5px;">28</li><li style="box-sizing: border-box; padding: 0px 5px;">29</li><li style="box-sizing: border-box; padding: 0px 5px;">30</li><li style="box-sizing: border-box; padding: 0px 5px;">31</li><li style="box-sizing: border-box; padding: 0px 5px;">32</li><li style="box-sizing: border-box; padding: 0px 5px;">33</li><li style="box-sizing: border-box; padding: 0px 5px;">34</li><li style="box-sizing: border-box; padding: 0px 5px;">35</li><li style="box-sizing: border-box; padding: 0px 5px;">36</li><li style="box-sizing: border-box; padding: 0px 5px;">37</li><li style="box-sizing: border-box; padding: 0px 5px;">38</li><li style="box-sizing: border-box; padding: 0px 5px;">39</li><li style="box-sizing: border-box; padding: 0px 5px;">40</li><li style="box-sizing: border-box; padding: 0px 5px;">41</li><li style="box-sizing: border-box; padding: 0px 5px;">42</li><li style="box-sizing: border-box; padding: 0px 5px;">43</li><li style="box-sizing: border-box; padding: 0px 5px;">44</li><li style="box-sizing: border-box; padding: 0px 5px;">45</li><li style="box-sizing: border-box; padding: 0px 5px;">46</li><li style="box-sizing: border-box; padding: 0px 5px;">47</li><li style="box-sizing: border-box; padding: 0px 5px;">48</li><li style="box-sizing: border-box; padding: 0px 5px;">49</li><li style="box-sizing: border-box; padding: 0px 5px;">50</li><li style="box-sizing: border-box; padding: 0px 5px;">51</li><li style="box-sizing: border-box; padding: 0px 5px;">52</li><li style="box-sizing: border-box; padding: 0px 5px;">53</li><li style="box-sizing: border-box; padding: 0px 5px;">54</li></ul>
* onVmCreated 初始化后的准备工作 *
其具体的逻辑如下所示:
<code class="hljs java has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-javadoc" style="color:#8800;box-sizing: border-box;">/**
* 向当前的runtime中载入libxposed_*.so
*/</span>
<span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">void</span> onVmCreated(JNIEnv* env) {
<span class="hljs-comment" style="color:#8800;box-sizing: border-box;">// Determine the currently active runtime</span>
<span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">const</span> <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">char</span>* xposedLibPath = NULL;
<span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">if</span> (!determineRuntime(&xposedLibPath)) {
ALOGE(<span class="hljs-string" style="color:#0880;box-sizing: border-box;">"Could not determine runtime, not loading Xposed"</span>);
<span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">return</span>;
}
<span class="hljs-comment" style="color:#8800;box-sizing: border-box;">// Load the suitable libxposed_*.so for it</span>
<span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">const</span> <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">char</span> *error;
<span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">void</span>* xposedLibHandle = dlopen(xposedLibPath, RTLD_NOW);
<span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">if</span> (!xposedLibHandle) {
ALOGE(<span class="hljs-string" style="color:#0880;box-sizing: border-box;">"Could not load libxposed: %s"</span>, dlerror());
<span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">return</span>;
}
<span class="hljs-comment" style="color:#8800;box-sizing: border-box;">// Clear previous errors</span>
dlerror();
<span class="hljs-comment" style="color:#8800;box-sizing: border-box;">// Initialize the library</span>
bool (*xposedInitLib)(XposedShared* shared) = NULL;
*(<span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">void</span> **) (&xposedInitLib) = dlsym(xposedLibHandle, <span class="hljs-string" style="color:#0880;box-sizing: border-box;">"xposedInitLib"</span>);
<span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">if</span> (!xposedInitLib) {
ALOGE(<span class="hljs-string" style="color:#0880;box-sizing: border-box;">"Could not find function xposedInitLib"</span>);
<span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">return</span>;
}
#<span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">if</span> XPOSED_WITH_SELINUX
xposed->zygoteservice_accessFile = &service::membased::accessFile;
xposed->zygoteservice_statFile = &service::membased::statFile;
xposed->zygoteservice_readFile = &service::membased::readFile;
#endif <span class="hljs-comment" style="color:#8800;box-sizing: border-box;">// XPOSED_WITH_SELINUX</span>
<span class="hljs-comment" style="color:#8800;box-sizing: border-box;">// 这里的xposed变量,其实是一个全局的XposedShare。</span>
<span class="hljs-comment" style="color:#8800;box-sizing: border-box;">// 调用XposedShare的onVmCreated则会根据不同的vm架构针对不同的实现。</span>
<span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">if</span> (xposedInitLib(xposed)) {
xposed->onVmCreated(env);
}
}</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li><li style="box-sizing: border-box; padding: 0px 5px;">21</li><li style="box-sizing: border-box; padding: 0px 5px;">22</li><li style="box-sizing: border-box; padding: 0px 5px;">23</li><li style="box-sizing: border-box; padding: 0px 5px;">24</li><li style="box-sizing: border-box; padding: 0px 5px;">25</li><li style="box-sizing: border-box; padding: 0px 5px;">26</li><li style="box-sizing: border-box; padding: 0px 5px;">27</li><li style="box-sizing: border-box; padding: 0px 5px;">28</li><li style="box-sizing: border-box; padding: 0px 5px;">29</li><li style="box-sizing: border-box; padding: 0px 5px;">30</li><li style="box-sizing: border-box; padding: 0px 5px;">31</li><li style="box-sizing: border-box; padding: 0px 5px;">32</li><li style="box-sizing: border-box; padding: 0px 5px;">33</li><li style="box-sizing: border-box; padding: 0px 5px;">34</li><li style="box-sizing: border-box; padding: 0px 5px;">35</li><li style="box-sizing: border-box; padding: 0px 5px;">36</li><li style="box-sizing: border-box; padding: 0px 5px;">37</li><li style="box-sizing: border-box; padding: 0px 5px;">38</li><li style="box-sizing: border-box; padding: 0px 5px;">39</li><li style="box-sizing: border-box; padding: 0px 5px;">40</li><li style="box-sizing: border-box; padding: 0px 5px;">41</li><li style="box-sizing: border-box; padding: 0px 5px;">42</li></ul>
* libxposed_dalvik.cpp hook环境初始化*
<code class="hljs scala has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-javadoc" style="color:#8800;box-sizing: border-box;">/** Called by Xposed's app_process replacement.
* 在被替换后的app_process中调用
*/</span>
bool xposedInitLib(xposed::XposedShared* shared) {
xposed = shared;
<span class="hljs-comment" style="color:#8800;box-sizing: border-box;">// 将自己的onVmCreated方法,指向onVmCreated方法</span>
xposed->onVmCreated = &onVmCreated;
<span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">return</span> <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">true</span>;
}
<span class="hljs-javadoc" style="color:#8800;box-sizing: border-box;">/** Called very early during VM startup.
* 在VM启动的时候调用,而且调用时机比较早
*/</span>
void onVmCreated(JNIEnv* env) {
<span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">if</span> (!initMemberOffsets(env))
<span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">return</span>;
<span class="hljs-comment" style="color:#8800;box-sizing: border-box;">// 找到小米系统的MIUI_RESOURCE做特殊处理</span>
j<span class="hljs-class" style="box-sizing: border-box;"><span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">class</span> <span class="hljs-title" style="color:#66066;box-sizing: border-box;">classMiuiResources</span> = <span class="hljs-title" style="color:#66066;box-sizing: border-box;">env</span>-><span class="hljs-title" style="color:#66066;box-sizing: border-box;">FindClass</span><span class="hljs-params" style="color:#66066;box-sizing: border-box;">(CLASS_MIUI_RESOURCES)</span>;</span>
<span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">if</span> (classMiuiResources != NULL) {
ClassObject* clazz = (ClassObject*)dvmDecodeIndirectRef(dvmThreadSelf(), classMiuiResources);
<span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">if</span> (dvmIsFinalClass(clazz)) {
ALOGD(<span class="hljs-string" style="color:#0880;box-sizing: border-box;">"Removing final flag for class '%s'"</span>, CLASS_MIUI_RESOURCES);
clazz->accessFlags &= ~ACC_FINAL;
}
}
env->ExceptionClear();
j<span class="hljs-class" style="box-sizing: border-box;"><span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">class</span> <span class="hljs-title" style="color:#66066;box-sizing: border-box;">classXTypedArray</span> = <span class="hljs-title" style="color:#66066;box-sizing: border-box;">env</span>-><span class="hljs-title" style="color:#66066;box-sizing: border-box;">FindClass</span><span class="hljs-params" style="color:#66066;box-sizing: border-box;">(CLASS_XTYPED_ARRAY)</span>;</span>
<span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">if</span> (classXTypedArray == NULL) {
ALOGE(<span class="hljs-string" style="color:#0880;box-sizing: border-box;">"Error while loading XTypedArray class '%s':"</span>, CLASS_XTYPED_ARRAY);
dvmLogExceptionStackTrace();
env->ExceptionClear();
<span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">return</span>;
}
prepareSubclassReplacement(classXTypedArray);
<span class="hljs-comment" style="color:#8800;box-sizing: border-box;">// 获取到全局的XposedBridge</span>
classXposedBridge = env->FindClass(CLASS_XPOSED_BRIDGE);
classXposedBridge = reinterpret_cast<jclass>(env->NewGlobalRef(classXposedBridge));
<span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">if</span> (classXposedBridge == NULL) {
ALOGE(<span class="hljs-string" style="color:#0880;box-sizing: border-box;">"Error while loading Xposed class '%s':"</span>, CLASS_XPOSED_BRIDGE);
dvmLogExceptionStackTrace();
env->ExceptionClear();
<span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">return</span>;
}
<span class="hljs-comment" style="color:#8800;box-sizing: border-box;">// 注册一些 XposedBridge 的 native 方法</span>
ALOGI(<span class="hljs-string" style="color:#0880;box-sizing: border-box;">"Found Xposed class '%s', now initializing"</span>, CLASS_XPOSED_BRIDGE);
<span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">if</span> (register_natives_XposedBridge(env, classXposedBridge) != JNI_OK) {
ALOGE(<span class="hljs-string" style="color:#0880;box-sizing: border-box;">"Could not register natives for '%s'"</span>, CLASS_XPOSED_BRIDGE);
dvmLogExceptionStackTrace();
env->ExceptionClear();
<span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">return</span>;
}
xposedLoadedSuccessfully = <span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">true</span>;
}</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li><li style="box-sizing: border-box; padding: 0px 5px;">21</li><li style="box-sizing: border-box; padding: 0px 5px;">22</li><li style="box-sizing: border-box; padding: 0px 5px;">23</li><li style="box-sizing: border-box; padding: 0px 5px;">24</li><li style="box-sizing: border-box; padding: 0px 5px;">25</li><li style="box-sizing: border-box; padding: 0px 5px;">26</li><li style="box-sizing: border-box; padding: 0px 5px;">27</li><li style="box-sizing: border-box; padding: 0px 5px;">28</li><li style="box-sizing: border-box; padding: 0px 5px;">29</li><li style="box-sizing: border-box; padding: 0px 5px;">30</li><li style="box-sizing: border-box; padding: 0px 5px;">31</li><li style="box-sizing: border-box; padding: 0px 5px;">32</li><li style="box-sizing: border-box; padding: 0px 5px;">33</li><li style="box-sizing: border-box; padding: 0px 5px;">34</li><li style="box-sizing: border-box; padding: 0px 5px;">35</li><li style="box-sizing: border-box; padding: 0px 5px;">36</li><li style="box-sizing: border-box; padding: 0px 5px;">37</li><li style="box-sizing: border-box; padding: 0px 5px;">38</li><li style="box-sizing: border-box; padding: 0px 5px;">39</li><li style="box-sizing: border-box; padding: 0px 5px;">40</li><li style="box-sizing: border-box; padding: 0px 5px;">41</li><li style="box-sizing: border-box; padding: 0px 5px;">42</li><li style="box-sizing: border-box; padding: 0px 5px;">43</li><li style="box-sizing: border-box; padding: 0px 5px;">44</li><li style="box-sizing: border-box; padding: 0px 5px;">45</li><li style="box-sizing: border-box; padding: 0px 5px;">46</li><li style="box-sizing: border-box; padding: 0px 5px;">47</li><li style="box-sizing: border-box; padding: 0px 5px;">48</li><li style="box-sizing: border-box; padding: 0px 5px;">49</li><li style="box-sizing: border-box; padding: 0px 5px;">50</li><li style="box-sizing: border-box; padding: 0px 5px;">51</li><li style="box-sizing: border-box; padding: 0px 5px;">52</li><li style="box-sizing: border-box; padding: 0px 5px;">53</li><li style="box-sizing: border-box; padding: 0px 5px;">54</li><li style="box-sizing: border-box; padding: 0px 5px;">55</li><li style="box-sizing: border-box; padding: 0px 5px;">56</li><li style="box-sizing: border-box; padding: 0px 5px;">57</li><li style="box-sizing: border-box; padding: 0px 5px;">58</li><li style="box-sizing: border-box; padding: 0px 5px;">59</li></ul>
JNI方法注册逻辑
这里注册的几个方法都是,Xposed核心的几个方法函数。
<code class="hljs vala has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">
<span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">int</span> register_natives_XposedBridge(JNIEnv* env, jclass clazz) {
<span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">const</span> JNINativeMethod methods[] = {
NATIVE_METHOD(XposedBridge, getStartClassName, <span class="hljs-string" style="color:#0880;box-sizing: border-box;">"()Ljava/lang/String;"</span>),
<span class="hljs-comment" style="color:#8800;box-sizing: border-box;">// 获得Runtime</span>
NATIVE_METHOD(XposedBridge, getRuntime, <span class="hljs-string" style="color:#0880;box-sizing: border-box;">"()I"</span>),
<span class="hljs-comment" style="color:#8800;box-sizing: border-box;">// 启动SystemServer</span>
NATIVE_METHOD(XposedBridge, startsSystemServer, <span class="hljs-string" style="color:#0880;box-sizing: border-box;">"()Z"</span>),
<span class="hljs-comment" style="color:#8800;box-sizing: border-box;">// 获取Xposed的版本信息</span>
NATIVE_METHOD(XposedBridge, getXposedVersion, <span class="hljs-string" style="color:#0880;box-sizing: border-box;">"()I"</span>),
<span class="hljs-comment" style="color:#8800;box-sizing: border-box;">// 初始化navtive</span>
NATIVE_METHOD(XposedBridge, initNative, <span class="hljs-string" style="color:#0880;box-sizing: border-box;">"()Z"</span>),
<span class="hljs-comment" style="color:#8800;box-sizing: border-box;">// hook一个方法的native实现</span>
NATIVE_METHOD(XposedBridge, hookMethodNative, <span class="hljs-string" style="color:#0880;box-sizing: border-box;">"(Ljava/lang/reflect/Member;Ljava/lang/Class;ILjava/lang/Object;)V"</span>),
<span class="hljs-preprocessor" style="color:#444444;box-sizing: border-box;">#ifdef ART_TARGET</span>
NATIVE_METHOD(XposedBridge, invokeOriginalMethodNative,
<span class="hljs-string" style="color:#0880;box-sizing: border-box;">"(Ljava/lang/reflect/Member;I[Ljava/lang/Class;Ljava/lang/Class;Ljava/lang/Object;[Ljava/lang/Object;)Ljava/lang/Object;"</span>),
<span class="hljs-preprocessor" style="color:#444444;box-sizing: border-box;">#endif</span>
NATIVE_METHOD(XposedBridge, setObjectClassNative, <span class="hljs-string" style="color:#0880;box-sizing: border-box;">"(Ljava/lang/Object;Ljava/lang/Class;)V"</span>),
NATIVE_METHOD(XposedBridge, dumpObjectNative, <span class="hljs-string" style="color:#0880;box-sizing: border-box;">"(Ljava/lang/Object;)V"</span>),
NATIVE_METHOD(XposedBridge, cloneToSubclassNative, <span class="hljs-string" style="color:#0880;box-sizing: border-box;">"(Ljava/lang/Object;Ljava/lang/Class;)Ljava/lang/Object;"</span>),
};
<span class="hljs-keyword" style="color:#0088;box-sizing: border-box;">return</span> env->RegisterNatives(clazz, methods, NELEM(methods));
}</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li><li style="box-sizing: border-box; padding: 0px 5px;">21</li><li style="box-sizing: border-box; padding: 0px 5px;">22</li><li style="box-sizing: border-box; padding: 0px 5px;">23</li><li style="box-sizing: border-box; padding: 0px 5px;">24</li><li style="box-sizing: border-box; padding: 0px 5px;">25</li></ul>
我们看到RegisterNatives这个方法的时候不是很理解,这里做一个简介。
以前在jni中写本地方法时,都会写成 Java_com_example_hellojni_HelloJni_stringFromJNI的形式,函数名很长,而且当类名变了的时候,函数名必须一个一个的改,麻烦。
现在好了有了RegisterNatives,可以简化我们的书写
和传统方法相比,使用RegisterNatives的好处有三点:
1. C++中函数命名自由,不必像javah自动生成的函数声明那样,拘泥特定的命名方式;
2. 效率高。传统方式下,Java类call本地函数时,通常是依靠VM去动态寻找.so中的本地函数(因此它们才需要特定规则的命名格式),而使用RegisterNatives将本地函数向VM进行登记,可以让其更有效率的找到函数;
3. 运行时动态调整本地函数与Java函数值之间的映射关系,只需要多次call RegisterNatives()方法,并传入不同的映射表参数即可。
原文地址: http://blog.youkuaiyun.com/yzzst/article/details/47834077
971

被折叠的 条评论
为什么被折叠?



