绕过移动端系统限制的 dlopen 库 byOpen

byOpen是一个绕过移动端系统限制的增强版dlfunctions库。

软件基本信息

维度 详情
1 软件类型 手机开发工具
2 开发语言

Java C/C++ Lua

3 授权协议

Apache-2.0

4 操作系统

OS X

支持特性

Android

支持App中加载和使用Android系统库接口(即使maps中还没有被加载也支持)。

Android 7以上dlopen, System.load都是被限制调用的,虽然目前 上有Nougat_dlfunctions等库通过从maps中找so库来绕过加载限制。

不过对于app中还没被加载到maps的so库,这种方式就不行了。

而byOpen不仅支持fake dlopen方式从maps加载,还可以将还没加载到maps的so库绕过系统限制强行加载进来使用,实现更加通用化得dlopen。

注:目前的实现方式理论上还是比较通用的,至少我这Android 10上测试ok,但还没完整详细测试过,是否使用请自行评估。

相关原理

具体实现原理还是比较简单的,主要还是借鉴了一种绕过Android P对非SDK接口限制的简单方法的思想和实现方式。

虽然这篇文章中主要目的是为了绕过hide api,不过它里面使用的将自己假装成系统调用的方式,一样可以用到System.loadLibrary上去,让系统以为是系统自身在调用System.loadLibrary

从而绕过Android N的classloader-namespace限制,将系统/system/lib中任意so库加载到maps中,然后再通过fake dlopen的方式去dlsym。

增强版fake dlopen

关于fake dlopen的方式实现, 上已有很多实现,比如:

  • Nougat_dlfunctions

  • Enhanced_dlfunctions

  • byOpen参考了里面的实现,重新实现了一遍,并且做了一些小改进:

  • 不在/proc/self/maps中的系统库,也能绕过限制强行加载进来使用

  • 除了从.dynsym中检索符 ,还支持从.symtab中检索符 (参考:Enhanced_dlfunctions,顺带修复了里面的一些bug)

  • 整个dlopen过程只有一次malloc分配(省去整个符 表的内存分配和copy)

  • 兼容原始dlopen,如果是低版本android系统,没有限制,还是会优先切到原生dlopen上去直接调用

  • Android例子

    Android相关测试App例子在:Android Sample

    注:目前自带的App测试例子里面的系统库我写死了,有些系统版本上有可能不存在,请先改成用户自己的库和符 名,再编译测试

    publicclassMainActivityextendsAppCompatActivity{

    privatestaticfinalStringSYSTEM_LIBRARY= “curl”;

    privatestaticfinalStringSYMBOL_NAME= “curl_version”;

    除了Native版本dlopen接口,byOpen额外提供了java版本的System.loadLib rary接口在java层直接绕过系统库加载。

    关键代码如下:

    staticpublicbooleanloadLibrary( StringlibraryName) {

    MethodforName = Class.class.getDeclaredMethod( “forName”, String.class);

    MethodgetDeclaredMethod = Class.class.getDeclaredMethod( “getDeclaredMethod”, String.class, Class[].class);

    Class<?> systemClass = ( Class<?>) forName. invoke( null, “java.lang.System”);

    MethodloadLibrary = ( Method) getDeclaredMethod. invoke(systemClass, “loadLibrary”, newClass[]{ String.class});

    loadLibrary. invoke(systemClass, libraryName);

    }

    而native版本的dlopen_android.c实现中,我将这段绕过的系统加载的方式,通过jni重新实现了一遍,然后和fake dlopen无缝结合到了一起。

    iOS

    为了在通过调用一些私有接口的时候避免被苹果检测到,byOpen也通过自己实现dlopen/dlsym直接从已经加载进来的images列表里面直接查找对应symbol地址来调用。

    当然,为了更加安全,相关调用的库符 硬编码字符串等,用户可以自行做层变换加密,不要直接编译进app。

    接口用法

    相关静态库和接口在:dlopen.h

    相关使用方式跟原生dlopen完全相同:

    typedefby_char_tconst* (* curl_version_t);

    by_pointer_thandle = by_dlopen( “libcurl.so”, BY_RTLD_LAZY);

    if(handle)

    {

    by_pointer_taddr = by_dlsym(handle, “curl_version”);

    if(addr)

    {

    curl_version_tcurl_version = ( curl_version_t)addr;

    by_print( “curl_version: %s”, curl_version);

    }

    by_dlclose(handle);

    }

    编译

    编译需要先安装:xmake

    Android直接编译库

    $xmake f -pandroid –ndk=~ /file/android-ndk-r20b

    $xmake

    通过gradle编译测试Apk

    $ cdsrc/android

    $./gradlew app:assembleDebug

    通过xmake直接编译apk

    $xmake apk_build

    通过xmake直接安装测试apk

    $xmake apk_test

    iOS直接编译库

    $xmake f -p iphoneos -a [armv7|arm64]

    $xmake

    macOS

    我们也可以在macOS下编译测试,也是支持的:

    $xmake

    $xmake run

    声明:本站部分文章及图片源自用户投稿,如本站任何资料有侵权请您尽早请联系jinwei@zod.com.cn进行处理,非常感谢!

    上一篇 2020年7月26日
    下一篇 2020年7月26日

    相关推荐