当前位置: 首页 > ai >正文

crackme006

crackme006

名称
软件名称aLoNg3x.1.exe
加壳方式
保护方式Serial
编译语言Delphi
调试环境Win10 64位
使用工具x32dbg,ida pro,PEid,DarkDe4
破解日期2025-06-05

脱壳

1. 先用PEid查壳

01-PEid查壳
查到无壳

寻找Serial

  • 查询到编程语言为Delphi

  • 导出Delphi符号表信息到x32dbg,用IDA Pro 打开程序
    02-ida pro 打开程序

  • 添加常见Delphi库的符号

常见Delphi库
b32vcl
bds2006
delphi
d5vcl
d4vcl
c4vcl
bds
  • 快捷键Shift+F5,如下图所示
    03-IDA Pro Signatures

  • 导出map文件,File->Produce file->Create MAP file...
    04-导出map文件

  • 安装SwissArmyKnife插件,导入上一步生成的map文件。x32dbg中插件->SwissArmyKnife->Load->MAP file
    15-导入map文件

  • 用DarkDe4打开PE文件
    16-DarDe4查看Delphi程序

  • 查看窗体结构
    07-DarDe4查看Delphi窗体结构

  • 寻找flag,点击 About-Help按钮,发现Flag:隐藏Cancella和Ok两个按钮
    08-Find-Flag

  • 在DarkDe4中可以发现Cancella的id为:2D0,Ok按钮的id为:2CC
    09-DarDe4查看控件Id

  • 查找Cancella的调用 鼠标右键->搜索->当前模块->常数 输入2D0
    10-查找常数2D0

  • 选中地址=00442EF2反汇编=mov eax,dword ptr ds:[ebx+2D0] 跳转到SetVisible函数的调用处,发现关键函数调用call <along3x.1.sub_442AF4>
    11-SetVisible的调用处

  • 分析函数调用call <along3x.1.sub_442AF4>
    12-分析隐藏Cancella算法

mov eax,dword ptr ss:[ebp-4] ;取nome字符串首地址
call <along3x.1.unknown_libname_1145> ;获取nome字符串的长度
cmp eax,5 ;nome字符串长度与5比较
jle <along3x.1.loc_442B78> nome字符串长度小于等于5则字节,跳转到along3x.1.loc_442B78
mov eax,dword ptr ss:[ebp-4] ;取nome字符串首地址
movzx eax,byte ptr ds:[eax+4]; 取nome[4]的ASCII
mov ecx,7
xor edx,edx;情况edx
div ecx ;eax除以7,商存入eax,余数存入edx中
mov eax,edx;余数存入eax
add eax,2;eax = 余数+2
call <along3x.1.sub_442A20>;求eax的阶乘
mov esi,eax ;阶乘结果存入esi
xor ebx,ebx ;清空ebx
mov eax,dword ptr ss:[ebp-4];取nome字符串首地址
call <along3x.1.unknown_libname_1145>;nome字符串的长度
test eax,eax  ;eax按位与
jle <along3x.1.loc_442B65> ;nome长度为0跳转到along3x.1.loc_442B65
mov edx,1  ;索引初值为1
along3x.1.loc_442B54: mov ecx,dword ptr ss:[ebp-4] ;取nome字符串首地址
movzx ecx,byte ptr ds:[ecx+edx-1];取nome[edx-1]的ascii
imul ecx,esi ;nome[edx-1]的ascii乘以阶乘
add ebx,ecx;nome[edx-1]的ascii乘以阶乘结果累加到ebx中
inc edx;索引自增1
dec eax;字符串长度自减1
jne <along3x.1.loc_442B54>; eax不为0跳转到along3x.1.loc_442B54
sub ebx,dword ptr ss:[ebp-8];累加结果减去strToInt(codice)
cmp ebx,7A69;结果是否等于7A69
jne <along3x.1.loc_442B74>;不等于7A69跳出
mov bl,1
  • 综上分析出算法,写下c++代码注册机
#include<stdio.h>
#include<stdlib.h>
#include<string.h>int factorial(int n)
{if (n == 1)return 1;return n * factorial(n - 1);
}int serial1(char* name)
{int len = strlen(name);if (len <= 5){return -1;}int res = 0;int resA = (name[4] % 7 + 2);resA = factorial(resA);for (int index = 0; index < len; index++){res += name[index] * resA;}res -= 0x7A69;return res;
}
int main()
{char nome[1024]={0};printf("请输入Nome得出codice解锁Cancella:\n");scanf("%s", nome);int res = serial1(nome);if (res == -1){printf("字符串长度必须大于5\r\n");return 0;}printf("序列号为:%d\r\n", res);return 0;
}
  • 查找Ok的调用 鼠标右键->搜索->当前模块->常数 输入2CC
    在这里插入图片描述
  • 选中 地址=00442DCC反汇编=mov eax,dword ptr ds:[ebx+2CC] ,跳转到SetVisible函数的调用处,发现关键函数调用call <along3x.1.sub_442BA0>
    14-SetVisible的调用处
  • 分析call <along3x.1.sub_442BA0>
    15-分析隐藏Ok算法
mov eax,dword ptr ss:[ebp-8]; 取codice字符串首地址
call <along3x.1.unknown_libname_1145> ;取codice字符串长度
cmp eax,5 ; 比较字符串长度与5
jle <along3x.1.loc_442C4A> ;字符串长度小于等于5则跳转出去
mov eax,dword ptr ss:[ebp-8]; 取codice首地址
call <along3x.1.unknown_libname_1145> ; 取codice字符串长度
mov esi,eax
cmp esi,1 ; 字符串长度与1比较
jl <along3x.1.loc_442C28> ;字符串长度小于1跳转出去
along3x.1.loc_442BF9: lea eax,dword ptr ss:[ebp-C] ;取codice首地址
call <along3x.1.System::UniqueString(System::AnsiString &)>
lea eax,dword ptr ds:[eax+esi-1]; 取codice[esi-1]的地址
push eax ; codice[esi-1]的地址入栈
mov eax,dword ptr ss:[ebp-8] ; 取codice的首地址
movzx eax,byte ptr ds:[eax+esi-1] ; 取codice[esi-1]的ascci
imul eax ; eax = codice[esi-1]*codice[esi-1]
movsx eax,ax; 取积的低16位
imul esi ; 乘以当前索引
mov ecx,19
cdq 
idiv ecx; 除以19
add edx,41; 除以19的余数+0x41
pop eax ; 将codice[esi-1]的地址赋值给eax
mov byte ptr ds:[eax],dl; 将结果的低8位赋值给codice[esi-1]
dec esi ; esi 自减1
test esi,esi 判断esi是否为0
jne <along3x.1.loc_442BF9> ; esi不为零循环继续
  • 综上分析出算法,写下c++代码注册机
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
char* serial2(char* codice)
{int len = strlen(codice);if (len <= 5){return NULL;}int res = len;char ans[1024] = {0};for (int index = len - 1; index >= 0; index --){ans[index] = (codice[index] * codice[index] * (index + 1) % 0x19) + 0x41;}return ans;
}
int main()
{char codice[1024] = { 0 };printf("请输入codice得出nome解锁Ok:\n");scanf("%s", codice);char* ans_str = serial2(codice);if (ans_str == NULL){printf("字符串长度必须大于5\r\n");return 0;}printf("序列号为:%s\r\n", ans_str);return 0;
}
http://www.xdnf.cn/news/12978.html

相关文章:

  • 抽象类和接口(全)
  • 98.错误走百度翻译API的苦98步
  • 深入浅出JavaScript中的ArrayBuffer:二进制数据的“瑞士军刀”
  • 从数据到价值:企业构建大数据价值链的核心战略
  • 闭合逻辑检测(保留最大连通分量)
  • 浏览器中 SignalR 连接示例及注意事项
  • 信创领域下的等保合规建设及解读
  • ava多线程实现HTTP断点续传:原理、设计与代码实现
  • 大学生职业发展与就业创业指导教学评价
  • 用 FFmpeg 实现 RTMP 推流直播
  • ArcGIS Pro裁剪栅格影像
  • 洞见未来医疗:RTC技术如何重塑智慧医疗新生态
  • __VUE_PROD_HYDRATION_MISMATCH_DETAILS__ is not explicitly defined.
  • android RecyclerView 加载不同的item
  • 基于STM32物联网智能鱼缸智能家居系统
  • Android Framework 之 AudioDeviceBroker
  • 关于TFLOPS、GFLOPS、TOPS
  • 高等三角函数大全
  • 基于Flask,MySQL和MongoDB实现的在线阅读系统
  • (每日一道算法题)子集
  • day51 python CBAM注意力
  • 当文化遇见科技:探秘国际数字影像创新生态高地
  • python爬虫——气象数据爬取
  • 了解Android studio 初学者零基础推荐(4)
  • LangChain + LangSmith + DeepSeek 入门实战:构建代码生成助手
  • 深入理解 React 样式方案
  • VRRP(虚拟路由冗余协议)深度解析
  • 循环语句之while
  • Netty自定义协议解析
  • R语言速释制剂QBD解决方案之一