JAVA反序列化之URLDNS链分析

news2024/12/22 13:25:53
简单介绍下urldns链

在此之前最好有如下知识,请自行bing or google学习。
        什么是序列化 反序列化 ?特点!
        java对象反射调用?
        hashmap在java中是一种怎样的数据类型?
        dns解析记录有那些?

思考代码本身设计

废话不说,我们直接上代码 (代码调用链在下面分析)

    public static void main(String[] args) throws Exception {
       // Person person = new Person( name: "aa", age: 22);
        HashMap<URL,Integer> hashmap= new HashMap<URL,Integer>();
        hashmap.put(new URL("http://xxxx.dnslog.cn"),1);
    }

思考如上代码能不能发起一个dns请求! 为什么?

现在解答
        能,因为hashmap.put 中会触发了url类中的hashcode方法,这个方法会调用getHostAddress(u) 从而发起dns请求。

那么为什么是这样的设计呢?
        学过数据结构都知道,有一种数据结构叫做哈希表。简单来说就是依据数据的hash(这里也不一定非要是hash,一定的算法即可),来确定在表中的位置,若hash意外相同(因为表的长度是有限的,算法hash终会有撞的)(这里的hash也不要跟MD5什么的算法混淆),则在相应位置以链表的形式追加数据。这样的好处显而易见,就是可以提前预判自己的存储位置,从而加快代码运行速度。
        那么在java中,hashmap就是这样的一种数据结构。存入的数据都要调用hashcode计算hash值,以此来作为hash表位置的依据。由于java的特性,如果这个数据重写了hashcode方法,则调用的会是这个对象的hashcode方法
        那么为什么URL类要重写hashcode方法呢?请看代码

 public static void main(String[] args) {
        try {
            // 实例化第一个URL对象
            URL url1 = new URL("https://1vg1kk469fx17563.aliyunddos1017.com");

            // 实例化第二个URL对象
            URL url2 = new URL("https://51cto.com");

            // 输出两个URL对象的hashCode值
            System.out.println("URL1 hashCode: " + url1.hashCode());
            System.out.println("URL2 hashCode: " + url2.hashCode());
        } catch (MalformedURLException e) {
            e.printStackTrace();
        }

这两个url对象的hashcode值是否相等呢!答案是的,注:1vg1kk469fx17563.aliyunddos1017.com是51cto.com的别名

为什么会如此。原因在于 虽然说是两个域名长得是不一样,但是你们最终解析的地址是一样的啊,那么你们可以算为同一个对象吗?显然java设计者考虑到了这个问题,他规定hashcode的值不是由url字符串算的,而是根据最终解析地址来算的。所以啊,hashcode被重写,在hashcode中调用了getHostAddress方法,解析dns地址得到host地址来计算hash。

代码方法调用链分析

put方法追进去

 put方法调用了hash把url对象传了进去

 调用对象的hashcode方法

 判断类中的hashcode的值(其初始值=-1) 表示该类url第一次调用hashcode,之后就把这个值存储起来,以备下次调用hashcode直接返回该值。这样设计的目的也是为了避免多次发起dns解析减少运算。若为-1 则调用handler.hashcode

 跟入gethostaddress方法

反序列化链的应用

如上hashmap.put会调用hashcode函数,那么hashcode能不能为反序列化所调用呢?

答案是肯定的,hashmap重写了readobject,这样反序列化会切入到自己的逻辑中。且在readobject中调用了key的hashcode方法

那么为什么hashmap为什么要重写readobject的呢?
        序列化是对象之间的传输,要保证在一个jvm的对象传到另一个jvm,其对象的是一致的。就拿hashmap来说,hash表的存储位置顺序,传到另一个jvm要保证是一致的。不能出现存储的map数据位置不一致的情况,否者这就不是同一个对象了。而重写了readobject 则hashmap在反序列化的时候就更方便调整计算Key和Value的值了.....

URLDNS链分析

前面我们分析,我们第一次建立url对象时其内部的hashcode为默认值-1
在hash.put之后,hashcode就更新了,这样的话在反序列化的时候hashcode不为-1,就无法发起dns请求。但这可是序列化传输对象啊!想要一个怎么样的url对象不可能!
好在hashcode没有不可序列化的标识符,这就意味着这个成员属性是我们可控的。
只需在hash.put改过之后 用反射的方法再将url对象的hashcode的值在改为-1,不就行了。

上代码

package urldns;

import java.io.*;
import java.lang.reflect.Field;
import java.net.URL;
import java.util.HashMap;

public class hashmap {
    public static void main(String[] args) throws Exception {
       // Person person = new Person( name: "aa", age: 22);
        HashMap<URL,Integer> hashmap= new HashMap<URL,Integer>();
        URL url = new URL("http://xxxx.xxxx.xx");
        hashmap.put(url,1);
        // 获取URL类的hashCode字段
        Field hashCodeField = URL.class.getDeclaredField("hashCode");
        hashCodeField.setAccessible(true);
        // 修改URL对象的hashCode值
        hashCodeField.set(url, -1);

        serialize(hashmap);
        unserialize("ser.bin");
    }
    public static void serialize(Object obj) throws IOException, IOException {
        ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("ser.bin"));
        oos.writeObject(obj);
    }
    public static Object unserialize(String Filename) throws IOException, ClassNotFoundException {
        ObjectInputStream ois = new ObjectInputStream(new FileInputStream(Filename));
        Object obj = ois.readObject();
        return obj;
    }



}

分析调试如下

readobect打上断点

 因为hashmap重写了readobject所以会走到这个方法中

readobject中有调用的key的hashcode方法 

 此刻就来到了url的hashcode方法了,我们传入对象hashcode值就是-1让它进入handler.hashcode方法

之后的调试就和之前的一样的了

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1351089.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

canvas绘制网格线示例

查看专栏目录 canvas示例教程100专栏&#xff0c;提供canvas的基础知识&#xff0c;高级动画&#xff0c;相关应用扩展等信息。canvas作为html的一部分&#xff0c;是图像图标地图可视化的一个重要的基础&#xff0c;学好了canvas&#xff0c;在其他的一些应用上将会起到非常重…

ArkTS - @Builder自定义构建函数

这个Builder作用就是可以把组件样式抽离出来&#xff0c;写成公共组件&#xff0c;下边记录下全局自定义构建函数用法及注意的地方。 官方文档&#xff1a;开发者可以将重复使用的UI元素抽象成一个方法&#xff0c;在build方法里调用。 一、用法 下边代码&#xff0c;我在Co…

LangChain(0.0.340)官方文档十一:Agents之Agent Types

LangChain官网、LangChain官方文档 、langchain Github、langchain API文档、llm-universe《Agent Types》、《Examples using AgentType》 文章目录 一、快速入门1.1 概念1.2 基本示例1.2.1 配置LangSmith1.2.2 使用LCEL语法创建Agents1.2.3 使用自定义runtime执行1.2.4 使用A…

uniapp中用户登录数据的存储方法探究

Hello大家好&#xff01;我是咕噜铁蛋&#xff01;作为一个博主&#xff0c;我们经常需要在应用程序中实现用户登录功能&#xff0c;并且需要将用户的登录数据进行存储&#xff0c;以便在多次使用应用程序时能够方便地获取用户信息。铁蛋通过科技手段帮大家收集整理了些知识&am…

八大算法排序@选择排序

目录 选择排序概念算法思想示例步骤1步骤2步骤...n最后一步 代码实现时间复杂度空间复杂度特性总结 选择排序 概念 选择排序&#xff08;Selection Sort&#xff09;是一种简单直观的排序算法。基本思想是在未排序的序列中找到最小&#xff08;或最大&#xff09;元素&#xf…

BIO和NIO编程(待完善)

目录 IO模型 BIO NIO 常见问题 IO模型 Java共支持3种网络编程IO模式&#xff1a;BIO&#xff0c;NIO&#xff0c;AIO BIO 同步阻塞模型&#xff0c;一个客户端连接对应一个处理线程 代码示例&#xff1a; Server端&#xff1a; public class BioServer {private static …

K8S集群部署MySql

挂载MySQL数据卷 在k8s集群中挂载MySQL数据卷 需要安装一个NFS。 在主节点安装NFS yum install -y nfs-utils rpcbind 在主节点创建目录 mkdir -p /nfs chmod 777 /nfs 更改归属组与用户 chown -R nfsnobody:nfsnobody /nfs 配置共享目录 echo "/nfs *(insecure,rw,s…

工业相机如何实现实时和本地Raw格式图像和Bitmap格式图像的保存和相互转换(C#代码,UI界面版)

工业相机如何实现实时和本地Raw图像和Bitmap图像的保存和相互转换&#xff08;C#代码&#xff0c;UI界面版&#xff09; 工业相机图像格式工业相机实现Raw图像和Bitmap图像的保存和转换的技术背景在相机SDK中获取图像转换图像的代码分析工业相机回调函数里保存Bitmap图像数据工…

【Spring】spring的容器创建

目录 控制反转IOC 依赖注入DI 创建spring的容器方式&#xff1a; 思考&#xff1a; spring整合Junit4 控制反转IOC 把对象的创建和对象之间的调用过程&#xff0c;交给Spring管理&#xff0c;IOC是容器&#xff0c;是思想。&#xff01;&#xff01;&#xff01; 依赖注入…

Redis源码——压缩列表

压缩列表ziplist本质上就是一个字节数组&#xff0c;是Redis为了节约内存而设计的一种线性数据结构&#xff0c;可以包含多个元素&#xff0c;每个元素可以是一个字节数组或一个整数。Redis的有序集合、散列和列表都直接或者间接使用了压缩列表。当有序集合或散列表的元素个数比…

打破无声世界:让您的网站会说话

导语&#xff1a;在当今的互联网世界&#xff0c;技术创新日新月异&#xff0c;为广大开发者提供了无数便捷的工具。本文将为您介绍前端文本语音API&#xff0c;这一神奇的技术能够实现文字到语音的转换&#xff0c;为您的项目增添更多可能性。同时&#xff0c;我们还将为您提供…

AI-数学-高中-1.集合(集合特性、常见数集和集合表示方法)

1.集合的三大特性 示例&#xff1a; 2.常见数集&#xff1a; 自然数就是没有负数的整数&#xff0c;即0和正整数。&#xff08;如0&#xff0c;1&#xff0c;2……&#xff0c;0既不是正整数&#xff0c;也不是 负整数 0是整数&#xff09; 整数就是没有小数位 &#xff0c;即…

如何下载Sentinel-1数据

Sentinel-1是欧洲空间局&#xff08;ESA&#xff09;的一组地球观测卫星&#xff0c;属于Copernicus计划的一部分。该计划旨在为全球环境监测提供数据&#xff0c;并支持应对气候变化、自然灾害和人类活动的挑战。Sentinel-1卫星的主要任务是提供全天候、全时段、高分辨率的合成…

FreeRTOS内核控制函数

常见内核控制函数 其中一些函数注意事项和理解&#xff1a; taskYIELD() 挑选了就绪列表中优先级最高的函数进行运行 四个和临界区有关的函数 在临界区中的函数不会被打断&#xff01;&#xff01;&#xff01;比如在创建任务时会后下图这种情况&#xff1a; 似乎上述解释有…

【实用工具】FFmpeg常用的命令

前言 FFmpeg是一个强大的多媒体处理工具&#xff0c;可以用于处理音频、视频和图像。 命令格式 ffmpeg {1} {2} -i {3} {4} {5} 上面命令中&#xff0c;五个部分的参数依次如下。 1.全局参数 2.输入文件参数 3.输入文件 4.输出文件参数 5.输出文件 常见命令行参数 -c&…

【驱动序列】简单聊聊开发驱动程序的缘由和驱动程序基本信息

大家好&#xff0c;我是全栈小5&#xff0c;欢迎来到《小5讲堂》&#xff0c;这是《驱动程序》专栏序列文章。 这是2024年第4篇文章&#xff0c;此篇文章是结合了C#知识点实践序列文章&#xff0c;博主能力有限&#xff0c;理解水平有限&#xff0c;若有不对之处望指正&#xf…

Django HttpResponse 响应对象

目录 一、概述二、测试三、属性和方法四、解读 request 参数 一、概述 所谓 HttpRequest 响应就是服务器返回给客户端的数据&#xff0c;HttpRequest 由程序员自己创建&#xff0c;一般他们通过两种方式来创建。 不使用模板&#xff0c;直接调用 HttpResponse()&#xff0c;返…

虚幻UE 材质-边界混合之PDO像素深度偏移量

2024年的第一天&#xff01;&#xff01;&#xff01;大家新年快乐&#xff01;&#xff01;&#xff01; 可能是长大了才知道 当你过得一般 你的亲朋好友对你真正态度只可能是没有表露出来的冷嘲热讽了 希望大家新的一年平安、幸福、 永远活力满满地追求自己所想做的、爱做的&…

《3D数学基础-图形和游戏开发》阅读笔记 | 3D数学基础 (学习中)

文章目录 3D数学基础矢量/向量概述 - 什么是向量单位矢量&#xff1a;只关注方向不关注大小 数学运算矢量的加法与减法减法的几何意义计算一个点到另一个点的位移矢量的点积与叉积 矩阵矩阵的几何意义 3D数学基础 矢量/向量 在笔记中 变量使用小写字母表示&#xff0c;a由于…

VisioForge SDKs for .NET cRACK

VisioForge 为软件开发人员提供视频捕获、编辑和播放解决方案 使用我们的开发人员软件&#xff0c;您可以创建应用程序来捕获来自各种来源&#xff08;例如网络摄像头、IP 摄像机、摄像机或 PC 屏幕&#xff09;的视频。视频可以保存为所有流行的格式&#xff0c;例如 MP4、Web…