windows程序逆向笔记(一)

1.吾爱破解
l 按钮-程序运行的日志、插件加载的信息查看
e 按钮-模块信息,程序加载的所有模块、库 都可以看到路径等 双击就可以看到基地址
m 按钮-内存信息 对于 e按钮中 的各个模块的基地址等
t 按钮-线程信息
w 按钮-窗口信息
h 按钮- 一些句柄的信息
c 按钮-反汇编窗口 或者双击 从寄存器的 EIP shift+加号回到之前的位置
p 按钮-记录修改信息 可以在这做还原 恢复
k 按钮-调用堆栈
b 按钮-断点
ALT+F9 反回用户领空
F12 OD暂停

vc6编译特点: (rdata 只读数据段)
入口点代码是固定的代码,入口调用的API也是相同的,其中有的push地址不同程序可能不同,区段有四个 也是固定的.text .rdata .data .rsrc
一般调用的api:[<&MSVCRT.__set__app_type>][<&MSVCRT.__p__fmode>][<&MSVCRT.__p__commode>]等

vs编译特点:
入口点固定,一般第一个是call,第二个是jmp
区段:.text .rdata .data .rsrc .reloc(重定位)
易语言:
易语言独立编译是调用的vc编译,因为和vc相同(独立编译在Exeinfo PE 里 易语言会被识别成vc(因为是用微软的连接器))
区分vc6:找个call调用,点进去,看看是不是加载了一些易语言核心库(jmp dword ptr ds:[0x48DC6C] jmp dword ptr ds:[0x48DC70] jmp dword ptr ds:[0x48DC74] jmp dword ptr ds:[0x48DC64]等)
非独立编译:入口压栈之后,会加载运行库
例如:ascii “GetNewSock”,0 ascii “error”,0 等 也可以在 e按钮里查看加载库信息 fnr 和fne 都是易语言支持库文件
看不到代码,用ctrl+a 或者用数据分析 就可以看到上面这些ascii “xx” 等
Delphi编译特点:
区段: CODE DATA BSS .idata .tls .rdata .reloc .rsrc
.net
有时候打开就运行 插件-ILLY-RUN/stop ILLY 可以让.net可以中断
在 e按钮里 看模块信息,会加载一堆 .net库
VB和QT (VB语言的编码用的unicode)
和.net一样,在模块里加载的库来分辨

加壳:
UPX一般把区段压缩成三个区段,壳的区段是任意命名的
Themida 或WinLicense (一个是授权,一个是非授权,一个壳)壳 一般第一个区段是 空的,然后是 .rsrc 和 .idata 然后还有两个任意命名的区段
VMP壳 看区段,会把加密壳的段放在.data 和 .reloc .rsrc中间,额外添加三个区段,一般是 .XXX0,.XXX,.XXX1 这样来命名
shielden壳 分析代码 会显示 是 se加壳的
ns(北斗)壳 开始两个压栈 ( 可能 区段信息: 按顺序 X0 X1 X2 )

脱壳 一般壳的代码比较短,壳代码结束的地方就是OEP
1.找OEP (在Import REConstructor中 OEP=找到的地址-基地址 RAV)
2.Dump镜像文件
3.修复IAT
4.修复重定位表,修复资源,修复VMOPE等

FSG脱壳: RVA 怎么找:  在ope里进call 函数,然后查看内存     RVA=找到的起始地址 - 基地址    大小 是在call内存里 最后一个减去RVA的地址
		在Import REC里,点显示无效的 ,有许多FFFFF的 删除指针

	有时候xp上可以打开,windows7等无法打开,可能是ISA资源没有修复,也可能是因为ASLR (用CFF explorer打开程序,然后Nt Headers,然后File Header,然后点右下角,把 Relocation info stripped from file的勾选上(不勾选是支持))
   OD载入每次入口不一样:我们可以把重定位勾上(关闭),就可以修复

简单排查崩溃问题
	在od打开,在strongod中,把 忽略所有异常 去掉,然后 options中,在Exceptions中 把异常类型的钩全部去掉,然后点运行,崩溃了,看堆栈窗口,然后右键跟随到修复的地方,
	在崩溃的地方下个断点,然后运行会发现 有地址指向空的地方,把地址复制下来,到有壳时候的这个地址去查看内容。(一般就是因为其起始位置和大小写错了)

修改:①retn,在函数开始的地方直接反汇 ②用nop填充

windows常用函数:
1.MessageBoxA/W
消息框

2.ShellExecuteA/W
3.WinExec
4.CreateProcessA/W
弹网页常用三个函数

5.CreateThread

6.RegCreateKeyExA/W
7.RegOpenKeyExA/W
8.RegDeleteKeyExA/W
注册表

explorer.exe http://www.52pojie.cn/thread-384195-1-1.html

CreateWindowExA/w     创建窗口
DialogBoxParamA/W

资源修改
1.利用资源编辑器修改版权
Restorator
ResEdit
ResHacker

2.利用API定位修改版权的地方
SetDlgItemTextW/A (DialogBox控件设置文本)

3.利用十六进制编辑器修改
C32Asm
Winhex


课外:给Exe程序添加弹窗
1.添加MessageBoxA的导入表并获取VA
MessageBoxA
MessageBoxA  ord:0 rva: 001AA187 VA:005AA187

2.添加一个新的区段,并植入汇编代码(弹窗并跳回原来的EP)
push Style(0)
push Title
push Text
push hOwner(0)
call dword ptr ds:[0x5AA187]

3.修改EP到新的起始位置并保存

很多老壳的出口点是 401000

大小比较自校验:
	有的软件脱壳后无法运行,可以查看是否进行了大小比较,从而判断是否进行了大小自校验

小知识:
一般关键跳的上面1-3个call 是关键call
je是根据上面的比较结果来选择跳不跳 test al,al 是比较上面call 的返回值 这种情况 call 就是影响跳不跳的关键(可以进入call函数内部,修改寄存器的值 使之可以跳转或不跳转)

除了通过字符串,还可以根据API来寻找,有时候call在里面,要跳出去当前call,回到上一层或者再上几层call ,然后查看上面比较 来修改

ini文件断点使用函数:GetPrivateProfileStringA
Alt+F9 反回程序领空     (系统领空是无法修改的!!!!! )(大地址是系统领空 小地址是程序领空)

查找不到字符串,也找不到函数时,可以 右键→查看→user32 进入user32模块,然后 右键→查找->二进制字符串 ,然后输入十六进制字符串(万能断点特征码) :F3 A5 8B C8 83 E1 03 F3 A4 E8 
	然后下完断点,输入注册码以后,回到程序领空,然后继续向下执行 多看堆栈  (万能断点在xp下比较好用)
对于vb程序来说,修改返回值,messagebox等都没有用,在断点里有vb用的 rtcMsgbox 是vb里的 消息类弹窗

提示注册的信息库,就叫做 NAG  举例:(运行程序,出弹窗,然后返回OD,F12暂停,然后查看调用堆栈(K按钮),然后选择系统领空的
	user32.messageboxExA,右键,选择 显示调用,然后加断点,重载程序,然后运行,寻找关键条,注意寻找段首和断尾(一般retn为断尾)!!!!!!)
jnz  根据标志位跳转,zf=0则实现跳转,zf=1 则不跳转,一般根据返回值 或查看上面是否有比较等可以修改标志寄存器的值

BC++ 的程序脱壳后打不开,可能不是自校验,需要手动查找 ITA的地址
	手动查找方法:到达OEP后,离OEP很近有一个call,我们选中后回车,跟踪call的里面寻找 IAT,然后向上翻动,到 段首 的位置,然后选中段首那一行,右键,
		数据窗口中跟随->内存地址,然后在下面的数据窗口右键,(有可能是 Hex/ascii),然后右键, 长型 -> 地址 (更改回地址样式),然后再ImPrc里,输入OEP,
		然后在RVA里输入 计算后的地址(数据窗口中的地址-基地址),然后在大小里输入1000(这个数比较随意,只要大过这个段就行),然后点 获取输入表,
		然后点 显示无效函数,然后在无效函数那里 右键,删除指针,然后转存即可

使用Dark:假设注册页面三个按钮,把程序载入DD,然后点 过程,找到三个按钮的窗口,(可以先先右键,查看附件数据看一下信息,)然后双击,根据段首的地址,
		在OD里载入程序,然后查找该地址,下断点然后 运行程序,在注册码那里的按钮断掉,其他的断点关掉。  然后按照对比,找到注册码就可以了。

程序破解也可以使用单步法,有时候某个call里跳出(注册类型)的窗口,而上面有跳转可以跳过这个call ,一般就修改这个跳转跳过这个call就可以了
F12 暂停法寻找注册码:载入od,运行程序,弹出注册失败等提示框后,反汇OD,F12,然后 执行到用户代码,关闭掉提示框,然后程序会返回到程序领空,
	然后向上寻找关键跳 (一般关键跳上面就是关键call) ,一般需要修改标志位的话,需要进入关键call 里,在关键call里单步执行,如果遇到假码了,
	F8别太快,慢慢来,里面可以找到注册码

制作内存补丁:先载入程序,找到关键跳,然后打开注册编写器,然后 选择 制作内存补丁, 选择程序,输入标题,然后点 添加数据: 
		修改地址(关键跳地址)   修改范围(可以不用写)  修改长度 (关键跳地址后面的一列,每2个数字算一个长度,假设 0F8489040000 这是6个长度)
		原始指令(修改长度的那一个数据,地址后面的一列)  修改指令(NOP 是 90,根据在OD中NOP填充多少行 就填写多少个 90)
		然后点击生成就行了。 然后运行破解补丁就可以
针对易语言的push窗体法(网络验证):程序载入od, 到地址 401000处,然后 右键->查找->二进制字符串->然后输入FF 25(找窗体事件。找按钮事件是FF 55),确定
		到易语言体这里(上面有个 push 0x520...) ,然后点击右键->查找->命令 ,输入命令 :push 10001,点查找,然后下面有个 push 0x520.....复制下来,
		然后把刚开始 通过FF 25那里的查找的push 覆盖掉(绕过掉开始主界面的窗口),然后点汇编,然后复制到可执行文件 。这样来回的重复,就可以了
退出暗装的解决办法:(这里以一个打开自动退出的暗装为例)载入od,先运行,发现自动退出,重新载入,在插件->常用断点设置->常用断点,勾选上
		ExitProcess(程序退出)断点,确定。然后运行程序,在断点处,右下角堆栈窗口中,(在API下面)有个 返回到 (程序名)  来自(程序名),在这一行,右键,
		反汇编窗口跟随,然后上面有个call(就是退出函数的call)。然后上面有个跳转,修改跳转,可以跳过这个call,然后复制到可执行程序即可
网络验证的本地突破:先把程序在dark里打开,过程,寻找那个按钮,有时候点一个按钮,弹出的界面才有那个按钮,那要先找外层的按钮。找到地址后,去od里
		然后一直F8,然后F8不动了以后(可能是连接服务器或者弹错等),可以NOP尝试一下 ,然后继续向下找到关键条(一个错误提示后面一般有个跳转),一般
		也跳向了失败,也NOP掉, 然后运行查看是否成功
		
VB的通用技巧:载入od,右键->运行脚本->打开,然后选择脚本文件 (需要脚本支持,比如 vb按钮事件.txt|.osc|.osc.txt)。之后会自动下断,然后运行,如果是
		重启验证,可以运行一下,在断点下面,往下翻页查看找到 xx xx,0xFFFF(%85的VB程序用这个数值,和四个F作比较,影响下面的关键跳),在这里下断点,然后把其他
		的断点删除,然后这就是关键比较,看看可以修改下面的关键跳,有多个地方显示注册点时,可以复制这条比较命令,然后 右键->查找->所有命令,然后在
		查找到的命令,右键,在每个命令上设置断点,然后进行相应修改。
所有模块间的调用(VB运行之后自动退出):载入od,发现运行之后自动退出,右键->查找->所有模块间的调用,找到vb的退出函数 X__vbaEnd,全部下断,然后F9运行
		程序,然后查找关键跳 (可以跳过call退出函数的地方)进行修改,有的地方没有跳过函数,就可以不用理他。  假如有关机指令等,可以搜索字符串,找到这
		个字符串,然后段首下断,找到写入那句话,数据窗口中跟随,然后数据窗口中选中,空格键,然后 勾选上 保持大小,把指令用0填充,然后确定,然后保存就行了。

脱壳八法:
esp定律: 基本上第一个命令 是 pushad 就可以用esp定律 同时也可以看 右边寄存器窗口,只有esp是红色的,就可以使用esp定律
在esp 寄存器上点 右键 然后 数据窗口跟随,然后选择数据(只要是从esp跟随过去的,数据选多少都行),选中后点右键,然后
选择 断点->硬件访问->然后随便选一个 ,然后运行到断点处,然后单步执行,一般碰到 跳转 大跳转 跳过来 或者 retn
代码变成看不懂(也可能不变) 一般就到oep了
单步跟踪: 开始,先F8,然后看哪个call跑飞了,就F7进入这个call,继续F8,然后按照上面的循环,如果有往上跳转的,直接在下面按
F4(运行到所选,前提是跳转实现再这么做),一直F8,看到 popad ,一般就快到OEP附近了
两次断点:先设置od,在选项,调试设置,异常,把所有的都打上勾(全部忽略),确定。 然后 Alt+m 键,先在 第一个段(与程序名相同的段).rsrc那下F2断点,
然后按 shift+F9 ,然后在Alt+M,在 401000处下断,然后 shift +F9,然后按照单步跟踪法脱壳。
最后一次异常法:载入od,选项->调试设置->把所有的打上勾的全部取消(不勾选),然后 shift +F9,再一次 shift +F9 (看看 按几次程序能正常启动,假如
第二次启动,那么异常就只有一次),然后重新载入程序,按异常的次数按shift +F9,然后在右下角堆栈窗口,有一个SE(SE处理程序/SExx句柄等),在
上面 右键->反汇编窗口跟随(或者根据中间的地址去查找),然后F2断点,然后shift +F9,然后运行到断点处,然后取消断点,然后按照单步跟踪法,脱壳
SFX :载入od,选项->调试设置->异常,把所有的都打上勾(全部忽略),然后选择 SFX, 选择 字节方式跟踪真正入口处(单选的最后一个),然后重新载入,然后等待
它自动获取真正的入口
模拟跟踪法: 载入od后,可以查看内存,找到 SFX的地址(第一列),然后输入命令 (tc eip < SFX的地址)然后断下来就是 OEP(按e查看基址)一般不直接使用,而是:
先使用两次断点法,(第二次断点不一定是401000,根据基址来寻找,一般是 基地址+ 1000)到接近oep的位置,然后在使用模拟跟踪法。
出口标志: 载入od,假如有 pushad,可以右键,查找命令 ,输入相应的命 popad,取消 整个块 选项,然后查找,然后再popad处F4,然后F8,然后查看是
否到达oep,如果跑飞了,就继续向下寻找 popad,重复查找,一直到F4可以断下来,然后单步向下找到OEP即可
一步OPE: 载入od,直接运行程序,然后看右下角堆栈,先拉到最后,然后往上拉,找到 程序名.地址 那里,(如果(堆栈窗口)没有向上的括号)然后反汇编窗口跟随
(第二列地址跟随也可),然后反汇编窗口跟随(第二列地址跟随也可),删除分析,然后再看右下角堆栈,有向上的括号,找到 段首,找到
返回到 程序名.地址 ,然后 在反汇编窗口跟随地址,然后在 向上翻,查找他的oep(一般是段首),然后
右键,数据窗口中跟随,然后再下面的数据窗口中 右键,断点,硬件执行断点,然后重新载入,直接运行到断点,然后脱壳
如果OEP找对,又无法运行,就用loadpe ,先修正镜像,然后 完全脱壳。然后再用Import rec修复即可

猜你喜欢

转载自blog.csdn.net/xiaotu0821/article/details/85036661
今日推荐