软件安全逆向——调试分析
调试分析
可理解
PE:win32平台下的可执行文件数据格式(.exe,.dll)
加壳
全称为可执行程序资源压缩
加壳工具:分为压缩类和加密类
附加在原程序上的解压程序的作用过程:通过Windows加载器载入内存后,先于原始程序执行,得到控制权;执行过程中对原始程序进行解密,还原,还原完成后再把控制权交还给原始程序,执行原来的代码程序。
Windows系统是哟个的处理器存取模式及对应的内存层面:用户模式(虚拟内存地址)和内核模式(物理内存地址)。
程序从虚地址到实地址(物理内存地址)的转换过程称为程序的再定位
存放差异
PE文件中的数据按照磁盘数据标准存放,当一个数据节不足0x200时,空位会被0x00填充,超出时会将下一个0x200分配给这个节使用,因此文件中的数据节大小永远是0x200的1整数倍;
PE文件中的数据按照内存数据标准存放,以0x1000字节为基本单位组织,空位以0x00补全,超出把下一节分配给它,文件中的数据总是0x1000的整数倍;
x64dbg快捷键:
F2 设断点 F8单步步过(不进入) F7单步步过(会步入子程序) F9 运行 F4运行到选定位置
需掌握
PE文件格式
- 在程序被执行时,操作系统会按照PE文件格式的约定去相应地方准确定位各种类型的资源并分别装入内存的不同区域;
- 将可执行文件分成若干数据节,
- rsrc:存放程序的资源;
- text:存放编译产生的二进制机器代码
- idata:导入表,放可执行文件用到的外部函数与文件信息
- data:初始化数据模块,宏定义,初始变量啥的
进程空间
PE对应的进程支配了自己独立的4GB虚拟空间(此空间中定位的地址称为虚拟地址);如今可访问内存已突破4GB限制,但是独立的进程拥有独立的虚拟地址空间的内存管理机制还在沿用。
PE文件与虚拟地址间的映射关系
- 相对虚拟地址(RVA):虚拟地址相对于装载基址的偏移量
- 文件偏移地址(FO):PE文件中的数据在文件中的地址,是相对于文件开头的偏移量
- 虚拟地址(VA):PE文件中的数据被装入内存后的地址(VA=IB+RVA)
- 装载基址(IB):PE文件装入内存时的基地址
PE文件代码注入【实验考察】
注入的PE文件中需包含Printf函数
- 使用x32dbg打开PE文件,记录程序入口地址(如0x0041101e,有
<EntryPoint>的提示) - 在main函数中的空白位置(cc,如00411400),右键选择二进制,进入“编辑”
- 在弹出窗口输入“you are injected”
- 选中更新部分,右键“分析”,将选区视为“ASCII”
- 在“!”的下一行改为十六进制的00(字符串结束符)
- 在00下一行(或其他空位)按空格,依次输入
1 | push 0x00411400 ;字符串地址 |
- 记录下新输入的这个
push的地址(如0x00411412)选择“补丁”保存修补文件 - 用LoadPE打开修补文件,更改程序入口点
EntryPoint为0x00011412(因为要减去IB,IB此时假定为0x00400000),点击save,即成功
软件破解【实验考察】
对于一个字符串输入的.exe文件,利用x32dbg打开,右键“搜索字符串”
破解方式一
定位出错信息行代码(’wrong()…’),双击跳转,可找到对应的push命令地址如(0x00411B61),发现其核心分支判断依据为
1 | test eax,eax ;仅在eax为0时ZF=1,否则置0;若ZF=1,则je跳转到00411B61,执行输出wrong语句 |
因此直接将je指令改为jne,则程序截然相反,即输入错误密码,但进入验证成功分支
此时并未真正修改,还是需要打补丁
破解方式二
进入主函数,发现在call的位置验证密码用的verifyPwd函数,双击进入,在mov eax,dword ptr ss:[ebp+8]处开始更改,将其修改为’mov eax ,1’(取消其验证功能)并把其到pop edi之间的代码全都改为nop(右键二进制,选NOP填充),即可成功破解。
第四章 结
