欢迎来到 嗅灵易学

零基础也能上手的脚本技术课,一对一答疑带你入门

[原创]Unity3D手游破盾之旅

[原创]Unity3D手游破盾之旅

工具与环境:
手机: 小米4
系统版本: 4.4.2
Hook 框架: Cydia substrate 和 iqyi的xHook
某易游戏出了一款篮球游戏,试玩了一下,内容就不过多的评价了,出于职业习惯,对它的保护系统倒是很感兴趣。
先行基础是必须会用Cydia substrate这个hook框架,如果不会用请先去论坛搜索教程。
先静态分析一下libmono.so,各种关键函数都搜不到,应该是对so进行处理了,然而,在动态运行时,总要还原的嘛。
先定义MonoImage结构体,后续dump文件时有用。

struct _MonoImage {  

    int   ref_count;  

    void *raw_data_handle;  

    char *raw_data;  

    int raw_data_len;  

};

闲话少说,直接上神器Cydia substrate,使用Cydia substrate框架去hook dlopen函数和
hook libmono.so中的mono_image_open_from_data_with_name,启动代码如下:

MSConfig(MSFilterLibrary, "/system/lib/libdvm.so");

Void* (*old_dlopen)(const char *filename, int myflags);

void* new_dlopen( const char *filename, int myflags) {

    if(!(strstr(filename, "/system/lib/")))

    {

        LOGE("[dlopen] The dlopen name : %s.\n", filename);

    }

    void *handle = NULL;

    handle = orig_dlopen(filename, myflags);

    if(strstr(filename, "libunity.so")) {

        hookU3D();

    } 

    return handle;

}

MSInitialize {

//获取dlopen地址

    void *dlopen_addr = get_remote_addr(getpid(), "/system/bin/linker", (void *)dlopen);

    //hook dlopen方法

    MSHookFunction((void*)dlopen_addr, (void*)&new_dlopen, (void**)&orig_dlopen);

}

//hookU3D函数和替换函数如下:

_MonoImage *(* orig_my_open)(char *data, int32_t data_len, int need_copy, int *status, int refonly, char *name);

_MonoImage* new_ my_open(char *data, int32_t data_len, int need_copy, int *status, int refonly, char *name)

{

    _MonoImage *ret = orig_my_open(data, data_len, need_copy, status, refonly, name); 

    if(strstr(name, "Assembly-CSharp")) {

        if(strstr(name, "arp.dl"))

        {

            saveDllFile(ret->raw_data,data_len, getFilePath(".dll", "Assembly-CSharp").c_str());

        }

        else {

            saveDllFile(ret->raw_data,data_len,getFilePath(".dll","Assembly-CSharp-firstpass").c_str());

        }

    }

    return ret;

}

void hookU3D()

{

    void *myhandle = dlopen("libmono.so", RTLD_NOW | RTLD_GLOBAL);

    void*addr = dlsym(myhandle, "mono_image_open_from_data_with_name");

    MSHookFunction(addr, (void *) new_my_open,(void **) &orig_my_open);

}

不出所料,游戏崩了,通过代码打印出函数所在地址的前8位:

void printOpcode(char *addr)

{

    LOGD("Addr %p --> 8 : %02x %02x %02x %02x %02x %02x %02x %02x",addr,addr[0],addr[1],addr[2],addr[3],addr[4],addr[5],addr[6],addr[7]);

    LOGD("Addr %p --> 16 : %02x %02x %02x %02x %02x %02x %02x %02x",addr,addr[8],addr[9],addr[10],addr[11],addr[12],addr[13],addr[14],addr[15]);

    LOGD("Addr %p --> 24 : %02x %02x %02x %02x %02x %02x %02x %02x",addr,addr[16],addr[17],addr[18],addr[19],addr[20],addr[21],addr[22],addr[23]);

    LOGD("Addr %p --> 32 : %02x %02x %02x %02x %02x %02x %02x %02x",addr,addr[24],addr[25],addr[26],addr[27],addr[28],addr[29],addr[30],addr[31]);

}

输出结果:

注意:上传附件及图片大小不得大于30M。

⚠️ 版权声明:
本博客所有内容(含教程、源码、工具)仅供个人技术学习与研究交流使用,严禁商用、倒卖、二次分发及非法用途
未经作者书面授权,任何组织或个人不得转载、复制或用于其他平台,违者将追究相关责任。

0 0 0 举报
复制成功