脱壳(PEspin 0.3x)

12 篇文章 1 订阅
3 篇文章 0 订阅

脱壳(PEspin 0.3x)

  

脱壳总结:

  ① 找OEP 难点在于硬件断点有时会失效,解决方法通过特征定位
  ② 找到清除硬件断点的异常函数 配置异常环境(尽可能接收所有的异常),通过在异常点设置硬件断点,来判断前一个异常函 数是否有清除代码,可以最终判断出第三个异常(STI 特权指令异常)的异常函数有清除代 码。
  ③ 解密IAT 按照通用方法,在OEP处的第一个API函数所在的IAT设置硬件写入断点,展开分析。 首先会找到填充IAT的点,然后再通过跟踪找到获取API的地方,之后写脚本(脚本中需要加 一个分支,nop掉硬件断点清除代码)
  ④ 修复代码段,重建IAT 使用通用导入表修复工具,重建IAT
  ⑤ dump、修复IAT
  

开始脱壳

(1)用PEID查看程序信息

  只知道这个PESpin壳,是什么编译器写的也不知道,不过这是一个GUI窗口程序,区段都被改名为15pb了,文件也只有23k的大小,小巧精湛,推测是汇编写的。

在这里插入图片描述
  
(2)找到OEP

  常见API下断点,当断下之后看其返回地址是否是来自主模块,是的话再去调用上一层

	GetVersion 
	GetModuleHandleA 
	GetSystemTimeOfFileTime

  我首先用OD在GetVersionAPI下断点没用,然后测试GetModuleHandleA 就成功,找到OEP界面如下:

在这里插入图片描述
  值得注意的是 下面的一串jmp代码,查看机器码为 FF25
xxx。这说明这是调用IAT地址的代码。(FF15、FF25)

  点击FF25的代码,右键数据窗口跟随,在内存地址上下一个硬件写入断点,重新运行起来后发现没有断下来,说明硬件断点被壳干掉了。

  
(3)分析OEP处的IAT

  在OEP处发现IAT加密了,接下来应该解密IAT,常用方法

	① 在加密的IAT处下访问断点,重新调试,在断点断下附近分析 
	② 在壳获取IAT的过程中的API下断点 
		GetProcAddress,
		GetModuleHandleA/W,
		LoadLibraryA/W 使用第一种方法,
		断点未断下,猜测硬件断点被反。 

  反硬件断点的方法:

①异常回调中可以将调试寄存器清0 
②SetThreadContext以及这个函数的下层函数
③SetUnhandledExceptionFilter 设置顶层异常函数

  函数下断未断下,说明是异常回调起的作用
  
(4)配置OD找到清除硬件断点的地方

  1、选项->调试设置->异常 ,设置如下

在这里插入图片描述
  
  2、插件->StrongOD->Options
在这里插入图片描述
  
  3、接下来就是重新调试,按F9和Shift+F9(跳过异常) 先查看大概又多少个异常断点,经过我的测试,有八、九个异常。
  发出前四个异常的图,第3和第4个异常为同一段代码。因为经过测试,清除硬件断点的地方是第三个异常的回调函数清除了硬件断点。

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
  需要排查找出对硬件断点清0的地方 在异常点设置硬件断点,看能不能断下能不能断下,能断下说明当前异常点前面的异常处理 函数中没有对硬件断点清0
  
  4、每次在一个异常处下硬件断点后,查看OD左下角提示,查看是因为异常断下的,还是因为硬件断点断下的。如果是硬件断点先断下,说明此异常之前,硬件断点没有被清除。

在这里插入图片描述
在这里插入图片描述
  
  5、经过测试,发现在第四个异常处,也就是STI指令的时候,硬件断点就没有断下,显示的是指令异常,说明在第四个异常处之前,硬件断点就已经被干掉了。也就是说,被第三个异常的回调函数干掉了。

  6、找到重新走到第三个异常指令STI处,点击OD 查看->SEH链,双击地址进入异常回调函数

在这里插入图片描述
  
  5、OD动态分析,或者dump内存用IDA分析,可以知道这里就是清0硬件断点的地方。

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

  
(5)找到操作IAT地址的两个地方

  为了方便调试,在第三个异常处下一个断点,然后把OD的环境恢复默认的,每次来到第三个异常处,进入异常回调,把407F57之下的清0操作都NOP掉(Del键)。同时要先进入OEP,在FF25的代码地址里下硬件写入断点,先找到写入IAT的地方,随后单步跟踪一会儿(头一次跟踪可能要十多二十分钟,熟悉后一分钟不到),熟悉壳的花指令代码后就能找到获取IAT的地方。
  第一此按F9要按两次,来到一个为jmp xxx的地方,因为有花指令,要按Ctrl+UP 键才能看到写入IAT 的地方,记录地址
  :红色的代码,说明这部分代码是被动态解密出来的。

在这里插入图片描述
在这里插入图片描述
  
(6)找到操作IAT的地方,后就写OD脚本,要注意的是,脚本里面要把清0硬件断点的地方干掉。

		// 1.定义变量
		var dwClearBreak    // 清除硬件断点的地方
		var dwGetIatAddr    // 得到IAT地址的偏移
		var dwWriteIatAddr  // 写入IAT地址的偏移
		var dwOEP           // 入口点
		var dwTemp          // 临时变量

		mov dwClearBreak, 407F57   // 清除硬件断点的地方
		mov dwGetIatAddr, 405F9F   // 得到IAT地址的偏移
		mov dwWriteIatAddr, 40618C // 写入IAT地址的偏移
		mov dwOEP, 401120 // 入口点

		// 2.设置断点
		bc 			  // 清除所有软件断点
		bphwc 		  // 清除所有硬件断点
		bpmc 		  // 清除所有内存断点		
		bphws dwGetIatAddr, "x"   // 设置硬件执行断点
		bphws dwWriteIatAddr, "x" 
		bphws dwClearBreak, "x" 
		bphws dwOEP, "x" 

		// 3. 构造循环	
		run 
		cmp dwClearBreak, eip 		
		fill dwClearBreak, 1E, 90  // 将清除硬件断点的地方NOP
	_case1:
		run
		cmp dwGetIatAddr, eip 
		jnz _case2 
		mov dwTemp, eax  // 获取IAT地址
		jmp _case1 

	_case2:
		cmp dwWriteIatAddr, eip 
		jnz _case3 
		mov [edi], dwTemp // 填入IAT
		jmp _case1 

	_case3:
		cmp dwOEP, eip 
		jnz _case1 
		MSG "到达OEP!"

  
(7)修复IAT
  脚本跑完来到OEP后,重新找到IAT的地址看看,发现不对劲,每个地址之间被00分隔开了。这时候dump内存并没有达到脱壳的目的。

在这里插入图片描述
  
  Ctrl+M转到内存窗口,打开通用输入表修复工具(UIF),把数据填好,修复IAT,然后dump内存,脱壳完毕。

在这里插入图片描述
  
(8)程序地址

链接:https://pan.baidu.com/s/18q4r6st7ciOundzUqBqc4A 
提取码:h6yj 
解压码:1234    (大多杀软会报毒)
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值