0x00 前言
仅作为笔记,对之前的内容进行补充
Registry
Registry是可以单独创建的
LocateRegistry.createRegistry(1099);
实例化RegistryImpl对象
public static Registry createRegistry(int port) throws RemoteException {
return new RegistryImpl(port);
}
创建LiveRef并且将LiveRef封装为UnicastServerRef,然后setup
public RegistryImpl(int var1) throws RemoteException {
//创建 LiveRef
LiveRef var2 = new LiveRef(id, var1);
//UnicastServerRef封装LiveRef
this.setup(new UnicastServerRef(var2));
}
这里通过exportObject,主要是两个目的,一个是开启soket监听,还有一个就是注册远程类以及创建DGCI
private void setup(UnicastServerRef var1) throws RemoteException {
this.ref = var1;
//调用UnicastServerRef 的exportObject
var1.exportObject(this, (Object)null, true);
}
RegistryImpl代理,创建target对象
public Remote exportObject(Remote var1, Object var2, boolean var3) throws RemoteException {
Class var4 = var1.getClass();
Remote var5;
try {
//创建sun.rmi.registry.RegistryImpl代理
var5 = Util.createProxy(var4, this.getClientRef(), this.forceStubUse);
} catch (IllegalArgumentException var7) {
throw new ExportException("remote object implements illegal remote interface", var7);
}
//检测接口Remote
if (var5 instanceof RemoteStub) {
this.setSkeleton(var1);
}
//创建target对象
Target var6 = new Target(var1, this, var5, this.ref.getObjID(), var3);
this.ref.exportObject(var6);
this.hashToMethod_Map = (Map)hashToMethod_Maps.get(var4);
return var5;
}
创建代理
public static Remote createProxy(Class<?> var0, RemoteRef var1, boolean var2) throws StubNotFoundException {
Class var3;
try {
//获取对应的class,会去校验是否是Remote的子类
var3 = getRemoteClass(var0);
} catch (ClassNotFoundException var9) {
throw new StubNotFoundException("object does not implement a remote interface: " + var0.getName());
}
//检测withoutStubs中是否包含由类名创建的_Stub组成的内容,
//如果有则返回false,没有则创建并且返回false
if (var2 || !ignoreStubClasses && stubClassExists(var3)) {
return createStub(var3, var1);
} else {
ClassLoader var4 = var0.getClassLoader();
Class[] var5 = getRemoteInterfaces(var0);
RemoteObjectInvocationHandler var6 = new RemoteObjectInvocationHandler(var1);
try {
return (Remote)Proxy.newProxyInstance(var4, var5, var6);
} catch (IllegalArgumentException var8) {
throw new StubNotFoundException("unable to create proxy", var8);
}
}
}
private static Class<?> getRemoteClass(Class<?> var0) throws ClassNotFoundException {
while(var0 != null) {
// 反射获取接口,create的时候为:sun.rmi.registry.RegistryImpl
Class[] var1 = var0.getInterfaces();
for(int var2 = var1.length - 1; var2 >= 0; --var2) {
//判断是否是Remote.class的子类,是的话直接返回
if (Remote.class.isAssignableFrom(var1[var2])) {
return var0;
}
}
var0 = var0.getSuperclass();
}
throw new ClassNotFoundException("class does not implement java.rmi.Remote");
}
private static RemoteStub createStub(Class<?> var0, RemoteRef var1) throws StubNotFoundException {
//类名+_Stub
String var2 = var0.getName() + "_Stub";
try {
//调用输入类的构造方法
Class var3 = Class.forName(var2, false, var0.getClassLoader());
Constructor var4 = var3.getConstructor(stubConsParamTypes);
return (RemoteStub)var4.newInstance(var1);
} catch (ClassNotFoundException var5) {
throw new StubNotFoundException("Stub class not found: " + var2, var5);
} catch (NoSuchMethodException var6) {
throw new StubNotFoundException("Stub class missing constructor: " + var2, var6);
} catch (InstantiationException var7) {
throw new StubNotFoundException("Can't create instance of stub class: " + var2, var7);
} catch (IllegalAccessException var8) {
throw new StubNotFoundException("Stub class constructor not public: " + var2, var8);
} catch (InvocationTargetException var9) {
throw new StubNotFoundException("Exception creating instance of stub class: " + var2, var9);
} catch (ClassCastException var10) {
throw new StubNotFoundException("Stub class not instance of RemoteStub: " + var2, var10);
}
}
设置setSkeleton,同时会创建skel
public void setSkeleton(Remote var1) throws RemoteException {
//检测withoutSkeletons是否存在
if (!withoutSkeletons.containsKey(var1.getClass())) {
try {
//不存在则创建类_Skel
this.skel = Util.createSkeleton(var1);
} catch (SkeletonNotFoundException var3) {
withoutSkeletons.put(var1.getClass(), (Object)null);
}
}
}
然后通过exportObject开启socket,并且绑定远程对象,至此,Registry启动完成
public void exportObject(Target var1) throws RemoteException {
synchronized(this) {
//检测socket是否开启
this.listen();
++this.exportCount;
}
boolean var2 = false;
boolean var12 = false;
try {
var12 = true;
//将target绑定到ObjectTable中去
super.exportObject(var1);
var2 = true;
var12 = false;
} finally {
if (var12) {
if (!var2) {
synchronized(this) {
this.decrementExportCount();
}
}
}
}
if (!var2) {
synchronized(this) {
this.decrementExportCount();
}
}
}
DGCI
在创建Registry的时候,生成Target,会同时创建DGCI分布式垃圾回收。
DGCImpl.class
rt.jar!\sun\rmi\transport\DGCImpl.class
在创建的DGCImpl_Skel(服务端)中,通过dispatch触发反序列化
server
通过stub绑定,进行序列化
然后通过skel进行反序列化