Skip to content

Commit 4335b2d

Browse files
committed
备份
1 parent a4ada47 commit 4335b2d

File tree

3 files changed

+145
-2
lines changed

3 files changed

+145
-2
lines changed

src/develop/DailyDev.md

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -407,8 +407,6 @@ registry.addHandler(new WsServerNodeHandler(), "/*")
407407
```java
408408
@Override
409409
public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
410-
registry.addHandler(shellWebSocketHandler, "/ws/shell/{sessionId}")
411-
.setAllowedOrigins("*");
412410

413411
registry.addHandler(new WsServerNodeHandler(), "/*") // ❌ 错误:拦截所有路径
414412
.addInterceptors(new WsHandshakeInterceptor())

src/develop/Java/9_Hook.md

Lines changed: 141 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,141 @@
1+
# Java Hook 方法整理
2+
3+
在 Java 中,Hook 技术主要用于在不修改原始代码的情况下,对程序的执行流程进行拦截和增强。根据 Hook 生效的时机,可以将其分为 **静态 Hook (编译期/加载期)****动态 Hook (运行期)**
4+
5+
## 1. 静态 Hook (Static Hook)
6+
7+
静态 Hook 指在程序运行之前(编译阶段)或类加载阶段(Load Time)修改字节码。
8+
9+
### 1.1 AspectJ (编译时织入 - Compile-Time Weaving)
10+
11+
AspectJ 是最成熟的 AOP 框架,它可以在编译阶段将切面代码直接织入到目标类的 `.class` 文件中。
12+
13+
* **原理**:使用 `ajc` 编译器代替 `javac`,在编译时修改字节码。
14+
* **优点**
15+
* 运行效率高(无运行时代理开销)。
16+
* 功能最强(可 Hook 构造函数、静态方法、final 方法、私有方法)。
17+
* **缺点**:需要特定的编译工具链支持,配置相对复杂。
18+
* **示例**
19+
```java
20+
public aspect LogAspect {
21+
// 定义切点:所有 Service 结尾类的所有方法
22+
pointcut serviceMethods(): execution(* *..*Service.*(..));
23+
24+
// 前置通知
25+
before(): serviceMethods() {
26+
System.out.println("Before method execution");
27+
}
28+
}
29+
```
30+
31+
### 1.2 Java Agent (Premain - 加载时织入)
32+
33+
利用 JVM 的 `Instrumentation` API,在类加载(Class Loading)阶段修改字节码。
34+
35+
* **原理**
36+
1. 编写一个包含 `premain` 方法的 Agent Jar
37+
2. 启动应用时添加参数 `-javaagent:myagent.jar`。
38+
3. JVM 启动时加载 Agent,调用 `premain`。
39+
4. Agent 注册 `ClassFileTransformer`。
40+
5. 当类被加载时,Transformer 拦截字节码并进行修改(使用 ASM, Javassist, ByteBuddy 等库)。
41+
* **示例**
42+
```java
43+
public static void premain(String agentArgs, Instrumentation inst) {
44+
inst.addTransformer(new MyClassFileTransformer());
45+
}
46+
```
47+
* **场景**:全链路监控(SkyWalking, Pinpoint)、全局日志埋点。
48+
49+
---
50+
51+
## 2. 动态 Hook (Runtime Hook)
52+
53+
动态 Hook 指在程序运行过程中,动态地创建代理对象或修改已加载的类。
54+
55+
### 2.1 动态代理 (Dynamic Proxy)
56+
57+
JDK 自带的动态代理机制,基于接口实现。
58+
59+
* **原理**:利用 `java.lang.reflect.Proxy` 在内存中生成一个实现了目标接口的新类。
60+
* **限制****只能代理接口**,无法代理未实现接口的类。
61+
* **示例**
62+
```java
63+
Service proxy = (Service) Proxy.newProxyInstance(loader, interfaces, handler);
64+
```
65+
66+
### 2.2 CGLIB / ByteBuddy (子类代理)
67+
68+
通过生成目标类的子类来实现代理。
69+
70+
* **原理**:在运行时动态生成目标类的子类,并重写非 `final` 方法,在子类中插入拦截逻辑。
71+
* **优点**:无需接口,可代理普通类。
72+
* **限制****无法代理 final 类或 final 方法**
73+
* **场景**Spring AOP (无接口时默认使用 CGLIB)。
74+
* **示例 (CGLIB)**
75+
```java
76+
Enhancer enhancer = new Enhancer();
77+
enhancer.setSuperclass(TargetClass.class);
78+
enhancer.setCallback((MethodInterceptor) (obj, method, args, proxy) -> {
79+
System.out.println("Before " + method.getName());
80+
Object result = proxy.invokeSuper(obj, args); // 注意调用 invokeSuper
81+
System.out.println("After " + method.getName());
82+
return result;
83+
});
84+
TargetClass proxy = (TargetClass) enhancer.create();
85+
```
86+
87+
### 2.3 Java Agent (Agentmain - 运行时重定义)
88+
89+
利用 JVMAttach 机制,在 JVM 运行时动态注入 Agent
90+
91+
* **原理**
92+
1. 通过 `VirtualMachine.attach(pid)` 连接到目标 JVM 进程。
93+
2. 加载 Agent Jar,触发 `agentmain` 方法。
94+
3. 获取 `Instrumentation` 实例。
95+
4. 调用 `inst.retransformClasses(targetClass)` 触发类的重定义。
96+
* **能力**:可以在不重启应用的情况下修改类逻辑(热部署)。
97+
* **限制**:运行时修改字节码有严格限制(如不能新增/删除字段或方法,只能修改方法体)。
98+
* **场景**Arthas (在线诊断), JRebel (热部署)。
99+
* **示例**
100+
```java
101+
// Agentmain 入口
102+
public static void agentmain(String agentArgs, Instrumentation inst) {
103+
inst.addTransformer(new MyClassFileTransformer(), true);
104+
try {
105+
// 触发已加载类的重转换
106+
inst.retransformClasses(TargetClass.class);
107+
} catch (UnmodifiableClassException e) {
108+
e.printStackTrace();
109+
}
110+
}
111+
112+
// Attach 客户端代码 (通常在另一个进程运行)
113+
public static void main(String[] args) throws Exception {
114+
String pid = "12345"; // 目标 JVM 进程 ID
115+
VirtualMachine vm = VirtualMachine.attach(pid);
116+
vm.loadAgent("/path/to/agent.jar");
117+
vm.detach();
118+
}
119+
```
120+
121+
### 2.4 Native Hook (JNI / JVMTI)
122+
123+
跳出 JVM 层面,直接在操作系统或 Native 层面进行 Hook
124+
125+
* **原理**:使用 JNI 调用 C/C++ 代码,利用操作系统的 Hook 技术(如 PLT Hook, Inline Hook)或 JVMTI (JVM Tool Interface) 事件回调。
126+
* **场景**
127+
* JVM 自身性能分析(Profiler)。
128+
* 深度调试。
129+
* 系统级调用监控。
130+
131+
---
132+
133+
### 总结对比
134+
135+
| 类别 | 技术方案 | 生效时机 | 核心特点 | 适用场景 |
136+
| :--- | :--- | :--- | :--- | :--- |
137+
| **静态 Hook** | **AspectJ (CTW)** | 编译期 | 修改 .class 文件,性能最高,无限制 | 复杂切面,高性能要求 |
138+
| **静态 Hook** | **Java Agent (Premain)** | 类加载期 | 修改字节码,无侵入 | APM 监控,字节码增强 |
139+
| **动态 Hook** | **JDK 动态代理** | 运行时 | 基于接口,生成代理对象 | RPC, 简单 AOP |
140+
| **动态 Hook** | **CGLIB/ByteBuddy** | 运行时 | 基于子类,生成代理对象 | Spring AOP |
141+
| **动态 Hook** | **Java Agent (Attach)** | 运行时 | 重定义已加载的类 (Retransform) | 在线诊断 (Arthas),热修复 |

src/others/Treasure.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,10 @@ star: "1"
2323

2424
[Syntax Highlight](https://github.com/sbarex/SourceCodeSyntaxHighlight):Mac预览各种代码文件的扩展
2525

26+
[LuLu](https://github.com/objective-see/LuLu):免费Mac防火墙,提醒app联网
27+
28+
[Maccy](https://maccy.app/):Mac上的剪切板,非常好用
29+
2630
# 宝藏博客
2731

2832
[王帅真 | 王帅真的个人博客,分享编程与思维认知](https://blog.qizong007.top/)

0 commit comments

Comments
 (0)