首页
论坛
课程
招聘
[原创]xhook+xp改机尝试
2021-7-30 16:38 19507

[原创]xhook+xp改机尝试

2021-7-30 16:38
19507

java层的hook现在对很多app已经免疫了,安卓的一些属性读取,可以通用

1
system_property_get

之前通过frida脚本来尝试了一下。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
Interceptor.attach(Module.findExportByName("libc.so", "__system_property_get"), {
        onEnter: function (args) {
            str = getStr(args[0]);
            args2 = ptr(args[1]);
        },
 
        onLeave: function (retval) {
            if (str) {
                if (str.indexOf("ro.serialno") != -1) {
 
                }
            }
        }
    });

现在切到xp上
这个底层函数来读取。很多大型app都是这样读取的,当然还有一个oaid。

 

不过先尝试hook这个函数。尝试用xhook这个框架来搭配xposed使用。

 

看雪上也有篇文章介绍了原理:https://bbs.pediy.com/thread-265351.htm
官方文档介绍到xhook_register 这个函数。

  1. 注册 hook 信息
    1
    2
    3
    4
    int xhook_register(const char  *pathname_regex_str, 
                    const char  *symbol, 
                    void        *new_func, 
                    void       **old_func);
    在当前进程的内存空间中,在每一个符合正则表达式 pathname_regex_str 的已加载ELF中,每一个调用 symbol 的 PLT 入口点的地址值都将给替换成 new_func。之前的 PLT 入口点的地址值将被保存在 old_func 中。

new_func 必须具有和原函数同样的函数声明。

 

成功返回 0,失败返回 非0。

 

pathname_regex_str 只支持 POSIX BRE (Basic Regular Expression) 定义的正则表达式语法。

 

也就是利用了这一点,可以通用替换systemproperty的函数地址。

 

然后. 执行 hook
int xhook_refresh(int async);
根据前面注册的 hook 信息,执行真正的 hook 操作。

 

给 async 参数传 1 表示执行异步的 hook 操作,传 0 表示执行同步的 hook 操作。

 

成功返回 0,失败返回 非0。

 

xhook 在内部维护了一个全局的缓存,用于保存最后一次从 /proc/self/maps 读取到的 ELF 加载信息。每次一调用 xhook_refresh 函数,这个缓存都将被更新。xhook 使用这个缓存来判断哪些 ELF 是这次新被加载到内存中的。我们每次只需要针对这些新加载的 ELF 做 hook 就可以了。

 

实际上就可以利用这个,xphook住app的时候,就给他注入进去,从而达到替换函数地址,自己的进程也就能用这个函数了。
本次尝试就是单纯把大佬的代码抠了一遍实现。

 

image-20210730155447843

 

xhook里的这些c文件,要改的就是biz.c。 也可以集成到自己的ndk里面。

 

 

这是部分代码,目的就是替换函数地址。

 

可单独用ndk-build编译一下,拿到对应架构的so文件,这里我继承到自己的xp插件中

 

 

包括一些ndk中静态注册的方法,也一定copy过来,官方给出的demo,说的很详细了。

 

一定要在app里面加载这个so文件。否则hook就会失效。

 


了解原理之后,目标是 手机查看器这个app。

1
2
3
4
5
6
7
8
9
private void hookNativePhone(Context context, String phoneInfo) throws JSONException {
        Biz.getInstance().init(context);
        if (Biz.getInstance().isInited()) {
            TraceUtil.e("Biz init success");
            Biz.getInstance().start(new JSONObject(phoneInfo));
        } else {
            TraceUtil.e("Biz init error");
        }
    }

核心就是这一串,phoneinfo就是各种手机信息,

1
public static String str = "{\"androidId\":\"0352fb39b7b57095\",\"board\":\"GM1910\",\"bootloader\":\"unknown\",\"brand\":\"OnePlus\",\"buildID\":\"N2G48C\",\"codename\":\"REL\",\"device\":\"aosp\",\"display\":\"N2G48C\",\"fingerprint\":\"google/android_x86/x86:7.1.2/N2G48C/N975FXXU1ASGO:/release-keys\",\"getBSSID\":\"00:AA:38:94:db:69\",\"getCellLocation\":\"[1028,32305,0]\",\"getDataActivity\":\"0\",\"getDeviceId\":\"865166021690246\",\"getExtraInfo\":\"\\\"40938\\\"\",\"getIpAddress\":\"822153388\",\"getLine1Number\":\"\",\"getLocalHost\":\"localhost/127.0.0.1\",\"getMacAddress\":\"00:db:09:94:69:38\",\"getNetworkId\":\"0\",\"getNetworkOperator\":\"46000\",\"getNetworkOperatorName\":\"CHINA MOBILE\",\"getNetworkType\":\"0\",\"getRadioVersion\":\"\",\"getRssi\":\"-43\",\"getSSID\":\"\\\"40938\\\"\",\"getSimOperator\":\"46000\",\"getSimOperatorName\":\"China Mobile GSM\",\"getSimSerialNumber\":\"89860034346691847727\",\"getSubscriberId\":\"460006963910613\",\"getSubtype\":\"0\",\"getType\":\"1\",\"getTypeName\":\"WIFI\",\"hardware\":\"android_x86\",\"host\":\"ubuntu\",\"incremental\":\"N975FXXU1ASGO\",\"manufacturer\":\"OnePlus\",\"model\":\"GM1910\",\"product\":\"GM1910\",\"release\":\"7.1.2\",\"scanResultsBSSID\":\"00:AA:38:94:db:69\",\"scanResultsCapabilities\":\"[ESS]\",\"scanResultsFrequency\":\"2457\",\"scanResultsLevel\":\"-38\",\"scanResultsSSID\":\"40938\",\"sdk\":\"25\",\"sdkInt\":\"25\",\"serial\":\"00a9b25c\",\"tags\":\"release-keys\",\"time\":\"1616072733000\",\"type\":\"user\",\"user\":\"build\",\"version\":\"09\",\"widthPixels\":\"2.0\"}";

抠了一串出来。hook到了这个进程之后,可以给个主动调用的条件。

 

启动的时候,原始的信息

 

 

然后调用一下,再去检测systemPropertyget试试

 

我这里就随便写了个接口来触发一下。

 

点击环境检测,可以看到,读出来的这些属性明显改变了

 

 

然后从日志中也能看出来,这些也是直接就改变了。

 

通用这种方式,也可以解决一些在ndk中读取属性的方式了。

 

又或者还有一种syscall读取的方式,这种就是究极怪物了。等我研究一哈再来。。。

文档

XHOOK: https://github.com/iqiyi/xHook/blob/master/README.zh-CN.md
xposed-dy: https://github.com/Lstaynight/xposed-dy


恭喜ID[飞翔的猫咪]获看雪安卓应用安全能力认证高级安全工程师!!

最后于 2021-7-30 16:39 被chionyuna编辑 ,原因: 链接没显示
收藏
点赞3
打赏
分享
最新回复 (8)
雪    币: 2016
活跃值: 活跃值 (4230)
能力值: ( LV3,RANK:25 )
在线值:
发帖
回帖
粉丝
supperlitt 活跃值 2021-8-3 10:59
2
0
66666
雪    币: 3200
活跃值: 活跃值 (423)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
疯子Tear 活跃值 2021-8-3 15:08
3
0
yyds
雪    币: 105
活跃值: 活跃值 (265)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
雅鸦歌 活跃值 2021-8-3 17:59
4
0
dy 风控一键识别了 低版本还行 
雪    币: 518
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
河北小风 活跃值 2021-8-3 20:35
5
0
我也去试试了
雪    币: 1584
活跃值: 活跃值 (1658)
能力值: ( LV3,RANK:25 )
在线值:
发帖
回帖
粉丝
chionyuna 活跃值 2021-8-3 21:03
6
0
雅鸦歌 dy 风控一键识别了 低版本还行 [em_1]
dy风控的是oaid吧!
雪    币: 40
活跃值: 活跃值 (103)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
sanlic 活跃值 2021-9-7 13:48
7
0
为啥不直接修改build.prop
雪    币: 173
活跃值: 活跃值 (44)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
三九111 活跃值 2021-12-2 23:27
8
0
有没有联系方式?
雪    币: 1622
活跃值: 活跃值 (659)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
hhhaiai 活跃值 2021-12-4 16:59
9
0
mark
游客
登录 | 注册 方可回帖
返回