Skip to content

Commit

Permalink
Merge pull request #664 from bytedance/main-hotupdate
Browse files Browse the repository at this point in the history
Main hotupdate
  • Loading branch information
cnguoyj-leminis authored Jul 25, 2024
2 parents 60da438 + 0aa1d2c commit be09ef4
Show file tree
Hide file tree
Showing 24 changed files with 553 additions and 283 deletions.
5 changes: 3 additions & 2 deletions rasp/jvm/JVMAgent/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ jar {
}

shadowJar {
relocate 'org.apache.commons', 'agent.org.apache.commons'
relocate 'org.apache.commons', 'rasp.org.apache.commons'
relocate 'META-INF/native/libnetty', 'META-INF/native/librasp_netty'
}
}

Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,9 @@ public class SmithAgent {
private static Object SmithProberProxyObj = null;
private static long jvmHeapFree = 150;
private static long jvmMetaFree = 20;
private static String probeVersion;
private static String checksumStr;
private static String proberPath;
private static String probeVersion = null;
private static String checksumStr = null;
private static String proberPath = null;
private static Instrumentation instrumentation = null;

public static Object getClassLoader() {
Expand All @@ -48,13 +48,11 @@ public static Object getSmithProbe() {
}

public static void PreProxy(Object MethodNameObj,int classID, int methodID, Object[] args) {

if(SmithProberProxyObj != null) {
String MethodName = (String)MethodNameObj;
Class<?>[] argType = new Class[]{int.class,int.class,Object[].class};
Reflection.invokeMethod(SmithProberProxyObj,MethodName,argType,classID,methodID,args);
}

}

public static void PostProxy(Object MethodNameObj,int classID, int methodID, Object[] args, Object ret, boolean blocked) {
Expand Down Expand Up @@ -104,8 +102,7 @@ private static boolean loadSmithProber(String proberPath, Instrumentation inst)
Class<?>[] loadclassargType = new Class[]{String.class};
SmithProberClazz = (Class<?>)Reflection.invokeMethod(xLoader,"loadClass", loadclassargType,smithProbeClassName);

SmithAgentLogger.logger.info("SmithProbe ClassLoader:"+SmithProberClazz.getClassLoader());

SmithAgentLogger.logger.info("SmithProbe classloader:"+SmithProberClazz.getClassLoader());
Class<?>[] emptyArgTypes = new Class[]{};
if (SmithProberClazz != null) {
Constructor<?> constructor = SmithProberClazz.getDeclaredConstructor();
Expand Down Expand Up @@ -220,7 +217,7 @@ private static class MyCallable implements Callable<String> {
public String call() throws Exception {
xLoaderLock.lock();
try {
if(xLoader != null) {
if(SmithProberObj != null) {
String agent = System.getProperty("rasp.probe");

if(unLoadSmithProber()) {
Expand All @@ -244,9 +241,8 @@ public String call() throws Exception {
SmithAgentLogger.logger.warning(proberPath + " loading fail!");
}
else {
System.setProperty("smith.status", "attach");
System.setProperty("smith.rasp", probeVersion+"-"+checksumStr);

System.setProperty("smith.status", "attach");
System.setProperty("rasp.probe", "smith");
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,13 +29,14 @@ protected Class<?> findClass(String name) throws ClassNotFoundException {
if (classData != null) {
return defineClass(name, classData, 0, classData.length);
}
} catch (IOException ex) {
}
catch (IOException ex) {
throw new ClassNotFoundException("Failed to load class: " + name, ex);
}
} catch (ClassNotFoundException e) {
// If the class is not found in JAR file,try to load from parent class loader
return super.findClass(name);
//throw e;
throw e;
} catch(Throwable t) {
throw t;
}

return null;
Expand Down
3 changes: 0 additions & 3 deletions rasp/jvm/JVMProbe/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,6 @@ dependencies {
implementation group: 'org.ow2.asm', name: 'asm-tree', version: '9.6'
implementation group: 'org.ow2.asm', name: 'asm-commons', version: '9.6'
implementation group: 'io.netty', name: 'netty-all', version: '4.1.85.Final'
implementation group: 'com.fasterxml.jackson.core', name: 'jackson-databind', version: '2.14.0'
implementation group: 'com.fasterxml.jackson.dataformat', name: 'jackson-dataformat-yaml', version: '2.14.0'
implementation group: 'org.apache.commons', name: 'commons-lang3', version: '3.11'
implementation group: 'com.lmax', name: 'disruptor', version: '3.4.4'
implementation 'com.google.code.gson:gson:2.8.9'
Expand Down Expand Up @@ -49,7 +47,6 @@ shadowJar {
relocate 'com.lmax.disruptor', 'rasp.com.lmax.disruptor'
relocate 'com.google','rasp.com.google'
relocate 'com.esotericsoftware', 'rasp.com.esotericsoftware'
relocate 'com.fasterxml.jackson', 'rasp.com.fasterxml.jackson'
relocate 'javassist', 'rasp.javassist'
relocate 'META-INF/native/libnetty', 'META-INF/native/librasp_netty'
}
135 changes: 102 additions & 33 deletions rasp/jvm/JVMProbe/src/main/java/com/security/smith/SmithProbe.java
Original file line number Diff line number Diff line change
@@ -1,8 +1,5 @@
package com.security.smith;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.dataformat.yaml.YAMLFactory;
import com.lmax.disruptor.EventHandler;
import java.io.InputStreamReader;
import java.io.Reader;
Expand Down Expand Up @@ -61,15 +58,25 @@
import java.io.File;
import java.io.FileOutputStream;
import java.security.CodeSource;
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
import java.util.jar.JarFile;


import java.io.FileOutputStream;
import java.io.IOException;

import com.google.gson.Gson;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonArray;
import com.google.gson.GsonBuilder;
import com.security.smith.client.message.*;

import java.io.File;
import java.io.FileOutputStream;

import java.io.ByteArrayOutputStream;
import java.io.PrintStream;

class DetectTimerTask extends TimerTask {
private boolean isCancel = false;
private SmithProbe Probe = null;
Expand Down Expand Up @@ -202,37 +209,48 @@ public void init() {
limits = new ConcurrentHashMap<>();

MessageSerializer.initInstance(proberVersion);
MessageEncoder.initInstance();
MessageDecoder.initInstance();

heartbeat = new Heartbeat();

client = new Client(this);
try {
client = new Client(this);
}
catch(Throwable e) {
SmithLogger.exception(e);
}

disruptor = new Disruptor<>(new EventFactory<Trace>() {
@Override
public Trace newInstance() {
return new Trace();
}
}, TRACE_BUFFER_SIZE, DaemonThreadFactory.INSTANCE);

rulemgr = new Rule_Mgr();
ruleconfig = new Rule_Config(rulemgr);

smithProxy = new SmithProbeProxy();

InputStream inputStream = getResourceAsStream("class.yaml");

ObjectMapper objectMapper = new ObjectMapper(new YAMLFactory());
InputStream inputStream = this.getClass().getResourceAsStream("/class.yaml");

try {
for (SmithClass smithClass : objectMapper.readValue(inputStream, SmithClass[].class)) {
if(!isBypassHookClass(smithClass.getName())) {
if(inputStream != null) {
SmithLogger.logger.info("find class.yaml");
try {
Reader xreader = new InputStreamReader(inputStream);
YamlReader yamlReader = new YamlReader(xreader);
for (SmithClass smithClass : yamlReader.read(SmithClass[].class)) {
smithClasses.put(smithClass.getName(), smithClass);
}
} catch (IOException e) {
SmithLogger.exception(e);
}
} catch (IOException e) {
SmithLogger.exception(e);
}
else {
SmithLogger.logger.info("not find class.yaml");
}


SmithLogger.logger.info("probe init leave");
}
private boolean isBypassHookClass(String className) {
Expand Down Expand Up @@ -302,28 +320,27 @@ public void stop() {

inst.removeTransformer(this);
reloadClasses();
SmithLogger.logger.info("probe stop 0");
SmithLogger.logger.info("Transformer stop");

disable = true;
scanswitch = false;

ClassUploadTransformer.getInstance().stop();

SmithLogger.logger.info("probe stop 1");
SmithLogger.logger.info("Upload Transformer stop");

detectTimer.cancel();
smithproxyTimer.cancel();
SmithLogger.logger.info("probe stop 2");
SmithLogger.logger.info("detect Timer stop");

client.stop();
SmithLogger.logger.info("probe stop 3");

SmithLogger.logger.info("client stop");

ruleconfig.destry();
SmithLogger.logger.info("probe stop 4");
SmithLogger.logger.info("ruleconfig stop");

rulemgr.destry();
SmithLogger.logger.info("probe stop 5");
SmithLogger.logger.info("rulemgr stop");

detectTimerTask = null;
detectTimer =null;
Expand Down Expand Up @@ -380,6 +397,9 @@ public void uninit() {
proberPath = null;
MessageSerializer.delInstance();

MessageEncoder.delInstance();
MessageSerializer.delInstance();
MessageDecoder.delInstance();
SmithLogger.logger.info("probe uninit leave");
SmithLogger.loggerProberUnInit();

Expand Down Expand Up @@ -466,7 +486,13 @@ public void onEvent(Trace trace, long sequence, boolean endOfBatch) {
Filter filter = filters.get(new ImmutablePair<>(trace.getClassID(), trace.getMethodID()));

if (filter == null) {
client.write(Operate.TRACE, trace);
Gson gson = new GsonBuilder()
.registerTypeAdapter(Trace.class, new TraceSerializer())
.registerTypeAdapter(Trace.class, new TraceDeserializer())
.create();
JsonElement jsonElement = gson.toJsonTree(trace);

client.write(Operate.TRACE, jsonElement);
return;
}

Expand All @@ -481,7 +507,13 @@ public void onEvent(Trace trace, long sequence, boolean endOfBatch) {
if (exclude.length > 0 && Arrays.stream(exclude).anyMatch(pred))
return;

client.write(Operate.TRACE, trace);
Gson gson = new GsonBuilder()
.registerTypeAdapter(Trace.class, new TraceSerializer())
.registerTypeAdapter(Trace.class, new TraceDeserializer())
.create();
JsonElement jsonElement = gson.toJsonTree(trace);

client.write(Operate.TRACE, jsonElement);
}

public void printClassfilter(ClassFilter data) {
Expand Down Expand Up @@ -582,7 +614,13 @@ private void checkClassFilter(ClassLoader loader, String className, byte[] class
classFilter.setTransId();
classFilter.setStackTrace(Thread.currentThread().getStackTrace());

client.write(Operate.SCANCLASS, classFilter);
Gson gson = new GsonBuilder()
.registerTypeAdapter(ClassFilter.class, new ClassFilterSerializer())
.registerTypeAdapter(ClassFilter.class, new ClassFilterDeserializer())
.create();
JsonElement jsonElement = gson.toJsonTree(classFilter);

client.write(Operate.SCANCLASS, jsonElement);
SmithLogger.logger.info("send metadata: " + classFilter.toString());
Thread.sleep(1000);
sendByte(classfileBuffer, classFilter.getTransId());
Expand Down Expand Up @@ -694,11 +732,11 @@ public byte[] transform(ClassLoader loader, String className, Class<?> classBein
methodMap
);


classReader.accept(classVisitor, ClassReader.EXPAND_FRAMES);

return classWriter.toByteArray();
} catch (Throwable e) {
}
catch(Throwable e) {
SmithLogger.exception(e);
}

Expand Down Expand Up @@ -733,6 +771,26 @@ public void onControl(int action) {
reloadClasses();
}

public static JsonElement convertJarsToJsonElement(Set<Jar> jars) {
Gson gson = new Gson();

JsonArray jarsArray = new JsonArray();
for (Jar jar : jars) {
JsonObject jarObj = new JsonObject();
jarObj.addProperty("path", jar.getPath());
jarObj.addProperty("implementationTitle", jar.getImplementationTitle());
jarObj.addProperty("implementationVersion", jar.getImplementationVersion());
jarObj.addProperty("specificationTitle", jar.getSpecificationTitle());
jarObj.addProperty("specificationVersion", jar.getSpecificationVersion());
jarsArray.add(jarObj);
}

JsonObject jsonObj = new JsonObject();
jsonObj.add("jars", jarsArray);

return jsonObj;
}

@Override
public void onDetect() {
SmithLogger.logger.info("on detect");
Expand Down Expand Up @@ -770,7 +828,9 @@ public void onDetect() {
jars.add(jar);
}

client.write(Operate.DETECT, Collections.singletonMap("jars", jars));
JsonElement jsonElement = convertJarsToJsonElement(jars);

client.write(Operate.DETECT, jsonElement);
}

@Override
Expand Down Expand Up @@ -940,7 +1000,13 @@ public void onScanAllClass() {
classFilter.setRuleId(rule_id);
classFilter.setStackTrace(Thread.currentThread().getStackTrace());

client.write(Operate.SCANCLASS, classFilter);
Gson gson = new GsonBuilder()
.registerTypeAdapter(ClassFilter.class, new ClassFilterSerializer())
.registerTypeAdapter(ClassFilter.class, new ClassFilterDeserializer())
.create();
JsonElement jsonElement = gson.toJsonTree(classFilter);

client.write(Operate.SCANCLASS, jsonElement);
SmithLogger.logger.info("send metadata: " + classFilter.toString());
sendClass(clazz, classFilter.getTransId());

Expand Down Expand Up @@ -1004,7 +1070,10 @@ private void sendByte(byte[] data, String transId) {
//int send_length = Math.min(packetSize, data.length - offset);
classUpload.setClassData(data);

client.write(Operate.CLASSUPLOAD, classUpload);
Gson gson = new Gson();
JsonElement jsonElement = gson.toJsonTree(classUpload);

client.write(Operate.CLASSUPLOAD, jsonElement);
SmithLogger.logger.info("send classdata: " + classUpload.toString());
//}
}
Expand Down
Loading

0 comments on commit be09ef4

Please sign in to comment.