(一)简介

Android中的 Native Hook是一个非常吸引人的技术节点,诱使开发人员产生绚烂多彩的想法,并带来精彩的体验。在软件调试、逆向、安全等场景中得到采用,各大知名软件公司如byte dance、baidu、tencent等都有自己的开源注入和hook项目。

本文代码来自github,只做了适当的剪裁和优化,主要是为了验证和测试,源代码的技术基本未有改动。

具体的技术细节,本文不做阐述,有兴趣和想法的人自己动手验证吧。

有想法的人和行动派总是在实践中找到自我和快感,因此,armeabi-v7a和arm64-v8a架构相关的指令架构和hook技术细节,请自行探讨。

工程代码下载地址点击下载

(二)测试

64位hooktest测试源码:

#include <stdio.h>

#include "And64InlineHook.h"

typedef int (*ptr_old_puts)(const char *);

ptr_old_puts old_puts = 0;

int new_puts(const char *string)
{
    return old_puts("inlineHook success");
}




int hook()
{
    A64HookFunction((void*const)puts,(void*const)new_puts,(void **)&old_puts);

    return 0;
}


int main()
{
    puts("test");
    hook();
    puts("test");

    return 0;
}

32位hooktest测试代码:

#include <stdio.h>
#include <errno.h>

#include "inlineHook.h"

int (*old_puts)(const char *) = NULL;

int new_puts(const char *string)
{
    return old_puts("inlineHook 32 success");
}

int hook()
{
    if (registerInlineHook((uint32_t) puts, (uint32_t) new_puts, (uint32_t **) &old_puts) != ELE7EN_OK) {
        printf("registerInlineHook error:%d\r\n",errno);
        return -1;
    }
    if (inlineHook((uint32_t) puts) != ELE7EN_OK) {
        printf("inlineHook error:%d\r\n",errno);
        return -1;
    }

    printf("hook ok\r\n");

    return 0;
}

int unHook()
{
    if (inlineUnHook((uint32_t) puts) != ELE7EN_OK) {
        printf("inlineUnHook error:%d\r\n",errno);
        return -1;
    }

    return 0;
}

int main()
{
    puts("test0");
    getchar();
    hook();
    puts("test1");
    getchar();
    unHook();
    puts("test2");
}

测试步骤:

  1. adb push hooktest /data/local/tmp
  2. 执行adb shell,执行cd /data/local/tmp,接下来执行chmod 777 ./hooktest
  3. 执行./hooktest

注意:

  1. 先执行puts在再调用hook,是因为linux上的延迟加载,若函数没有被调用,执行hook时可能会找不到导出函数puts而失败。
  2. . old_puts是函数指针,也就是说是它是一个二级指针。

32位hook测试结果截图:
在这里插入图片描述
64位hook测试输出截图:

在这里插入图片描述

代码基于Android studio 3.5集成和开发测试。

Logo

旨在为数千万中国开发者提供一个无缝且高效的云端环境,以支持学习、使用和贡献开源项目。

更多推荐