深入浅出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就像"代码魔术",用得好能实现强大功能,用不好会引发灾难,请遵守法律法规使用! 🎩✨

相关推荐
墨染天姬26 分钟前
【android 驱动开发九】生产者-消费者模型
android·驱动开发
android_xc2 小时前
Android Studio适配butterknife遇到的坑
android·ide·android studio·butterknife
2501_915918413 小时前
uni-app 项目 iOS 上架效率优化 从工具选择到流程改进的实战经验
android·ios·小程序·uni-app·cocoa·iphone·webview
00后程序员张3 小时前
如何在不同 iOS 设备上测试和上架 uni-app 应用 实战全流程解析
android·ios·小程序·https·uni-app·iphone·webview
米豆同学5 小时前
SufraceFlinger图像合成原理(3)-SurfaceFlinger中Layer的创建和销毁
android
米豆同学5 小时前
SufraceFlinger图像合成原理(2)-SurfaceFlinger与应用进程间的通信
android
用户2018792831675 小时前
uses-library:系统应用报NoClassDefFoundError问题
android
叽哥5 小时前
Kotlin学习第 4 课:Kotlin 函数:从基础定义到高阶应用
android·java·kotlin
mg6685 小时前
安卓玩机工具----安卓“搞机工具箱”最新版 控制手机的玩机工具
android·智能手机
诺诺Okami5 小时前
Android Framework- Activity启动2
android