软件大小: 851 KB
软件语言: 英文
软件类别: 国外软件 / 共享版 / 文字处理
应用平台: Win9x/NT/2000/XP
界面预览: 无
加入时间: 2003-07-02 17:09:04
推荐等级: ★★★★
软件下载: http://count.skycn.com/softdown.php?id=12742&url=http://on165-http.skycn.net:8080/down/lemmy40.exe
软件介绍:
是一套文字编辑软件。是Unix上的文件编辑器(vi)的Windows版本。它提供了vi的所有功能。以下列出几个unix下的vi所没有的功能:1、分割视窗模式,允许向上移四个分割视窗。2、支持Windows的剪贴簿。3、可以直接拖拉文件到Lemmy中。4、可以设定字型与颜色,并且支持语法高亮度显示。5、状态列显示资讯。6、可从文件选单中,选取最近使用过的文件。7、支持印表机打印,也可以把语法高亮度印出来喔。虽然它是个文字编辑器,但对Windows的使用者来说,是一套很不好用的编辑器。
破解工具:OllyDby1.09,TRW1.22
作者声明:初学破解,仅作学习交流之用,失误之处敬请大侠赐教!
无壳,VC编写,这个软件的注册部分是在安装文件夹下的lemreg.exe文件中!
先在TRW中用bpx getwindowtexta下断找断点,再用OD载入lemreg.exe分析!
【简要过程】:
用户名:ShenGe[BCG]
试验码:1234567887654321
.............(略)
0040179B PUSH EAX
<---EAX="1234567887654321",假码
0040179C PUSH ECX
<---ECX="ShenGe[BCG]",用户名
0040179D LEA ECX, DWORD PTR DS:[ESI+68]
004017A0 CALL LEMREG.004019F0
<---这个是关键的Call,跟进!①
004017A5 TEST EAX, EAX
004017A7 JE SHORT LEMREG.004017FF
<---关键跳转!不跳就完了!
004017A9 PUSH 0
004017AB PUSH 30
004017AD PUSH LEMREG.0042E0B0
<---"Check
the values supplied"入栈!
004017B2 CALL LEMREG.0041EE0E
<---注册码错误!
004017B7 PUSH 3E8
004017BC MOV ECX, ESI
004017BE CALL LEMREG.0041B8AA
004017C3 MOV ECX, EAX
004017C5 CALL LEMREG.0041BB07
004017CA PUSH 3E8
004017CF MOV ECX, ESI
004017D1 CALL LEMREG.0041B8AA
004017D6 MOV EDI, DWORD PTR DS:[<&USER32.Send>
004017DC MOV ESI, EAX
004017DE PUSH -1
; /lParam
= FFFFFFFF
004017E0 PUSH 0
;
|wParam = 0
004017E2 MOV ECX, DWORD PTR DS:[ESI+1C]
; |
004017E5 PUSH 0B1
; |Message
= EM_SETSEL
004017EA PUSH ECX
; |hWnd
= 81637000
004017EB CALL EDI
; \SendMessageA
004017ED MOV EDX, DWORD PTR DS:[ESI+1C]
004017F0 PUSH 0
;
/lParam = 0
004017F2 PUSH 0
;
|wParam = 0
004017F4 PUSH 0B7
; |Message
= EM_SCROLLCARET
004017F9 PUSH EDX
; |hWnd
= 81637040
004017FA CALL EDI
; \SendMessageA
004017FC POP EDI
004017FD POP ESI
004017FE RETN
004017FF MOV ECX, ESI
00401801 CALL LEMREG.00418656
00401806 POP EDI
00401807 POP ESI
00401808 RETN
★★★★★★★★★
①跟进那个关键的Call,来到以下代码:
004019F0 PUSH EBX
004019F1 PUSH EBP
004019F2 PUSH ESI
004019F3 PUSH EDI
004019F4 MOV EDI, ECX
004019F6 PUSH 8
004019F8 OR EBP, FFFFFFFF
004019FB CALL LEMREG.00417E88
00401A00 MOV ESI, DWORD PTR SS:[ESP+1C]
00401A04 ADD ESP, 4
00401A07 MOV EBX, EAX
00401A09 XOR EDX, EDX
☆☆☆☆☆☆☆☆☆☆
00401A0B MOVSX EAX, BYTE PTR DS:[ESI]
<---取假码第1位
00401A0E MOVSX ECX, BYTE PTR DS:[ESI+1]
<---取假码第2位
下面这1段对取得的字符进行判断,并进行不同的处理:
对于字符在[0,9]的,Hex值减0x30
对于字符在[A,F]的,Hex值减0x37
其余字符为不合法字符
≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈
00401A12 CMP EAX, 30
00401A15 JL SHORT LEMREG.00401A21
00401A17 CMP EAX, 39
00401A1A JG SHORT LEMREG.00401A21
00401A1C SUB EAX, 30
00401A1F JMP SHORT LEMREG.00401A32
00401A21 CMP EAX, 41
00401A24 JL SHORT LEMREG.00401A30
00401A26 CMP EAX, 46
00401A29 JG SHORT LEMREG.00401A30
00401A2B SUB EAX, 37
00401A2E JMP SHORT LEMREG.00401A32
00401A30 XOR EAX, EAX
00401A32 CMP ECX, 30
00401A35 JL SHORT LEMREG.00401A41
00401A37 CMP ECX, 39
00401A3A JG SHORT LEMREG.00401A41
00401A3C SUB ECX, 30
00401A3F JMP SHORT LEMREG.00401A52
00401A41 CMP ECX, 41
00401A44 JL SHORT LEMREG.00401A50
00401A46 CMP ECX, 46
00401A49 JG SHORT LEMREG.00401A50
00401A4B SUB ECX, 37
00401A4E JMP SHORT LEMREG.00401A52
≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈
00401A50 XOR
ECX, ECX
-------------------------
00401A52 SHL AL, 4
00401A55 ADD AL, CL
-------------------------
☆☆☆☆☆☆☆☆☆☆
这1段实现如下功能:Char(如"12")--->Hex(转换成0x12)
00401A57 ADD
ESI, 2
<---指针指向下一组
00401A5A MOV BYTE PTR DS:[EBX+EDX], AL
<---结果存入DS:[EBX+EDX]中
我的结果在内存中表示为:
12 34 56 78
87 65 43 21
00401A5D INC EDX
00401A5E CMP EDX, 8
<---循环控制,循环8次
00401A61 JL SHORT LEMREG.00401A0B
00401A63 PUSH EBX
<---EBX的值为上面运算后的结果
在内存中为12 34 56
78 87 65 43 21
00401A64 MOV ECX, EDI
00401A66 CALL LEMREG.00401060
<---跟进此Call看看②,此Call后的返回
值在EBX中为:B6 7C
EE 16 84 13 91 EE
00401A6B MOV EDX, DWORD PTR SS:[ESP+14]
<---EDX="ShenGe[BCG]"
00401A6F OR ECX, FFFFFFFF
00401A72 MOV EDI, EDX
00401A74 XOR EAX, EAX
00401A76 REPNE SCAS BYTE PTR ES:[EDI]
<---取用户名位数
00401A78 NOT ECX
00401A7A DEC ECX
00401A7B CMP ECX, 8
<---判断用户名位数是否大于等于8
00401A7E JBE SHORT LEMREG.00401A87
00401A80 MOV ECX, 8
<---ECX=8,估计只取用户名8位运算
00401A85 JMP SHORT LEMREG.00401A93
00401A87 MOV EDI, EDX
00401A89 OR ECX, FFFFFFFF
00401A8C XOR EAX, EAX
00401A8E REPNE SCAS BYTE PTR ES:[EDI]
00401A90 NOT ECX
00401A92 DEC ECX
00401A93 TEST ECX, ECX
00401A95 JLE SHORT LEMREG.00401AA8
00401A97 PUSH ECX
<---ECX=8
00401A98 PUSH EBX
<---EBX指向B6
7C EE 16 84 13 91 EE
00401A99 PUSH EDX
<---EDX="ShenGe[BCG]"
00401A9A CALL LEMREG.004079F0
<---比对的Call,这个代码我就不列出来了
这个Call将用户名的前8位字符的Hex与
B6 7C EE 16
84 13 91 EE分别进行比较是否相等,
即要求注册码经过转换后的值要与用户名
的Hex值相等。
00401A9F ADD ESP, 0C
00401AA2 TEST EAX, EAX
00401AA4 JNZ SHORT LEMREG.00401AA8
<---比较不相等此处会跳!
00401AA6 XOR EBP, EBP
<---EBP=0
00401AA8 PUSH EBX
00401AA9 CALL LEMREG.00417EC4
00401AAE ADD ESP, 4
00401AB1 MOV EAX, EBP
<---EAX=EBP,标志位!
00401AB3 POP EDI
00401AB4 POP ESI
00401AB5 POP EBP
00401AB6 POP EBX
00401AB7 RETN 8
★★★★★★★★★
②跟进这个Call:
00401060 SUB ESP, 8
00401063 MOV EDX, DWORD PTR SS:[ESP+C]
<---EDX指向内存中
12 34 56 78
87 65 43 21
00401067 PUSH EBX
00401068 PUSH ESI
00401069 PUSH EDI
☆☆☆☆☆☆☆☆☆☆
0040106A MOV AL, BYTE PTR DS:[EDX+4]
<---AL=87,取第5位
0040106D MOV EDI, ECX
0040106F MOV CL, BYTE PTR DS:[EDX+2]
<---CL=56,取第3位
00401072 MOV BYTE PTR SS:[ESP+C], AL
<---AL的值存入SS:[ESP+C]
00401076 MOV AL, BYTE PTR DS:[EDX+7]
<---AL=21,取第8位
00401079 MOV BYTE PTR SS:[ESP+D], CL
<---CL的值存入SS:[ESP+D]中
0040107D MOV CL, BYTE PTR DS:[EDX]
<---CL=12,取第1位,唉!后面懒得写了!
0040107F MOV BYTE PTR SS:[ESP+E], AL
00401083 MOV AL, BYTE PTR DS:[EDX+6]
00401086 MOV BYTE PTR SS:[ESP+F], CL
0040108A MOV CL, BYTE PTR DS:[EDX+3]
0040108D MOV BYTE PTR SS:[ESP+10], AL
00401091 MOV AL, BYTE PTR DS:[EDX+5]
00401094 MOV BYTE PTR SS:[ESP+11], CL
00401098 MOV CL, BYTE PTR DS:[EDX+1]
0040109B MOV BYTE PTR SS:[ESP+12], AL
☆☆☆☆☆☆☆☆☆☆
上面这一小段是将内存中的值重新排序,对应关系如下:
原值:
12 34 56 78 87 65 43 21
↓
↓ ↓ ↓ ↓ ↓ ↓ ↓
对应于在原值中的位置:5 3 8 1 7 4 6 2
----------------------------------------------
排序后: 87 56 21 12 43 78 65
34
0040109F LEA ESI, DWORD PTR SS:[ESP+C]
004010A3 XOR EAX, EAX
004010A5 MOV BYTE PTR SS:[ESP+13], CL
004010A9 SUB ESI, EDX
004010AB MOV CL, BYTE PTR DS:[EAX+EDI+14]
<---[EDI+14]中指向的内存中为
定值31 2A CF 04 C7 6B
F4 DA
CL=0x31
CL=0x2A
.....(略)
004010AF MOV BL, BYTE PTR DS:[ESI+EDX]
<---[ESI]中为重新排序后的值
87 56 21 12
43 78 65 34
BL=0x87
BL=0x56
....(略)
004010B2 XOR CL, BL
<---CL=CL^BL=0x31^0x87=0xB6
CL=0x2A^0x56=0x7C
....(略)
004010B4 INC EAX
004010B5 MOV BYTE PTR DS:[EDX], CL
<---作或运算后的结果存入DS:[EDX]中
我最后得到的为:B6 7C
EE 16 84 13 91 EE
004010B7 INC EDX
004010B8 CMP EAX, 8
004010BB JL SHORT LEMREG.004010AB
004010BD POP EDI
004010BE POP ESI
004010BF POP EBX
004010C0 ADD ESP, 8
004010C3 RETN 4
【总结】:用户名长度必须大于或等于8,注册码与用户名前8位有关。具体算法见我下
面逆推我的注册码过程:
程序中置定值31 2A CF 04 C7 6B F4 DA与注册码作运算!
S--->53---->53^31=62
h--->68---->68^2A=42
e--->65====>65^CF=AA
n--->6E====>6E^04=6A
G--->47====>47^C7=80
e--->65====>65^6B=0E
[--->5B====>5B^F4=AF
B--->42====>42^DA=98
原值:
6A 98 42 0E 62 AF 80 AA
--------------------------------------------
对应于在原值的位置: 5 3 8 1 7 4 6 2
↑ ↑
↑ ↑ ↑ ↑ ↑ ↑
排序后: 62 42 AA 6A 80 0E AF 98
由此得到我的注册码为:6A98420E62AF80AA
软件注册成功后将注册信息保存在注册表的:
"HKEY_LOCAL_MACHINE\Software\Lemmy\Lemmy\Registration"下。
给出一个可用注册码:
用户名:ShenGe[BCG]
注册码:6A98420E62AF80AA
Cracked By ShenGe[BCG] 2003.07.03