加解密学习:简单的用户名密码组合式验证程序的解密流程

这里以160个CrackMe之033为例


1.工具与环境

Windows 7 sp1 64bit

吾爱破解OD


2.破解流程

首先运行一下程序了解程序功能,可以看到是一个普通的用户名+序列号方式验证的crackme程序。



尝试输入用户名和密码




输入错误后发现有弹出提示,提示文字将帮助我们找到程序流程,这个程序比较特别弹出两次文本提示框,猜测是为了混淆




在OD界面下,主线程,模块窗口点击右键----查找-----所有参考文本字串



可以看到这边有着两个 No luck there ,mate!


点击进入到该文本所在的地址,可以发现有两部分对于文本框参数进行描述的汇编代码,通过观测发现,有一块文本框参数描述的汇编代码前面有一段程序,从0040137E开始到004013C1结束




试着分析这段代码,发现是一个判断输入字符串是否是从大写A到Z的函数


函数注释如下:

0040137E  /$  8B7424 04     mov esi,dword ptr ss:[esp+0x4]    ;将字符串源的偏移地址填入到esi中
00401382  |.  56            push esi								;将esi数据填入到堆栈
;以循环的方式将字符串的每一个字符进行比对以确定字符在大写的A-Z之间
00401383  |>  8A06          /mov al,byte ptr ds:[esi]				;将esi指向的数据填入到低位
00401385  |.  84C0          |test al,al								;比较AX寄存器低16位是否为0
00401387  |.  74 13         |je XCruehead.0040139C					;如果ZF寄存器为1则转移到指定地址
00401389  |.  3C 41         |cmp al,0x41							;比较AX寄存器的低16位和0x41
0040138B  |.  72 1F         |jb XCruehead.004013AC					;如果小于则转移
0040138D  |.  3C 5A         |cmp al,0x5A							;比较AX寄存器的低16位和0x5A
0040138F  |.  73 03         |jnb XCruehead.00401394					;如果小于等于则转移
00401391  |.  46            |inc esi								;esi自加1
00401392  |.^ EB EF         |jmp XCruehead.00401383					;跳转到指定地址,这里会返回到上方进行下一次判断
00401394  |>  E8 39000000   |call Cruehead.004013D2					;调用指定地址程序
00401399  |.  46            |inc esi								;esi自加1
0040139A  |.^ EB E7         \jmp XCruehead.00401383					;跳转到指定地址,这里会返回到上方进行下一次判断
0040139C  |>  5E            pop esi									;从堆栈中读取最初的esi地址
0040139D  |.  E8 20000000   call Cruehead.004013C2					;调用子程序
004013A2  |.  81F7 78560000 xor edi,0x5678							;将edi和0x5678异或(仅一个1一个0时结果为1)
004013A8  |.  8BC7          mov eax,edi								;将edi赋值到eax
004013AA  |.  EB 15         jmp XCruehead.004013C1					;调用子程序
004013AC  |>  5E            pop esi 								;将堆栈中数据复制到esi中
;配置消息弹出框并将数据进行显示
004013AD  |.  6A 30         push 0x30                                ; 填入数据到堆栈中  /Style = MB_OK|MB_ICONEXCLAMATION|MB_APPLMODAL
004013AF  |.  68 60214000   push Cruehead.00402160                   ; 填入数据到堆栈中 |Title = "No luck!"
004013B4  |.  68 69214000   push Cruehead.00402169                   ; 填入数据到堆栈中|Text = "No luck there, mate!"
004013B9  |.  FF75 08       push [arg.1]                             ; 填入数据到堆栈中 |hOwner
004013BC  |.  E8 79000000   call <jmp.&USER32.MessageBoxA>           ; 调用消息框函数显示文字提示 \MessageBoxA
004013C1  \>  C3            retn                                     ;函数结束,返回



到这里可以判断这是一个前置判断的预处理函数,肯定是最先执行的


搜索call  0040137E,找到了调用这一函数位置,发现这边存储(放入堆栈)我们之前输入的名称和序列号



继续往下查看,可以看到在调用了先前0040137E起始的判断字符类型函数后,又调用起始位置为004013D8的函数,该函数处理我们输入的序列号数据


004013D8的函数注释如下:



之后,将把序列号和我们的用户名进行一个比较,从而判断输入的用户名序列号是否匹配


关键跳转位置在00401243处,我们将此处修改为JMP 0040124C







程序就能够正常的跳出成功提示了




3.总结


从该类简单的弹窗式名称密码校验程序算法中我们可以了解到,需要用户输入的名称和序列号在之后的验证中往往相辅相成,有所联系。

在整个流程中,先寻找文字,再寻找子函数,分析函数用途,再去追踪函数调用,最终找到关键跳转,是攻破此类程序基本的解密流程。



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值