windows 脚本拖壳-01

Posted 不会写代码的丝丽

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了windows 脚本拖壳-01相关的知识,希望对你有一定的参考价值。

概述

本文会利用x32dbg 脚本脱掉一个加壳后的exe.

软件运行后:

我们这里的目的不是在于点击注册后,显示破解成功。而是将其加密后的原始程序还原回来。

看段数据很明显,进行自定义段操作

导入表为空,证明我们dump程序后需要还原导入表。

我们将其拖入x32dbg中.

OE:直接执行了pushad操作,证明壳程序想保护上下文,而后运行中还原。

pushad 将所有寄存器保存到栈
pushfd 保存标志寄存器保存到栈

我们首先运行到第二行pushfd,然后给esp设置硬件访问断点.


思想 壳程序必须将寄存器还原,所以下次一定会访问

我们直接运行到访问断点命中:


断点命中时的代码,很明显看不出什么,单步跟入多次跳转。

直到下面的步骤,发现这是标准VC6.0的OEP,所以进行dump操作

我们dump的程序名:CrackMe_dump.exe,双击运行程序后。。。奔溃

查看日志

跳转到对应的地址

在观察程序的内存布局,发现这个内存在进程归属一个堆地址,很明显,壳程序对PE的IAT做了手脚

我们回到原始的加密程序,查看他是如何处理函数调用的:

函数调用栈结构


函数返回时栈结构,明显篡改了返回地址,执行ret后,首先会执行系统调用后再返回原始代码地址。

我们得出这个壳处理IAT思想:

于是乎我们这样这么玩:
编写一个脚本负责调用壳代码,将真实的函数地址还原回IAT。在进行dump

首先我们首先需要知道壳代码的IAT范围,当然这里你可以手动分析也可以利用Syclla



//如果手动分析的话IAT就是475000 或者你用Syclla的 00475018也是没问题。因为手动分析的代码段程序没调用
mov $addrIat,0x00475000
//如果手动分析的话是IAT的结果,你当然也可以Syclla的结果00475018+108 也是没问题。因为手动分析的代码段程序没调用
mov $addrIatEnd,   0x00475120


fix_loop:
	mov $addrIatItem,dword:[$addrIat]
	cmp $addrIatItem,0
	je fix_next

	//设置为新的EIP地址
	mov cip,$addrIatItem
find_ret:
	sti

	//判断是否到了ret
	cmp byte:[cip],0xc3
	jnz find_ret

	//到了ret,取栈顶的地址,存入对应的IAT
	mov dword:[$addrIat],dword:[csp]
	log "fix old addr p:$addrIatItem -->p:dword:[csp]"
	jmp fix_next
	jmp find_ret

fix_next:
	add $addrIat,4
	cmp $addrIat,$addrIatEnd
	je exit
	jmp fix_loop
exit:
ret

右键载入脚本运行

修复后在进行fix dump

参考

样本和脚本
各种编译器的OEP样子

以上是关于windows 脚本拖壳-01的主要内容,如果未能解决你的问题,请参考以下文章

windows 脚本拖壳-01

将注入进行到底:利用Mono注入C#游戏脚本

从零写一个Asp.net core手脚架 (异常处理)

Windows Server 2008中使用计划任务定时执行BAT bat进行PHP脚本的执行

vue.js的手脚架vue-cli项目搭建

windows下配置启动脚本并设置开机自启及相应关闭脚本