CrackMe003:NAG窗口(4C法)和浮点计算
下面是网上的160个CrackMe的部分逆向笔记,包括逆向思路、注册机实现和逆向中常用的知识整理
注意:逆向前一定要先操作一下软件,熟悉软件的运行现象;逆向一定要自己操作一遍,看是很难看会的(高手除外)
文章目录
- 1.现象
- 2.NAG窗口破解
- 思路1:Timer思路(特殊场景)
- 思路2:偏移4C思路(通用法)
- VB程序启动顺序
- 破解步骤
- step 1.找VBHeader结构起始地址
- step 2.找VBHeader中偏移4C处的内容
- step 3.更改窗口的启动顺序
- 3.序列号破解
- key 1.用户名生成临时序列号
- key 2.连续3次浮点运算
- 注册机
- 4.扩展:浮点类型的汇编
- 浮点寄存器
- 常用浮点指令
- 示例
- 5.参考
CrackMe002和CrackMe003是同一个作者用VB写的小程序;CrackMe003多了一个NAG窗口,难度也不是很大
1.现象
运行软件,会先弹出一个NAG窗口,什么也不能操作,几秒钟后会弹出验证用户名和序列号的主窗口
要求:需要去掉NAG窗口和逆向出正确的序列号
2.NAG窗口破解
思路1:Timer思路(特殊场景)
前置知识
- 基地址:PE文件加载到内存后被称为映像文件(
Image File
),映像文件优先载入的地址是由PE文件中的ImageBase
决定(相对地址),默认是0x400000
- 第一行代码地址:是由PE文件的AddressOfEntryPoint(即脱壳中的EP)决定,默认是
0x01000
因此,正常的程序在0x401000
(= 0x400000 + 0x01000)开始执行第一行代码
- 1.猜测
程序的NAG几秒钟后会自动消失,猜测可能是类似定时器的机制控制的
注意:逆向就是要大胆猜测,然后实验猜测是否正确?有时要实验很多种才会成功,其实这与调试程序bug是一样的思路
- 2.实验
在内存窗口中,先定位到0x401000
位置,然后Ctrl+B
搜索Timer
(Timer是VB程序默认的定时器变量),搜索结果如下:
VB中计时器的单位是ms,上图中0x1B58
= 7000ms = 7s;重新运行程序,看一看是不是大概7s时间,NAG窗口消失,发现果然是,说明猜测是正确的(可以说是运气好,但是只有逆向多了才会有这种好运气的)
- 3.破解思路
因此,Timer思路就是将0x1B5
改成一个很小的值(比如0x001);现象就是NAG一闪而过,很难被捕捉到,给人的感觉就是NAG窗口被去掉了
4.破解操作
下面是破解的操作步骤
- 1.OD加载程序,内存窗口中
Ctrl+G
,定位到0x401000 - 2.
Ctrl+B
搜索Timer
,修改计数器变量对应秒数为0x0001(要注意好大小端)
- 1.OD加载程序,内存窗口中
局限性:计时器默认名如果不是Timer,内存中搜索的方法就会失效
思路2:偏移4C思路(通用法)
VB程序启动顺序
VB程序的每个窗口都有启动顺序,这个顺序就保存在程序开始执行位置的偏移4C附近定义的一个结构体中
当前顺序:现在程序中会先启动
NAG窗口
,后启动序列号验证窗口
破解思路:如果找到启动顺序位置,将
NAG窗口
放在序列号验证窗口
后面,自然就自动去除掉NAG窗口了(想法是好的,就是不知道怎么实现?继续看下面吧…)
下面是VB程序可能的框架:
VB涉及到的相关结构体:
//VBHeader结构定义
Signature array[1..4] of char; //00H,签名,必须为VB5!
LanguageDll array[1..14] of char; //06H,语言链接库名,通常为”*"或者vb6chsdll
...
AGUTTable DWORD; //4CH,指针,指向Form GuI描述表,***关键位置***
...//AGUTTable结构定义(大小是0x50)
Signature DWORD //00H,必须是50000000
FomID TGUID //04H,可能是以GUID方式命名的formID
Index BYTE //24H,窗体的序号,***关键位置***
Flag1 BYTE //28H,第一个窗体的启动标志,可能是90 也可能是10
AGUIDescriptionTable DWORD //48H,指针指向以“FFCC…“开始的FormGUI表
Flag3 DWORD //4CH,意义不明
AGUTTable
结构体中,偏移是0x24的Index就是启动顺序;索引到AGUTTable
位置是通过VBHeader为基准,偏移0x4C;因此使用修改启动顺序的方法也叫4C思路
破解步骤
step 1.找VBHeader结构起始地址
OD加载程序,没有加壳的程序默认会停在OEP处,VB程序典型的OEP附近汇编如下,多调试几次VB程序自己就会发现
00401164 .- FF25 4CB14000 jmp dword ptr ds:[40B14C] ; MSVBVM50.EVENT_SINK_Release
0040116A $- FF25 8CB14000 jmp dword ptr ds:[40B18C] ; MSVBVM50.ThunRTMain
00401170 > $ 68 D4674000 push 4067D4 ; 00401170是OEP指向地址,OD加载后会停在这行
00401175 . E8 F0FFFFFF call 0040116A ; <jmp.&MSVBVM50.#100>
#说明:入口点处的push压入stack的数据就是VBHeader首地址,即VBHeader首地址是4067D4
step 2.找VBHeader中偏移4C处的内容
在内存窗口中,Ctrl+G
,定位到4067D4地址,偏移4C
处(AGUTTable
结构)的内容是0x406868
step 3.更改窗口的启动顺序
内存窗口中,定位到0x406868
,会发现2块类似的结构(AGUTTable
结构),每块的大小是0x50个bytes,查看每块结构的偏移0x24
处
NAG窗口:启动顺序是00,即第一个被程序加载的窗口
序列号验证窗口:启动顺序是01
去掉NAG窗口方法:直接将NAG窗口和序列号验证窗口的启动顺序互换,保存二进制修改
经验证,的确不再显示NAG窗口了;至此,NAG被去掉了,使用了2种方式,推荐使用第2种
3.序列号破解
这个程序与CrackMe002的逆向思路是一样的,暴力破解和直接通过函数栈帧找到正确序列号的逻辑在CrackMe002里有介绍,下面是总结的操作流程:
1.先输入错误的用户名和序列号(test123/456),根据错误弹窗里的字符串先找到调用弹窗的代码和关键跳转
2.在关键跳转所在函数起始位置设置断点,反复调试函数起始位置和关键跳转之间的代码,分析根据用户名生成序列号的逻辑
笨方法,继续用上面的思路破解CrackMe003的序列号;为了写出注册机,下面将调试时发关键节点整理成了笔记(一定要自己操作一下,你才会知道下面说的是什么意思)
key 1.用户名生成临时序列号
调试中发现了如下计算临时序列号的公式:
临时序列号 = 用户名长度 * 0x15B38 + 用户名第一个字符的ASCII码,结果用十进制表示的字符串
示例:用户名test123
对应的临时序列号(字符串)是622332
(记住这个值,后面会用到)
key 2.连续3次浮点运算
用户名计算出临时序列号会经历3次浮点运算操作,操作套路基本一样(如果不熟悉浮点运算,通过单步调试观察栈帧,一样可以得到下面的结果);下面直接给出了3次操作的截图
第一次操作:
622332 -> 622334
第二次操作:
622334*3-2=1867000
第三次操作:
1867000+15 -> 1867015
注册机
经过上面key1和key2,很容易写出简单的注册机
#include "StdAfx.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main() {char user_name[100] = {0}; //用户名printf("请输入用户名:");scanf_s("%s", user_name, 100);//计算序列号int user_serial = strlen(user_name) * 0x15B38 + user_name[0];//用户名计算临时序列号float serial = 0.0;serial = user_serial + 2.0; //第一次操作serial = serial * 3.0 -2.0; //第二次操作serial = serial + 15.0; //第三次操作printf("用户名:%s, 对应的序列号:%f\n", user_name, serial);system("pause");return 0;
}
验证结果如下,说明整个逆向的思路和注册机是正确的
如果你是第一次逆向浮点运算,可以看一下我以前整理的浮点汇编的笔记(直接粘贴在下面了);如果想学一下C++代码逆向成汇编的典型特征,推荐看《C++反汇编与逆向分析》;如果是大牛,可以直接忽略下面
4.扩展:浮点类型的汇编
CrackMe003的生成序列号算法使用了浮点的相关运算,下面简要介绍逆向中浮点类型的相关知识
C++中,32位操作系统中2种浮点数据类型:
- 单精度(float):内存中占用4个bytes
- 双精度(double):8个bytes
浮点类型的编码就不详细介绍了,对于逆向来说,只要知道基本格式(符号位 + 指数部分 + 科学计数法中的位数部分
)就行,下面主要介绍一下浮点数指令
浮点寄存器
区别:普通数据类型操作使用的是通用寄存器(
eax
、ecx
等),浮点数据类型操作使用的是浮点寄存器(ST0
~ST7
)stack实现:浮点寄存器是通过使用栈(stack)来实现的,共8个栈空间组成(
ST0
~ST7
),且每个浮点寄存器占用8个bytes,浮点寄存器使用类似于入栈和出栈的操作使用顺序:每次操作的都是
ST0
,从而影响其他浮点寄存器(ST1
~ST7
)- 入栈:如果
ST0
中没有数据,直接放进ST0
;如果ST0
中有数据,ST7
数据丢弃,依次将ST6
数据放入ST7
,…,ST0
数据放入ST1
,新数据放入ST0
- 出栈:执行相反操作
- 入栈:如果
常用浮点指令
指令 | 使用方法 | 说明 |
---|---|---|
fld/fild
|
fld/fild PUSH_DATA | 将浮点数/整数PUSH_DATA压入ST0中 |
fst/fist
|
fst/fist POP_ADDR | 将ST0中的数据以浮点/整数形式存入POP_ADDR地址中 |
fstp/fistp | fstp/fistpPOP_ADDR | 相对于fst/fist,会多执行一次出栈操作 |
fldz、fld1
|
fldz、fld1 | 将0.0、1.0压入ST0中 |
fadd
|
fadd addr | 将addr地址内的数据与ST0做加法,结果存入ST0中 |
fcom
|
fcom addr | 将addr地址内的数据与ST0进行实数比较,影响对应标志位 |
ftst
|
ftst | 比较ST0是否是0.0,影响对应标志位 |
说明:以p
结尾的指令基本都会执行一次出栈操作;其他运算指令与普通指令类似,只需要在指令前面加一个f
即可
示例
Debug版本的浮点操作示例(C++代码与反汇编代码对应)
#include "stdafx.h"
#include <windows.h>
int main(int argc, char* argv[])
{;---生成栈帧和stack上分配部分空间的初始化代码--- int test_int = 3;
0096B65E mov dword ptr [test_int],3 float test_float = (float)test_int; //通过ST0做中转,将int转成float类型
0096B665 fild dword ptr [test_int] ;将整数test_int压入ST0中
0096B668 fstp dword ptr [test_float] ;将ST0中的数据以浮点的形式存入test_float,且ST0中数据出栈printf("test_float=%f", test_float); //float数据通过ST0中转后,放入stack上预留好空间
0096B66B fld dword ptr [test_float] ;将浮点数test_float压入ST0中
0096B66E sub esp,8 ;浮点数作为变参函数的参数,需要转换成双精度浮点存储在stack上
0096B671 fstp qword ptr [esp] ;将ST0中的数据以浮点的形式存入eap执行的地址,且ST0中数据出栈
0096B674 push offset string "test_float=%f" (9BDC7Ch)
0096B679 call @ILT+4360(_printf) (96A10Dh)
0096B67E add esp,0Ch test_int = (int)test_float;
0096B681 fld dword ptr [test_float] ;将浮点数test_float压入ST0中
0096B684 call @ILT+2085(__ftol2_sse) (96982Ah) ;调用_ftol函数进行浮点数转换
0096B689 mov dword ptr [test_int],eax return 0;
0096B69D xor eax,eax
}
简要结论:
1.通过ST0寄存器实现整数和浮点数的转换
2.float类型的浮点数占用4个bytes空间,但是在实际处理时都是按照8个bytes方式进行处理
3.浮点数作为参数,不能直接压入stack中;因为push指令只能传4个bytes大小,会出现数据损失(printf以整数方式输出浮点数会出现错误的根因);作为返回值也有类似的处理
至此,CrackMe003逆向完了,想学逆向就尽量不要爆破掉程序就完事,尽量多学点里面的基础知识
5.参考
- 1.VB程序逆向反汇编常见的函数 - 笨笨D幸福 - 博客园 (cnblogs.com)
- 2.常用软件可以在这里下载:爱盘 - 最新的在线破解工具包 (52pojie.cn)
- 3.160个Crackme_鬼手56的博客-CSDN博客
- 4.《使用OllyDbg从零开始Cracking》系列的文章也不错
CrackMe003:NAG窗口(4C法)和浮点计算相关推荐
- 去VB程序NAG窗口方法-4C法
去除VB程序的程序启动时的NAG窗口,基本原理就是寻找到每珍具窗口的启动顺序,再改变窗口的启顺序就可以了. 具体实列如下: 当程序启动时,会出现一个NAG窗口,如下所示: OD载入程序:EP处 VB程 ...
- nag在逆向中是什么意思_OD 实验(四) - 去除 NAG 窗口的几种方法
程序: 运行 弹出一个窗口,说要注册 点击确定,到主窗口 关闭主窗口 然后弹出提醒注册的对话框 逆向程序 用 OD 打开程序 GetModuleHandleA 获取程序模块的句柄,程序在内存中的基址 ...
- OllyDbg笔记-初识PE文件(nag窗口破解)
目录 基本概念 代码与实例 基本概念 这里主要是记录下PE文件结构: PE文件结构,它在硬盘上的存储结构跟载入内存时候的存储结构是一样的. 在PE文件结构里边找出想要的东西,当这个文件映射到内存后, ...
- 4. OD-去除烦人的nag窗口(去除提醒用户购买正版的警告窗口)
所有函数返回值均放入eax中 扩展修改nop 选中语句->右键菜单->二进制->用nop填充 三种方式 1. 修改标志位je为jmp 2. 扩选判断语句+call,全部改为nop 3 ...
- 去除WinRAR 5.01(32位) NAG窗口
前阵子重装系统,顺手下了一个免费的WinRAR(32位 版本号5.01).用了没多久发现这货带NAG窗口,关闭NAG窗口后居然还跳出广告窗口,如下图,不胜其扰下决定去除NAG窗口. 毕竟WinRAR是 ...
- 逆向破解--除去软件nag窗口
作者是名新手,能力有限,文章中如果有和不正确的地方,希望各位前辈指出 本文仅作为学习的记录,做分享- 我们有时候会用非注册软件,然后软件提供者希望更多的人注册他的软件,因此烦人的nag窗口出现了,不堪 ...
- nag在逆向中是什么意思_OD调试4----去除nag窗口的几种方法
本实验所用程序如下,一个主窗口,两个nag窗口.nag本意为烦人唠叨的意思.在这里指的是不断弹出来窗口,例如注册窗口. 这里第一个和第三个为烦人的nag窗口,这里我们要将它去除.接下来就介绍四种方法, ...
- LeetCode 674. 最长连续递增序列 (滑动窗口 计数法)
LeetCode 674. 最长连续递增序列 滑动窗口 右边界不断往右移动 左边界收缩条件:当右边界的值小于等于其左边的值时(递减) 左边界收缩到右边界当前位置 class Solution {pub ...
- linux终端窗口玩法
ctrl + shift + = 放大终端窗口的字体显示 ctrl + - 缩小终端窗口的字体显示 开启多个窗口(不在一个窗口) Ctrl + Alt + T Alt + n对应的就会切换到第n个终端 ...
最新文章
- 开发日记-20190807 关键词 读书笔记《Linux 系统管理技术手册(第二版)》DAY 21
- spring-mybatis.xml 访问html5,Spring mvc无xml配置及利用JdbcTemplate访问数据库
- leetcode#42 Trapping rain water的五种解法详解
- Java zip 压缩 文件夹删除,移动,重命名,复制
- Be My Eyes app:我是你的眼
- 黑客专用Linux发行版Kali Linux发布滚动更新版2016.1
- 性能测试:性能测试指标评估方法
- 查看mysql所有命令
- sqoop增量导入hive_Sqoop 增量导MySQL数据 至Hive
- Android IPC(二)Messenger实现跨进程双向通信
- javamail 邮件发送、带格式、已保存
- 教你如何学习思维导图
- 期货交易有什么套利技巧?
- 像素(px)到底是个什么单位
- 软件架构的10个质量属性
- git删除所有文件夹(清空远程仓库)
- ganache命令行安装
- Android秀翻天的操作——使用协程进行网络请求
- 当在浏览器中输入一个域名后,会发生什么
- Android 性能优化之线程优化
热门文章
- 阿里研究院启动2017年度淘宝村辅助认证活动(附表格下载)
- win10WLAN选项消失解决方法
- 每日一学 | 2021-05-19 | Power BI 学习笔记03、04
- [笔记]unity渲染类零碎代码记录(100多条)
- 光伏发电站|太阳能电池板辐照度(4G)无线直流电压汇集电流测量采集监控技术方案
- [ web 漏洞篇 ] 常见web漏洞总结之 RCE 远程代码 / 命令执行漏洞总结
- 软件产品发布基本流程
- 打开日志管理的潘多拉盒子
- 5G 和 WiFi-6,谁是智能制造的主角?
- 间充质干细胞最新研究成果进展(2021年10月)