crackme009
crackme009
名称 | 值 |
---|---|
软件名称 | Andrénalin.2.exe |
加壳方式 | 无 |
保护方式 | serial |
编译语言 | Microsoft Visual Basic |
调试环境 | win10 64位 |
使用工具 | x32dbg,PEid |
破解日期 | 2025-06-18 |
脱壳
1. 先用PEid查壳
- 查到无壳
前置知识
该vb程序会用到较多的Variant变量和官方查询不到vb函数,请先阅读如下两篇文章
- VB逆向基础(一)
- vb逆向常用函数
寻找Serial
- 寻找flag,用x32dbg打开程序,
鼠标右键->搜索->当前模块->字符串
,发现存在字符串L"RiCHTiG !"
“richtig”在德语中意为“正确的”
- 双击
地址=00402308 反汇编=mov dword ptr ss:[ebp-B4],andrénalin.2.401CA8 字符串地址=00401CA8 字符串=L"RiCHTiG !""
,跳转到代码
0040228C | call dword ptr ds:[<&__vbaHresultCheckObj>] |
00402292 | mov eax,dword ptr ss:[ebp-58] |
00402295 | lea ecx,dword ptr ss:[ebp-34] |
00402298 | mov dword ptr ss:[ebp-64],eax |
0040229B | lea eax,dword ptr ss:[ebp-6C] |
0040229E | push eax | key
0040229F | push ecx | Name运算后的结果字符串
004022A0 | mov dword ptr ss:[ebp-58],0 |
004022A7 | mov dword ptr ss:[ebp-6C],8008 |
004022AE | call dword ptr ds:[<&__vbaVarTstEq>] | 判断两个变量是否相等,不相等eax返回0x0,相等返回0xFFFFFFFF
004022B4 | lea ecx,dword ptr ss:[ebp-5C] |
004022B7 | mov ebx,eax |
004022B9 | call dword ptr ds:[<&__vbaFreeObj>] |
004022BF | lea ecx,dword ptr ss:[ebp-6C] |
004022C2 | call dword ptr ds:[<&__vbaFreeVar>] |
004022C8 | test bx,bx |name运算后与key相等,则弹出正确对话框,否则跳走
004022CB | je andrénalin.2.402391 |
004022D1 | call dword ptr ds:[<&rtcBeep>] | 弹出正确对话框分支
004022D7 | mov ebx,dword ptr ds:[<&__vbaVarDup>] |
004022DD | mov ecx,80020004 |
004022E2 | mov dword ptr ss:[ebp-94],ecx |
004022E8 | mov eax,A |
004022ED | mov dword ptr ss:[ebp-84],ecx |
004022F3 | lea edx,dword ptr ss:[ebp-BC] |
004022F9 | lea ecx,dword ptr ss:[ebp-7C] |
004022FC | mov dword ptr ss:[ebp-9C],eax |
00402302 | mov dword ptr ss:[ebp-8C],eax |
00402308 | mov dword ptr ss:[ebp-B4],andrénalin.2.401CA8 | 常量L"RiCHTiG !"
00402312 | mov dword ptr ss:[ebp-BC],8 |
0040231C | call ebx |
0040231E | lea edx,dword ptr ss:[ebp-AC] |
00402324 | lea ecx,dword ptr ss:[ebp-6C] |
00402327 | mov dword ptr ss:[ebp-A4],andrénalin.2.401C3C |
00402331 | mov dword ptr ss:[ebp-AC],8 |
0040233B | call ebx |
0040233D | lea edx,dword ptr ss:[ebp-9C] |
00402343 | lea eax,dword ptr ss:[ebp-8C] |
00402349 | push edx |
0040234A | lea ecx,dword ptr ss:[ebp-7C] |
0040234D | push eax |
0040234E | push ecx |
0040234F | lea edx,dword ptr ss:[ebp-6C] |
00402352 | push 30 |
00402354 | push edx |
00402355 | call dword ptr ds:[<&rtcMsgBox>] | 弹出对话框
- 从以上代码看出Name的运算 关联局部变量
dword ptr ss:[ebp-34]
,跟踪dword ptr ss:[ebp-34]
的赋值,往前翻阅x32dbg发现一个for循环,分析发现该循环的作用是累加Name字符串的ascii值,将结果保存在dword ptr ss:[ebp-34]
中
004020F8 | push edx | Variant字符串
004020F9 | push eax | 出参,字符串长度
004020FA | mov dword ptr ss:[ebp-AC],ebx |
00402100 | mov dword ptr ss:[ebp-BC],ebx |
00402106 | call dword ptr ds:[<&__vbaLenVar>] | 字符串长度
0040210C | lea ecx,dword ptr ss:[ebp-BC] |
00402112 | push eax | 参数5,循环变量的上限
00402113 | lea edx,dword ptr ss:[ebp-118] |
00402119 | push ecx | 参数4,循环初始值固定值,Int类型
0040211A | lea eax,dword ptr ss:[ebp-108] |
00402120 | push edx | 参数3,循环临时上限,Long类型 给__vbaVarForNext用
00402121 | lea ecx,dword ptr ss:[ebp-24] |
00402124 | push eax | 参数2,循环步长,Long类型
00402125 | push ecx | 参数1,当前循环变量值
00402126 | call dword ptr ds:[<&__vbaVarForInit>] |
0040212C | mov edi,dword ptr ds:[<&__vbaFreeVarList>] |
00402132 | test eax,eax |
00402134 | je andrénalin.2.4021D6 |
0040213A | lea edx,dword ptr ss:[ebp-6C] |
0040213D | lea eax,dword ptr ss:[ebp-24] |
00402140 | push edx |
00402141 | push eax |
00402142 | mov dword ptr ss:[ebp-64],1 |
00402149 | mov dword ptr ss:[ebp-6C],ebx |
0040214C | call dword ptr ds:[<&__vbaI4Var>] | 将一个variant转换为I4
00402152 | lea ecx,dword ptr ss:[ebp-44] |
00402155 | push eax | I4值
00402156 | lea edx,dword ptr ss:[ebp-7C] |
00402159 | push ecx | 字符串首地址
0040215A | push edx | edx+10 表示长度
0040215B | call dword ptr ds:[<&rtcMidCharVar>] | vb中Mid,截取字符串,返回给eax
00402161 | lea eax,dword ptr ss:[ebp-7C] | 字符
00402164 | lea ecx,dword ptr ss:[ebp-58] |
00402167 | push eax | variant字符串
00402168 | push ecx |
00402169 | call dword ptr ds:[<&__vbaStrVarVal>] | 将Variant字符串转换成裸字符串
0040216F | push eax | 裸字符串
00402170 | call dword ptr ds:[<&rtcAnsiValueBstr>] | 将字符串第一个字符转换成ascii值
00402176 | mov word ptr ss:[ebp-B4],ax |
0040217D | lea edx,dword ptr ss:[ebp-34] |
00402180 | lea eax,dword ptr ss:[ebp-BC] |
00402186 | push edx | 参数3,上一次的和
00402187 | lea ecx,dword ptr ss:[ebp-8C] |
0040218D | push eax | 参数2新的字符ascii值
0040218E | push ecx | 参数1,返回结果
0040218F | mov dword ptr ss:[ebp-BC],ebx |
00402195 | call dword ptr ds:[<&__vbaVarAdd>] | 将字符ascii值累加
0040219B | mov edx,eax |
0040219D | lea ecx,dword ptr ss:[ebp-34] |
004021A0 | call esi |
004021A2 | lea ecx,dword ptr ss:[ebp-58] |
004021A5 | call dword ptr ds:[<&__vbaFreeStr>] |
004021AB | lea edx,dword ptr ss:[ebp-7C] |
004021AE | lea eax,dword ptr ss:[ebp-6C] |
004021B1 | push edx |
004021B2 | push eax |
004021B3 | push ebx |
004021B4 | call edi |
004021B6 | add esp,C |
004021B9 | lea ecx,dword ptr ss:[ebp-118] |
004021BF | lea edx,dword ptr ss:[ebp-108] |
004021C5 | lea eax,dword ptr ss:[ebp-24] |
004021C8 | push ecx | 参数3,循环临时上限,Long类型
004021C9 | push edx | 参数2,循环临时步长,Long类型
004021CA | push eax | 参数1,循环当前值,Long类型
004021CB | call dword ptr ds:[<&__vbaVarForNext>] |
004021D1 | jmp andrénalin.2.402132 |
- 出了for循环继续分析,分析发现该段代码功能是,将Name字符串ascii累加值sum做乘法
res = sum*0x499602D2
,然后将结果res 转换成字符串ans,再将字符串ans第4位和第9位字符替换为"-",最后将字符串ans与key比较,相等则提示成功
004021D6 | lea ecx,dword ptr ss:[ebp-34] |
004021D9 | lea edx,dword ptr ss:[ebp-AC] |
004021DF | push ecx | 加数,字符串ascii累加值
004021E0 | lea eax,dword ptr ss:[ebp-6C] |
004021E3 | push edx | 常量499602D2
004021E4 | push eax | 运算结果
004021E5 | mov dword ptr ss:[ebp-A4],499602D2 |
004021EF | mov dword ptr ss:[ebp-AC],3 |
004021F9 | call dword ptr ds:[<&__vbaVarMul>] |
004021FF | mov edx,eax | double型结果
00402201 | lea ecx,dword ptr ss:[ebp-34] |
00402204 | call esi | __vbaVarMove 将edx值移动到ecx中
00402206 | mov ebx,dword ptr ds:[<&__vbaMidStmtVar>] |
0040220C | lea ecx,dword ptr ss:[ebp-34] |
0040220F | push ecx | 参数4,double型上一步乘积结果
00402210 | push 4 | 起始位置4
00402212 | lea edx,dword ptr ss:[ebp-AC] |
00402218 | push 1 | 长度1
0040221A | push edx | 替换子字符串"-"
0040221B | mov dword ptr ss:[ebp-A4],andrénalin.2.401C34 | 常量"-"
00402225 | mov dword ptr ss:[ebp-AC],8 |
0040222F | call ebx | __vbaMidStmtVar 将第4位开始长度为1替换成"-"
00402231 | lea eax,dword ptr ss:[ebp-34] | 替换结果
00402234 | lea ecx,dword ptr ss:[ebp-AC] |
0040223A | push eax | 待替换原串
0040223B | push 9 | 替换起始位置9
0040223D | push 1 | 替换长度1
0040223F | push ecx | 替换子字符串"-"
00402240 | mov dword ptr ss:[ebp-A4],andrénalin.2.401C34 |
0040224A | mov dword ptr ss:[ebp-AC],8 |
00402254 | call ebx | __vbaMidStmtVar 将第9位开始长度为1替换成"-"
00402256 | mov eax,dword ptr ss:[ebp+8] |
00402259 | push eax |
0040225A | mov edx,dword ptr ds:[eax] |
0040225C | call dword ptr ds:[edx+304] |
00402262 | push eax |
00402263 | lea eax,dword ptr ss:[ebp-5C] |
00402266 | push eax |
00402267 | call dword ptr ds:[<&__vbaObjSet>] |
0040226D | mov ebx,eax |
0040226F | lea edx,dword ptr ss:[ebp-58] |
00402272 | push edx |
00402273 | push ebx |
00402274 | mov ecx,dword ptr ds:[ebx] |
00402276 | call dword ptr ds:[ecx+A0] |
0040227C | test eax,eax |
0040227E | jge andrénalin.2.402292 |
00402280 | push A0 |
00402285 | push andrénalin.2.401C20 |
0040228A | push ebx |
0040228B | push eax |
0040228C | call dword ptr ds:[<&__vbaHresultCheckObj>] |
00402292 | mov eax,dword ptr ss:[ebp-58] |
00402295 | lea ecx,dword ptr ss:[ebp-34] |
00402298 | mov dword ptr ss:[ebp-64],eax |
0040229B | lea eax,dword ptr ss:[ebp-6C] |
0040229E | push eax | key
0040229F | push ecx | Name运算后的结果字符串
004022A0 | mov dword ptr ss:[ebp-58],0 |
004022A7 | mov dword ptr ss:[ebp-6C],8008 |
004022AE | call dword ptr ds:[<&__vbaVarTstEq>] | 判断两个变量是否相等,不相等eax返回0x0,相等返回0xFFFFFFFF
- 综上写出注册机代码
#include<stdio.h>
#include<string.h>
int main()
{printf("请输入Name获取Key:\r\n");char name[1024] = { 0 };scanf("%s", name);int len = strlen(name);long long sum = 0;for (int i = 0; i < len; i++){sum += name[i];}sum = sum * 0x499602D2;char ans[1024] = { 0 };sprintf(ans, "%lld", sum);len = strlen(ans);if (len >= 9){ans[3] = '-';ans[8] = '-';printf("Key:%s\r\n",ans);}else{printf("Key计算错误\r\n");}return 0;
}
总结Crackme
- 输入Name,将Name值输入注册机,点击OK按钮