找回密码
 立即注册→加入我们

QQ登录

只需一步,快速开始

搜索
热搜: 下载 VB C 实现 编写
查看: 3419|回复: 0

动态注入并执行android代码到进程

[复制链接]
发表于 2016-6-3 16:07:47 | 显示全部楼层 |阅读模式

欢迎访问技术宅的结界,请注册或者登录吧。

您需要 登录 才可以下载或查看,没有账号?立即注册→加入我们

×
网上可以见到很多帖子是如何注入进程并钩取c层api的例子,而动态的让目标进程加载一个dex并执行这个dex却没看到

c层的注入很简单,可以参考adbi,ptrace进去修改当前指令指针寄存器,构造一个dlopen的指令并调用,类似于win上getcontext修改eip

java层稍复杂一些,加载dex->解析dex->查找目标类->调用函数,下面是测试用例,我们的目标是打log

  1. import android.util.Log;
  2. public class injectjava {
  3.     static void initialize(){
  4.         Log.i("INJECTJAVA","injectava called");
  5.     }
  6. }
复制代码


执行注入的代码:


  1. #define LOGI(...)  __android_log_print(ANDROID_LOG_ERROR, "INJECTJAVA", __VA_ARGS__)
  2. #define DEXNAME "/data/local/tmp/inject.dex"


  3. typedef void Object;
  4. typedef void ClassObject;
  5. typedef void Thread;
  6. typedef uint8_t u1;
  7. typedef uint32_t u4;
  8. struct JNIEnvExt
  9. {
  10.     const struct JNINativeInterface* funcTable;
  11.     const struct JNINativeInterface* baseFuncTable;
  12.     u4      envThreadId;
  13.     Thread* self;
  14. };

  15. typedef void DexOptHeader;
  16. typedef void DexStringId;
  17. typedef void DexTypeId;
  18. typedef void DexFieldId;
  19. typedef void DexMethodId;
  20. typedef void DexProtoId;
  21. typedef void DexLink;
  22. typedef void DexClassLookup;

  23. struct DexHeader
  24. {
  25.     u1  magic[8];           /* includes version number */
  26.     u4  checksum;           /* adler32 checksum */
  27.     u1  signature[20];       /* SHA-1 hash */
  28.     u4  fileSize;           /* length of entire file */
  29.     u4  headerSize;         /* offset to start of next section */
  30.     u4  endianTag;
  31.     u4  linkSize;
  32.     u4  linkOff;
  33.     u4  mapOff;
  34.     u4  stringIdsSize;
  35.     u4  stringIdsOff;
  36.     u4  typeIdsSize;
  37.     u4  typeIdsOff;
  38.     u4  protoIdsSize;
  39.     u4  protoIdsOff;
  40.     u4  fieldIdsSize;
  41.     u4  fieldIdsOff;
  42.     u4  methodIdsSize;
  43.     u4  methodIdsOff;
  44.     u4  classDefsSize;
  45.     u4  classDefsOff;
  46.     u4  dataSize;
  47.     u4  dataOff;
  48. };

  49. struct DexClassDef
  50. {
  51.     u4  classIdx;           /* index into typeIds for this class */
  52.     u4  accessFlags;
  53.     u4  superclassIdx;      /* index into typeIds for superclass */
  54.     u4  interfacesOff;      /* file offset to DexTypeList */
  55.     u4  sourceFileIdx;      /* index into stringIds for source file name */
  56.     u4  annotationsOff;     /* file offset to annotations_directory_item */
  57.     u4  classDataOff;       /* file offset to class_data_item */
  58.     u4  staticValuesOff;    /* file offset to DexEncodedArray */
  59. };

  60. struct DexFile
  61. {
  62.     DexOptHeader *pOptHeader;
  63.     DexHeader *pHeader;
  64.     DexStringId *pStringIds;
  65.     DexTypeId *pTypeIds;
  66.     DexFieldId *pFieldIds;
  67.     DexMethodId *pMethodIds;
  68.     DexProtoId *pProtoIds;
  69.     DexClassDef *pClassDefs;
  70.     DexLink *pLinkData;
  71.     DexClassLookup *pClassLookup;
  72. };

  73. struct DvmDex
  74. {
  75.     DexFile*            pDexFile;
  76. };

  77. int (*dvmDexFileOpenPartial)(const void* addr, int len, DvmDex** ppDvmDex)=0;
  78. int (*dexSwapAndVerify)(void* addr, int len)=0;
  79. JNIEnv* (*dvmGetJNIEnvForThread)()=0;
  80. Object* (*dvmDecodeIndirectRef)(JNIEnv* env, jobject jobj)=0;
  81. Object* (*dvmDecodeIndirectRef_)(Thread* self, jobject jobj)=0;
  82. ClassObject* (*dvmDefineClass)(DvmDex* pDvmDex, const char* descriptor, Object* classLoader)=0;
  83. DexClassLookup* (*dexCreateClassLookup)(DexFile* pDexFile)=0;

  84. void inject()
  85. {
  86.     /*
  87.      * C层hook
  88.      */



  89.     /*
  90.      * JAVA层hook
  91.      */
  92.     //获取关键函数指针

  93.     do
  94.     {
  95.         void* hdvm = dlopen("libdvm.so", RTLD_LAZY | RTLD_GLOBAL);
  96.         if(!hdvm)
  97.         {
  98.             LOGI("libdvm not exist!");
  99.             break;
  100.         }
  101.         dvmDexFileOpenPartial = (typeof(dvmDexFileOpenPartial))dlsym(hdvm, "dvmDexFileOpenPartial");
  102.         if(!dvmDexFileOpenPartial)
  103.         {
  104.             dvmDexFileOpenPartial = (typeof(dvmDexFileOpenPartial))dlsym(hdvm, "_Z21dvmDexFileOpenPartialPKviPP6DvmDex");
  105.             if(!dvmDexFileOpenPartial)
  106.                 LOGI("dvmDexFileOpenPartial not exist!");
  107.         }
  108.         dexSwapAndVerify = (typeof(dexSwapAndVerify))dlsym(hdvm, "dexSwapAndVerify");
  109.         if(!dexSwapAndVerify)
  110.         {
  111.             dexSwapAndVerify = (typeof(dexSwapAndVerify))dlsym(hdvm, "_Z16dexSwapAndVerifyPhi");
  112.             if(!dexSwapAndVerify)
  113.                 LOGI("dexSwapAndVerify not exist!");
  114.         }
  115.         dvmGetJNIEnvForThread = (typeof(dvmGetJNIEnvForThread))dlsym(hdvm, "dvmGetJNIEnvForThread");
  116.         if(!dvmGetJNIEnvForThread)
  117.         {
  118.             dvmGetJNIEnvForThread = (typeof(dvmGetJNIEnvForThread))dlsym(hdvm, "_Z21dvmGetJNIEnvForThreadv");
  119.             if(!dvmGetJNIEnvForThread)
  120.                 LOGI("dvmGetJNIEnvForThread not exist!");
  121.         }
  122.         dvmDecodeIndirectRef = (typeof(dvmDecodeIndirectRef))dlsym(hdvm, "dvmDecodeIndirectRef");
  123.         if(!dvmDecodeIndirectRef)
  124.         {
  125.             dvmDecodeIndirectRef = (typeof(dvmDecodeIndirectRef))dlsym(hdvm, "_Z20dvmDecodeIndirectRefP7_JNIEnvP8_jobject");
  126.             if(!dvmDecodeIndirectRef)
  127.             {
  128.                 dvmDecodeIndirectRef_ = (typeof(dvmDecodeIndirectRef_))dlsym(hdvm, "_Z20dvmDecodeIndirectRefP6ThreadP8_jobject");
  129.                 if(!dvmDecodeIndirectRef_)
  130.                     LOGI("dvmDecodeIndirectRef_ not exist!");
  131.             }
  132.         }

  133.         dvmDefineClass = (typeof(dvmDefineClass))dlsym(hdvm, "dvmDefineClass");
  134.         if(!dvmDefineClass)
  135.         {
  136.             dvmDefineClass = (typeof(dvmDefineClass))dlsym(hdvm, "_Z14dvmDefineClassP6DvmDexPKcP6Object");
  137.             if(!dvmDefineClass)
  138.                 LOGI("dvmDefineClass not exist!");
  139.         }

  140.         dexCreateClassLookup = (typeof(dexCreateClassLookup))dlsym(hdvm, "dexCreateClassLookup");
  141.         if(!dexCreateClassLookup)
  142.         {
  143.             dexCreateClassLookup = (typeof(dexCreateClassLookup))dlsym(hdvm, "_Z20dexCreateClassLookupP7DexFile");
  144.             if(!dexCreateClassLookup)
  145.                 LOGI("dexCreateClassLookup not exist!");
  146.         }

  147.         if(!dvmDexFileOpenPartial || !dexSwapAndVerify || !dvmGetJNIEnvForThread || !dvmDefineClass || !dexCreateClassLookup || (!dvmDecodeIndirectRef && !dvmDecodeIndirectRef_))
  148.             break;
  149.         LOGI("InitOk");


  150.         //读取dex以便动态加载
  151.         char* dexdata = 0;
  152.         int dexlen;
  153.         int dexfd = open(DEXNAME, O_RDONLY);
  154.         if(dexfd == -1)
  155.         {
  156.             LOGI("can't open inject.dex!");
  157.             break;
  158.         }

  159.         struct stat st = {0};
  160.         fstat(dexfd , &st);
  161.         if(st.st_size)
  162.         {
  163.             dexlen = st.st_size;
  164.             dexdata = (char*)malloc(st.st_size);
  165.             if(dexdata)
  166.                 read(dexfd, dexdata, st.st_size);
  167.         }

  168.         close(dexfd);

  169.         if(!dexdata)
  170.         {
  171.             LOGI("read inject.dex fail!");
  172.             break;
  173.         }

  174.         int result;
  175.         DvmDex* dvmDex = 0;
  176.         JNIEnv* env =0;
  177.         jclass java_lang_Class =0;
  178.         jmethodID java_lang_Class_forName =0;
  179.         jclass java_lang_ClassLoader =0;
  180.         jmethodID java_lang_ClassLoader_getSystemClassLoader =0;
  181.         jobject jSystemClassLoader =0;
  182.         Object* SystemClassLoader =0;
  183.         jstring com_injectjava_str =0;
  184.         jclass com_injectjava =0;
  185.         jmethodID com_injectjava_initialize =0;


  186.         DexFile* pDexFile = 0;
  187.         int csize,i;

  188.         dexSwapAndVerify(dexdata, dexlen);
  189.         result = dvmDexFileOpenPartial(dexdata, dexlen, &dvmDex);
  190.         if(result != 0)
  191.         {
  192.             LOGI("dvmDexFileOpenPartial fail!");
  193.             goto END1;
  194.         }

  195.         env = dvmGetJNIEnvForThread();
  196.         if(!env)
  197.         {
  198.             LOGI("dvmGetJNIEnvForThread fail!");
  199.             goto END1;
  200.         }

  201.         java_lang_Class = env->FindClass("java/lang/Class");
  202.         if(!java_lang_Class)
  203.         {
  204.             LOGI("java_lang_Class null!");
  205.             goto END1;
  206.         }
  207.         java_lang_Class_forName = env->GetStaticMethodID(java_lang_Class, "forName", "(Ljava/lang/String;ZLjava/lang/ClassLoader;)Ljava/lang/Class;");
  208.         if(!java_lang_Class_forName)
  209.         {
  210.             LOGI("java_lang_Class_forName null!");
  211.             goto END1;
  212.         }
  213.         java_lang_ClassLoader = env->FindClass("java/lang/ClassLoader");
  214.         if(!java_lang_ClassLoader)
  215.         {
  216.             LOGI("java_lang_ClassLoader null!");
  217.             goto END1;
  218.         }
  219.         java_lang_ClassLoader_getSystemClassLoader = env->GetStaticMethodID(java_lang_ClassLoader, "getSystemClassLoader", "()Ljava/lang/ClassLoader;");
  220.         if(!java_lang_ClassLoader_getSystemClassLoader)
  221.         {
  222.             LOGI("java_lang_ClassLoader_getSystemClassLoader null!");
  223.             goto END1;
  224.         }
  225.         jSystemClassLoader = env->CallStaticObjectMethod(java_lang_ClassLoader, java_lang_ClassLoader_getSystemClassLoader, "()Ljava/lang/ClassLoader;");
  226.         if(!jSystemClassLoader)
  227.         {
  228.             LOGI("jSystemClassLoader null!");
  229.             goto END1;
  230.         }


  231.         LOGI("InitOk1");

  232.         if(dvmDecodeIndirectRef)
  233.             SystemClassLoader = dvmDecodeIndirectRef(env, jSystemClassLoader);
  234.         else
  235.             SystemClassLoader = dvmDecodeIndirectRef_(((JNIEnvExt*)env)->self, jSystemClassLoader);

  236.         if(!SystemClassLoader)
  237.         {
  238.             LOGI("SystemClassLoader null!");
  239.             goto END1;
  240.         }

  241.         pDexFile = dvmDex->pDexFile;
  242.         pDexFile->pClassLookup = dexCreateClassLookup(dvmDex->pDexFile);
  243.         csize = pDexFile->pHeader->classDefsSize;
  244.         for(i=0;i<csize;i++)
  245.         {
  246.             pDexFile->pClassDefs[i].accessFlags | 0x10000;
  247.         }

  248.         dvmDefineClass(dvmDex, "Lcom/injectjava;", SystemClassLoader);
  249.         com_injectjava_str = env->NewStringUTF("com.injectjava");
  250.         if(!com_injectjava_str)
  251.         {
  252.             LOGI("com_injectjava null!");
  253.             goto END1;
  254.         }
  255.         com_injectjava = (jclass)env->CallStaticObjectMethod(java_lang_Class, java_lang_Class_forName, com_injectjava_str, true, jSystemClassLoader);
  256.         if(!com_injectjava)
  257.         {
  258.             LOGI("com_injectjava null!");
  259.             goto END1;
  260.         }
  261.         com_injectjava_initialize = env->GetStaticMethodID(com_injectjava, "initialize", "()V");
  262.         if(!com_injectjava_initialize)
  263.         {
  264.             LOGI("com_injectjava_initialize null!");
  265.             goto END1;
  266.         }
  267.         env->CallStaticVoidMethod(com_injectjava, com_injectjava_initialize);


  268.         LOGI("InitOk2");
  269.         END1:
  270.         free(dexdata);
  271.     }
  272.     while(false);
  273. }
复制代码


将要执行的dex放到/data/local/tmp/inject.dex即可
06-03 15:47:34.984 16197-16197/com.example.hellojni E/INJECTJAVA: InitOk
06-03 15:47:35.074 16197-16197/com.example.hellojni E/INJECTJAVA: InitOk1
06-03 15:54:08.304 16197-16197/com.example.hellojni I/INJECTJAVA: injectava called
回复

使用道具 举报

本版积分规则

QQ|Archiver|小黑屋|技术宅的结界 ( 滇ICP备16008837号 )|网站地图

GMT+8, 2024-11-21 20:28 , Processed in 0.035865 second(s), 25 queries , Gzip On.

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表