ZEVMS 冒险岛服务端V79 ver2 破解服务端登录人数限制(3)Java Agent动态修改静态变量
上次我们通过X64dbg 拿到了运行脚本,本次我们使用Java Agent做进一步分析
- 试着dump 字节码,能否将解密后的字节码拿到
- 分析程序运行过程,试着动态修改变量以达成目的
在开始之前,大体介绍一下Java Agent,在java程序启动前或启动中可以对字节码进行修改。非常多框架和特性用到了java agent,比如 AspectJ 通过使用java agent织入字节码增强实现AOP,一些RPC框架使用java agent来做一些session id统一侵入等。参考文档:https://blog.csdn.net/ancinsdn/article/details/58276945
要加载java agent 当然,启动脚本也要做相应的修改:
java -javaagent:F:\workspace\class-dump-agent\target\dump-agent-1.0-SNAPSHOT.jar -server -Dnet.sf.odinms.wzpath=wz gui.ZEVMS 其中F:\workspace\class-dump-agent\target\dump-agent-1.0-SNAPSHOT.jar为java agent package后的jar包
1.dump 字节码
在类加载后,可以尝试将字节码存到文件中,逻辑很简单
public class ClassDumpAgent implements ClassFileTransformer {
public byte[] transform(ClassLoader loader, String className, Class<?> classBeingRedefined, ProtectionDomain protectionDomain, byte[] classfileBuffer) throws IllegalClassFormatException {
String filePath = "/tmp/" + className.replace('.', '/') + ".class";
System.out.println("dump "+className + " to "+filePath + " size="+classfileBuffer.length);
try {
File file = new File(filePath);
File fileParent = file.getParentFile();
if(!fileParent.exists()){
fileParent.mkdirs();
}
OutputStream out = new FileOutputStream(filePath);
InputStream is = new ByteArrayInputStream(classfileBuffer);
byte[] buff = new byte[1024];
int len = 0;
while((len=is.read(buff))!=-1){
out.write(buff, 0, len);
}
is.close();
out.close();
System.out.println("dump "+ className + " complete");
} catch (Exception e) {
System.out.println(e.getMessage());
e.printStackTrace();
}
return null;
}
}
但结果不理想,dump出来的字节码依旧还是加密过的。
究其原因,是该加密的class文件是jvm里的C++书写的BootStrap ClassLoader解密和加载的,而不是在java层自己写的ClassLoader负责解密的,java agent拿到的依旧是输入到jvm之前的字节码。
可以说该JVM中,class文件的格式本就是加密后的方式,相当于jvm输入字节码的协议都修改了。
2.实时修改变量
虽然字节码反编译不好做,但是加载之后的类还是要遵循java内存模型的,所以我们可以通过反射拿到这些类的方法、成员变量,看看有什么办法。
public class ClassDumpAgent implements ClassFileTransformer {
static Set classNames = new HashSet(){{
this.add("constants.ServerConstants");
this.add("gui.ZEVMS");
this.add("server.ServerProperties");
this.add("handling.world.MapleParty");
}};
public byte[] transform(ClassLoader loader, final String className, final Class<?> classBeingRedefined, ProtectionDomain protectionDomain, final byte[] classfileBuffer) throws IllegalClassFormatException {
String classNamePot = className.replace('/','.');
if(!classNames.contains(classNamePot)){
return null;
}
new Thread(new Runnable() {
@Override
public void run() {
startDump(className,classBeingRedefined,classfileBuffer);
}
}).start();
return null;
}
public void startDump(String className,Class<?> classBeingRedefined, byte[] classfileBuffer){
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
String classNamePot = className.replace('/','.');
try {
Class cc = Class.forName(classNamePot);
Field[] fields = Class.forName(classNamePot).getDeclaredFields();
Method[] methods = cc.getDeclaredMethods();
System.out.println("CLASS: "+classNamePot);
System.out.println("field-------");
Object instance = null;
for(Field field : fields){
System.out.println(field.getName() + ":" +field.getType().getName()+ "static:" + Modifier.isStatic(field.getModifiers()));
if(field.getName().equals("instance")){
field.setAccessible(true);
instance = field.get(Object.class);
System.out.println(instance);
}
if(field.getName().equals("显示人数")){
field.setAccessible(true);
Object f = field.get(instance);
System.out.println(f);
}
if(field.getName().equals("props")){
field.setAccessible(true);
Object f = field.get(Object.class);
Properties props = (Properties)f;
props.list(System.out);
}
}
System.out.println("method-------");
for(Method method: methods){
System.out.println(method.getName());
}
System.out.println("dump "+ className + " complete");
} catch (Exception e) {
System.out.println(e.getMessage());
e.printStackTrace();
}
}
}
这样就可以将一些感兴趣的类静态变量内容打印出来看一下了
接下来这就是个纯体力和解密的活了,最终我找到了这个变量, handling.world.MapleParty 类中的静态变量"容纳人数"(PS:这个老哥是真的都起中文变量名呀)。
只消将这个变量设置大一些,就可以了。
实际运行时发现该变量不是程序启动后就设置的,而是有一个延时,所以程序里做了个循环设置的操作
Class cc = Class.forName(classNamePot);
Field[] fields = Class.forName(classNamePot).getDeclaredFields();
Method[] methods = cc.getDeclaredMethods();
Object instance = null;
for(Field field : fields){
if(Modifier.isStatic(field.getModifiers())){
field.setAccessible(true);
Object f = field.get(Object.class);
System.out.println("class="+classNamePot+" field=" + field.getName()+
":" +field.getType().getName()+ " static:" + " value=" + f);
}
if(field.getName().equals("容纳人数")){
field.setAccessible(true);
field.set(Object.class,MAX_USERS);
final Field fl = field;
instance = field.get(Object.class);
System.out.println(field.getName() +" value="+instance);
new Thread(new Runnable() {
@Override
public void run() {
try {
int trys=6;
while (trys>0) {
Thread.sleep(10000);
Object f = fl.get(Object.class);
System.out.println(fl.getName() + " value=" + f);
fl.set(Object.class,MAX_USERS);
System.out.println(fl.getName() + " value=" + MAX_USERS);
trys--;
}
} catch (Exception e) {
e.printStackTrace();
}
}
}).start();
}
}
至此,通过外挂一个java agent 程序来动态修改程序参数的程序,最终实现了解除服务端不允许超过一个用户登录的限制,虽然粗糙但是管用。

看的我热血沸腾啊
怎么收藏这篇文章?
想想你的文章写的特别好https://www.237fa.com/
想想你的文章写的特别好https://www.ea55.com/
想想你的文章写的特别好www.jiwenlaw.com
文章的确不错啊https://www.cscnn.com/
兄弟写的非常好 https://www.cscnn.com/
真好呢
真好呢
《了不起的女孩》国产剧高清在线免费观看:https://www.jgz518.com/xingkong/35060.html
《帕哈甘吉(导演剪辑版 )》剧情片高清在线免费观看:https://www.jgz518.com/xingkong/135688.html
哈哈哈,写的太好了https://www.lawjida.com/
哈哈哈,写的太好了https://www.lawjida.com/
情感真挚自然,字里行间传递出强烈的感染力。
跳出常规思维,角度独特,令人耳目一新。
对权力结构的解构充满勇气与智慧。
内容的丰富性和深度让人仿佛置身于知识的海洋,受益匪浅。
新项目准备上线,寻找志同道合的合作伙伴coinsrore.com
2025年10月新盘 做第一批吃螃蟹的人coinsrore.com
新车新盘 嘎嘎稳 嘎嘎靠谱coinsrore.com
新车首发,新的一年,只带想赚米的人coinsrore.com
新盘 上车集合 留下 我要发发 立马进裙coinsrore.com
做了几十年的项目 我总结了最好的一个盘(纯干货)coinsrore.com
新车上路,只带前10个人coinsrore.com
新盘首开 新盘首开 征召客户!!!coinsrore.com
新项目准备上线,寻找志同道合 的合作伙伴coinsrore.com
新车即将上线 真正的项目,期待你的参与coinsrore.com
新盘新项目,不再等待,现在就是最佳上车机会!coinsrore.com
新盘新盘 这个月刚上新盘 新车第一个吃螃蟹!coinsrore.com
2025年10月新盘 做第一批吃螃蟹的人coinsrore.com
新车新盘 嘎嘎稳 嘎嘎靠谱coinsrore.com
新车首发,新的一年,只带想赚米的人coinsrore.com
新盘 上车集合 留下 我要发发 立马进裙coinsrore.com
做了几十年的项目 我总结了最好的一个盘(纯干货)coinsrore.com
新车上路,只带前10个人coinsrore.com
新盘首开 新盘首开 征召客户!!!coinsrore.com
新项目准备上线,寻找志同道合 的合作伙伴coinsrore.com
新车即将上线 真正的项目,期待你的参与coinsrore.com
新盘新项目,不再等待,现在就是最佳上车机会!coinsrore.com
新盘新盘 这个月刚上新盘 新车第一个吃螃蟹!coinsrore.com