码迷,mamicode.com
首页 > 编程语言 > 详细

Java逆向基础之简单的补丁

时间:2018-04-21 11:19:03      阅读:272      评论:0      收藏:0      [点我收藏+]

标签:java补丁crackme

本文参考:http://www.vuln.cn/7118

本文参考:《Reverse Engineering for Beginners》Dennis Yurichev著

本文需要用到IDA


简单的补丁

看一个例子

public class nag {
	public static void nag_screen() {
		System.out.println("This program is not registered");
	};

	public static void main(String[] args) {
		System.out.println("Greetings from the mega-software");
		nag_screen();
	}
}

我们怎样去掉打印"This program is not registered"这个字符串?

编译后用IDA载入class文件

作者的IDA view视图同步显示了hex的值,可能装了插件或者改了设置,这里的IDA view视图与hex需要切换视图

ALT+T,搜索文本This program is not registered,定位到相关指令附近

技术分享图片

我们首先尝试将getstatic指令改成返回指令

点击getstatic,然后点击hex视图

技术分享图片

可以看到B2 00 02对应这条指令

右键修改B2 为B1,然后右键应用更改

技术分享图片

再切回IDA view视图

技术分享图片

最后菜单点击Edit-->Patch Program-->Apply patches to input file,将更改应用到文件

技术分享图片

在弹出的对话框点确定即可修改class文件

但是这么修改运行的时候会报错,可能是有一些栈和帧的校验

C:\Users\admin\Desktop>java nag
Error: A JNI error has occurred, please check your installation and try again
Exception in thread "main" java.lang.VerifyError: Expecting a stack map frame
Exception Details:
  Location:
    nag.nag_screen()V @1: nop
  Reason:
    Error exists in the bytecode
  Bytecode:
    0x0000000: b100 0212 03b6 0004 b1

        at java.lang.Class.getDeclaredMethods0(Native Method)
        at java.lang.Class.privateGetDeclaredMethods(Unknown Source)
        at java.lang.Class.privateGetMethodRecursive(Unknown Source)
        at java.lang.Class.getMethod0(Unknown Source)
        at java.lang.Class.getMethod(Unknown Source)
        at sun.launcher.LauncherHelper.validateMainClass(Unknown Source)
        at sun.launcher.LauncherHelper.checkAndLoadMain(Unknown Source)

原作者在JDK1.7下不工作,我在1.8下也是,报的是栈帧映射异常

既然此路不通,那么就选另一条路,去掉nag()方法的调用

找到main方法

技术分享图片

中间的

.line 8

invokestatic nag.nag_screen()V

这一句就是调用nag()方法,查看对应的hex视图

技术分享图片

其中的B8 00 06就是调用这个方法

改成00 00 00(填充3个NOP指令)

技术分享图片

对应的IDA view视图

技术分享图片

变成了3个nop指令

最后菜单点击Edit-->Patch Program-->Apply patches to input file,将更改应用到文件

修改完看运行效果

技术分享图片

修改成功


再看第二个例子

这是一个简单的crackme的例子

public class password {
	public static void main(String[] args) {
		System.out.println("Please enter the password");
		String input = System.console().readLine();
		if (input.equals("secret"))
			System.out.println("password is correct");
		else
			System.out.println("password is not correct");
	}
}

反编译后的class用IDA打开

搜索字符串"secret"定位到判断代码附近

技术分享图片

其中ifeq指令当栈顶int型数值等于0时跳转 ,栈顶存的是String.equals()方法的返回值

首先我们考虑改跳转的位置,改到line 6后面的getstatic指令那里,那么这个指令对应偏移块是多少呢

点击getstatic,状态栏会显示

技术分享图片

这个偏移块是24

目标就是将ifeq met002_35修改成ifeq met002_24

ifeq指令所在偏移块是21,35-21=14对应16进制是E,找出hex视图对应的E

技术分享图片

可以看到99 00 0E,所以我们要修改其中的E

那么改成多少呢,24-21=3对应16进制的3,所以将E改成3

技术分享图片

再看看IDA view视图符不符合预期

技术分享图片

最后菜单点击Edit-->Patch Program-->Apply patches to input file,将更改应用到文件

原作者的修改在JDK1.7下不工作,我这里的JDK1.8也报错了

C:\Users\admin\Desktop>java password
Error: A JNI error has occurred, please check your installation and try again
Exception in thread "main" java.lang.VerifyError: Expecting a stackmap frame at branch target 24
Exception Details:
  Location:
    password.main([Ljava/lang/String;)V @21: ifeq
  Reason:
    Expected stackmap frame at this location.
  Bytecode:
    0x0000000: b200 0212 03b6 0004 b800 05b6 0006 4c2b
    0x0000010: 1207 b600 0899 0003 b200 0212 09b6 0004
    0x0000020: a700 0bb2 0002 120a b600 04b1
  Stackmap Table:
    append_frame(@35,Object[#20])
    same_frame(@43)

        at java.lang.Class.getDeclaredMethods0(Native Method)
        at java.lang.Class.privateGetDeclaredMethods(Unknown Source)
        at java.lang.Class.privateGetMethodRecursive(Unknown Source)
        at java.lang.Class.getMethod0(Unknown Source)
        at java.lang.Class.getMethod(Unknown Source)
        at sun.launcher.LauncherHelper.validateMainClass(Unknown Source)
        at sun.launcher.LauncherHelper.checkAndLoadMain(Unknown Source)

这里必须要提的是,这种改法再JDK1.6上是可以运行的

我们也尝试将if eq 这个占用3个字节的指令用0(NOP指令)填充,结果也是校验失败,不能工作

貌似再JDK1.7上比1.6多了更多的帧栈校验


接下来我们尝试替换整个equals方法,并用iconst_1将常数1压入栈顶,这样后面ifeq判断的时候值始终为flase,就不往偏移块35跳转了

iconst_1的指令是0x04

技术分享图片

即将图中的2B 12 07 B6 00 08改成04 00 00 00 00 00

改完后看下IDA view视图

技术分享图片

改完之后工作正常

Java逆向基础之简单的补丁

标签:java补丁crackme

原文地址:http://blog.51cto.com/7317859/2106049

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!