浅谈逆向——从案例谈OD的使用(OD的使用2)

从TraceMe谈OD基本操作

案例来自加密与解密第四版 附上下载链接 传送门:

链接: https://pan.baidu.com/s/1CBjbHRWnd-ULrsWfiAZhlg 提取码: 9ede

准备工作

Windows程序由于要使用API函数,在分析中以API函数作为切入点就使过程变得容易起来。·先了解程序序列号验证流程。
1.输入用户名和序列号;
2.使用GetDlgItemTextA函数把字符读出;
3.对输入字符进行计算;
4.使用lstrcmp函数进行比较.
所以上述的函数就是我们下断点分析的目标,追踪程序序列号验证过程。
(这种为了解密制作的小程序一般称为"CrackMe)
在这里插入图片描述

在这里插入图片描述

加载目标文件进行调试

为了让OD中断在程序入口点,在加载前需要在Options->Debugging options中设置。在event标签里,一般需要将断点设置在WinMain处。
在这里插入图片描述

寄存器

ESP 栈指针 指向栈顶
EIP 当前要执行指令(无法通过寄存器面板修改,只能通过在反汇编窗口New origin here改变EIP及当前执行指令的位置,程序会从这条指令开始执行)

寄存器下方显示的是标志寄存器
C,P,…,O;只能在0/1之间切换

单步追踪

F2 设置断点
F7 单步步进 遇到call指令跟进
F8 单步步过 遇到call指令路过,不跟进
F9/菜单栏中播放按钮 运行程序
F12 暂停程序 处理死循环使用

Ctrl+F2 重新调试目标程序(OD将结束目标进程并重新加载它)
Ctrl+F7 在用户按ESC/F12或遇到其他断点时停止重复单步步进
Ctrl+F8 在用户按ESC/F12或遇到其他断点时停止重复单步步过
Ctrl+F9 直到出现ret指令时中断,返回调用call指令的位置。执行到返回(Execute till return)OD会停止在第一个ret/retf/iret 遇到ret指令时暂停还是路过 在调试选项中设置
➖ 在进入子程序的过程中,回看之前单步追踪的代码

Alt+F9 若进入系统领空,可瞬间回到应用程序领空 Execute till user code(执行到用户代码)
双击EIP或者点击view菜单中的C 让光标回到当前EIP指向的语句

call XXXXXX 表示调用XXXXXX处的子程序(调用完毕后返回call指令的下一条语句,在栈中这条语句被作为返回地址压入)
ret 返回地址出栈,从而实现转移到返回地址处

领空”这个词来形容我们在调试某个程序的时候的正在操作或观察的内存区域,在某一时刻,CPU 的 CS:IP(EIP) 所指向的某一段代码的所有者所在的区域。指向程序区域称为程序领空,指向操作系统(操作系统也是一种应用程序)称为系统领空。

设置断点

断点(Break point)可以让程序中断在指定的地方,从而对其进行分析。
将光标移动至所需要处,点击F2键或者双击Hex dump(16进制机械码)即可设置断点,取消方法同设置。(设置断点后虚拟地址背景变为红色,正常情况为黑色,对比图如下)
在这里插入图片描述
设置断点后,使用Alt+B或单击菜单功能项中的B打开断点窗口,激活和已禁止表示断点激活的状态,按空格键可以切换二者。选中后DEL键可以删除断点,也可以通过右键菜单来管理这些断点,在断点窗口中不显示硬件断点。
在这里插入图片描述

当关闭程序时,OD自动将当前应用程序的断点位置保存在其安装目录下的*.udd 文件中,在下次运行时这些断点依然有效,如果断点设置在了当前应用程序之外,OD将发出警告。在调试选项中安全栏,取消在代码段外设置断点时警告可关闭警告。
在这里插入图片描述

实例调试分析(TraceMe.exe)

Win32程序大量调用了系统提供的API函数,在合适的API函数下断就容易发现关键代码。
1

  • 获取文本框中的字符,通常使用的API函数是GetDlgItemText(A/W)/GetWindowText(A/W)函数,也可以直接发送消息获取文本框中的文本。

  • 使用Ctrl+G 打开跟随表达式窗口,查找上述API函数,设置断点查看程序获取输入使用的方法,如果这个函数被调用,OD就会在调用时中断(操作系统不同,函数入口地址不同)。
    首先来到函数入口处,将虚拟地址拉宽会在地址后看到字符串(操作系统动态链接库.API函数名),程序通过这种方法调用了Windows操作系统动态链接库USER32.DLL的API的。

  • 在这里插入图片描述

  • 设置了断点就开始捕捉任何对下断函数的调用,用OD加载程序后输入并确定,逐个尝试,直到程序中断在OD中,位置就是函数GetDlgItemTextA开始的地方。

  • 另一种方法查找函数的调用地址,在反汇编窗口右键菜单-查找当前模块的名称或者按下Ctrl+N,获取TraceMe的API名称列表,这个窗口中列出了程序所有调用的系统动态链接库的函数,想要查找关注的API函数,只需要输入名称。在目标函数上按Enter或者通过右键菜单反汇编窗口中跟随即可。若OD中有CmdBar.dll插件,会显示命令行环境,使得下断更加方便。

  • 在这里插入图片描述

  • 使用F8单步走出或者Alt+F9回到函数调用的地方到达程序领空。开始分析
  • 在这里插入图片描述
  • 阅读代码时要清楚API函数的定义(查手册)
  • API函数大都采用_stdcall调用约定,即函数入口参数按从右到左顺序入栈,由被调用者清理栈中的参数,返回值放在eax寄存器中。相关API函数,push指令入栈传送给API。

如果使用的是GetWindowText函数,会把取出的文本放到由lpString(LPTSTR 是一个长指针,指向由空字符终止的字符串)指定的位置。要想获取数据需要在LPTSTR lpString 处在数据窗口处查看eax的值。单步步过,直到发现所需的信息。

爆破法解决问题

在这里插入图片描述
004011F5处不跳转表示注册成功,使用如下方法判断。

  • OD寄存器面板 在执行到跳转行时,可以通过双击标志寄存器ZF来该表ZF的值(跳转的判断条件),但是无法保存,只能调试用。
  • 将跳转用空指令填充,双击所选行反汇编代码,使用nop替换跳转,没有跳转指令程序只能依次运行,达到了和更改标志寄存器同样的效果。目前修改的是内存中的数据,为了使修改一直有效,必须把这个变化写入磁盘文件,OD提供了这个功能。
    选中修改后的部分,单击右键,选择复制到可执行文件->选择。
    右键保存,会让你生成一个新文件,新文件就是修改过后实现你功能的文件。

在这里插入图片描述
在这里插入图片描述

通过屏蔽程序的某些功能或者改变程序流程使程序的保护方法失效的方法称为爆破。

算法分析

在这里插入图片描述

跟进虚拟地址为004011E5的子程序 call 00401340,子程序初始化栈
程序利用esp来访问参数,利用ebp来处理字符串name[i]
在这里插入图片描述

  • 401367h 获取405030h处的数据 使用的方法在数据窗口中 用Ctrl+G打开跟随表达式窗口 输入地址即可以十六进制机器码的形式显示出来。
  • lstrcmp原型
int lstrcmp(LPCTSTR lpString1  LPCTSTR lpString2 );
//	如果相等返回0
  • 高级语言描述©
BOOL RE(TCHAR *rCode,TCHAR *name,int len)
{
	int i,j;
	unsigned long code=0;
	char Table[8]={0xC,0xA,0x13,0x9,0xC,0xB,0xA,0x8};
	for(i=3,j=0;i<len;i++,j++)
	{
		if(j>7)
		j=0;
		code+=((BYTE)name[i])*Table[j];
	}
	wsprintf(name,TEXT("%ld"),code);
	if(lstrcmp(rCode,name)==0)
		return true;
	else
		return false;
}
  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值