深入浅出Hook

深入浅出Hook技术

一、Hook是什么?

Hook(钩子)就像**"代码钓鱼"**,你可以:

  • 拦截 原本要执行的函数/方法
  • 修改 它的行为(比如改参数、改返回值)
  • 监控 谁调用了它(记录日志)

举个生活例子:

你家的门铃原本会"叮咚",你加了个Hook后变成:"叮咚~主人,有客人来啦!"

二、安卓Hook的常见用途

  1. 改App行为(比如破解VIP功能)
  2. 自动化测试(模拟点击、输入)
  3. 性能监控(统计方法耗时)
  4. 安全防护(防止恶意调用)
  5. 系统定制(修改系统级功能)

三、Hook的三种常见方式

1. 代理模式Hook(最安全)

java 复制代码
// 原始类
public class Door {
    public void ring() {
        System.out.println("叮咚");
    }
}

// Hook方案:用代理类
public class ProxyDoor {
    private Door target;
    
    public ProxyDoor(Door target) {
        this.target = target;
    }
    
    public void ring() {
        System.out.println("记录:有人按门铃");
        target.ring(); // 依然执行原方法
        System.out.println("Hook:主人,有客人来啦!");
    }
}

// 使用
Door door = new Door();
ProxyDoor proxy = new ProxyDoor(door);
proxy.ring(); // 增强版门铃

2. 反射Hook(需要找对目标)

java 复制代码
// 原始方法
public class Phone {
    private void call(String number) {
        System.out.println("正在拨打:" + number);
    }
}

// Hook方案:反射修改私有方法
try {
    Phone phone = new Phone();
    Method method = Phone.class.getDeclaredMethod("call", String.class);
    method.setAccessible(true); // 突破private限制
    
    // 替换实现
    method.invoke(phone, "110"); // 实际拨打110
} catch (Exception e) {
    e.printStackTrace();
}

3. 动态代理(针对接口)

java 复制代码
// 原始接口
public interface ICamera {
    void takePhoto();
}

// Hook方案:动态代理
ICamera camera = (ICamera) Proxy.newProxyInstance(
    loader,
    new Class[]{ICamera.class},
    (proxy, method, args) -> {
        System.out.println("拍照前检查权限");
        // 这里可以替换成其他相机实现
        return null; 
    }
);

camera.takePhoto(); // 被代理的方法

四、安卓特有Hook技术

1. 系统服务Hook(需要root)

java 复制代码
// 例如Hook剪贴板服务
try {
    // 获取原始服务
    IBinder clipboardBinder = ServiceManager.getService("clipboard");
    IBinder proxyBinder = (IBinder) Proxy.newProxyInstance(
        loader,
        new Class[]{IBinder.class},
        new ClipboardHookHandler(clipboardBinder)
    );
    
    // 替换系统服务
    Field field = ServiceManager.class.getDeclaredField("sCache");
    field.setAccessible(true);
    Map<String, IBinder> cache = (Map) field.get(null);
    cache.put("clipboard", proxyBinder);
} catch (Exception e) {
    e.printStackTrace();
}

2. Xposed框架(免root)

java 复制代码
// 示例:拦截所有Toast显示
public class ToastHook implements IXposedHookLoadPackage {
    @Override
    public void handleLoadPackage(XC_LoadPackage.LoadPackageParam lpparam) {
        XposedHelpers.findAndHookMethod(
            android.widget.Toast.class,
            "show",
            new XC_MethodHook() {
                @Override
                protected void beforeHookedMethod(MethodHookParam param) {
                    Log.d("Hook", "即将显示Toast");
                }
            });
    }
}

五、Hook的风险与防御

风险

  • 稳定性问题:Hook失败可能导致崩溃
  • 兼容性问题:不同系统版本行为不同
  • 法律风险:恶意Hook可能违法

防御Hook的方案

java 复制代码
// 1. 检查调用栈
StackTraceElement[] stackTrace = Thread.currentThread().getStackTrace();
for (StackTraceElement element : stackTrace) {
    if (element.getClassName().contains("xposed")) {
        throw new SecurityException("检测到Xposed!");
    }
}

// 2. 签名校验
if (!"正版签名".equals(getPackageManager().getPackageInfo(pkgName, 0).signatures[0].toCharsString())) {
    System.exit(0);
}

六、Hook实战案例

案例1:拦截短信发送

java 复制代码
// 使用Xposed Hook短信发送
XposedHelpers.findAndHookMethod(
    android.telephony.SmsManager.class,
    "sendTextMessage",
    String.class, String.class, String.class, PendingIntent.class, PendingIntent.class,
    new XC_MethodHook() {
        @Override
        protected void beforeHookedMethod(MethodHookParam param) {
            String number = (String) param.args[0];
            String text = (String) param.args[2];
            Log.d("SMS_HOOK", "拦截短信:" + number + " 内容:" + text);
            param.setResult(null); // 阻止发送
        }
    }
);

案例2:修改网络请求返回值

java 复制代码
// 使用OkHttp拦截器Hook
OkHttpClient client = new OkHttpClient.Builder()
    .addInterceptor(chain -> {
        Request request = chain.request();
        if (request.url().toString().contains("api/vip")) {
            String fakeResponse = "{\"isVip\":true}";
            return new Response.Builder()
                .code(200)
                .body(ResponseBody.create(fakeResponse, MediaType.get("application/json")))
                .build();
        }
        return chain.proceed(request);
    })
    .build();

七、如何学习Hook?

  1. 先学Java反射(Class、Method、Field)
  2. 理解动态代理(Proxy.newProxyInstance)
  3. 研究Xposed框架(适合安卓逆向)
  4. 实践小案例(如修改返回值、监控函数调用)

Hook就像"代码魔术",用得好能实现强大功能,用不好会引发灾难,请遵守法律法规使用! 🎩✨

相关推荐
阿巴斯甜21 小时前
Android 报错:Zip file '/Users/lyy/develop/repoAndroidLapp/l-app-android-ble/app/bu
android
Kapaseker21 小时前
实战 Compose 中的 IntrinsicSize
android·kotlin
xq95271 天前
Andorid Google 登录接入文档
android
黄林晴1 天前
告别 Modifier 地狱,Compose 样式系统要变天了
android·android jetpack
冬奇Lab1 天前
Android触摸事件分发、手势识别与输入优化实战
android·源码阅读
城东米粉儿2 天前
Android MediaPlayer 笔记
android
Jony_2 天前
Android 启动优化方案
android
阿巴斯甜2 天前
Android studio 报错:Cause: error=86, Bad CPU type in executable
android
张小潇2 天前
AOSP15 Input专题InputReader源码分析
android
_小马快跑_2 天前
Kotlin | 协程调度器选择:何时用CoroutineScope配置,何时用launch指定?
android