首页
社区
课程
招聘
[原创]【Android】深入底层Binder拦截
发表于: 2023-11-30 20:05 17687

[原创]【Android】深入底层Binder拦截

2023-11-30 20:05
17687

Android平台进程Binder通信的动态分析和拦截。

Binder作为Android系统跨进程通信的核心机制。网上也有很多深度讲解该机制的文章,如:

这些文章和系统源码可以很好帮助我们理解Binder的实现原理和设计理念,为拦截做准备。借助Binder拦截可以我们可以扩展出那些能力呢:

一直以来实时分析和拦截进程的Binder通信是通过Java层的AIDL接口代理来实现的。借助于Android系统Binder服务接口设计的规范,上层的接口均继承于IBinder

如一下为代理目标对象的所有的接口API的方法:

1、对于已经生成的Binder服务对象,在应用进程可参与实现逻辑之前就已经缓存了,我们需要找到并且进行替换(AMS、PMS、WMS等),如AMS在Android 8.0之后的缓存如下:

因此我们需要找到并且替换它,如:

2、对于后续运行过程中才获取的Binder服务,则需要代理ServiceManager,源码如下:

因此我们的代理如下:

这样每次在第一次访问该服务时,就会调用IServiceManager中的getService的方法,而该方法已经被我们代理拦截,我们可以通过参数可以识别当前获取的是哪个服务,然后将获取的服务对象代理后在继续返回即可。

但是:这样的方案并不能拦截进程中所有的Binder服务。我们面临几大问题:

首先,Android源码越来越庞大,了解所有的服务工作量很大,因此有哪些服务已经被缓存排查非常困难。

其次,厂商越来越钟情于扩展自定义服务,这些服务不开源,识别和适配更加耗时。

再次,有一部分服务只有native实现,并不能通过Java层的接口代理进行拦截(如:Sensor/Audio/Video/Camera服务等)。

我们都知道Binder在应用进程运行原理如下图:

不管是Java层还是native层的接口调用,最后都会通过ioctl函数访问共享内存空间,达到跨进程访问数据交换的目的。因此我们只要拦截ioctl函数,即可完成对所有Binder通信数据的拦截。底层拦截有以下优势:

1)可以拦截所有的Binder通信。

2)底层拦截稳定,高兼容性。从Android 4.xAndroid 14,近10年的系统版本演进,涉及到Binder底层通信适配仅两次;一次是支持64位进程(当时需要同时兼容32位和64位进程访问Binder服务)。另一次是华为鸿蒙系统的诞生,华为ROMBinder通信协议中增加了新的标识字段。

C/C++层的函数拦截,并不像Java层一样系统提供了较为稳定的代理工具,在这里不是我们本期讨论的重点,可以直接采用网上开源的Hook框架:

ioctl函数为系统底层设备访问函数,调用及其频繁,而Binder通信调用只是其中调用者之一,因此需要快速识别非Binder通信调用,不影响程序性能。

函数定义:

request的参数定义:

对应的源码:

快速过滤:

目标源码:http://aospxref.com/android-14.0.0_r2/xref/frameworks/native/libs/binder

重点解析发送(即BC_TRANSACTIONBC_REPLY)和接收(即BR_TRANSACTIONBR_REPLY)的类型数据。

修改数据分为以下几种:

1)修复调用时参数数据。

2)修复调用后返回的结果数据。

如果数据修复不改变当前数据的长度,只是内容的变化,则可以直接通过地址进行修改。否则需要创建新的内存进行修改后将新的数据地址设置到BINDER_WRITE_READ结构的buffer成员。此时处理好内存的释放问题。

3)直接拦截本次调用。

为了保障稳定性,不打断Binder的调用流程(通常这也是拦截和逆向方案保障稳定的最重要原则之一)。我们可以将目标函数code修改成父类处理的通用方法,然后通过修复调用的返回值即可完成拦截。

Binder调用数据结构如下:

bwrbinder_write_read,从源码中了解到ioctlBINDER_WRITE_READ类型的arg数据结构为:

不管是传入还是返回的数据,都是一组BC命令或BR命令,也就是说一次调用上层会打包几个命令一起传递。因此我们需要通过循环来找到我们的命令。

dump数据如下:

txnbinder_transaction_data,Binder方法调用的方法参数信息定义如下:

dumo数据如下:

Binder通信数据头如下,即可解析出目标服务名:

Binder通信数据中标识该服务方法的参数是txn->codeAIDL定义类在编译后会为每个方法自动生成静态的方法。

如定义的Binder接口方法为:

则编译后生成的类为:

因此我们可以通过反射的方式,找到服务名对应的类所有静态成员变量,然后找到与code值相等的成员即为此方法。

这里可能需要解决私有API的限制解除问题。

日志输出如下:

首先需要借助数据封装类Parcel

借助该类可以解析一些比较简单的数据,快速的找到目标内容。而对于比较复杂的数据,如参数值为Intent,该参数类型嵌套了多层的Parcelable成员,因此在native层通过Parcel来解析,兼容性比较差。因此我们选择通过回调到Java层来解析,修改后再格式化为nativebuffer数据。这里需要处理好Javanative层的数据交换问题,以及回收。

native层:

Java层:

Binder的数据解析和打印不会改变原数据内容,因此相对简单,如果要对数据进行修改,则相对复杂一些。修复的数据需要替换原数据,因此需要进行如下操作。

1、数据替换。

txn中方法参数的数据指针指向新创建的数据区。

2、修正对象指针。

如果传入的参数包含Binder对象,如register方法的Observe。因此修复的数据可能导致偏移的地址前移或者后移,因此需要重新计算偏移,如:

3、内存释放。

需要保存原地址A和新的地址AA的映射关系到自定义的内存池中。

Binder通信命令出现BC_FREE_BUFFERBR_FREE_BUFFER时,则通过该命令要释放的AA地址,然后从内存池找到与之对应A的地址,并设置回去让上层继续释放,完成内存使用的闭环。

如果你有需要,可以直接使用我们已经封装好的SDK来实现相应的功能,该项目已经开源,链接地址如下:

Gitee

Github

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Proxy;
 
private static void getInterface(Class<?> cls, final HashSet<Class<?>> ss) {
    Class<?>[] ii;
    do {
        ii = cls.getInterfaces();
        for (final Class<?> i : ii) {
            if (ss.add(i)) {
                getInterface(i, ss);
            }
        }
        cls = cls.getSuperclass();
    } while (cls != null);
}
 
private static Class<?>[] getInterfaces(Class<?> cls) {
    final HashSet<Class<?>> ss = new LinkedHashSet<Class<?>>();
    getInterface(cls, ss);
    if (0 < ss.size()) {
        return ss.toArray(new Class<?>[ss.size()]);
    }
    return null;
}
 
public static Object createProxy(Object org, InvocationHandler cb) {
    try {
        Class<?> cls = org.getClass();
        Class<?>[] cc = getInterfaces(cls);
        return Proxy.newProxyInstance(cls.getClassLoader(), cc, cb);
    } catch (Throwable e) {
        Logger.e(e);
    } finally {
        // TODO release fix proxy name
    }
    return null;
}
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Proxy;
 
private static void getInterface(Class<?> cls, final HashSet<Class<?>> ss) {
    Class<?>[] ii;
    do {
        ii = cls.getInterfaces();
        for (final Class<?> i : ii) {
            if (ss.add(i)) {
                getInterface(i, ss);
            }
        }
        cls = cls.getSuperclass();
    } while (cls != null);
}
 
private static Class<?>[] getInterfaces(Class<?> cls) {
    final HashSet<Class<?>> ss = new LinkedHashSet<Class<?>>();
    getInterface(cls, ss);
    if (0 < ss.size()) {
        return ss.toArray(new Class<?>[ss.size()]);
    }
    return null;
}
 
public static Object createProxy(Object org, InvocationHandler cb) {
    try {
        Class<?> cls = org.getClass();
        Class<?>[] cc = getInterfaces(cls);
        return Proxy.newProxyInstance(cls.getClassLoader(), cc, cb);
    } catch (Throwable e) {
        Logger.e(e);
    } finally {
        // TODO release fix proxy name
    }
    return null;
}
// source code: http://aospxref.com/android-9.0.0_r61/xref/frameworks/base/core/java/android/app/ActivityManager.java
package android.app;
 
public class ActivityManager {
 
    public static IActivityManager getService() {
        return IActivityManagerSingleton.get();
    }
 
    private static final Singleton<IActivityManager> IActivityManagerSingleton =
            new Singleton<IActivityManager>() {
                @Override
                protected IActivityManager create() {
                    final IBinder b = ServiceManager.getService(Context.ACTIVITY_SERVICE);
                    final IActivityManager am = IActivityManager.Stub.asInterface(b);
                    return am;
                }
            };
}
// source code: http://aospxref.com/android-9.0.0_r61/xref/frameworks/base/core/java/android/app/ActivityManager.java
package android.app;
 
public class ActivityManager {
 
    public static IActivityManager getService() {
        return IActivityManagerSingleton.get();
    }
 
    private static final Singleton<IActivityManager> IActivityManagerSingleton =
            new Singleton<IActivityManager>() {
                @Override
                protected IActivityManager create() {
                    final IBinder b = ServiceManager.getService(Context.ACTIVITY_SERVICE);
                    final IActivityManager am = IActivityManager.Stub.asInterface(b);
                    return am;
                }
            };
}
Object obj;
if (Build.VERSION.SDK_INT < 26) {// <= 7.0
    obj = ReflectUtils.getStaticFieldValue("android.app.ActivityManagerNative", "gDefault");
} else {// 8.0 <=
    obj = ReflectUtils.getStaticFieldValue("android.app.ActivityManager", "IActivityManagerSingleton");
}
Object inst = ReflectUtils.getFieldValue(obj, "mInstance");
ReflectUtils.setFieldValue(obj, "mInstance", createProxy(inst));
Object obj;
if (Build.VERSION.SDK_INT < 26) {// <= 7.0
    obj = ReflectUtils.getStaticFieldValue("android.app.ActivityManagerNative", "gDefault");
} else {// 8.0 <=
    obj = ReflectUtils.getStaticFieldValue("android.app.ActivityManager", "IActivityManagerSingleton");
}
Object inst = ReflectUtils.getFieldValue(obj, "mInstance");
ReflectUtils.setFieldValue(obj, "mInstance", createProxy(inst));
// source code: http://aospxref.com/android-9.0.0_r61/xref/frameworks/base/core/java/android/os/ServiceManager.java
package android.os;
 
public final class ServiceManager {
    private static final String TAG = "ServiceManager";
 
    private static IServiceManager sServiceManager;
}
// source code: http://aospxref.com/android-9.0.0_r61/xref/frameworks/base/core/java/android/os/ServiceManager.java
package android.os;
 
public final class ServiceManager {
    private static final String TAG = "ServiceManager";
 
    private static IServiceManager sServiceManager;
}
Class<?> cls = ReflectUtils.findClass("android.os.ServiceManager");
Object org = ReflectUtils.getStaticFieldValue(cls, "sServiceManager");
Object pxy = new createProxy(org);
if (null != pxy) {
    ReflectUtils.setStaticFieldValue(getGlobalClass(), "sServiceManager", pxy);
}
Class<?> cls = ReflectUtils.findClass("android.os.ServiceManager");
Object org = ReflectUtils.getStaticFieldValue(cls, "sServiceManager");
Object pxy = new createProxy(org);
if (null != pxy) {
    ReflectUtils.setStaticFieldValue(getGlobalClass(), "sServiceManager", pxy);
}
// source code: http://aospxref.com/android-13.0.0_r3/xref/frameworks/av/camera/ICamera.cpp
 
class BpCamera: public BpInterface<ICamera>
{
public:
    explicit BpCamera(const sp<IBinder>& impl)
        : BpInterface<ICamera>(impl)
    {
    }
   
    // start recording mode, must call setPreviewTarget first
    status_t startRecording()
    {
        ALOGV("startRecording");
        Parcel data, reply;
        data.writeInterfaceToken(ICamera::getInterfaceDescriptor());
        remote()->transact(START_RECORDING, data, &reply);
        return reply.readInt32();
    }
}
// source code: http://aospxref.com/android-13.0.0_r3/xref/frameworks/av/camera/ICamera.cpp
 
class BpCamera: public BpInterface<ICamera>
{
public:
    explicit BpCamera(const sp<IBinder>& impl)
        : BpInterface<ICamera>(impl)
    {
    }
   
    // start recording mode, must call setPreviewTarget first
    status_t startRecording()
    {
        ALOGV("startRecording");
        Parcel data, reply;
        data.writeInterfaceToken(ICamera::getInterfaceDescriptor());
        remote()->transact(START_RECORDING, data, &reply);
        return reply.readInt32();
    }
}
#include <sys/ioctl.h>
 
int ioctl(int fildes, unsigned long request, ...);
#include <sys/ioctl.h>
 
int ioctl(int fildes, unsigned long request, ...);
// source code: http://aospxref.com/android-14.0.0_r2/xref/bionic/libc/kernel/uapi/linux/android/binder.h
#define BINDER_WRITE_READ _IOWR('b', 1, struct binder_write_read)
#define BINDER_SET_IDLE_TIMEOUT _IOW('b', 3, __s64)
#define BINDER_SET_MAX_THREADS _IOW('b', 5, __u32)
#define BINDER_SET_IDLE_PRIORITY _IOW('b', 6, __s32)
#define BINDER_SET_CONTEXT_MGR _IOW('b', 7, __s32)
#define BINDER_THREAD_EXIT _IOW('b', 8, __s32)
#define BINDER_VERSION _IOWR('b', 9, struct binder_version)
#define BINDER_GET_NODE_DEBUG_INFO _IOWR('b', 11, struct binder_node_debug_info)
#define BINDER_GET_NODE_INFO_FOR_REF _IOWR('b', 12, struct binder_node_info_for_ref)
#define BINDER_SET_CONTEXT_MGR_EXT _IOW('b', 13, struct flat_binder_object)
#define BINDER_FREEZE _IOW('b', 14, struct binder_freeze_info)
#define BINDER_GET_FROZEN_INFO _IOWR('b', 15, struct binder_frozen_status_info)
#define BINDER_ENABLE_ONEWAY_SPAM_DETECTION _IOW('b', 16, __u32)
#define BINDER_GET_EXTENDED_ERROR _IOWR('b', 17, struct binder_extended_error)
// source code: http://aospxref.com/android-14.0.0_r2/xref/bionic/libc/kernel/uapi/linux/android/binder.h
#define BINDER_WRITE_READ _IOWR('b', 1, struct binder_write_read)
#define BINDER_SET_IDLE_TIMEOUT _IOW('b', 3, __s64)
#define BINDER_SET_MAX_THREADS _IOW('b', 5, __u32)
#define BINDER_SET_IDLE_PRIORITY _IOW('b', 6, __s32)
#define BINDER_SET_CONTEXT_MGR _IOW('b', 7, __s32)
#define BINDER_THREAD_EXIT _IOW('b', 8, __s32)
#define BINDER_VERSION _IOWR('b', 9, struct binder_version)
#define BINDER_GET_NODE_DEBUG_INFO _IOWR('b', 11, struct binder_node_debug_info)
#define BINDER_GET_NODE_INFO_FOR_REF _IOWR('b', 12, struct binder_node_info_for_ref)
#define BINDER_SET_CONTEXT_MGR_EXT _IOW('b', 13, struct flat_binder_object)
#define BINDER_FREEZE _IOW('b', 14, struct binder_freeze_info)
#define BINDER_GET_FROZEN_INFO _IOWR('b', 15, struct binder_frozen_status_info)
#define BINDER_ENABLE_ONEWAY_SPAM_DETECTION _IOW('b', 16, __u32)
#define BINDER_GET_EXTENDED_ERROR _IOWR('b', 17, struct binder_extended_error)
// source code: http://aospxref.com/android-14.0.0_r2/xref/frameworks/native/libs/binder/IPCThreadState.cpp
void IPCThreadState::threadDestructor(void *st) {
    ioctl(self->mProcess->mDriverFD, BINDER_THREAD_EXIT, 0);
}
 
status_t IPCThreadState::getProcessFreezeInfo(pid_t pid, uint32_t *sync_received, uint32_t *async_received) {
    return ioctl(self()->mProcess->mDriverFD, BINDER_GET_FROZEN_INFO, &info);
}
 
status_t IPCThreadState::freeze(pid_t pid, bool enable, uint32_t timeout_ms) {
    return ioctl(self()->mProcess->mDriverFD, BINDER_FREEZE, &info) < 0);
}
 
void IPCThreadState::logExtendedError() {
    ioctl(self()->mProcess->mDriverFD, BINDER_GET_EXTENDED_ERROR, &ee) < 0);
}
 
status_t IPCThreadState::talkWithDriver(bool doReceive) {
    // 实际Binder调用通信
    return ioctl(mProcess->mDriverFD, BINDER_WRITE_READ, &bwr);
}
// source code: http://aospxref.com/android-14.0.0_r2/xref/frameworks/native/libs/binder/IPCThreadState.cpp
void IPCThreadState::threadDestructor(void *st) {
    ioctl(self->mProcess->mDriverFD, BINDER_THREAD_EXIT, 0);
}
 
status_t IPCThreadState::getProcessFreezeInfo(pid_t pid, uint32_t *sync_received, uint32_t *async_received) {
    return ioctl(self()->mProcess->mDriverFD, BINDER_GET_FROZEN_INFO, &info);
}
 
status_t IPCThreadState::freeze(pid_t pid, bool enable, uint32_t timeout_ms) {
    return ioctl(self()->mProcess->mDriverFD, BINDER_FREEZE, &info) < 0);
}
 
void IPCThreadState::logExtendedError() {
    ioctl(self()->mProcess->mDriverFD, BINDER_GET_EXTENDED_ERROR, &ee) < 0);
}
 
status_t IPCThreadState::talkWithDriver(bool doReceive) {
    // 实际Binder调用通信
    return ioctl(mProcess->mDriverFD, BINDER_WRITE_READ, &bwr);
}
static int ioctl_hook(int fd, int cmd, void* arg) {
    if (cmd != BINDER_WRITE_READ || !arg || g_ioctl_disabled) {
        return g_ioctl_func(fd, cmd, arg);
    }
}
static int ioctl_hook(int fd, int cmd, void* arg) {
    if (cmd != BINDER_WRITE_READ || !arg || g_ioctl_disabled) {
        return g_ioctl_func(fd, cmd, arg);
    }
}
struct binder_write_read {
  // 调用时传入的数据
     binder_size_t write_size;// call data
     binder_size_t write_consumed;// call data
     binder_uintptr_t write_buffer;// call data
   
    // 结果返回数据
     binder_size_t read_size;// recv data
     binder_size_t read_consumed;// recv data
     binder_uintptr_t read_buffer;// recv data
};
struct binder_write_read {
  // 调用时传入的数据
     binder_size_t write_size;// call data
     binder_size_t write_consumed;// call data
     binder_uintptr_t write_buffer;// call data

[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!

最后于 2023-12-1 09:42 被Tiony.bo编辑 ,原因:
收藏
免费 20
支持
分享
最新回复 (26)
雪    币: 3004
活跃值: (30866)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
感谢分享
2023-12-1 09:39
1
雪    币: 709
活跃值: (2420)
能力值: ( LV12,RANK:1010 )
在线值:
发帖
回帖
粉丝
3
学习了
2023-12-3 08:55
0
雪    币: 116
活跃值: (1012)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
受教了
2023-12-3 16:07
0
雪    币: 181
活跃值: (2943)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
学习了
2023-12-4 13:18
0
雪    币: 1671
活跃值: (215817)
能力值: ( LV4,RANK:40 )
在线值:
发帖
回帖
粉丝
6
tql
2023-12-9 13:31
0
雪    币: 450
活跃值: (3210)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
7
mark
2023-12-11 15:43
0
雪    币: 450
活跃值: (3210)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
8
我的建议是直接在Java层hook transact函数
简单方便,一步到位。
2023-12-11 18:24
0
雪    币: 345
活跃值: (586)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
9
学习了
2023-12-14 14:22
0
雪    币: 220
活跃值: (636)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
10
恋空 我的建议是直接在Java层hook transact函数 简单方便,一步到位。
正如文中所说,Java层的HOOK无法拦截native层的Binder通信
2023-12-19 22:27
0
雪    币: 3354
活跃值: (14003)
能力值: ( LV9,RANK:230 )
在线值:
发帖
回帖
粉丝
11
其实我之前用的也是类似这种方案,但是发现很多native层改不全,很多都是服务都是在native层,最好的办法是我搞了个magisk模块,注入服务端,再导入framework.jar,和service.jar 直接在服务端hook,非常方便,还有一些ipc通讯,比如oaid这种,他是不走系统服务的,走的是小米的安全中心,还需要去额外hook小米安全中心。
拿到我们在服务端留的代理服务,直接和服务端交互就行了,服务端可以作为控制台 ,负责各种数据的分发和接受处理。这是最完美的架构。
2023-12-27 10:09
0
雪    币: 1110
活跃值: (3244)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
12
# ls -al /sys/kernel/tracing/events/binder
total 0
drwxr-xr-x  35 root readtracefs 0 1970-01-01 08:00 .
drwxr-xr-x 128 root readtracefs 0 1970-01-01 08:00 ..
drwxr-xr-x   2 root readtracefs 0 1970-01-01 08:00 binder_alloc_lru_end
drwxr-xr-x   2 root readtracefs 0 1970-01-01 08:00 binder_alloc_lru_start
drwxr-xr-x   2 root readtracefs 0 1970-01-01 08:00 binder_alloc_page_end
drwxr-xr-x   2 root readtracefs 0 1970-01-01 08:00 binder_alloc_page_start
drwxr-xr-x   2 root readtracefs 0 1970-01-01 08:00 binder_command
drwxr-xr-x   2 root readtracefs 0 1970-01-01 08:00 binder_free_lru_end
drwxr-xr-x   2 root readtracefs 0 1970-01-01 08:00 binder_free_lru_start
drwxr-xr-x   2 root readtracefs 0 1970-01-01 08:00 binder_ioctl
drwxr-xr-x   2 root readtracefs 0 1970-01-01 08:00 binder_ioctl_done
drwxr-xr-x   2 root readtracefs 0 1970-01-01 08:00 binder_lock
drwxr-xr-x   2 root readtracefs 0 1970-01-01 08:00 binder_locked
drwxr-xr-x   2 root readtracefs 0 1970-01-01 08:00 binder_read_done
drwxr-xr-x   2 root readtracefs 0 1970-01-01 08:00 binder_return
drwxr-xr-x   2 root readtracefs 0 1970-01-01 08:00 binder_set_priority
drwxr-xr-x   2 root readtracefs 0 1970-01-01 08:00 binder_transaction
drwxr-xr-x   2 root readtracefs 0 1970-01-01 08:00 binder_transaction_alloc_buf
drwxr-xr-x   2 root readtracefs 0 1970-01-01 08:00 binder_transaction_buffer_release
drwxr-xr-x   2 root readtracefs 0 1970-01-01 08:00 binder_transaction_failed_buffer_release
drwxr-xr-x   2 root readtracefs 0 1970-01-01 08:00 binder_transaction_fd_recv
drwxr-xr-x   2 root readtracefs 0 1970-01-01 08:00 binder_transaction_fd_send
drwxr-xr-x   2 root readtracefs 0 1970-01-01 08:00 binder_transaction_node_to_ref
drwxr-xr-x   2 root readtracefs 0 1970-01-01 08:00 binder_transaction_received
drwxr-xr-x   2 root readtracefs 0 1970-01-01 08:00 binder_transaction_ref_to_node
drwxr-xr-x   2 root readtracefs 0 1970-01-01 08:00 binder_transaction_ref_to_ref
drwxr-xr-x   2 root readtracefs 0 1970-01-01 08:00 binder_transaction_update_buffer_release
drwxr-xr-x   2 root readtracefs 0 1970-01-01 08:00 binder_unlock
drwxr-xr-x   2 root readtracefs 0 1970-01-01 08:00 binder_unmap_kernel_end
drwxr-xr-x   2 root readtracefs 0 1970-01-01 08:00 binder_unmap_kernel_start
drwxr-xr-x   2 root readtracefs 0 1970-01-01 08:00 binder_unmap_user_end
drwxr-xr-x   2 root readtracefs 0 1970-01-01 08:00 binder_unmap_user_start
drwxr-xr-x   2 root readtracefs 0 1970-01-01 08:00 binder_update_page_range
drwxr-xr-x   2 root readtracefs 0 1970-01-01 08:00 binder_wait_for_work
drwxr-xr-x   2 root readtracefs 0 1970-01-01 08:00 binder_write_done
-rw-r--r--   1 root readtracefs 0 1970-01-01 08:00 enable
-rw-r--r--   1 root readtracefs 0 1970-01-01 08:00 filter

大哥用这个,劲大!

最后于 2023-12-27 10:23 被Amun编辑 ,原因:
2023-12-27 10:20
0
雪    币: 1490
活跃值: (9913)
能力值: ( LV9,RANK:240 )
在线值:
发帖
回帖
粉丝
13
跑通了。比较在意的是运用场景,第三方ROM扩展Framework服务 能展开说说吗。
2023-12-27 16:12
0
雪    币: 220
活跃值: (636)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
14
珍惜Any 其实我之前用的也是类似这种方案,但是发现很多native层改不全,很多都是服务都是在native层,最好的办法是我搞了个magisk模块,注入服务端,再导入framework.jar,和service ...
感谢您的关注,就像文中所说,在Server端拦截实现的确可以达到目的,但是只能采用开源的AOSP的ROM定制,或者ROOT系统,方案量,没办法通用,同样面临厂商定制的服务无法识别的问题。
2023-12-27 18:11
1
雪    币: 220
活跃值: (636)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
15
misskings 跑通了。比较在意的是运用场景,第三方ROM扩展Framework服务 能展开说说吗。
第三方ROM可以通过本框架拦截后找到对应的类和方法(仅Java层方法)。
适用场景并不太多,就像文中所说的,插件化方案的开发和适配,应用或SDK的服务端访问监测,免安装运行方案的开发和适配,应用运行时动态分析等。本方案的优势就是轻量,且兼容性好。
后面会上线应用重封装项目,免安装项目,都会用到,届时再和大家一起分享。
2023-12-27 18:16
0
雪    币: 1490
活跃值: (9913)
能力值: ( LV9,RANK:240 )
在线值:
发帖
回帖
粉丝
16
Tiony.bo 第三方ROM可以通过本框架拦截后找到对应的类和方法(仅Java层方法)。 适用场景并不太多,就像文中所说的,插件化方案的开发和适配,应用或SDK的服务端访问监测,免安装运行方案的开发和适配,应用运行 ...
好的。感觉simple输出的太过于简单。希望后期优化。感觉用的上。
2023-12-28 14:23
0
雪    币: 3354
活跃值: (14003)
能力值: ( LV9,RANK:230 )
在线值:
发帖
回帖
粉丝
17
Tiony.bo 感谢您的关注,就像文中所说,在Server端拦截实现的确可以达到目的,但是只能采用开源的AOSP的ROM定制,或者ROOT系统,方案量,没办法通用,同样面临厂商定制的服务无法识别的问题。
不需要那么麻烦,用magisk模块,实现热插拔,编译个驱动内核注入就行了。
2023-12-28 16:25
0
雪    币: 1110
活跃值: (3244)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
18

https://github.com/dxwu/BinderFilter
可以拿这个改改,整个 ko 驱动模块装上。

最后于 2023-12-28 17:57 被Amun编辑 ,原因:
2023-12-28 17:45
0
雪    币: 220
活跃值: (636)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
19
Amun https://github.com/dxwu/BinderFilter可以拿这个改改,整个&nbsp;ko&nbsp;驱动模块装上。
酷,已Star
2023-12-29 10:00
1
雪    币: 220
活跃值: (636)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
20
珍惜Any 不需要那么麻烦,用magisk模块,实现热插拔,编译个驱动内核注入就行了。
哈哈,支持
2023-12-29 10:00
0
雪    币: 450
活跃值: (3210)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
21
Amun #&nbsp;ls&nbsp;-al&nbsp;/sys/kernel/tracing/events/binder total&nbsp;0 drwxr-xr-x& ...
确实牛逼
2024-1-14 21:39
0
雪    币: 0
活跃值: (629)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
22
珍惜Any 其实我之前用的也是类似这种方案,但是发现很多native层改不全,很多都是服务都是在native层,最好的办法是我搞了个magisk模块,注入服务端,再导入framework.jar,和service ...
你好大牛,有已实现好的获取小米oaid吗?qq:876529930
2024-1-29 00:08
0
雪    币: 507
活跃值: (1742)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
23
这个的解析部分感觉更详细,就是适配工作量看起来挺大,可以参考参考

https://github.com/foundryzero/binder-trace
2024-1-29 09:46
0
雪    币: 220
活跃值: (636)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
24
seeeseee 这个的解析部分感觉更详细,就是适配工作量看起来挺大,可以参考参考 https://github.com/foundryzero/binder-trace
确实,非常详细,学习了
2024-2-17 10:12
0
雪    币: 1379
活跃值: (2796)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
25
感谢分享
2024-9-18 13:41
0
游客
登录 | 注册 方可回帖
返回
//