标 题:Splish-crackme (10千字)
发信人:刀剑啸
时 间:2002-6-9 11:26:36
详细信息:
这是我以前写的一个教程,当初为了交差是用英文写的,也不想在再用中文写了,请大家凑合着看,
Splishcrackme
。CrackMe下载
Crackme name:splish
Author: DJX
Protection: Nag&Serial&hard code
tools: TRW2000 v1.22 Ultraedit v8.0 Windasm v9.0
Intro:This is my second tourial.
Let's begin:
Frist disable the Nag
Use trw2000 load the programit break on the entry point
:00401000 6A00 push 00000000
* Reference To: KERNEL32.GetModuleHandleA Ord:0111h
|
:00401002 E883070000 Call 0040178A
:00401007 A380344000 mov dword ptr [00403480] eax
* Reference To: KERNEL32.GetCommandLineA Ord:00B6h
|
:0040100C E873070000 Call 00401784
:00401011 6A0A push 0000000A
:00401013 FF3584344000 push dword ptr [00403484]
:00401019 6A00 push 00000000
:0040101B FF3580344000 push dword ptr [00403480]
:00401021 E806000000 call 0040102C <--press F8 trace into
:00401026 50 push eax
wo goes here:
* Referenced by a CALL at Address:
|:00401021
|
:0040102C 55 push ebp
:0040102D 8BEC mov ebp esp
:0040102F 83C4B0 add esp FFFFFFB0
:00401032 C7056F3440005E010000 mov dword ptr [0040346F] 0000015E
:0040103C C70573344000C8000000 mov dword ptr [00403473] 000000C8
:00401046 6A00 push 00000000
* Reference To: USER32.GetSystemMetrics Ord:0143h
|
:00401048 E8D7060000 Call 00401724
:0040104D 50 push eax
:0040104E FF356F344000 push dword ptr [0040346F]
:00401054 E808040000 call 00401461
:00401059 A377344000 mov dword ptr [00403477] eax
:0040105E 6A01 push 00000001
* Reference To: USER32.GetSystemMetrics Ord:0143h
|
:00401060 E8BF060000 Call 00401724
:00401065 50 push eax
:00401066 FF3573344000 push dword ptr [00403473]
:0040106C E8F0030000 call 00401461
:00401071 A37B344000 mov dword ptr [0040347B] eax
:00401076 FF7508 push [ebp+08]
:00401079 E8F9030000 call 00401477 <---Here call the nagchange the code E8F9030000 to 90909090that ok!
:0040107E C745D030000000 mov [ebp-30] 00000030
:00401085 C745D403000000 mov [ebp-2C] 00000003
Second find the hard code:
Load splish with trw2000 enter a code like "aaa" and bpx hmemcpyand do pmodule
We goes here:
* Reference To: USER32.GetWindowTextA Ord:015Bh
|
:0040136A E8BB030000 Call 0040172A
:0040136F 8D0553134000 lea eax dword ptr [00401353] <--do "d eax" we'll find the hard code "HardCoded"
:00401375 8D1D15324000 lea ebx dword ptr [00403215] <--do "d ebx" we got "aaa"
At last find the serial:
enter name:DJX
serial:aaa
do "bpx hmemcpy" and click the buttoand then do "PMODULE"we goes here:
* Reference To: USER32.GetWindowTextA Ord:015Bh
|
:004015F1 E834010000 Call 0040172A <--get the serial
:004015F6 85C0 test eax eax <--if the lenth of serial is 0jump
:004015F8 0F8495000000 je 00401693
:004015FE A367344000 mov dword ptr [00403467] eax <--store it into 00403467
:00401603 6A0B push 0000000B
:00401605 6836324000 push 00403236
:0040160A FF7508 push [ebp+08]
* Reference To: USER32.GetWindowTextA Ord:015Bh
|
:0040160D E818010000 Call 0040172A <--get the name
:00401612 85C0 test eax eax <--if the lenth of name is 0jump
:00401614 7468 je 0040167E
:00401616 A363344000 mov dword ptr [00403463] eax <--store it into 00403463
:0040161B 33C9 xor ecx ecx
:0040161D 33DB xor ebx ebx
:0040161F 33D2 xor edx edx
:00401621 8D3536324000 lea esi dword ptr [00403236] <--load the nameand then count a temp code and store it into 00403258
:00401627 8D3D58324000 lea edi dword ptr [00403258]
:0040162D B90A000000 mov ecx 0000000A
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00401650(C)
|
:00401632 0FBE041E movsx eax byte ptr [esi+ebx]
:00401636 99 cdq
:00401637 F7F9 idiv ecx
:00401639 33D3 xor edx ebx
:0040163B 83C202 add edx 00000002
:0040163E 80FA0A cmp dl 0A
:00401641 7C03 jl 00401646
:00401643 80EA0A sub dl 0A
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00401641(C)
|
:00401646 88141F mov byte ptr [edi+ebx] dl
:00401649 43 inc ebx
:0040164A 3B1D63344000 cmp ebx dword ptr [00403463]
:00401650 75E0 jne 00401632
:00401652 33C9 xor ecx ecx
:00401654 33DB xor ebx ebx
:00401656 33D2 xor edx edx
:00401658 8D3542324000 lea esi dword ptr [00403242] <--load the serialand then count anther temp code and store it into 0040324D
:0040165E 8D3D4D324000 lea edi dword ptr [0040324D]
:00401664 B90A000000 mov ecx 0000000A
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0040167A(C)
|
:00401669 0FBE041E movsx eax byte ptr [esi+ebx]
:0040166D 99 cdq
:0040166E F7F9 idiv ecx
:00401670 88141F mov byte ptr [edi+ebx] dl
:00401673 43 inc ebx
:00401674 3B1D67344000 cmp ebx dword ptr [00403467]
:0040167A 75ED jne 00401669
:0040167C EB2A jmp 004016A8 <--jump to compare the two temp code
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00401614(C)
|
:0040167E 6A00 push 00000000
* Possible StringData Ref from Data Obj ->"Splish Splash"
|
:00401680 680A304000 push 0040300A
* Possible StringData Ref from Data Obj ->"Please enter your name."
|
:00401685 68A0304000 push 004030A0
:0040168A 6A00 push 00000000
* Reference To: USER32.MessageBoxA Ord:01BBh
|
:0040168C E8B7000000 Call 00401748
:00401691 EB62 jmp 004016F5
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004015F8(C)
|
:00401693 6A00 push 00000000
* Possible StringData Ref from Data Obj ->"Splish Splash"
|
:00401695 680A304000 push 0040300A
* Possible StringData Ref from Data Obj ->"Please enter your serial number."
|
:0040169A 68B8304000 push 004030B8
:0040169F 6A00 push 00000000
* Reference To: USER32.MessageBoxA Ord:01BBh
|
:004016A1 E8A2000000 Call 00401748
:004016A6 EB4D jmp 004016F5
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0040167C(U)
|
:004016A8 8D354D324000 lea esi dword ptr [0040324D] <--load the serial temp code
:004016AE 8D3D58324000 lea edi dword ptr [00403258] <--load the name temp code
:004016B4 33DB xor ebx ebx
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004016CB(U)
|
:004016B6 3B1D63344000 cmp ebx dword ptr [00403463]
:004016BC 740F je 004016CD
:004016BE 0FBE041F movsx eax byte ptr [edi+ebx]
:004016C2 0FBE0C1E movsx ecx byte ptr [esi+ebx]
:004016C6 3BC1 cmp eax ecx <--key comparetimes=name lenth
:004016C8 7518 jne 004016E2
:004016CA 43 inc ebx
:004016CB EBE9 jmp 004016B6
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004016BC(C)
|
:004016CD 6A00 push 00000000
* Possible StringData Ref from Data Obj ->"Splish Splash"
|
:004016CF 680A304000 push 0040300A
* Possible StringData Ref from Data Obj ->"Good job now keygen it."
|
:004016D4 6842304000 push 00403042
:004016D9 6A00 push 00000000
* Reference To: USER32.MessageBoxA Ord:01BBh
|
:004016DB E868000000 Call 00401748
:004016E0 EB13 jmp 004016F5
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004016C8(C)
|
:004016E2 6A00 push 00000000
* Possible StringData Ref from Data Obj ->"Splish Splash"
|
:004016E4 680A304000 push 0040300A
* Possible StringData Ref from Data Obj ->"Sorry please try again."
|
:004016E9 6867304000 push 00403067
:004016EE 6A00 push 00000000
* Reference To: USER32.MessageBoxA Ord:01BBh
|
:004016F0 E853000000 Call 00401748
The keygen code:
#include "stdio.h"
#define N 100
main()
{char name[N]code;
int iajdmname_len;
printf("the hard code is: HardCoded\n");
printf("Please input your name:");
scanf("%s"name);
name_len=strlen(name);
printf("Your serial is:\n");
for(i=0;i {a=name[i]; d=a%10; m=d^i; m=m+2; if(m>=10) m=m-10; printf("The %d letter could be one of:"i); for(j=0;j<10;j++) {code=m+j*10; if(code>48) {if(code<122) printf("%c"code); else break;} } printf("\n"); } } 最后对这个crackme的序列号做个说明: 1,电脑资料
《Splishcrackme》(https://www.unjs.com)。一个注册名可以对应多个注册码
2。注册码只有和注册名位数相同的部分才起作用,位数多于名字的部分可以为任意值
********************The end************************
--------------------------------------------------------------------------------
标 题:菜鸟对Splish-crackme的算法分析(高手勿入)!-我的第一次~~ (8千字)
发信人:winroot
时 间:2002-8-26 16:49:19
详细信息:
菜鸟对Splish-crackme的算法分析
作者:winroot
工具: TRW2000 v1.22 W32dasmVGOLD
环境:M$ win98
这是我第一次写pj文章请大家指教.因我是只大菜鸟所以文中难免有错误请各位高手指正.
这个crackme有3问(Nag&Serial&hard code)其他两个很简单无太大意义也就不必说了.
主要是name/serial
W32dasmVGOLD点击菜单项的参考-->字符串数据参考-->"Sorry please try again"
出错后我们看到
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004016C8(C)<------从这里跳出错的我们就跳回去
|
:004016E2 6A00 push 00000000
* Possible StringData Ref from Data Obj ->"Splish Splash"
|
:004016E4 680A304000 push 0040300A
* Possible StringData Ref from Data Obj ->"Sorry please try again."
|
:004016E9 6867304000 push 00403067
:004016EE 6A00 push 00000000
_________________________________________________________________________
到了004016C8我们往上看看到
:004016A6 EB4D jmp 004016F5
无条件跳~~~那么她下面的部分就与这句上面部分无关(不知对不对??)
我们就来看这句话的下面:
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0040167C(U)
|
:004016A8 8D354D324000 lea esi dword ptr [0040324D] //传送地址给esi
:004016AE 8D3D58324000 lea edi dword ptr [00403258] //传送地址给edi
:004016B4 33DB xor ebx ebx//ebx=0
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004016CB(U)
|
:004016B6 3B1D63344000 cmp ebx dword ptr [00403463] |
:004016BC 740F je 004016CD //跳走到正确 |
:004016BE 0FBE041F movsx eax byte ptr [edi+ebx] |
:004016C2 0FBE0C1E movsx ecx byte ptr [esi+ebx] |
:004016C6 3BC1 cmp eax ecx | 这里肯定是关键
:004016C8 7518 jne 004016E2//不等就跳失败 |
~~~~~~~~~~~~~~ ~~~~~~~~~~~~ |
:004016CA 43 inc ebx //加1 |
:004016CB EBE9 jmp 004016B6//我就是跳~~~~~ |
在这里会有几个疑问:
1.如果eax=ecx每次ebx=ebx加1然后直到eax和dword ptr [00403463]相等.
那么dword ptr [00403463]是什么?
2.dword ptr [00403258]
dword ptr [0040324D]
里面究竟是什么?
那么我们就搜索这几个地址~~~
___________________________________________________________________________
先不要看代码先看下面的解释
* Referenced by a CALL at Address:
|:00401402
|
:004015E4 55 push ebp
:004015E5 8BEC mov ebp esp
:004015E7 6A20 push 00000020
:004015E9 6842324000 push 00403242
:004015EE FF750C push [ebp+0C]
* Reference To: USER32.GetWindowTextA Ord:015Bh
|
:004015F1 E834010000 Call 0040172A//取serial
:004015F6 85C0 test eax eax//此时eax=serial长度如果serial长度是0出错
:004015F8 0F8495000000 je 00401693//跳出
:004015FE A367344000 mov dword ptr [00403467] eax//把eax的值送入00403467
:00401603 6A0B push 0000000B
:00401605 6836324000 push 00403236
:0040160A FF7508 push [ebp+08]
* Reference To: USER32.GetWindowTextA Ord:015Bh
|
:0040160D E818010000 Call 0040172A//取name
:00401612 85C0 test eax eax//看eax=name的长度是不是0
:00401614 7468 je 0040167E
:00401616 A363344000 mov dword ptr [00403463] eax//把eax的值送入00403463
:0040161B 33C9 xor ecx ecx//
:0040161D 33DB xor ebx ebx// 清0
:0040161F 33D2 xor edx edx//
:00401621 8D3536324000 lea esi dword ptr [00403236]//读取name计算完后存入00403258
:00401627 8D3D58324000 lea edi dword ptr [00403258]
:0040162D B90A000000 mov ecx 0000000A//ecx=10
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00401650(C)
|
:00401632 0FBE041E movsx eax byte ptr [esi+ebx]//先符号扩展再传送给eax
:00401636 99 cdq//双字扩展.(把EAX中的字的符号扩展到EDX中去)
:00401637 F7F9 idiv ecx//除以10将余数放入edx
:00401639 33D3 xor edx ebx//两者异或
:0040163B 83C202 add edx 00000002//edx=edx+2
:0040163E 80FA0A cmp dl 0A//如果dl不小于10就跳dl=edx
:00401641 7C03 jl 00401646
:00401643 80EA0A sub dl 0A//dl=dl-10
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00401641(C)
|
:00401646 88141F mov byte ptr [edi+ebx] dl//传值
:00401649 43 inc ebx//自加一
:0040164A 3B1D63344000 cmp ebx dword ptr [00403463]//比较name长度如果不相等就跳
:00401650 75E0 jne 00401632
:00401652 33C9 xor ecx ecx//
:00401654 33DB xor ebx ebx// 清零
:00401656 33D2 xor edx edx//
:00401658 8D3542324000 lea esi dword ptr [00403242]//读取serial计算完后存入0040324D
:0040165E 8D3D4D324000 lea edi dword ptr [0040324D]
:00401664 B90A000000 mov ecx 0000000A//eax=10
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0040167A(C)
|
:00401669 0FBE041E movsx eax byte ptr [esi+ebx]//变成双字节
:0040166D 99 cdq //双字扩展.(把EAX中的字的符号扩展到EDX中去)
:0040166E F7F9 idiv ecx//除以10将余数放入dl=edx
:00401670 88141F mov byte ptr [edi+ebx] dl//将dl值传入edi+ebx
:00401673 43 inc ebx//ebx自加一
:00401674 3B1D67344000 cmp ebx dword ptr [00403467]//比较如果不等就跳
:0040167A 75ED jne 00401669
:0040167C EB2A jmp 004016A8// 绝对跳转
我觉得肯定有和我一样的初学者会问:你是怎么知道取serial和取name???
答案是:你看* Reference To: USER32.GetWindowTextA Ord:015Bh
说明调用GetWindowText这个函数(如果和我一样没有学过编程的人就需要查winapi)
GetWindowText
参数 类型及说明
hwnd Long,欲获取文字的那个窗口的句柄
lpString String,预定义的一个缓冲区,至少有cch+1个字符大小;随同窗口文字载入
cch Long,lpString缓冲区的长度
那么在汇编中它就会表现为:
:00401603 6A0B push 0000000B//
:00401605 6836324000 push 00403236//3个参数
:0040160A FF7508 push [ebp+08]//
:004015F1 E834010000 Call 0040172A//取name
这时eax=name长度
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
知道这些我们来解答上面的问题:
1.dword ptr [00403463]是什么?
:00401616 A363344000 mov dword ptr [00403463] eax//把eax的值送入00403463
是name的长度
2.dword ptr [00403258]
dword ptr [0040324D]
里面究竟是什么?
:00401621 8D3536324000 lea esi dword ptr [00403236]//读取00403236存入00403258
:00401627 8D3D58324000 lea edi dword ptr [00403258]
那么00403236是什么?看:00401605 6836324000 push 00403236
是GetWindowText的一个参数是什么呢?我们用trw看一下是输入的name
所以dword ptr [00403258]是name ascii对应的数值.
同理:dword ptr [0040324D]是serial ascii对应的数值.
好了既然是算法分析我们就看他把name怎么变了??
从00401632到00401650是个循环!!!!
只要仔细分析就不难得出:
____________________________________________________________循环直到ebx=eax_______
| |
| |~如果大于10就减10| |
|~>esi+ebx--->eax---->edx=edx%ebx--->edx=edx^ebx--->edx=edx+2| |-|
| |~小于10就跳 |
name|
|
~>eax=name长度设为变量i
计算完后存入00403258
再看
____________________________________________________________循环直到ebx=eax_______
| |
| |
|~>esi+ebx--->eax---->edx=edx%ebx------------------------------------------------|
|
serail|
|
~>eax=serail长度设为变量
计算完后存入0040324D
最后两者比较注册码只有和注册名位数相同的部分才起作用
这就是我的算法分析~~~~!!!!!
如果要写注册机只要把注册吗那段求逆就行了
#include "stdio.h"
main()
{char name[30]serial;
int ijabmn;
printf(" your name:");
scanf("%s"name);
n=strlen(name);
printf("your serial is:");
for(i=0;i {a=name[i]; b=a%10; m=b^i; m=m+2; if(m>=10) m=m-10; for(j=0;j<10;j++) {serial=m+j*10; if(serial>48) {if(serial<122) printf("%c"serial); else break;} } } printf("\n"); } -------------------------------------------------------------------------------- Copyright©2000-2026 看雪学院(www.pediy.com) All Rights Reserved (编辑:天命孤独)