首页
苏兮影视
随笔记
壁纸
更多
直播
时光轴
友联
关于
统计
Search
1
软件添加id功能按钮
708 阅读
2
v2ray节点搭建
507 阅读
3
typecho非常有特色的模块
460 阅读
4
QQxml消息卡片生成源码
421 阅读
5
Linux下提权常用小命令
366 阅读
谈天说地
建站源码
经验教程
资源分享
动漫美图
登录
Search
标签搜索
java
flutter
springboot
rust
安卓
linux
vue
docker
joe
快捷键
git
fish shell
maven
redis
netty
dart
groovy
js
设计模式
rpc
尽意
累计撰写
95
篇文章
累计收到
38
条评论
首页
栏目
谈天说地
建站源码
经验教程
资源分享
动漫美图
页面
苏兮影视
随笔记
壁纸
直播
时光轴
友联
关于
统计
搜索到
2
篇与
的结果
Java动态代理rpc
Java 动态代理在远程过程调用(RPC)中非常有用,可以隐藏网络通信的复杂性,使得远程调用看起来像是本地方法调用。场景说明假设我们有一个简单的服务接口 CalculatorService,它提供了加法和减法的功能。我们希望客户端可以通过动态代理的方式调用这个服务接口,实际上这些调用会通过网络发送到远程的服务端进行计算。1. 定义服务接口首先定义一个服务接口 CalculatorService:// 服务接口 public interface CalculatorService { int add(int a, int b); int subtract(int a, int b); }2. 实现服务端服务端实现了 CalculatorService 接口,并在远程提供服务:import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.net.ServerSocket; import java.net.Socket; // 服务端实现类 public class CalculatorServiceImpl implements CalculatorService { @Override public int add(int a, int b) { return a + b; } @Override public int subtract(int a, int b) { return a - b; } public static void main(String[] args) throws Exception { ServerSocket serverSocket = new ServerSocket(8080); System.out.println("服务端启动,等待连接..."); while (true) { Socket clientSocket = serverSocket.accept(); ObjectInputStream input = new ObjectInputStream(clientSocket.getInputStream()); String methodName = input.readUTF(); int a = input.readInt(); int b = input.readInt(); ObjectOutputStream output = new ObjectOutputStream(clientSocket.getOutputStream()); CalculatorService service = new CalculatorServiceImpl(); if (methodName.equals("add")) { output.writeInt(service.add(a, b)); } else if (methodName.equals("subtract")) { output.writeInt(service.subtract(a, b)); } output.flush(); clientSocket.close(); } } }3. 实现客户端动态代理客户端使用动态代理调用远程服务:import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.net.Socket; // 动态代理处理器 public class RpcInvocationHandler implements InvocationHandler { private String host; private int port; public RpcInvocationHandler(String host, int port) { this.host = host; this.port = port; } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { Socket socket = new Socket(host, port); ObjectOutputStream output = new ObjectOutputStream(socket.getOutputStream()); output.writeUTF(method.getName()); for (Object arg : args) { output.writeObject(arg); } ObjectInputStream input = new ObjectInputStream(socket.getInputStream()); Object result = input.readObject(); input.close(); output.close(); socket.close(); return result; } } // 客户端代码 public class RpcClient { @SuppressWarnings("unchecked") public static <T> T getProxy(Class<T> serviceClass, String host, int port) { return (T) Proxy.newProxyInstance(serviceClass.getClassLoader(), new Class<?>[]{serviceClass}, new RpcInvocationHandler(host, port)); } public static void main(String[] args) { CalculatorService service = RpcClient.getProxy(CalculatorService.class, "localhost", 8080); int result1 = service.add(10, 5); int result2 = service.subtract(10, 5); System.out.println("加法结果: " + result1); System.out.println("减法结果: " + result2); } }4. 运行说明服务端:运行 CalculatorServiceImpl,它将开启一个 TCP 服务器,在 8080 端口等待客户端请求。客户端:运行 RpcClient,通过动态代理获得 CalculatorService 的代理对象,并调用 add 和 subtract 方法。这些方法调用将通过网络发送到服务端,由服务端处理并返回结果。5. 执行结果运行客户端后,输出如下:加法结果: 15 减法结果: 56. 解析服务端:简单实现了一个 TCP 服务器,通过 ObjectInputStream 和 ObjectOutputStream 来接收和发送请求。客户端:使用 JDK 动态代理,通过 RpcInvocationHandler 拦截方法调用,将方法名和参数序列化后发送给服务端,再从服务端获取结果。
2024年08月23日
22 阅读
0 评论
1 点赞
2024-08-13
js逆向xhs(二)
分享另一种思路,要明确我们最终的目的都是要拿到加密函数的返回值,这期间做的任何准备都是为了加密值做服务的,所以可以使用websocket作为通信,间接调用加密函数,拿到加密值使用netty作为ws服务器public class WebSocketServer { public static final ChannelGroup channelGroup = new DefaultChannelGroup(GlobalEventExecutor.INSTANCE); public static void main(String[] args) throws Exception { NioEventLoopGroup bossGroup = new NioEventLoopGroup(); NioEventLoopGroup workerGroup = new NioEventLoopGroup(); try { ServerBootstrap bootstrap = new ServerBootstrap(); bootstrap.group(bossGroup, workerGroup) .channel(NioServerSocketChannel.class) .childHandler(new ChannelInitializer<SocketChannel>() { @Override protected void initChannel(SocketChannel ch) { ChannelPipeline p = ch.pipeline(); p.addLast(new HttpServerCodec()); p.addLast(new HttpObjectAggregator(65536)); p.addLast(new HttpContentCompressor()); p.addLast(new WebSocketServerProtocolHandler("/")); p.addLast(new WebSocketFrameHandler()); } }); System.out.println("server run ..."); ChannelFuture future = bootstrap.bind(8080).sync(); future.channel().closeFuture().sync(); } finally { bossGroup.shutdownGracefully(); workerGroup.shutdownGracefully(); } } static class WebSocketFrameHandler extends ChannelInboundHandlerAdapter { @Override public void channelActive(ChannelHandlerContext ctx) throws Exception { super.channelActive(ctx); System.out.println(ctx.channel().remoteAddress()+":connect"); channelGroup.add(ctx.channel()); } @Override public void channelInactive(ChannelHandlerContext ctx) throws Exception { super.channelInactive(ctx); channelGroup.remove(ctx.channel()); System.out.println(ctx.channel().remoteAddress()+":disconnect"); } @Override public void channelRead(ChannelHandlerContext ctx, Object msg) { if (msg instanceof WebSocketFrame) { WebSocketFrame frame = (WebSocketFrame) msg; if (frame instanceof TextWebSocketFrame) { if (channelGroup.size()<2) return; channelGroup.stream().filter(ch->ch != ctx.channel()).forEach(ch->ch.writeAndFlush(frame)); } } } @Override public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) { System.out.println(ctx.channel().remoteAddress()+"连接出错:"+cause.getMessage()); ctx.close(); } } }在浏览器环境运行jsxhs这里由于用到了window全局变量储存加密函数,所以我们只要在控制台或者代码段地方执行我们直接的代码逻辑,因为是在xhs的网站作用域下,是可以直接使用全局变量的const singletonFunction = (function() { let instance; let executed = false; function createInstance() { if (!executed) { var sgin = window._webmsxyw; const ws = new WebSocket('ws://127.0.0.1:8080/'); ws.onopen = function(evt){ ws.send("我已连接,状态良好"); console.log("我已连接,状态良好"); } ws.onmessage = function(evt){ var data = JSON.parse(evt.data); console.log(data,data.c,data.i); ws.send(JSON.stringify(sgin(data.c,data.i))); } executed = true; } } return function() { if (!instance) { instance = createInstance; } return instance; }; })(); singletonFunction()();这里注入的方案有很多,也可以使用代理添加我们自己的逻辑,或者编写油猴脚本也是可以的。说一下手动注入吧,原理都大差不差点开全部选项,选择替换点击选择放置替换的文件夹选择文件夹后允许,勾选上本地替换依旧是找到加密函数的位置,通过搜索匹配右键该文件,选择替换内容将我们的代码添加到指定位置即可现在保存再刷新网页,就会走我们本地的js代码启动服务端先用websocket在线测试网站查看运行情况https://www.wetools.com/websocket是能成功拿到加密后的数据的接下来就是在项目中拿到这里加密的内容了使用okhttp连接ws服务器def client = new OkHttpClient() def request = new Request.Builder().url("ws://localhost:8080").build() client.newWebSocket(request,new WebSocketListener() { @Override void onMessage(@NotNull WebSocket webSocket, @NotNull String text) { super.onMessage(webSocket, text) println text } })现在加密值也拿到了,带上加密值正常请求接口即可
2024年08月13日
51 阅读
0 评论
3 点赞