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

相关推荐
信工院李平13 分钟前
安卓jks提取pem和pk8文件
android
二猛子25 分钟前
MySQL-多版本并发控制MVCC
android·mysql·adb
Yang-Never2 小时前
Git -> Git使用Patch失败error: patch failed: patch does not apply的解决办法
android·git·android studio
woodWu3 小时前
Android编译时动态插入代码原理与实践
android
百锦再4 小时前
Android Studio 实现自定义全局悬浮按钮
android·java·ide·app·android studio·安卓
百锦再4 小时前
Android Studio 项目文件夹结构详解
android·java·ide·ios·app·android studio·idea
老码识土4 小时前
Kotlin 协程源代码泛读:Continuation
android·kotlin
行墨6 小时前
Replugin 的hook点以及hook流程
android·架构
一一Null6 小时前
Access Token 和 Refresh Token 的双令牌机制,维持登陆状态
android·python·安全·flask
_祝你今天愉快6 小时前
深入理解 Android Handler
android