python写的第一个注册机
来源:互联网 发布:淘宝借贷在哪里 编辑:程序博客网 时间:2024/05/18 03:46
本文是从看雪上学习的。网址如下:http://bbs.pediy.com/showthread.php?threadid=23014 。
算法分析部分还是直接从那里贴过来吧,以后备用:
===========================================分析说明=====================================================
【软件名称】Bad Sector CrackMe1
【下载地址】附件(附KeyGen源码,本文和CrackMe1)
【应用平台】Win9x/NT/2000/XP
【软件大小】10K
【软件限制】没有。
【保护方式】用户名+序列号
【破 解 者】andy00
【破解难度】1/10
【破解声明】只是为了熟悉逆向工程。
【破解工具】OllyDbg,ResHacker,Windows自带计算器
【注册机下载】仅提供源代码,支持共享软件
【软件简介】My firts Crackme..ahh.This one is damn easy and I expect from anyoneto create keygen
for it, but if you cant code one,it would be enough to understand how it calculates real serial.
Enjoy btw. it's not packed/protected. -Bad Sector
;======================================================================================================
【分析过程】
为了熟悉逆向工程,静态分析能力,不调试
1、 直接用OllyDbg反汇编,无壳;
2、 在ResHacker看到用户名栏ID为C8,注册码栏为C9
3、 在OllyDbg查找输入函数GetWindowText和GetDlgItemText,顺利地找到了GetDlgItemText,
找到nIDDlgItem(要获取字符串的控件的ID)参数为03EB的那一个,这个GetDlgItemText应该就是获取输入的注册码的地方了.
(这里说明下,我在xp sp3下是用的GetDlgItemTextA这个函数)
00401139 6A 32 push 32 ; nMaxCount=32;
0040113B 68 F3204000 push Crackme1.004020F3 ; lpNameBuf=004020F3;
00401140 68 C8000000 push 0C8 ; nIDDlgItem=C8;
00401145 FF75 08 push dword ptr ss:[ebp+8]
00401148 E8 DE000000 call <jmp.&USER32.GetDlgItemTextA> ; eax=GetDlgItemTextA(hDlg,nIDDlgItem,lpNameBuf,nMaxCount);
;取用户名到004020F3,用户名字符个数放到eax
0040114D 83F8 00 cmp eax,0
00401150 0F84 99000000 je Crackme1.004011EF ; if(eax==0) goto 004011EF(失败消息);没有输入则失败
00401156 83F8 04 cmp eax,4
00401159 0F82 90000000 jb Crackme1.004011EF ; if(eax<4) goto 004011EF(失败消息);字符数<4失败
0040115F 33C9 xor ecx,ecx
00401161 33DB xor ebx,ebx
00401163 33F6 xor esi,esi ; ecx=ebx=esi=0;寄存器ECX,EBX,ESI清0
00401165 8945 FC mov dword ptr ss:[ebp-4],eax ; localVar1=eax;用局部变量localVar1保存字符个数
00401168 0FBE81 F3204000 movsx eax,byte ptr ds:[ecx+4020F3] ; eax=strUserName[ecx];取用户名第ecx+1个字符到eax
0040116F 83F8 20 cmp eax,20
00401172 74 07 je short Crackme1.0040117B ; if(eax==空格) goto 0040117B继续循环
;此处说明程序忽略空格
00401174 6BC0 04 imul eax,eax,4 ; eax=eax*4;
00401177 03D8 add ebx,eax ; ebx==ebx+eax;
00401179 8BF3 mov esi,ebx ; esi=ebx;
0040117B 41 inc ecx ; ecx=ecx+1;计数器增加1
0040117C 3B4D FC cmp ecx,dword ptr ss:[ebp-4]
0040117F ^ 75 E7 jnz short Crackme1.00401168 ; if(ecx!=localVar1) goto 00401168 没取完取下个字符;
00401181 83FE 00 cmp esi,0
00401184 74 69 je short Crackme1.004011EF ; if (esi==0) goto 004011EF(失败消息);若ESI等于0,则注册失败;
00401186 BB 89476500 mov ebx,654789 ; ebx=654789;
0040118B 0FBE81 F2204000 movsx eax,byte ptr ds:[ecx+4020F2] ; eax=lpNameBuf[ecx-1];取第ecx个字符
; 与后面结合可知此片循环从最后倒着取字符处理
00401192 4B dec ebx ; ebx=ebx-1;
00401193 6BC3 02 imul eax,ebx,2 ; eax=ebx*2;
00401196 03D8 add ebx,eax ; ebx=ebx+eax;
00401198 4B dec ebx ; ebx=ebx-1;
00401199 49 dec ecx ; ecx=ecx-1;
0040119A ^ 75 EF jnz short Crackme1.0040118B ; if(ecx!=0) goto 0040118B;若ecx==0,继续取字符;
0040119C 56 push esi ; arg1=esi;
0040119D 53 push ebx ; arg2=ebx;
0040119E 68 C7204000 push Crackme1.004020C7 ; lpFmt="BS-%lX-%lu";
004011A3 68 BB214000 push Crackme1.004021BB ; lpOut=004021BB;
004011A8 E8 6C000000 call <jmp.&USER32.wsprintfA> ; wsprintf(lpOut,lpFmt,arg2,arg1);
;用esi,ebx的值和格式"BS-%lX-%lu"生成正确的注册码放到004021BB
;此处可跟踪004021BB得到正确的注册码
004011AD 58 pop eax
004011AE 58 pop eax
004011AF 58 pop eax
004011B0 58 pop eax
004011B1 E8 01000000 call Crackme1.004011B7 ; SubFun004011B7();注册码检验函数
004011B6 C3 retn
;=================================SubFun004011B7()注册码逐位检验函数==================================
;以下过程取注册码并逐位验证
004011B7 33C9 xor ecx,ecx ; ecx=0;
004011B9 6A 32 push 32 ; nMaxCount=32;最多取50个字符
004011BB 68 57214000 push Crackme1.00402157 ; lpKeyBuf=00402157;注册码取到00402157
004011C0 68 C9000000 push 0C9 ; nIDDlgItem=C9;(注册码输入控件ID)
004011C5 FF75 08 push dword ptr ss:[ebp+8] ; hDlg=[ebp+8];
004011C8 E8 5E000000 call <jmp.&USER32.GetDlgItemTextA> ; eax=GetDlgItemTextA(hDlg,nIDDlgItem,lpKeyBuf,nMaxCount);
; 取输入的注册码到00402157
004011CD 83F8 00 cmp eax,0
004011D0 74 1D je short Crackme1.004011EF ; if(eax==0) goto 004011EF(失败消息);没有输入失败
004011D2 33C9 xor ecx,ecx ; ecx=0;
004011D4 0FBE81 57214000 movsx eax,byte ptr ds:[ecx+402157] ; eax=lpKeyBuf[ecx];取注册码第ecx+1个字符
004011DB 0FBE99 BB214000 movsx ebx,byte ptr ds:[ecx+4021BB] ; ebx=lpOut[0];取正确注册码第ecx+1个字符
004011E2 3BC3 cmp eax,ebx
004011E4 75 09 jnz short Crackme1.004011EF ; if(ebx!=eax) goto 004011EF(失败消息)不相等就失败;
004011E6 83F8 00 cmp eax,0
004011E9 74 19 je short Crackme1.00401204 ; if(eax==0) goto 00401204(成功消息);
; 此处可暴破
; 此处作者用eax==0判断字符取完
004011EB 41 inc ecx ; ecx=ecx+1;
004011EC ^ EB E6 jmp short Crackme1.004011D4 ; goto 004011D4(循环比较)继续下一位注册码比较;
004011EE C3 retn
;========================================注册失败消息================================================
004011EF 6A 10 push 10
004011F1 68 E4204000 push Crackme1.004020E4 ; ASCII "Nope"
004011F6 68 E9204000 push Crackme1.004020E9 ; ASCII "Try again"
004011FB FF75 08 push dword ptr ss:[ebp+8]
004011FE E8 34000000 call <jmp.&USER32.MessageBoxA>
00401203 C3 retn
;========================================注册成功消息==================================================
00401204 6A 40 push 40
00401206 68 D2204000 push Crackme1.004020D2 ; ASCII "Solved"
0040120B 68 D9204000 push Crackme1.004020D9 ; ASCII "Well done."
00401210 FF75 08 push dword ptr ss:[ebp+8]
00401213 E8 1F000000 call <jmp.&USER32.MessageBoxA>
00401218 C3 retn
;======================================================================================================
再贴上自己的python代码:
def zhuceji(usrname):unamelen=len(usrname)esi=0for i in range(unamelen):eax=ord(usrname[i])if eax != 32:eax=eax*4esi=eax+esiebx=0x654789print "%x" %ebxfor i in range(unamelen):ebx=ebx-1ebx+=ebx*2-1print "%x" %ebxebx=0xFFFFFFFF & ebx #只取ebx的后面八位print 'BS-%08X-%d' %(ebx,esi)while(1):usrname=raw_input("input usrname:")zhuceji(usrname)
- python写的第一个注册机
- 第一个注册机
- 我写的第一个用Python写的爬虫
- 我的第一个注册机.
- Python 写的第一个算法程序,果然很强大
- 第一个自己写的python程序:windows下备份文件
- 用 Python+Django 写的第一个 Hello World 程序
- 使用Python写的第一个网络爬虫程序
- 怎样开始写第一个基于python的selenium脚本
- eclipse+pydev写第一个python程序
- eclipse+pydev写第一个python程序
- 写的第一个blog
- 写的第一个博客
- 写的第一个Shader
- 写的第一个作业
- eclipse+python+pydev写第一个python程序
- Python的第一个程序
- Python的第一个程序
- 十年程序人生——转自黎活明
- STM32学习笔记1-软件安装
- 怎样在sdcard文件夹下面放置图片?
- 如何利用jconsole监视jvm
- WPF XAML里绑定数据源有哪几种呢?
- python写的第一个注册机
- 在使用VS创建 cocos2d-x 项目时遇到的一些问题
- Linux共享内存常见问题分析
- JAVA中API的各种应用
- [博弈]HDU 2176 取(m堆)石子游戏
- AOJ - 2224 Save your cat (最大生成树,Kruskal)
- 我的Java学习--对c语言的了解
- 1018. Public Bike Management (30)*
- JSP/Servlet环境配置