《加密与解密》第三篇非明码比较分析,个人实战
来源:互联网 发布:淘宝夜店装 编辑:程序博客网 时间:2024/06/01 10:23
所谓非明码就是软件没有在代码了直接写出与其计算出的序列号比较得出是否符合,而是通过一种绕弯的方式进行进行用户名与序列号比较,在OD或者某反汇编中难以找到正确的序列号而是通过一个等式进行判断用户是否输入正确:
K1(用户名) = K2(序列号)
在虚拟机中用OD打开例子程序serialt.exe,运行它、点Help/Register弹出一个对话框随便输入一个“Name :zhanghanyu123”,“123456789”、点击"OK"按钮弹出,在OD中点查找/所有匹配字符串、看这是一件捕获到你输入的Name和序列号了
双击这个地址来到关键代码处:
反汇编代码如下:
00401228 68 8E214000 push serialt.0040218E ; ASCII "ZHANGHANYU"0040122D E8 4C010000 call serialt.0040137E ; 调用计算用户名得出一个数值00401232 50 push eax00401233 68 7E214000 push serialt.0040217E ; ASCII "123456789"00401238 E8 9B010000 call serialt.004013D8 ; 调用计算一个输入的序列号得出数值
在0040122D这个地方下一个断点,重新跑程序,进入断点处,F7进入CALL调用的函数内部
具体分析如下:
0040137E 8B7424 04 mov esi,dword ptr ss:[esp+0x4] ; esi = 压入栈中的name存放地址00401382 56 push esi ; 再次将esi压入栈中00401383 8A06 mov al,byte ptr ds:[esi] ; esi的一个字节给al00401385 84C0 test al,al ; 比较al是否为空00401387 74 13 je short serialt.0040139C ; 空的那么就跳到0040139C地址处00401389 3C 41 cmp al,0x41 ; 字符与41h相比较(与“A”相比较)0040138B 72 1F jb short serialt.004013AC ; 如果小于A那么就不是字母跳到004013AC0040138D 3C 5A cmp al,0x5A ; 字符再次与5AH比较(与“z”比较)0040138F 73 03 jnb short serialt.00401394 ; al不低于5Ah(“z”ASCII值)就跳转0040139400401391 46 inc esi ; esi+1指向下一个字符(字节)00401392 ^ EB EF jmp short serialt.00401383 ; 无条件跳到00401383处执行循环00401394 E8 39000000 call serialt.004013D200401399 46 inc esi ; esi+1指向下一个字符0040139A ^ EB E7 jmp short serialt.00401383 ; 继续循环0040139C 5E pop esi ; esi出栈0040139D E8 20000000 call serialt.004013C2 ; 跳004013C2函数处004013A2 81F7 78560000 xor edi,0x5678 ; edi的字符相加的值域5678h进行异或运算004013A8 8BC7 mov eax,edi ; 得出的值给eax004013AA EB 15 jmp short serialt.004013C1 ; 跳004013C1返回函数外部指向下一行代码004013AC 5E pop esi004013AD 6A 30 push 0x30004013AF 68 60214000 push serialt.00402160 ; ASCII "Error! "004013B4 68 69214000 push serialt.00402169 ; ASCII "Incorrect!,Try Again"004013B9 FF75 08 push dword ptr ss:[ebp+0x8]004013BC E8 79000000 call <jmp.&USER32.MessageBoxA> ; 错误信息提示超出范围004013C1 C3 retn004013C2 33FF xor edi,edi ; edi清0004013C4 33DB xor ebx,ebx ; ebx清0004013C6 8A1E mov bl,byte ptr ds:[esi] ; 拿出esi数据中一个字节给bl004013C8 84DB test bl,bl ; 判断name中还有字符吗?004013CA 74 05 je short serialt.004013D1 ; 没有则跳到004013D1返回004013CC 03FB add edi,ebx ; 将ebx中的字符依次相加004013CE 46 inc esi ; esi+1指向下一个字符(字节)004013CF ^ EB F5 jmp short serialt.004013C6 ; 跳到004013C6循环次操作直到name字符没有为止004013D1 C3 retn ; 返回004013A2处004013D2 2C 20 sub al,0x20 ; al-20h 相当于吧小写字母变成大写字母004013D4 8806 mov byte ptr ds:[esi],al ; 得到的大写字母值重新放入esi中004013D6 C3 retn ; 返回00401399处返回外部,执行下一行代码!
F7继续执行同理下面CALL也一样,进入CALL内部
代码如下
代码具体分析如下:
004013C2 33FF xor edi,edi ; edi清0004013C4 33DB xor ebx,ebx ; ebx清0004013C6 8A1E mov bl,byte ptr ds:[esi] ; 拿出esi数据中一个字节给bl004013C8 84DB test bl,bl ; 判断name中还有字符吗?004013CA 74 05 je short serialt.004013D1 ; 没有则跳到004013D1返回004013CC 03FB add edi,ebx ; 将ebx中的字符依次相加004013CE 46 inc esi ; esi+1指向下一个字符(字节)004013CF ^ EB F5 jmp short serialt.004013C6 ; 跳到004013C6循环次操作直到name字符没有为止004013D1 C3 retn ; 返回004013A2处004013D2 2C 20 sub al,0x20 ; al-20h 相当于吧小写字母变成大写字母004013D4 8806 mov byte ptr ds:[esi],al ; 得到的大写字母值重新放入esi中004013D6 C3 retn ; 返回00401399处004013D7 C3 retn004013D8 33C0 xor eax,eax ; eax清0004013DA 33FF xor edi,edi ; edi清0004013DC 33DB xor ebx,ebx ; ebx清0004013DE 8B7424 04 mov esi,dword ptr ss:[esp+0x4] ; 存放序列号的地址给esi004013E2 B0 0A mov al,0xA ; al=0Ah004013E4 8A1E mov bl,byte ptr ds:[esi] ; 将esi地址第一个字节(字符)给bl004013E6 84DB test bl,bl ; bl是否为空(是否全部没有)004013E8 74 0B je short serialt.004013F5 ; 相等则直接跳走进行异或运算004013EA 80EB 30 sub bl,0x30 ; bl=bl-30h code[i]-30h004013ED 0FAFF8 imul edi,eax ; edi=edi*0ah相当与左移1位004013F0 03FB add edi,ebx ; 将每个字符计算出的数值加起来004013F2 46 inc esi ; esi指向下一个字符 循环004013F3 ^ EB ED jmp short serialt.004013E2004013F5 81F7 34120000 xor edi,0x1234 ; 最后结果进行异或运算004013FB 8BDF mov ebx,edi ; 值放入ebx中004013FD C3 retn ; 返回CALL下一行代码返回我们看见了核心的比较
代码分析如下:
00401241 3BC3 cmp eax,ebx ; eax(用户名的计算结果)是否等于ebx(序列号的计算结果)00401243 74 07 je short serialt.0040124C ; 相等跳到0040124C执行CALL00401245 E8 18010000 call serialt.004013620040124A ^ EB 9A jmp short serialt.004011E60040124C E8 FC000000 call serialt.0040134D00401251 ^ EB 93 jmp short serialt.004011E60040134D具体如下:
{
0040134D 6A 30 push 0x300040134F 68 29214000 push serialt.00402129 ; ASCII "Good work!"00401354 68 34214000 push serialt.00402134 ; ASCII "Great work!GOOD! Now try the next CrackMe!"00401359 FF75 08 push dword ptr ss:[ebp+0x8]0040135C E8 D9000000 call <jmp.&USER32.MessageBoxA> ; 执行注册信息成功的函数
}
分析后发现这个ebx和eax使我们主要注意的数据 只要计算结果ebx和eax相等就跳转注册成功的地方那么想办法让ebx和eax相等就行了
我做了如下修改:
我在计算name值函数里面讲xor edi,0x5678 修改成 imul edi,0x0h 这样edi等于0
同理 在序列号函数里面也修改成imul edi,0x0h
然后复制到可执行文件
在外部比较两个计算出的值相等
那么就转向注册成功!
当然你也可以直接将cmp ebx,eax 下面的je指令改为jne指令意思是不相等则跳转 直接转到注册成功!
同样可以成功!
分析完后发现这个例子程序就是利用这个等式进行软件注册的
K1(用户名) = K2(序列号)
完!
阅读全文
0 0
- 《加密与解密》第三篇非明码比较分析,个人实战
- 《加密与解密》第三篇解密篇“KeyFile保护攻击”个人实战例子(上)”
- RSA 非对称加密与解密
- 电子书:《加密与解密》第三版
- RSA加密与解密(比较详细))
- 《加密与解密(第三版)》读书笔记第2章(动态分析,OllyDbg基本操作)
- 《加密与解密(第三版)》读书笔记第3章(静态分析 IDA pro)
- 《加密与解密(第三版)》读书笔记第4章(逆向分析 阅读汇编代码)
- Java加密与解密的艺术-非对称加密
- 分析java的加密与解密机制
- 加密,解密算法比较
- Java对称与非对称加密解密,AES与RSA
- Java对称与非对称加密解密,AES与RSA
- Java对称与非对称加密解密,AES与RSA
- 关于RSA与AES加密解密个人理解
- 漫谈iOS RSA非对称加密与解密
- 漫谈iOS RSA非对称加密与解密
- Java加密与解密学习记录05-非对称加密算法
- AIDE MD主题配置
- 中国最好大学网爬取大学排名信息
- Oracle 删除表中记录 如何释放表及表空间大小
- Android LruCache : how to put and get user's data
- 学习Docker(2017-10-2)
- 《加密与解密》第三篇非明码比较分析,个人实战
- 【NOIP2016】换教室
- LinuxStudyNote(43)-图解Linux系统分区
- 刺杀
- some tips about python
- HDU 5521 Meeting
- 【Luogu3919】可持久化数组
- 组合数
- Swift开发指南:使用Swift与Cocoa和Objective-C(Swift 4)