JEP290实践 rmi中采用的局部过滤

rmi中采用的局部过滤

我们之前是调试过rmi的各种利用的,但是这里补充一个新的点(其实应该也能发现,有些地方比如SAC的确正是如此):rmi中的registerImpl也就是注册中心并不是必须的,参考:深入理解rmi原理 - 简书 (jianshu.com)

RMIRegistry 是必须的吗?

No,RMIRegistry 起到的作用只是为了方便client获取到stub对象,如果还有其他的方法让client拿到stub就不需要RMIRegistry 了,因为client一旦拿到了stub就不需要RMIRegistry 了

作者:春天里的布谷鸟
链接:https://www.jianshu.com/p/2c78554a3f36
来源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

我们熟知的bind, lookup, rebind 等等方法实际上是在操作registerImpl

可以看到有四个实现的接口

image-20230414165335531

bind

image-20230414165414651

bind,unbind

image-20230414165433229

list

image-20230414165452325

这个成员变量到底是什么呢

image-20230414165606258

客户端调用的 bind , lookuplist 等操作,实际上是操作 RegistryImplbindings 这个 Hashtable

不信的话可以复现一下,小调一波

老样子我们调试一下,在这里lookup断点

image-20230414171923019

一路进去,见到Lookup就进去

image-20230414171952629

image-20230414172026125

image-20230414172044784

然后到registerImpl_stub这里果然就进不去了,验证刚刚的说法,实际上那么多个lookup要操作的就只是registerImpl_stub

image-20230414172125028

然后可以看到下面就是典型的readObject啥的,原生反序列化

这里我们之所以称RegistryImpl 是一个特殊的对象,是因为 `RegistryImpl 导出过程中生成 Target 对象是一个“定制”的 Target 对象,具体体现在:

1.这个Target 中 id 的 objNum 是固定的,为 ObjID.REGISTRY_ID ,也就是 0 。
2.这个Target 中 disp 是 filter 为 RegisryImpl::RegistryFilter ,skel 为 RegsitryImpl_skel 的 UnicastServerRef 对象。
3.这个Target 中 stub 为 RegistryImpl_stub。

这里我也想调试的,但是没办法

image-20230414172842690

装插件也没用:(52条消息) IDEA 如何进入.class文件上打的的debug断点_idea 怎么断点到class文件里面去_jiuqijack的博客-CSDN博客

这个地方不是在lookup触发的。

image-20230414172956251

找了半天,原来是在创建这个对象的时候触发的

image-20230414173447826

从setup进去,

image-20230414202158839

可以看到,这里的id的objNum= 0

下面的 impl 是 这个RegistryImpl对象

disp的filter不为null (其实是RegistryImpl::RegistryFilter),skel为RegistryImpl_skel的UnicastServerRef

stub为registryImpl_stub

对比普通对象导出的过程中生成的Target, (以下是网图)

image-20230414210340568

具体导出过程:

首先LocateRegistry.createRegistry

image-20230414210544631

强制进去

image-20230414210817973

进去,调用了一些静态方法后,来到这个地方

image-20230414210857005

注意到LiveRef这个地方的id是0

image-20230414215350139

还有一处细节,我上面用的是jdk8u313,就是没有JEP290的,而你看下面

image-20230414215635313

这个是有JEP290限制的

所以整份代码读下来就是

new RegistryImpl(port)中会 new 一个UnicastServerRef对象,将 RegistryImplidOBJID.REGISTRY_ID,也就是 0 ) 存入到 LiveRef 对象,随后 LiveRef对象赋值到 UnicastServerRef 对象中的 ref 字段,并且将 RegsitryImpl::registryFilter 赋值给这个 UnicastServerRef 对象的 filter 字段:

随后我们单步进入this.setup(new UnicastServerRef(var2, RegistryImpl::registryFilter));

循规蹈矩的赋值

image-20230414215942236

注意filter

出来后,进入setup,可以看到马上exportObject

image-20230414220030706

然后就又来到刚刚前面分析过的地方

image-20230414220136157

1.这个Target 中 id 的 objNum 是固定的,为 ObjID.REGISTRY_ID ,也就是 0 。
2.这个Target 中 disp 是 filter 为 RegisryImpl::RegistryFilter ,skel 为 RegsitryImpl_skel 的 UnicastServerRef 对象。
3.这个Target 中 stub 为 RegistryImpl_stub。

exportObject

image-20230414220226948

会调用 TCPEndpoint.export

image-20230414220258843

再跟进

image-20230414220358890

这里调用的就是前面的exportObject

image-20230414220455447

服务端处理请求过程

这里不调了,调了一晚上调了个寂寞,根本找不到! 带带我5555555

处理请求是在 Transport#serviceCall,首先从输入流中读取 id , 匹配到 RegistryImpl 对象对应的 Target

image-20210823035056151

随后调用 UnicastServerRef.dispatch

image-20210823035329060

UnicastServerRef#dispatch 中,由于 UnicastServerRef.skel 不为 null ,所以会调用 UnicastServerRef#oldDispatch 方法:

image-20210823035439867

oldDispatch 中会先调用 unmarshalCustomCallData(in) 方法,再调用 RegistryImpl_skel.dispatch 方法。

image-20210823035730050

unmarshalCustomCallData 方法中会进行判断,如果 UnicastServerRef.filter 不为 null ,就会设置 ConnectionInputStreamserialFilter 字段值为 UnicastServerRef.filter (设置单个 ObjectInputStreamserialFilter 属性,局部过滤的体现):

image-20210823040109705

再看 RegistryImpl_skel.dispatch

image-20210827112153950

我们以 bind 为例来讲解:

image-20210827113103382

暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇