Skip to content

Commit 5130abb

Browse files
authored
Merge pull request #604 from 15911075183ma/feat-dubbo-hessian
feat: 新增对dubbo下hessian协议适配
2 parents 4c360f6 + e36ec1e commit 5130abb

File tree

5 files changed

+183
-6
lines changed

5 files changed

+183
-6
lines changed

dongtai-core/src/main/java/io/dongtai/iast/core/bytecode/enhance/plugin/framework/dubbo/DispatchDubbo.java

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,9 @@ public class DispatchDubbo implements DispatchPlugin {
1414
public static final String ALIBABA_DUBBO_PROXY_HANDLER = " com.alibaba.dubbo.rpc.proxy.AbstractProxyInvoker".substring(1);
1515
public static final String APACHE_DUBBO_PROXY_HANDLER = " org.apache.dubbo.rpc.proxy.AbstractProxyInvoker".substring(1);
1616

17+
//com.caucho.hessian.client.HessianProxy.sendRequest(java.lang.String,java.lang.Object[])
18+
public static final String DUBBO_PROXY_HESSIAN = " com.caucho.hessian.client.HessianProxy".substring(1);
19+
1720
@Override
1821
public ClassVisitor dispatch(ClassVisitor classVisitor, ClassContext context, Policy policy) {
1922
String className = context.getClassName();
@@ -33,7 +36,10 @@ public ClassVisitor dispatch(ClassVisitor classVisitor, ClassContext context, Po
3336
} else if (APACHE_DUBBO_PROXY_HANDLER.equals(className)) {
3437
classVisitor = new DubboProxyHandlerAdapter(classVisitor, context, " org.apache".substring(1));
3538
}
36-
39+
if (DUBBO_PROXY_HESSIAN.equals(className)){
40+
System.out.println("dispatch" + className);
41+
classVisitor = new DubboHessianAdapter(classVisitor, context);
42+
}
3743
return classVisitor;
3844
}
3945

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
package io.dongtai.iast.core.bytecode.enhance.plugin.framework.dubbo;
2+
3+
import io.dongtai.iast.core.bytecode.enhance.ClassContext;
4+
import io.dongtai.iast.core.bytecode.enhance.plugin.AbstractClassVisitor;
5+
import io.dongtai.iast.core.utils.AsmUtils;
6+
import io.dongtai.log.DongTaiLog;
7+
import org.objectweb.asm.ClassVisitor;
8+
import org.objectweb.asm.MethodVisitor;
9+
10+
/**
11+
* @author mazepeng
12+
* @date 2023/11/2 17:40
13+
*/
14+
public class DubboHessianAdapter extends AbstractClassVisitor {
15+
16+
private static final String HESSIAN_ADDREQUESTHEADERS = " com.caucho.hessian.client.HessianProxy.addRequestHeaders(com.caucho.hessian.client.HessianConnection)".substring(1);
17+
18+
public DubboHessianAdapter(ClassVisitor classVisitor, ClassContext context) {
19+
super(classVisitor, context);
20+
}
21+
22+
23+
@Override
24+
public MethodVisitor visitMethod(int access, String name, String descriptor, String signature, String[] exceptions) {
25+
MethodVisitor mv = super.visitMethod(access, name, descriptor, signature, exceptions);
26+
String signCode = AsmUtils.buildSignature(context.getClassName(), name, descriptor);
27+
if (HESSIAN_ADDREQUESTHEADERS.equals(signCode)) {
28+
DongTaiLog.debug("Adding dubbo provider source tracking by {}", signCode);
29+
System.out.println("hessian增强完成");
30+
mv = new DubboHessianAddRequestHeadersAdapter(mv, access, name, descriptor,this.context,"hessian",signCode);
31+
setTransformed();
32+
}
33+
return mv; }
34+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,121 @@
1+
package io.dongtai.iast.core.bytecode.enhance.plugin.framework.dubbo;
2+
3+
import io.dongtai.iast.core.bytecode.enhance.ClassContext;
4+
import io.dongtai.iast.core.bytecode.enhance.plugin.AbstractAdviceAdapter;
5+
import org.objectweb.asm.Label;
6+
import org.objectweb.asm.MethodVisitor;
7+
import org.objectweb.asm.Opcodes;
8+
import org.objectweb.asm.Type;
9+
import org.objectweb.asm.commons.Method;
10+
11+
/**
12+
* @author mazepeng
13+
* @date 2023/11/2 17:40
14+
*/
15+
public class DubboHessianAddRequestHeadersAdapter extends AbstractAdviceAdapter {
16+
17+
18+
private Label exHandler;
19+
20+
private final Type urlType;
21+
private static final Method URL_TO_STRING_METHOD = Method.getMethod("java.lang.String toString()");
22+
23+
24+
public DubboHessianAddRequestHeadersAdapter(MethodVisitor mv, int access, String name, String desc, ClassContext context, String type, String signCode) {
25+
super(mv, access, name, desc, context, type, signCode);
26+
this.urlType = Type.getObjectType("java/net/URL");
27+
28+
29+
}
30+
@Override
31+
public void visitMaxs(int maxStack, int maxLocals) {
32+
visitLabel(this.catchLabel);
33+
visitLabel(this.exHandler);
34+
leaveMethod(ATHROW);
35+
throwException();
36+
visitTryCatchBlock(this.tryLabel, this.catchLabel, this.exHandler, ASM_TYPE_THROWABLE.getInternalName());
37+
super.visitMaxsNew(maxStack, maxLocals);
38+
}
39+
40+
@Override
41+
protected void onMethodEnter() {
42+
this.tryLabel = new Label();
43+
visitLabel(this.tryLabel);
44+
enterMethod();
45+
this.catchLabel = new Label();
46+
this.exHandler = new Label();
47+
}
48+
49+
@Override
50+
protected void onMethodExit(int opcode) {
51+
leaveMethod(opcode);
52+
}
53+
private void leaveMethod(int opcode) {
54+
leaveScope();
55+
}
56+
private void leaveScope() {
57+
invokeStatic(ASM_TYPE_SPY_HANDLER, SPY_HANDLER$getDispatcher);
58+
push(false);
59+
invokeInterface(ASM_TYPE_SPY_DISPATCHER, SPY$leavePropagator);
60+
}
61+
62+
63+
private void enterMethod() {
64+
skipCollect();
65+
enterScope();
66+
Label endLabel = new Label();
67+
traceMethod();
68+
mark(endLabel);
69+
}
70+
71+
@Override
72+
protected void before() {
73+
}
74+
75+
@Override
76+
protected void after(int opcode) {
77+
}
78+
79+
private void skipCollect() {
80+
invokeStatic(ASM_TYPE_SPY_HANDLER, SPY_HANDLER$getDispatcher);
81+
loadArg(0);
82+
invokeInterface(ASM_TYPE_SPY_DISPATCHER,SPY$isSkipCollectDubbo);
83+
pop();
84+
}
85+
86+
private void enterScope() {
87+
invokeStatic(ASM_TYPE_SPY_HANDLER, SPY_HANDLER$getDispatcher);
88+
push(false);
89+
invokeInterface(ASM_TYPE_SPY_DISPATCHER, SPY$enterPropagator);
90+
}
91+
92+
private void isFirstScope() {
93+
invokeStatic(ASM_TYPE_SPY_HANDLER, SPY_HANDLER$getDispatcher);
94+
invokeInterface(ASM_TYPE_SPY_DISPATCHER, SPY$isFirstLevelPropagator);
95+
}
96+
97+
private void traceMethod() {
98+
invokeStatic(ASM_TYPE_SPY_HANDLER, SPY_HANDLER$getDispatcher);
99+
100+
//加载this 1
101+
loadThis();
102+
//2
103+
dup();
104+
visitFieldInsn(Opcodes.GETFIELD,"com/caucho/hessian/client/HessianProxy","_url","Ljava/net/URL;");
105+
invokeVirtual(this.urlType,URL_TO_STRING_METHOD);
106+
//参数 3
107+
loadArg(0);
108+
//arguments 4
109+
pushNull();
110+
//headers 5
111+
pushNull();
112+
//6
113+
push(this.classContext.getClassName());
114+
//7
115+
push(this.name);
116+
// 8
117+
push(this.signature);
118+
//获取静态getDispatcher
119+
invokeInterface(ASM_TYPE_SPY_DISPATCHER, SPY$traceDubboInvoke);
120+
}
121+
}

dongtai-core/src/main/java/io/dongtai/iast/core/handler/hookpoint/controller/impl/DubboImpl.java

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -145,9 +145,14 @@ public static void collectDubboRequestSource(Object handler, Object invocation,
145145
}
146146
}
147147

148+
if (handler.toString().startsWith("hessian")) {
149+
Map<String, String> oldHeaders = (Map<String, String>) requestMeta.get("headers");
150+
sHeaders.putAll(oldHeaders);
151+
}
152+
148153
if (!sHeaders.isEmpty()) {
149154
String traceIdKey = ContextManager.getHeaderKey();
150-
if (headers.containsKey(traceIdKey)) {
155+
if (sHeaders.containsKey(traceIdKey)) {
151156
ContextManager.parseTraceId(sHeaders.get(traceIdKey));
152157
} else {
153158
String newTraceId = ContextManager.currentTraceId();

dongtai-core/src/main/java/io/dongtai/iast/core/handler/hookpoint/service/trace/DubboService.java

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,17 @@
1515
public class DubboService {
1616
public static void solveSyncInvoke(MethodEvent event, Object invocation, String url, Map<String, String> headers,
1717
AtomicInteger invokeIdSequencer) {
18+
19+
1820
try {
21+
String traceId = ContextManager.nextTraceId();
22+
//当类型为HessianURLConnection,只处理添加请求头即可
23+
if (invocation.getClass().getSimpleName().equals("HessianURLConnection")) {
24+
Method method = invocation.getClass().getMethod("addHeader", String.class, String.class);
25+
method.setAccessible(true);
26+
method.invoke(invocation, ContextManager.getHeaderKey(), traceId);
27+
return;
28+
}
1929
TaintPoolUtils.trackObject(event, null, event.parameterInstances, 0, false);
2030
boolean hasTaint = false;
2131
int sourceLen = 0;
@@ -34,10 +44,11 @@ public static void solveSyncInvoke(MethodEvent event, Object invocation, String
3444
event.addParameterValue(1, headers, hasTaint);
3545
}
3646

37-
Method setAttachmentMethod = invocation.getClass().getMethod("setAttachment", String.class, String.class);
38-
setAttachmentMethod.setAccessible(true);
39-
String traceId = ContextManager.nextTraceId();
40-
setAttachmentMethod.invoke(invocation, ContextManager.getHeaderKey(), traceId);
47+
Method setAttachmentMethod = invocation.getClass().getMethod("setAttachment", String.class, String.class);
48+
setAttachmentMethod.setAccessible(true);
49+
setAttachmentMethod.invoke(invocation, ContextManager.getHeaderKey(), traceId);
50+
51+
4152

4253
// add to method pool
4354
event.source = false;

0 commit comments

Comments
 (0)