Reversing and Cracking first simple Progra-0x01

.很开心,今天学习破解自己的第一个程序。
  一个很小的c程序的例子,实现了一个简单的许可证检查。

#include <string.h>
#include <stdio.h>

int main(int argc, char *argv[]) {
        if(argc==2) {
		printf("Checking License: %s\n", argv[1]);
		if(strcmp(argv[1], "AAAA-Z10N-42-OK")==0) {
			printf("Access Granted!\n");
		} else {
			printf("WRONG!\n");
		}
	} else {
		printf("Usage: <key>\n");
	}
	return 0;
}

可以通过输入参数执行这个程序,我们的目标是破解此程序,以使我们绕过此密匙验证。
在这里插入图片描述
  想要查看二进制汇编代码,我们可以使用一个名为gdb(GNU)的调试器。终端输入’'gdb”和要打开的文件路径:
在这里插入图片描述
gdb基本命令
gdb基本命令1:
  backtrace(或bt): 查看各级函数调用及参数
  finish: 连续运行到当前函数返回为止,然后停下来等待命令
  frame(或f)帧编号: 选择栈帧
  info(或i) locals: 查看当前栈帧局部变量的值
  list(或l): 列出源代码,接着上次的位置往下列,每次默认列出10行
  list行号:列出从第几行开始的源代码
  list函数名:列出某个函数的源代码
  next(或n):执行下一行语句
  print(或p):打印表达式的值,通过表达式可以修改变量的值或者调用函数
  quit(或q):退出gdb调试环境
  set var:修改变量的值
  start:开始执行程序,停在main函数第一行语句前面等待命令
  step(或s):执行下一行语句,如果有函数调用则进入到函数中

gdb基本命令2:
  break(或b)行号:在某一行设置断点
  break函数名:在某个函数开头设置断点
  break…if…:设置条件断点
  continue(或c):从当前位置开始连续运行程序
  delete breakpoints 断点号:删除断点
  display 变量名:跟踪查看某个变量,每次停下来都显示它的值
  disable breakpoints 断点号:禁用某个断点
  enable 断点号:启用断点
  info(或i) breakpoints:查看当前设置了哪些断点
  run(或r):从头开始连续运行程序
  undisplay 跟踪显示号:取消跟踪显示

gdb基本命令3:
  watch:设置观察点
  info(或i) watchpoints:查看当前设置了哪些观察点
  x:从某个位置开始打印存储单元的内容,全部当成字节来看,而不是分哪个字节属于哪个变量
  disassemble:反汇编当前函数或者指定的函数,如果disassemble命令后面跟函数名或地址则反汇编指定的函数
  si:执行一条指令
  info registers:显示所有寄存器的当前值,在gdb中表示寄存器名时前面要加个$
  print $(寄存器):打印指定寄存器的值
  x/20 $rsp:显示内存中从当前栈顶开始的20个32位数。

下面回到开始的程序,设置为intel语法展示全部的汇编代码:
在这里插入图片描述
  从一开始顺序的读这段代码是毫无意义的,这里的主要功能显然是要call其它函数做字符串的比较(strcmp),因此只需要绘制粗略的控制流程心里图就可以了。
  开始的时候会和2进行比较
在这里插入图片描述
然后紧接着是jne的跳转

  5cc	cmp==2
  5d0	jne 623
  
  		5ea	printf
  		602	strcmp;	(compares strings return 0 if the same)
  		607	test eax, eax
  		609	jne 617	
  			(zeroflag=0  'string different'; ) if zf=1-->610	call puts
  			617
  			61c	puts
  
  623
  628	call puts

现在,我们通过在gdb中逐步执行它:
在main的开头设置一个断点(break *main)
在这里插入图片描述
可以看到RIP(指令指针)指向main中的第一个地址。
使用’si’来执行一条指令,然后来到新的地址,可以看到指令指针的值被修改了。
  现在逐步完成并按照上边控制图中的地址进行操作,使用’ni’进行单步执行,(重复的命令,只需要再次按下enter键就可以)
在这里插入图片描述
  可以判断628 call puts那里调用:printdf "Usage: " information
  再次运行程序,使用随机许可证密钥:
在这里插入图片描述
来到另外一处call的地方,这里的’printf’是检测许可证密钥的信息。
继续执行,来到分支部分ni,ni,ni,ni…
在这里插入图片描述
609 puts输出 “WRONG!”

设置断点再次执行,在执行’test eax,eax’之前停止
在这里插入图片描述
这里设置eax值为0xe,这表示’strcmp’是正确的并返回,zf=1,执行610 call puts:
在这里插入图片描述
再次ni继续执行
在这里插入图片描述
Access Granted!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值