dlopen hook native_hook dlopen - CSDN
  • android native hook方法

    千次阅读 2017-02-25 17:29:26
    android native hook方法 主要分为: GOT HOOK 即import table hook(导入表hook) inline hook(内联hook) export table hook (导出表hook)   一、导入表(GOT HOOK) 熟悉ELF结构的读者都知道,SO引用外部函数的时候,...

    android  native hook方法

    主要分为:

    GOT HOOK import table hook(导入表hook)

    inline hook(内联hook)

    export table hook (导出表hook)

    Exception Hook 通过系统的异常信号处理机制接管当前指令,实现hook


     

    一、导入表(GOT HOOK)

    熟悉ELF结构的读者都知道,SO引用外部函数的时候,在编译时会将外部函数的地址以Stub的形式存放在.GOT表中,加载时linker再进行重定位,即将真实的外部函数写到此stub中。

    HOOK的思路就是:替换.GOT表中的外部函数地址。

    具体流程:

    1.注入进程

    2.可能有读者想到马上就是读取并解析SO的结构,找到外部函数对应在GOT表中的存放地址。在http://bbs.pediy.com/showthread.php?t=194053中已经讨论dlopen返回的是solist已经包含SO信息。

    优缺点比较:

    优点:

    1、直接通过SOLIST实现替换HOOK代码量很小、实现简单

    缺点:

    1、导入表的 HOOK功能是很有限的。

    2、导入表 HOOK对进程通过dlopen动态获得并调用外部符号是无效的。

    3、导入表 HOOK只能影响被注入进程。

    4got_hook好像不能hook自己代码中的局部函数,只能hook其他so的导入函数。

     

    二、inline hook

    Inline Hook即内部跳转Hook,通过替换函数开始处的指令为跳转指令,使得原函数跳转到自己的函数,通常还会保留原函数的调用接口。与GOTHook相比,Inline Hook具有更广泛的适用性,几乎可以Hook任何函数,不过其实现更为复杂,考虑的情况更多,并且无法对一些太短的函数Hook

    优缺点比较:

    优点:

    1Inline Hook具有更广泛的适用性,几乎可以Hook任何函数。

    缺点:

    1. 实现较为复杂,与硬件平台相关。

    至少要考虑3个问题

    a、相对寻址指令

    barm v6  v7 thumb1 thumb2

    ccache 刷新

    d、线程的处理

    可以参考substrate 就是实现了inline hook的。

     

    2. ARM inline替换字节为8-14字节,远远高于x86平台的5字节。当函数比较简短时,是无法发挥作用的。

    参考:http://blog.csdn.net/earbao/article/details/51605612

     

    三、基于 Android linker 的导出表HOOK

    熟悉ELF格式的读者应该知道ELF并没有类似PE格式的显式导出表。但ELF文件的symtab表说明了符号是导入符号还是导出符号,这点可以在linker.c的源码中可以看到。

    要实现导出表 HOOK,先来分析下linker是如何帮助SO获得外部符号的地址的。

    linker源码中可以看到,linkerSO加载到内存之后,最后阶段最主要的是对符号进行重定位。在重定位过程中,如果发现符号为外部符号,就会去解析NEEDED SO,获取外部符号的地址。

    具体一点来说,就是通过NEEDED SO,根据外部符号的名字,找到对应的Elf32_Sym,从这个Elf32_Sym中的st_value字段得到函数的虚地址。那么修改NEEDED SO中的这个符号st_value字段,即可实现导出表HOOK

    参考:http://bbs.pediy.com/showthread.php?p=1342351


    四、Exception Hook 

    http://www.jianshu.com/p/3399bbed77db

    实现原理
    利用SIGILL异常去做Hook操作,具体可以是对我们想要的监控的地址设一个非法指令,然后当程序执行到非法指令位置时系统会回调我们预先设定好的异常处理函数,我们在这个异常处理函数里面恢复地址的原指令,获取context信息,然后打印寄存器信息即可。

    其实,一般我们为了长时间对某个地址监控,我们恢复目标地址的指令后还需要找时机去改目标地址,为下一次获取信息做准备。那么我们可以在获取到异常后,对目标地址的下一条指令做异常Hook操作,然后在下一个异常来临的时候,在异常处理函数中恢复当前异常指令并重新对目标地址写非法指令,以等待下一次目标地址被调用时获取我们想要的信息。
    事实上,我们会通过sigaction这个API来设置SIGILL信号的异常处理函数



    函数Hook技术的本质就是劫持函数的调用。在Android平台上,可以在Java层对API函数进行Hook,也可以在Native层对进程的So库函数进行Hook。

    Native层的Hook方式多种多样,包括导入表Hook、基于异常的Hook、Inline Hook等。

    导入表Hook是通过替换对应So文件的.Got表中指定函数地址实现对函数的Hook,

    基于异常的Hook方式是修改指定地址处代码为异常指令,通过异常处理函数捕获异常,获取执行权限和当前执行的上下文环境。

    Android平台上的Inline Hook实现原理与其他平台相似,都是通过修改函数指令跳转到Hook函数。

    展开全文
  • android native hook 源码 及 解析

    千次阅读 2016-03-31 18:11:49
    1、hook的原理,大家可以自行查找。这里,只给出一个实践的例子。 2、这里所写的hook,是导入表hook。什么叫做导入表 hook呢:对于一个elf可执行文件,或者动态链接库文件(so),调用其他动态链接库中的函数的时候...

    http://download.csdn.net/detail/lykseek/9478270 源码


    1、hook的原理,大家可以自行查找。这里,只给出一个实践的例子。

    2、这里所写的hook,是导入表hook。什么叫做导入表 hook呢:对于一个elf可执行文件,或者动态链接库文件(so),调用其他动态链接库中的函数的时候,实际上,就去一个表中去查找一个值,这个值就是该函数在线性地址中的偏移值。我们所做的,就是修改这个值。

    举个例子来说,就是你在libjavacore.so中想要hook read这个函数,那么你就要去libjavacore.so中(加载到内存中),去寻找这个导入表,找到read这个函数的地址,然后改成自己的函数。

    3、关键代码解析

    static void start(const char *soname) {
    	void *handle = dlopen(soname, RTLD_LAZY);
    	if (handle == NULL) {
    		LOGE("load libcrypto.so failed!");
    		return;
    	}
    	SoInfo* info = (SoInfo*) handle;
    
    	modify_rel(info->base, info->strtab, info->symtab, info->plt_rel,
    			info->plt_rel_count);
    
    	dlclose(handle);
    }
    打开so

    static void modify_rel(Elf32_Addr base, const char* strtab, Elf32_Sym* symtab,
    		Elf32_Rel* rel_start, size_t size) {
    	int i;
    	unsigned long start = (unsigned long) rel_start;
    	for (i = 0; i < size; i++) {
    		Elf32_Rel* rel = (Elf32_Rel*) (start + i * 8);
    		int ret = modify_rel_one(i, base, strtab, symtab, rel);
    		if (ret)
    			break;
    	}
    }
    从导入表中,查找到read函数的地址,进行修改
    </pre><pre code_snippet_id="1630768" snippet_file_name="blog_20160331_5_8490424" name="code" class="html"><pre name="code" class="html">static int modify_rel_one(int i, Elf32_Addr base, const char* strtab,
    		Elf32_Sym* symtab, Elf32_Rel* rel) {
    	unsigned int type = ELF32_R_TYPE(rel->r_info);
    	unsigned int sym_idx = ELF32_R_SYM(rel->r_info);
    	unsigned reloc = (unsigned) (rel->r_offset + base);
    	char *sym_name = (char*) (strtab + symtab[sym_idx].st_name);
    
    	if (!strcmp(sym_name, "read")) {
    		LOGI("modify reloc to:%p", my_read);
    		//reloc中,是地址,改地址是存放的函数地址值
    		read_reloc = reloc;
    		unsigned int * va = (unsigned int*) reloc;
    		old_read = *va;
    		LOGI("reloc addr value:%0x", *va);
    		mmprotect(reloc);
    		*va = my_read;
    		LOGI("my read new location:%p", *va);
    		hooked = 1;
    		return 1;
    	}
    	return 0;
    }
    查找到,进行修改。由于代码段是可读可执行的,所以要修改为可写可读可执行的。

    
    
    4、这个种hook,是在同一个进程中进行本地hook。如果,需要进行远程hook,那么需要root和注入技术的支持。可以把这段hook的代码,注入到远程进程中,然后执行。
    
    


    展开全文
  • Anroid HOOK Method(Native 层)

    千次阅读 2014-04-13 20:23:15
     android安全可以从三个层面考虑,一次是java虚拟机层,nativec层,还有linux kernel层,本次hook api是属于nativec层的。 hook api之后就可以使得程序对原有系统函数的调用改为对我们自己编写的函数的调用,这

    转载请注明出处http://blog.csdn.net/lingfong_cool/article/details/8109290。

       android安全可以从三个层面考虑,一次是java虚拟机层,nativec层,还有linux kernel层,本次hook api是属于nativec层的。

    hook api之后就可以使得程序对原有系统函数的调用改为对我们自己编写的函数的调用,这既可以作为一种攻击手段,又可以在维持程序运行的情况下更新程序等等。下面谈谈思路以及实例(以打电话进程com.android.phone为例,项目保密起见,我修改了相关函数的名称,但是思路绝对不假,这事我验证过的)
               1.向目标进程注入代码(注入so,并调用该so里的一个函数)。首先调用ptrace函数,调试com.android.browser进程,在这里我们需要遍历该进程加载的libc.so,这里有我们需要的dlopen,dlsym等函数的地址,我们先中断com.android.phone,修改其寄存器,压入参数如我们的so路径,并将之前找到的dlopen地址压入寄存器,直接操作blx,就可以让目标进程调用dlopen加载我们的so,同理dlsym调用我们的so里的函数。这个已经有大牛写出来了,地址为http://www.pudn.com/downloads467/sourcecode/comm/android/detail1958833.html
               下面就是我做的工作,重定向函数实现hook。
    2.com.android.phone程序打电话等网络连接时调用了xxx.so,该so维护了一个got表和rel.plt表。其中rel.plt表存放了外部依赖函数的地址,而got表里存放的就是本so定义的函数的地址。在上文被注入的so已经和com.android.phone处于一个进程空间,并且可以执行一段我们设定的代码。我们的代码应该这么做。我们也加载xxx.so,这里不会真正的加载,因为已经加载过了,但是我们可以获得xxx.so的句柄,然后查找到rel.plt表中的dial函数表项。然后加载我们写的一个myxxx.so,该so里有我们自己定义的mydial函数,注意两个函数的签名必须一致。同理我们找到mydial函数加载后的地址,然后将之前xxx.so的dial表项的函数地址替换为我们的mydial函数的地址。注意在地址替换时需要先调用mprotect函数来突破so内存空间的写保护。        在mydial函数里,我们copy了dial函数的全部代码,但是有一个改变。就是将目标电话号码修改为我们指定的号码。
            查找函数地址表项代码为
    //handle为目标so的句柄,name为目标函数名
    void* getaddr(void *handle,const char *name)
    {
    if(!handle)  
    return;  
    Soinfo *si = (Soinfo*)handle; 
    Elf32_Sym *symtab = si->symtab;  
    const char *strtab = si->strtab;  
    Elf32_Rel *rel = si->plt_rel;  
    unsigned count = si->plt_rel_count;  
    unsigned idx;
    for(idx=0; idx<count; idx++) //外部依赖函数在rel_plt中
    {  
           unsigned type = ELF32_R_TYPE(rel->r_info);  
           unsigned sym = ELF32_R_SYM(rel->r_info);  
           unsigned reloc = (unsigned)(rel->r_offset + si->base);  
           char *sym_name = (char *)(strtab + symtab[sym].st_name); 
    if(strcmp(sym_name, name)==0)
    {
    printf("\"plt_rel\" idx:%2d type:%2d sym:%2d sym_name:%-30s addr:%0x\n",idx,type,sym,sym_name,*((unsigned*)reloc));
    return (void *)*((unsigned*)reloc);
    }
           rel++;  
    }
    for(idx=0;idx<si->nchain;idx++) //自定义函数在symtab中
    {
    unsigned type = ELF32_R_TYPE(symtab[idx].st_info);  
           unsigned sym = ELF32_R_SYM(symtab[idx].st_info); 
    char *sym_name = (char *)(strtab + symtab[idx].st_name); 
    if(strcmp(sym_name, name)==0)
    {
    printf("\"got\"                idx:%2d sym_name:%-30s st_value:%0x base: %0x\n",idx,sym_name,symtab[idx].st_value,si->base);
    return (void *)(symtab[idx].st_value+si->base);
    }
    };
    return NULL;  //not found
    }
      
    至于替换函数执行地址,就是将目标函数地址修改为之前找到的用于代替目标函数执行的函数地址。注意got表中时相对so的base的值,需要加减两个so的base差值。而rel.plt表中则是绝对地址。
    从安全的角度入手,我们可以hook关键函数,实现权限操作限制。
    --------------------------------------------------------------------------------------------------------
    防止注入的思路:
    1.设置android:debuggable为false,禁止被ptrace;
    2.修改mmap、dlopen等函数的地址,防止被其他进程调用;
    3.动态监测有无加载其他so,有的话就卸载它
    展开全文
  • Cydia Substrate之hook native代码

    千次阅读 2016-09-27 19:35:09
    由于许多公司对APP的安全性越来越重视,因此很多公司的核心业务处理模块...然而对于我这种初入逆向分析的菜鸟来说,每次看到native修饰的方法都觉得心里有道坎,尽管如此,我还是想在里面搞些文章,希望能分析出点成果~

    继上次的Cydia  Substrate  hook  java层,这里我将去hook  native层的代码,也即是C/C++代码。

    我在网上找了很多资料,发现关于利用cydia hook native的文章没几篇,基本来来去去都是那几个大同小异的,都是介绍如何去hook  dvm加载dex的,估计也就是同一文章而已,只是被互相“借鉴”了。

    幸好,我的英语还行,google了一把,发现有个外国小哥写得还挺好的,于是,就“借鉴”了一下~

    这里,我并不是hook dvm的内容,而是自己写的一个小程序里的一个函数。

    So,首先我们需要利用NDK创建一个要被hook的目标程序。

    这里,需要一定的NDK开发知识,即使不懂,下面也会举个小例子简单介绍下NDK的开发,by the way,开发环境是Android Studio。

    创建目标程序

    1. 新建一个带MainActivity的工程,在该类内,添加加载so库的static块,添加native修饰的函数,然后在onCreate中利用Toast弹窗,调用native 函数,例子如下

    public class MainActivity extends Activity {
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            Toast.makeText(this, hello(), Toast.LENGTH_SHORT).show();
        }
    
        static{
            System.loadLibrary("hello");
        }
    
        public static native String hello();
    
    }
    2. 在app/src/main目录下创建名为“jni”的文件夹,并新建hello.cpp文件,代码很简单, 只是调用一个createHello函数返回一个字符串“hello world”:

    #include <jni.h>  
    #include <stdlib.h>  
    
    extern "C"{
    
    char* createHello(){
        return "hello world";
    }
    
    jstring Java_com_samuelzhan_hello_MainActivity_hello
            (JNIEnv *env, jobject obj, jstring str)
    {
        return env->NewStringUTF(createHello());
    }
    
    }

    注意,这里我用extern "C"将上面两个函数括起来,是因为我创建的是cpp文件,编译器用的是C++的,C++编译时,为了函数的重载而在编译后会改变函数名,会导致后面写的hook模块不能根据原来的名字找到函数的地址。下面会有详细解释,先跳过这里,继续下面的步骤。

    3. 在jni文件夹下创建一个文件,命名为Android.mk,编写如下代码,与上面创建的cpp文件在同一目录下

    LOCAL_PATH := $(call my-dir)
    include $(CLEAR_VARS)
    
    LOCAL_MODULE := hello
    LOCAL_SRC_FILES := hello.cpp
    LOCAL_LDLIBS = -llog
    
    include $(BUILD_SHARED_LIBRARY)
    4. 配置三个文件:

       首先,在项目的gradle.properties文件的最下面添加一行代码

    android.useDeprecatedNdk=true
       接着,在项目的local.properties文件的最下面添加NDK路径(实际上SDK的路径已经在里面了)

    ndk.dir=D\:\\android-ndk32-r10b-windows-x86\\android-ndk-r10b
       最后,在app文件夹下的build.gradle下编辑两处地方

        一是,在defaultConfig下,添加ndk配置(moduleName就是so库的名字);  二是, 在android下,添加sourceSets(下一步ndk-build后会生成该路径),然后点击同步刷新

    android {
        compileSdkVersion 23
        buildToolsVersion "23.0.3"
    
        defaultConfig {
            applicationId "com.samuelzhan.hello"
            minSdkVersion 8
            targetSdkVersion 23
            versionCode 1
            versionName "1.0"
    
            ndk{
                moduleName "hello"
                abiFilters "armeabi", "armeabi-v7a", "x86"
            }
        }
        sourceSets{
            main{
                jni.srcDirs = []
                jniLibs.srcDirs = ['src/main/libs']
            }
        }
        buildTypes {
            release {
                minifyEnabled false
                proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
            }
        }
    }
    
    dependencies {
        compile fileTree(dir: 'libs', include: ['*.jar'])
        testCompile 'junit:junit:4.12'
        compile 'com.android.support:appcompat-v7:23.4.0'
    }
    5. NDK编译

    Alt+F12进入Android Studio的终端模式,cd命令到第二步创建的jni文件夹内,输入ndk-build  APP_ABI="armeabi",回车执行。(需要将ndk路径添加到环境变量)

    接着,刷新工程结构,发现会在app/src/main下多出两个文件夹libs和obj,libs里就存放着so库。

    6. APK打包,安装到手机上运行。

    运行结果,通过本地调用,从C代码中返回字符串“hello world”,通过Toast弹出:


    目标小程序已写好,那么接下来就是hook它了,将hello world的内容改变(在C代码里)。

    下载安装Cydia Substrate框架

    框架下载com.saurik.substrate.apk

    Cydia Substrate SDK

    注意,手机需root,而且android系统在4.4以下


    编写Cydia Substrate模块

    这里我将编写一个模块去hook 上面小程序中的createHello函数,修改返回值。

    和上面的小程序差不多,编写Substrate模块也是一个NDK开发的过程:

    1. 创建一个没有Activity的空工程, 并添加Cydia Substrate SDK:

    在app/src/main下创建jni文件夹,并加入三个文件(两个so库和一个头文件):



    2.  在jni文件夹下新建cpp文件,名字需双后缀,一定得带 .cy 后缀,如上面的 module.cy.cpp文件:

    #include "substrate.h"  
    #include <android/log.h>  
    #define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG, "zz", __VA_ARGS__)
    
    //配置,这里是hook可运行程序(即NDK小程序)的写法,下面那个就是hook dvm的写法  
    MSConfig(MSFilterExecutable,"/system/bin/app_process")
    //MSConfig(MSFilterLibrary, "libdvm.so");  
    
    //旧的函数地址,目的为了保留指向原来函数的入口,在新的函数执行  
    //完后,一般会再调用该函数,以确保程序的正常运行  
    char* (* hello)(void);
    
    //新的函数,替代hook的函数,返回修改后的值  
    char* newHello(void)
    {
        //直接返回新的字符串
        return "fuck the world";
        //执行原函数,确保程序运行正常,但这里代码简单,可以直接返回字符串即可  
        //return hello();  
    }
    
    //通过so库的绝对路径和函数名,找到其函数的映射地址  
    void* lookup_symbol(char* libraryname,char* symbolname)
    {
        //获取so库的句柄
        void *handle = dlopen(libraryname, RTLD_GLOBAL | RTLD_NOW);
        if (handle != NULL){
            //根据so库句柄和符号名(即函数名)获取函数地址
            void * symbol = dlsym(handle, symbolname);
            if (symbol != NULL){
                return symbol;
            }else{
                LOGD("dl error: %s", dlerror());
                return NULL;
            }
        }else{
            return NULL;
        }
    }
    
    MSInitialize
    {
        //获取hook函数的地址,最好不要用下面MS提供的方法
        void * symbol = lookup_symbol("/data/data/com.samuelzhan.hello/lib/libhello.so","createHello");
    //    MSImageRef  image=MSGetImageByName("/data/data/com.samuelzhan.hello/lib/libhello.so");
    //    void *symbol=MSFindSymbol(image, "createHello");
    
        //这里将旧函数的入口(参数一)指向hello(参数三),然后执行新函数(参数二)  
        MSHookFunction(symbol, (void*)&newHello, (void**)&hello);
    }  

    3. 在jni文件夹下创建Android.mk文件,将substrate提供的两个so库也加进去一起编译:

    LOCAL_PATH := $(call my-dir)
    
    include $(CLEAR_VARS)
    LOCAL_MODULE:= substrate-dvm
    LOCAL_SRC_FILES := libsubstrate-dvm.so
    include $(PREBUILT_SHARED_LIBRARY)
    
    include $(CLEAR_VARS)
    LOCAL_MODULE:= substrate
    LOCAL_SRC_FILES := libsubstrate.so
    include $(PREBUILT_SHARED_LIBRARY)
    
    
    include $(CLEAR_VARS)
    LOCAL_MODULE    := module.cy #生成的模块名
    LOCAL_SRC_FILES := module.cy.cpp #源文件名
    LOCAL_LDLIBS = -llog
    LOCAL_LDLIBS += -L$(LOCAL_PATH) -lsubstrate-dvm -lsubstrate
    include $(BUILD_SHARED_LIBRARY)

    4. 配置三个文件,gradle.properties和local.properties的设置和上面编写目标程序一样,各添加一句代码即可, 至于build.gradle基本也一样,只不过moduleName改为 “module.cy”,以及加上几个库。

    gradle.properties:

    android.useDeprecatedNdk=true
    local.properties:
    ndk.dir=D\:\\android-ndk32-r10b-windows-x86\\android-ndk-r10b

    build.gradle:

    android {
        compileSdkVersion 23
        buildToolsVersion "23.0.3"
    
        defaultConfig {
            applicationId "com.samuelzhan.cydiahookjni"
            minSdkVersion 8
            targetSdkVersion 23
            versionCode 1
            versionName "1.0"
    
            ndk{
                moduleName "module.cy"
                ldLibs "substrate"
                ldLibs "substrate-dvm"
                ldLibs "log"
            }
        }
    
        sourceSets{
            main{
                jni.srcDirs = []
                jniLibs.srcDirs=['src/main/libs']
            }
        }
    
        buildTypes {
            release {
                minifyEnabled false
                proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
            }
        }
    }
    
    dependencies {
        compile fileTree(dir: 'libs', include: ['*.jar'])
        testCompile 'junit:junit:4.12'
        compile 'com.android.support:appcompat-v7:23.4.0'
    }
    5. NDK编译,和目标程序一样,cd到jni文件夹,终端里输入命令ndk-build,回车。

    6. 配置AndroidManifest.xml文件,添加installLocation,hasCode, uses-permission:

    <manifest xmlns:android="http://schemas.android.com/apk/res/android"
        package="com.samuelzhan.cydiahookjni"
        android:installLocation="internalOnly">
    
        <uses-permission android:name="cydia.permission.SUBSTRATE"/>
        <application android:hasCode="false">
    
        </application>
    
    </manifest>
    7.打包,安装到手机,并在cydia substrate框架弹出来的消息框选择软重启。

    好了,这里看看重启后,是否能成功hook到createHello这个函数,并修改其返回内容呢?


    到此,已经成功hook到native代码的函数并修改。下面将针对期间extern “C”的问题进行详细说明



    -----------------------------------特殊问题补充----------------------------------

    在上面的Hello小程序中(目标程序),在编写cpp文件时,有一个extern "C"的代码块,这个extern "C"就是告诉C++编译器用C的规范去编译这个代码块的内容。

    那么,两者编译后的函数有什么区别呢?看看下面两幅图:

    当 extern "C" 的范围包括 createHello函数时,ndk-build后,利用IDA PRO打开libhello.so库:


    当 extern "C" 的范围不包括 createHello函数时,ndk-build后,利用IDA PRO打开libhello.so库:


    实际上,C++为了实现函数重载,编译器会在编译后修改函数的名字,在原函数名字加上前缀和后缀,而C编译器则不会。

    这就容易在cydia substrate模块中查找函数地址lookup_symbol调用 void* dlsym(void* handle, const char* symbolName)造成异常情况。

    比如,extern “C” 没有包括createHello这个函数,那么我在  dlsym()函数中传入的函数名“createHello”就没有太大意义了,因为C++编译器已经修改过函数名,这会抛出“symbol not defined”的错误。

    当然,你可以通过IDA PRO查看到修改过的函数名,将修改过的函数名传入到 dlsym()函数也是可以找到函数地址的。


    由于许多公司对APP的安全性越来越重视,因此很多公司的核心业务处理模块一般会采用NDK开发,通过jni机制调用C代码来实现模块功能。这种用C/C++开发出来的代码反编译分析的难度远远大于java开发,因为C/C++反编译过来的汇编语言可读性很差,这给反编译人员带来很大的挑战。

    然而对于我这种初入逆向分析的菜鸟来说,每次看到native修饰的方法都觉得心里有道坎,尽管如此,我还是想在里面搞些文章,希望能分析出点成果~


    展开全文
  • 这是一个同时支持ART和Dalvik两种模式,理论上支持安卓4.0.3以上所有版本,同时支持JAVA和NATIVE层,使用全局注入技术的侵入式HOOK框架。 本框架不需要额外的安装,可以静态编译到自己的APP中
  • 0x00 进程注入 通过ptrace机制,调用目标进程的dlopen来加载我们的so,实现进程注入。 这部分知识在Android中的so注入(inject)和挂钩(hook) - For both x86 and arm,有详细的解释,请读者先阅读这篇文章。 那么...
  • android hook native函数

    2019-08-06 01:30:03
    大概2年前写的代码,今天突然要用到,找了半天,这里记录下 用到的库: https://pan.baidu.com/s/1htuUQX2 #include <jni.h> #include <...typedef int (* pfnMSHookFunction)(void* result, ...
  • cydiaSubstrate hook java/native 研究记录

    千次阅读 2016-05-13 18:06:01
    前阵子研究hook相关的东西,自己在网上搜集了一些资料,整理并记录一下,希望能给研究Android hook的小伙伴...它可以修改任何主进程的代码,不管是用Java还是C/C++(native代码)编写的,是一款强大而实用的HOOK工具。
  • ART模式下基于Xposed Hook开发脱壳工具

    千次阅读 2018-03-05 12:04:19
    本文博客地址:http://blog.csdn.net/qq1084283172/article/details/78092365Dalvik模式下的Android加固技术已经很成熟了,Dalvik虚拟机模式下的Android加固技术也在不断的发展和加强,鉴于Art虚拟机比Dalvik虚拟机...
  • Android安全-Native Hook

    千次阅读 2015-09-09 13:45:20
    ...转载是因为他写的调理清楚,排版清楚,最重要的是因为他简单明了的说 清楚了 Android-Native Hook 目录[-] 0x1 原理 0x2 流程 0x3 实现 0x4 关键  0x01 e
  • 在anndroid studio 2.2 后,只用它编写native代码只可以支持用CMake进行,然后我正在准备用Cydia Substrate 来 hook native代码的时候,发现网上没有用CMake方法来编写cydia脚本的,然后就只有自己动手了,下面用一...
  • 对 VirtualApp hook过程的理解

    千次阅读 2017-09-25 18:12:42
    对virtualapp的讲解 网上已经很详细了,我想从一个例子加深一下对va hook过程的理解。
  • Android Native Hook

    2019-11-18 08:35:20
    Hook 直译过来就是“钩子”的意思,是指截获进程对某个 API 函数的调用,使得 API 的执行流程转向我们实现的代码片段,从而实现我们所需要得功能,这里的功能可以是监控、修复系统漏洞,也可以是劫持...Native Hook ...
  • 全能HOOK框架 JNI NATIVE JAVA ART DALVIK

    千次阅读 2017-06-29 14:46:29
    这是一个同时支持ART和Dalvik两种模式,理论上支持安卓4.0.3以上所有版本,同时支持JAVA和NATIVE层,使用全局注入技术的侵入式HOOK框架。 本框架不需要额外的安装,可以静态编译到自己的APP中
  • 一、知识回顾 在之前一篇文章中,已经介绍了Android中如何修改内存指令改变方法执行逻辑,当时那篇文章的大致流程很简单,在程序运行起来,dex文件被加载到内存中之后,通过读取maps文件,获取dex文件的内存其实...
  • 已经介绍了安卓 Native hook 原理,这里介绍 hook 技术的应用,及Cyida Substrate框架。 分析某APP,发现其POST请求数据经过加密,我们希望还原其明文。经分析,加密是在so中的Java_com_imohoo_jni_Main_abc()函数...
  • Android安全:Hook技术

    万次阅读 2017-03-25 15:13:00
    一、Hook技术 1.Hook英文翻译为“钩子”,而钩子就是在事件传送到终点前截获并监控事件的传输,像个钩子钩上事件一样,并且能够在钩上事件时,处理一些自己特定的事件; 2.Hook使它能够将自己的代码“融入”被勾住...
  • android中基于plt/got的hook实现原理

    千次阅读 2020-01-05 21:53:16
    native-hook示例开始 got全局符号表hook 远程注入hook操作 inline hook原理 native内存泄漏检测常用方式 概述 由于android系统是基于linux内核开发的,因此我们日常编写的so文件,实际上也是一个ELF文件,类似于...
  • hook(钩子函数)

    千次阅读 2019-06-10 09:52:41
    hook钩子: 使用技术手段在运行时动态的将额外代码依附现进程,从而实现替换现有处理逻辑或插入额外功能的目的。 它的技术实现要点有两个: 1)如何注入代码(如何将额外代码依附于现有代码中)。 2)如何确定...
  • 目录 概述 简单示例 ELF文件格式初探 装载、动态链接与重定位 PLT与GOT 如何定位基址? 如何修改呢?...我们今天就要借助一个示例来理解一下android平台下nativehook的操作和原理,不过在这之前,我们...
1 2 3 4 5 ... 20
收藏数 462
精华内容 184
关键字:

dlopen hook native