½ñÌìÖÜÈÕ£¬×òÌ컨ÁËÒ»ÌìµÄʱ¼ä×ÜËãÊǸ㶨ÁË£¬ÎÊÌ⻹ÊÇÏë¶ÔÓ¦ÓóÌÐòµÄÐÐΪ½øÐÐÀ¹½ØµÄ²Ù×÷£¬¾ÍÊÇÏñСÃ×ÊÖ»úÒ»Ñù£¬ÄÄЩӦÓÃÔÚ»ñÈ¡ÄãʲôȨÏÞµÄÐÅÏ¢¡£ÔÚ֮ǰд¹ý¶ÔÓ¦ÓóÌÐòµÄÐÐΪ½øÐÐÀ¹½ØµÄ·½Ê½(C²ã)ʵÏֵIJ©¿Í£¬ÔÚдÍêÕâÆªÖ®ºó£¬±¾À´ÏëÊǾ¡¿ìµÄ°ÑJava²ãÀ¹½ØµÄÎÄÕ½áÊøµÄ£¬µ«ÊÇÓÉÓÚ¸÷ÖÖÔÒò°É£¬ËùÒÔһֱûÓÐʱ¼äȥŪÕâЩÁË¡£½ñÌìËãÊÇÓпգ¬¾Í×ܽáһϰɡ£ÏÂÃæ½øÈëÕýÌ⣺
Ò»¡¢ÕªÒª
ÎÒÃÇÖªµÀÏÖÔÚһЩ°²È«Èí¼þ¶¼»áÓÐÒ»¸ö¹¦ÄܾÍÊÇÄܹ»À¹½ØÓ¦ÓõÄÐÐΪ(±ÈÈçµØÀíλÖÃÐÅÏ¢£¬Í¨Ñ¶Â¼µÈ)£¬ËùÒÔÕâÀï¾ÍÀ´ÊµÏÖÒÔÏÂÕâÑùµÄ¹¦ÄÜ£¬µ±È»ÊµÏÖÕâÑùµÄ¹¦ÄÜÓÐÁ½ÖÖ·½Ê½£¬Ò»ÖÖÊÇ´Óµ×²ã½øÐÐÀ¹½Ø£¬Õâ¸öÎÒÔÚ֮ǰµÄ²©¿ÍÖÐÒѾ½²½â¹ýÁË¡£
»¹ÓÐÒ»ÖÖ·½Ê½¾ÍÊÇ´ÓÉÏ²ã½øÐÐÀ¹½Ø£¬Ò²¾ÍÊÇÎÒÃǽñÌìËùҪ˵µÄÄÚÈÝ£¬ÕâÖÖ·½Ê½¶¼ÊÇ¿ÉÒԵ쬵±È»ºÜ¶àÈ˸ü¶àµÄÆ«ÏòÉϲ㣬ÒòΪµ×²ãÀ¹½ØÐèÒªÊìÖªBinderÐÒéºÍBinderµÄÊý¾Ý¸ñʽµÄ¡£ÉϲãÀ¹½Ø¾Í¼òµ¥µãÁË¡£
¶þ¡¢ÖªÊ¶µã¸ÅÒª
Ê×ÏÈÎÒÃÇÐèÒªÁ˽âÒ»µã֪ʶ¾ÍÊDz»¹ÜÊǵײãÀ¹½Ø»¹ÊÇÉϲãÀ¹½Ø£¬¶¼ÐèÒªÒ»¸ö¼¼ÊõÖ§³Ö£º½ø³Ì×¢È룬¹ØÓÚÕâ¸ö֪ʶµã£¬ÕâÀï¾Í²»×÷½âÊÍÁË¡£
Á˽âÁ˽ø³Ì×¢ÈëÖ®ºó£¬ÕâÆªÎÄÕÂÖ÷Òª½²½âÈýµã֪ʶ£º
1¡¢ÈçºÎ¶¯Ì¬¼ÓÔØso£¬²¢ÇÒÖ´ÐÐÆäÖеĺ¯Êý
2¡¢ÈçºÎÔÚC²ãÖ´ÐÐJava·½·¨(NDKÒ»°ãÊÇÖ¸JavaÖе÷ÓÃC²ãº¯Êý)
3¡¢ÈçºÎÐÞ¸Äϵͳ·þÎñ(Context.getSystemService(String...)Æäʵ·µ»ØÀ´µÄ¾ÍÊÇBinder¶ÔÏó)¶ÔÏó
µ±È»ÎÒÃÇ»¹ÐèҪһЩԤ±¸ÖªÊ¶£ºÖªµÀÈçºÎʹÓÃNDK½øÐбàÒëÏîÄ¿¡£
ÕâÆªÎÄÕ±àÒë»·¾³ÊÇWindowÏµģ¬¸öÈ˸оõ»¹ÊDz»·½±ã£¬»¹ÊÇÔÚUbuntu»·¾³Ï²Ù×÷±È½Ï·½±ã
»¹ÓÐÒ»µãÐèÒªÉùÃ÷£º¾ÍÊÇÀ¹½ØÐÐΪÊÇÐèÒªrootȨÏÞµÄ
Èý¡¢Àý×Ó
µÚÒ»¸öÀý×Ó£º¼òµ¥µÄ½ø³Ì×¢È빦ÄÜ
Ä¿µÄ£ºÏ£Íû½«ÎÒÃÇ×Ô¼ºµÄ¹¦ÄÜÄ£¿é(soÎļþ)×¢È뵽Ŀ±ê½ø³ÌÖУ¬È»ºóÐÞ¸ÄÄ¿±ê½ø³ÌÖеÄij¸öº¯ÊýµÄÖ´Ðйý³Ì
Îļþ£º×¢È빦ÄÜ¿ÉÖ´ÐÐÎļþpoison¡¢Ä¿±ê½ø³Ì¿ÉÖ´ÐÐÎļþdemo1¡¢ÐèҪעÈëµÄÄ£¿élibmyso.so
×¢È빦ÄܵĿÉÖ´ÐÐÎļþºËÐÄ´úÂëpoison.c£¬Õâ¸ö¹¦ÄÜÄ£¿éÔÚºóÃæ½²µ½µÄÀý×ÓÖÐÒ²»áÓõ½£¬ËùÒÔËûÊǹ«ÓõÄ
#include <unistd.h> #include <errno.h> #include <stdlib.h> #include <dlfcn.h> #include <sys/mman.h> #include <sys/ptrace.h> #include <sys/wait.h> #include "ptrace_utils.h" #include "elf_utils.h" #include "log.h" #include "tools.h" struct process_hook { pid_t pid; char *dso; } process_hook = {0, ""}; int main(int argc, char* argv[]) { LOGI("argv len:"+argc); if(argc < 2) exit(0); struct pt_regs regs; process_hook.dso = strdup(argv[1]); process_hook.pid = atoi(argv[2]); if (access(process_hook.dso, R_OK|X_OK) < 0) { LOGE("[-] so file must chmod rx\n"); return 1; } const char* process_name = get_process_name(process_hook.pid); ptrace_attach(process_hook.pid, strstr(process_name,"zygote")); LOGI("[+] ptrace attach to [%d] %s\n", process_hook.pid, get_process_name(process_hook.pid)); if (ptrace_getregs(process_hook.pid, ®s) < 0) { LOGE("[-] Can't get regs %d\n", errno); goto DETACH; } LOGI("[+] pc: %x, r7: %d", regs.ARM_pc, regs.ARM_r7); void* remote_dlsym_addr = get_remote_address(process_hook.pid, (void *)dlsym); void* remote_dlopen_addr = get_remote_address(process_hook.pid, (void *)dlopen); LOGI("[+] remote_dlopen address %p\n", remote_dlopen_addr); LOGI("[+] remote_dlsym address %p\n", remote_dlsym_addr); if(ptrace_dlopen(process_hook.pid, remote_dlopen_addr, process_hook.dso) == NULL){ LOGE("[-] Ptrace dlopen fail. %s\n", dlerror()); } if (regs.ARM_pc & 1 ) { regs.ARM_pc &= (~1u); regs.ARM_cpsr |= CPSR_T_MASK; } else { regs.ARM_cpsr &= ~CPSR_T_MASK; } if (ptrace_setregs(process_hook.pid, ®s) == -1) { LOGE("[-] Set regs fail. %s\n", strerror(errno)); goto DETACH; } LOGI("[+] Inject success!\n"); DETACH: ptrace_detach(process_hook.pid); LOGI("[+] Inject done!\n"); return 0; } |
ÎÒÃÇ¿´µ½£¬Õâ¸ö×¢È빦ÄܵĴúÂëºÍÎÒÃÇ֮ǰ˵µÄ´Óµ×²ã½øÐÐÀ¹½ØµÄÄÇÆªÎÄÕÂÖеÄ×¢Èë´úÂë(inject.c)²»Ì«Ò»Ñùѽ£¿Õâ¸öÊÇÓÐÈËÔÚÍøÉÏ´ÓиÄдÁËһϣ¬Æäʵ¹¦ÄÜÉÏÃ»Ê²Ã´Çø±ðµÄ£¬ÎÒÃÇ´Ómainº¯Êý¿ÉÒÔ¿´µ½£¬ÓÐÁ½¸öÈë¿Ú²ÎÊý£º
µÚÒ»¸öÊÇ£ºÐèҪעÈësoÎļþµÄȫ·¾¶
µÚ¶þ¸öÊÇ£ºÐèҪעÈë½ø³ÌµÄpid
Ò²¾ÍÊÇ˵£¬ÎÒÃÇÔÚÖ´ÐÐpoison³ÌÐòµÄʱºòÐèÒª´«µÝÕâÁ½¸öÖµ¡£ÔÚ֮ǰ˵µÀµÄ×¢Èë´úÂë(inject.c)ÖУ¬ÆäʵÕâÁ½¸ö²ÎÊýÊÇÔÚ´úÂëÖÐдËÀµÄ£¬Èç¹ûÍü¼ÇµÄͬѧ¿ÉÒÔ»ØÈ¥¿´Ò»Ï£¬¾ÍÊÇÇ°ÃæÌáµ½µÄ´Óµ×²ã½øÐÐÀ¹½ØµÄÄÇÆªÎÄÕ¡£
ÄÇôÕâÑùÐÞ¸ÄÖ®ºó£¬Ã²ËÆÁé»îÐÔ¸ü¸ßÁË¡£
µ±È»×¢È빦ÄܵĴúÂë²»Ö¹ÕâÒ»¸ö£¬ÆäʵÊÇÒ»¸ö¹¤³Ì£¬ÕâÀïÓÉÓÚÆª·ùµÄÔÒò¾Í²»×ö½éÉÜÁË¡£
ʹÓÃNDK±àÒëһϣ¬Éú³É¿ÉÖ´ÐÐÎļþ¾ÍOKÁË¡£
µÚÒ»²¿·Ö£º´úÂëʵÏÖ
1£©Ä¿±ê½ø³ÌÒÀÀµµÄsoÎļþinso.hºÍinso.c
__attribute__ ((visibility ("default"))) void setA(int i); __attribute__ ((visibility ("default"))) int getA(); |
inso.c´úÂë
#include <stdio.h> #include "inso.h" static int gA = 1; void setA(int i){ gA = i; } int getA(){ return gA; } |
±àÒë³ÉsoÎļþ¼´¿É£¬ÏîÄ¿ÏÂÔØ£ºhttp://download.csdn.net/detail/jiangwei0910410003/8138107
2£©Ä¿±ê½ø³ÌµÄ¿ÉÖ´ÐÐÎļþdemo1.c
Õâ¸ö¾Í¼òµ¥ÁË£¬¾ÍÊǷdz£¼òµ¥µÄ´úÂ룬ÆðÒ»¸öÑ»·Ã¿¸öÒ»¶Îʱ¼ä´òÓ¡ÊýÖµ£¬Õâ¸öÏîÄ¿ÐèÒªÒýÓÃÉÏÃæ±àÒëµÄinso.soÎļþ
Í·Îļþinso.h(ºÍÉÏÃæµÄÍ·ÎļþÊÇÒ»ÑùµÄ)
__attribute__ ((visibility ("default"))) void setA(int i); __attribute__ ((visibility ("default"))) int getA(); |
demo1.cÎļþ
#include <stdio.h> #include <unistd.h> #include "inso.h" #include "log.h" int main(){ LOGI("DEMO1 start."); while(1){ LOGI("%d", getA()); setA(getA() + 1); sleep(2); } return 0; } |
´úÂë¼òµ¥°É£¬¾ÍÊÇÖ´ÐÐÑ»·´òÓ¡ÊýÖµ£¬ÕâÀïʹÓõÄÊǵײãµÄlog·½·¨£¬ÔÚlog.hÎļþÖж¨ÒåÁË£¬Æª·ùÔÒò¡£
3£©×¢ÈëµÄÄ£¿é¹¦ÄÜÔ´Îļþmyso.c
#include <stdio.h> #include <stddef.h> #include <dlfcn.h> #include <pthread.h> #include <stddef.h> #include "log.h" __attribute__ ((__constructor__)) void Main() { LOGI(">>>>>>>>>>>>>Inject Success!!!!<<<<<<<<<<<<<<"); void (*setA_func)(int); void* handle = dlopen("libinso.so", RTLD_NOW); LOGI("Handle:%p",handle); //void (*setA_func)(int) = (void (*)(int))dlsym(handle, "setA"); setA_func = (void (*)(int))dlsym(handle,"setA"); LOGI("Func:%p",setA_func); if (setA_func) { LOGI("setA is Executing!!!"); (*setA_func)(999); } dlclose(handle); } |
˵Ã÷£º
Õâ¶Î´úÂëÐèÒª½âÊÍһϣ¬Ê×ÏÈÀ´¿´Ò»Ï£º
__attribute__ ((__constructor__)) |
gccΪº¯ÊýÌṩÁ˼¸ÖÖÀàÐ͵ÄÊôÐÔ£¬ÆäÖаüº¬£º¹¹Ô캯Êý(constructors)ºÍÎö¹¹º¯Êý(destructors)¡£
³ÌÐòÔ±Ó¦µ±Ê¹ÓÃÀàËÆÏÂÃæµÄ·½Ê½À´Ö¸¶¨ÕâЩÊôÐÔ£º
static void start(void) __attribute__ ((constructor)); static void stop(void) __attribute__ ((destructor)); |
´øÓÐ"¹¹Ô캯Êý"ÊôÐԵĺ¯Êý½«ÔÚmain()º¯Êý֮ǰ±»Ö´ÐУ¬¶øÉùÃ÷Ϊ"Îö¹¹º¯Êý"ÊôÐԵĺ¯ÊýÔò½«ÔÚmain()Í˳öʱִÐС£
Ó÷¨¾ÙÀý£º
#include <iostream> void breforemain() __attribute__((constructor)); void aftermain() __attribute__((destructor)); class AAA{ public: AAA(){std::cout << "before main function AAA" << std::endl;} ~AAA(){std::cout << "after main function AAA" << std::endl;} }; AAA aaa; void breforemain() { std::cout << "before main function" << std::endl; } void aftermain() { std::cout << "after main function" << std::endl; } int main(int argc,char** argv) { std::cout << "in main function" << std::endl; return 0; } |
Êä³ö½á¹û£º
before main function AAA before main function in main function after main function AAA after main function |
ÓеãÀàËÆÓÚSpringµÄAOP±à³Ì~~
»¹ÓÐÒ»¸ö¾ÍÊÇÎÒÃÇ¿ªÊ¼ËµµÄ£¬ÈçºÎ¼ÓÔØsoÎļþ£¬²¢ÇÒÖ´ÐÐÆäÖеĺ¯Êý£¬ÔÀíºÜ¼òµ¥£¬¾ÍÊÇ´ò¿ªsoÎļþ£¬È»ºó·µ»ØÒ»¸öº¯ÊýÖ¸Õë¡£
ÐèÒªµÄÍ·Îļþ£º#include <dlfcn.h>
ºËÐÄ´úÂ룺
´ò¿ªsoÎļþ£¬·µ»ØÒ»¸ö¾ä±úhandle:
void* handle = dlopen("libinso.so", RTLD_NOW); |
µÃµ½Ö¸¶¨µÄº¯ÊýÖ¸Õ룺
setA_func = (void (*)(int))dlsym(handle,"setA"); |
º¯ÊýÖ¸ÕëµÄ¶¨Ò壺
¾ÍÊÇÕâô¼òµ¥£¬ÓеãÀàËÆJavaÖж¯Ì¬¼ÓÔØjar°ü£¬È»ºóÖ´ÐÐÆäÖеķ½·¨¡£
µÚ¶þ²¿·Ö£º¿½±´Îļþ
ºÃÁË£¬µ½ÕâÀïÀë³É¹¦²»Ô¶ÁË£¬ÎÒÃDZ£Ö¤ÉÏÃæµÄ¹¤³Ì±àÒë¶¼ÄÜͨ¹ý£¬µÃµ½ÒÔÏÂÎļþ£ºdemo1¡¢poison¡¢libmyso.so¡¢libinso.soÈ»ºóÎÒÃǾͿÉÒÔʵ¼ùÁË
Ê×ÏÈÎÒ½«ÕâЩÎļþ¿½±´µ½ÊÖ»úÖеÄ/data/data/Ŀ¼ÖÐ
adb push demo1 /data/data/
adb push poison /data/data/
adb push libmyso.so /data/data/ |
¿½±´ÍêÖ®ºó£¬»¹ÐèÒª½øÈëadb shell£¬ÐÞ¸ÄËûÃǵÄȨÏÞ
chmod 777 demo1
chmod 777 poison
chmod 777 libmyso.so |
ÕâÀïҪעÒâµÄÊÇ£¬libinso.soÎļþÒªµ¥¶À¿½±´µ½/system/libÖУ¬²»È»ÔÚÖ´ÐÐdemo1µÄʱºò£¬»á±¨´í(ÕÒ²»µ½libinso.so)£¬µ±È»ÔÚ¿½±´µÄʱºò»áÓöµ½Ò»µãÎÊÌâ
±¨´í£º"Failed to push selection: Read-only
file system"
ÕâʱºòÖ»Òª¸Ä±äsystemĿ¼µÄ¹ÒÔØ¶ÁдÊôÐԾͺÃÁË
mount -o remount rw /system/ |
È»ºó½øÈëadb shellÔÚÐÞ¸ÄÒ»ÏÂ/systemµÄÊôÐÔ
È»ºó¾Í¿ÉÒÔ¿½±´ÁË£º
adb push libinso.so /system/lib/ |
È»ºó½øÈëµ½system/libÖУ¬ÐÞ¸Älibinso.soµÄÊôÐÔ
µÚÈý²¿·Ö£º¿ªÊ¼Ö´ÐÐ
È»ºó½øÈëµ½data/dataĿ¼ÖУ¬¿ªÊ¼Ö´ÐÐÎļþ£¬ÕâʱºòÎÒÃÇÐèÒª¿ªÈý¸öÖÕ¶Ë£ºÒ»¸öÊǼàÌýlogÐÅÏ¢£¬Ò»¸öÊÇÖ´ÐÐdemo1£¬Ò»¸öÊÇÖ´ÐÐpoison,ÈçÏÂͼËùʾ£º
1¡¢¼àÌýlogÐÅÏ¢

2¡¢Ö´ÐÐdemo1

3¡¢Ö´ÐÐpoison
./poison /data/data/libmyso.so 1440 |

ÕâÀïÎÒÃÇ¿´µ½£¬Ö´ÐÐpoisonÓÐÁ½¸öÈë¿Ú²ÎÊý£ºÒ»¸öÊÇsoÎļþµÄ·¾¶£¬Ò»¸öÊÇÄ¿±ê½ø³Ì(demo1)µÄpid¾ÍÊÇlogÐÅÏ¢ÖеÄÏÔʾµÄpid
µ½ÕâÀïÎÒÃǾÍʵÏÖÁËÎÒÃǵĵÚÒ»¸öÀý×ÓÁË¡£
µÚ¶þ¸öÀý×Ó£º½«Ä¿±ê½ø³Ì¸Ä³ÉAndroidÓ¦ÓÃ
ÏÂÃæ¼ÌÐø£º½«Ä¿±ê½ø³Ì¸Ä±ä³ÉÒ»¸öAndroidÓ¦ÓÃ
ÕâÀïºÍÉϱߵÄÎ¨Ò»Çø±ð¾ÍÊÇÎÒÃÇÐèÒª½«demo1±ä³ÉÒ»¸öAndroidÓ¦ÓÃ
ÄÇôÀ´¿´Ò»ÏÂÕâ¸öAndroidÓ¦ÓõĴúÂ룺
package com.demo.host; import android.app.Activity; import android.content.Context; import android.os.Bundle; import android.util.Log; public final class MainActivity extends Activity { private static int sA = 1; public static void setA(int a) { sA = a; } public static int getA() { return sA; } @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); new Thread() { public void run() { while (true) { Log.i("TTT", "" + getA()); setA(getA() + 1); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } } }; }.start(); } } |
´úÂëºÍdemo1µÄ¹¦ÄÜÒ»ÑùµÄ£¬Ð´¸öÑ»·£¬´òÓ¡ÊýÖµ£¬¹¤³ÌÏÂÔØµØÖ·£ºhttp://download.csdn.net/detail/jiangwei0910410003/8138227
Õâ¸öÓ¦Óþͱä³ÉÁËÎÒÃÇ×¢ÈëµÄÄ¿±ê½ø³Ì£¬µ«ÊÇÓÐÒ»¸öÎÊÌ⣬ÎÒÃÇÔõô²ÅÄÜÐÞ¸ÄsetA()·½·¨µÄÐÐÎªÄØ£¿ÔÚµÚÒ»¸ö°¸ÀýÖУ¬ÎÒÃÇÊǶ¯Ì¬¼ÓÔØlibinso.so£¬È»ºó»ñÈ¡µ½setA()º¯Êý£¬ÐÞ¸ÄÆ÷·µ»ØÖµ¡£ÕâÀïÎÒÃÇÐèÒª×öµÄ¾ÍÊÇÔõô¶¯Ì¬µÄÈ¥ÐÞ¸ÄÉÏÃæµÄMainActivityÖеÄsetA()·½·¨µÄ·µ»ØÖµ£¬ÆäʵÕâÀï¾Íµ½ÁËÎÒ¿ªÊ¼ËµµÄµÚ¶þ¸ö֪ʶµã£ºÈçºÎÔڵײãCÖе÷ÓÃJava·½·¨£¿
ÎÒÃÇÖªµÀÔÚʹÓÃNDKµÄʱºò£¬Java²ãµ÷ÓõײãCµÄʱºòÁ¬½ÓµÄŦ´ø¾ÍÊÇÄǸöJNIEnv±äÁ¿£¬Õâ¸ö±äÁ¿ÊÇ×÷Ϊº¯Êý²ÎÊý´«µÝ¹ýÀ´µÄ¡£ÄÇôÈç¹ûÎÒÃÇÔڵײãCÖлñÈ¡µ½Õâ¸ö±äÁ¿µÄ»°£¬¾Í¿ÉÒÔµ÷ÓÃJava·½·¨ÁË£¬µ«ÊÇÕâÀïÎÒÃÇÓÖûÓж¨Òå±¾µØ·½·¨£¬ÔõôµÃµ½JNIEnv±äÁ¿ÄØ£¿
´ð°¸¾ÍÊÇ#include <android_runtime/AndroidRuntime.h>Õâ¸öÍ·Îļþ£¬µÃµ½JVM±äÁ¿Ö®ºó£¬È»ºóµÃµ½µ±Ç°Ï̵߳ÄJNIEnv±äÁ¿£º
JavaVM* jvm = AndroidRuntime::getJavaVM(); LOGI("jvm is %p",jvm); jvm->AttachCurrentThread(&jni_env, NULL); //TODO ʹÓÃJNIEnv jvm->DetachCurrentThread(); |
ͨ¹ýAndroidRuntimeÖеÄgetJavaVM·½·¨»ñÈ¡jvm±äÁ¿£¬È»ºóÔÚ»ñÈ¡µ±Ç°Ï̵߳ÄJNIEnv±äÁ¿¼´¿É
¹ØÓÚAndroidRuntimeÕâ¸öÀàµÄ¶¨ÒåºÍʵÏÖÊÇÔÚ AndroidRuntimeÔ´ÂëĿ¼/jni/AndroidRuntime.cppÖÐ
ºÃÁË£¬µ±ÎÒÃÇÄõ½JNIEnv±äÁ¿Ö®ºó£¬ÎÒÃǾͿÉÒԸɺܶàÊÂÁË£¬ÒòΪÎÒÃÇÖªµÀÔÚŪNDKµÄʱºò£¬Èç¹ûʹÓÃJNIEnv±äÁ¿µÄʱºò¶¼Çå³þ£¬ËûºÃ±ÈJavaÖеķ´Éä»úÖÆ£¬¿ÉÒÔ¶¯Ì¬µÄ¼ÓÔØJavaÖеÄÀ࣬Ȼºó»ñÈ¡Æä·½·¨£¬×ֶεÈÐÅÏ¢£¬½øÐвÙ×÷¡£
µ«ÊÇÏÖÔÚ»¹ÓÐÒ»¸öÎÊÌ⣬¾ÍÊÇÎÒÃÇÔõôȥ¶¯Ì¬¼ÓÔØMainActivityÕâ¸öÀàÄØ£¿
µ«Êǵ±ÎÒÃdz¢ÊÔʹÓÃPathClassLoaderÈ¥¼ÓÔØMainActivityʱ£¬»áÅ×ClassNotFoundException
Ψһ¿ÉÐеķ½°¸ÊÇÕÒµ½host(Ä¿±êÓ¦ÓÃ)µÄPathClassLoader£¬È»ºóͨ¹ýÕâ¸öClassLoaderѰÕÒMainActivity
ÒòΪÎÒÃÇÊÇ×¢Èëµ½MainActivityÕâ¸öÓ¦ÓõĽø³ÌÖУ¬ÄÇôÎÒÃǵÄ×¢Èë´úÂëºÍMainActivityÊÇÔÚÒ»¸ö½ø³ÌÖеģ¬ÓÖÒòΪAndroidÖÐÒ»¸ö½ø³Ì¶ÔÓ¦Ò»¸öÈ«¾ÖContext¶ÔÏó£¬ËùÒÔÎÒÃÇÖ»ÒªµÃµ½Õâ¸ö½ø³ÌContext¶ÔÏóµÄÀà¼ÓÔØÆ÷¾Í¿ÉÒÔÁË
(ÆäʵAndroidÖжà¸öÓ¦ÓÃÊÇ¿ÉÒÔÅÜÔÚÒ»¸ö½ø³ÌÖеģ¬ËûÃÇ»áÓµÓÐÒ»¹²Í¬µÄÈ«¾ÖContext±äÁ¿£¬µ±È»Õâ¸öContext²»ÊÇÌØ¶¨µÄActivityµÄ£¬¶øÊÇApplication¶ÔÏó³ÖÓеÄContext)
ÒªÏëµÃµ½Ò»¸ö½ø³ÌÖеÄContext¶ÔÏó¡£Í¨¹ýÔĶÁÔ´Â룬·¢ÏÖ¿ÉÒÔͨ¹ýÏÂÃæµÄ·½Ê½¶ÁÈ¡µ½Context¶ÔÏó£º
Èç¹ûÊÇSystem_Process£¬¿ÉÒÔͨ¹ýÈçÏ·½Ê½»ñÈ¡
Context context = ActivityThread.mSystemContext |
Èç¹ûÊÇ·ÇSystem_Process£¨¼´ÆÕͨµÄAndroid½ø³Ì£©£¬¿ÉÒÔͨ¹ýÈçÏ·½Ê½»ñÈ¡
Context context = ((ApplicationThread)RuntimeInit.getApplicationObject()).app_obj.this$0 |
µ½ÕâÀÎÒÃǶ¼ÖªµÀ¸ÃÔõô°ìÁË£¬Ã»´í¾ÍÊÇÓ÷´Éä»úÖÆ£¬»ñÈ¡µ½È«¾ÖµÄContext±äÁ¿
ÉÏÃæµÄ˼·ÊÇÓÐÁË£¬ÏÂÃæÔÚÀ´ÕûÀíһϰɣº
Ê×ÏÈÎÒÃÇÐèҪעÈëµ½MainActivityËùÔڵĽø³Ì£¬È»ºóÐÞ¸ÄËûµÄsetA()·½·¨¡£
µ«ÊÇÎÒÃÇ×¢ÈëµÄʱºòÊǰÑsoÎļþ×¢Èëµ½Ò»¸ö½ø³ÌÖУ¬ËùÒÔÐèÒªÔڵײãÐÞ¸ÄsetA()·½·¨µÄÖ´ÐÐ
Èç¹ûµ×²ãÏëÐÞ¸Ä/Ö´ÐÐJava²ã·½·¨µÄ»°£¬±ØÐëÒªµÃµ½JNIEnv±äÁ¿
È»ºó¿ÉÒÔͨ¹ýAndroidRuntimeÀàÏȵõ½jvm±äÁ¿£¬È»ºóÔÚͨ¹ýjvm±äÁ¿µÃµ½JNIEnv±äÁ¿
µÃµ½JNIEnv±äÁ¿Ö®ºó£¬ÓÃJNIEnvµÄһЩ·½·¨È¥¶¯Ì¬¼ÓÔØMainActivityÀ࣬ȻºóÐÞ¸ÄËûµÄ·½·¨£¬µ«ÊÇ»á³öÏÖÒì³£ÕÒ²»µ½MainActivityÀà
ÕÒ²»µ½Õâ¸öÀàµÄÔÒòÊÇÀà¼ÓÔØÆ÷ÕҵIJ»¶Ô£¬ÎÒÃÇÐèÒªÕÒµ½È«¾ÖµÄContext¶ÔÏóµÄÀà¼ÓÔØÆ÷£¬ÒòΪÎÒÃÇÊÇ×¢Èëµ½ÁËMainActivityÕâ¸öÓ¦ÓõĽø³ÌÖУ¬Ò»¸ö½ø³ÌÓÐÒ»¸öÈ«¾ÖµÄContext¶ÔÏó£¬ËùÒÔÖ»ÒªµÃµ½ËüµÄÀà¼ÓÔØÆ÷¾Í¿ÉÒÔÁË¡£
È»ºóͨ¹ý²é¿´Ô´Â룬ÎÒÃÇ¿ÉÒÔÔÚJava²ãͨ¹ý·´Éä»ñÈ¡µ½Õâ¸ö¶ÔÏó¡£
×îºó£ºÍ¨¹ýÉÏÃæµÄ·ÖÎö£¬ÎÒÃÇ»¹ÐèҪһЩÏîÄ¿µÄÖ§³Ö£º
1¡¢µ×²ã»ñÈ¡JNIEnv¶ÔÏóµÄÏîÄ¿£¬Ò²¾ÍÊÇÎÒÃÇÐèҪעÈëµÄso¡£
2¡¢ÔÚÉϲ㻹ÐèÒªÒ»¸öÄ£¿é£¬È¥»ñÈ¡µ½È«¾ÖµÄContext¶ÔÏó£¬È»ºó¶¯Ì¬µÄ¼ÓÔØMainActivityÀ࣬ÐÞ¸ÄËûµÄ·½·¨¡£
|