TheBigMan's #6 keygen序列号,注册机
文章用到的可执行文件:点击下载程序
原可执行文件是加了壳的,脱壳后的文件是unpacked.exe,载入OllyDbg,看下引入了那些API,看到GetDlgItemTextA,在这里下断点,执行后输
入用户名solver,序列号99999999,点击check,被断下,看到以下代码的00401548至0040157C计算我们输入的用户名长度是否符合要求,
0040156A至00401578指示edi必须大于等于190h,且小于等于2300h,经过计算我们输入的用户名长度必须大于等于3,小于等于9,否则直接失
败,
00401539 |. E8 FA010000 call <jmp.&USER32.GetDlgItemTextA> ; \GetDlgItemTextA 0040153E |. 89C3 mov ebx, eax 00401540 |. 09DB or ebx, ebx ; 检测用户名长度 00401542 |. 75 04 jnz short 00401548 00401544 |. 31C0 xor eax, eax ; 如果用户名为空,跳转到出口 00401546 |. EB 50 jmp short 00401598 ; 跳到出口 00401548 |> BF BC020000 mov edi, 2BC 0040154D |. BE 30000000 mov esi, 30 00401552 |. B8 48000000 mov eax, 48 00401557 |. 99 cdq 00401558 |. F7FB idiv ebx 0040155A |. 29C6 sub esi, eax 0040155C |. 8D34B6 lea esi, [esi+esi*4] 0040155F |. 29F7 sub edi, esi 00401561 |. 6BFF 6B imul edi, edi, 6B 00401564 |. 81EF 6CCF0000 sub edi, 0CF6C 0040156A |. 81FF 00230000 cmp edi, 2300 00401570 |. 7F 08 jg short 0040157A ; 如果edi大于2300h则失败 00401572 |. 81FF 90010000 cmp edi, 190 00401578 |. 7D 04 jge short 0040157E ; edi必须大于等于190h,否则失败 0040157A |> 31C0 xor eax, eax 0040157C |. EB 1A jmp short 00401598 ; 跳到出口 0040157E |> 8D85 00FFFFFF lea eax, [ebp-100] ; eax地址存储着我们输入的用户名 00401584 |. 50 push eax 00401585 |. 53 push ebx ; 用户名长 00401586 |. FF75 08 push dword ptr [ebp+8] 00401589 |. E8 77FDFFFF call 00401305 ; 获取用户输入的serial并计算注册码,返回0失败 0040158E |. 83C4 0C add esp, 0C 00401591 |. 09C0 or eax, eax 00401593 |. 74 03 je short 00401598 00401595 |. 31C0 xor eax, eax 00401597 |. 40 inc eax 00401598 |> 5F pop edi 00401599 |. 5E pop esi 0040159A |. 5B pop ebx 0040159B |. C9 leave 0040159C \. C3 retn
00401305处的代码如下(前面的代码可以不看,我们来到下面):
004013AF |. E8 84030000 call <jmp.&USER32.GetDlgItemTextA> ; \GetDlgItemTextA 004013B4 |. 09C0 or eax, eax 004013B6 |. 0F84 48010000 je 00401504 ; 输入的序列号为空,失败 004013BC |. B8 CF110000 mov eax, 11CF 004013C1 |. 0FB68D E1FCFF>movzx ecx, byte ptr [ebp-31F] ; 输入的序列号第一位必须为T,Q,H,6,8中的 004013C8 |. 99 cdq 004013C9 |. F7F9 idiv ecx 004013CB |. 83FA 17 cmp edx, 17 004013CE |. 74 07 je short 004013D7 004013D0 |. 31C0 xor eax, eax 004013D2 |. E9 2D010000 jmp 00401504 ; 跳到失败 004013D7 |> 31DB xor ebx, ebx 004013D9 |. EB 0B jmp short 004013E6 004013DB |> 8B45 10 /mov eax, [ebp+10] ; 累加用户名的各个字符的ASCII值的和到[ebp-4] 004013DE |. 0FBE0418 |movsx eax, byte ptr [eax+ebx] 004013E2 |. 0145 FC |add [ebp-4], eax ; [ebp-4]存储用户名累加值sum1 004013E5 |. 43 |inc ebx 004013E6 |> 3B5D 0C cmp ebx, [ebp+C] ; [ebp+c]用户名len 004013E9 |.^ 7C F0 \jl short 004013DB 004013EB |. 31DB xor ebx, ebx 004013ED |. E9 83000000 jmp 00401475 004013F2 |> 8B55 10 /mov edx, [ebp+10] ; 用户名字符串 004013F5 |. 0FBE3C1A |movsx edi, byte ptr [edx+ebx] 004013F9 |. 8B75 FC |mov esi, [ebp-4] ; sum1 004013FC |. 89D9 |mov ecx, ebx 004013FE |. C1E1 02 |shl ecx, 2 00401401 |. 89DA |mov edx, ebx 00401403 |. 42 |inc edx 00401404 |. 29D1 |sub ecx, edx 00401406 |. 0FB68C0D E1FE>|movzx ecx, byte ptr [ebp+ecx-11F] ; [ebp-11f]存储的是ASCII表字符串 0040140E |. 89FA |mov edx, edi 00401410 |. 31CA |xor edx, ecx 00401412 |. 89F1 |mov ecx, esi ; sum1 00401414 |. 0FAFCB |imul ecx, ebx 00401417 |. 29F1 |sub ecx, esi 00401419 |. 89CE |mov esi, ecx 0040141B |. 83F6 FF |xor esi, FFFFFFFF 0040141E |. 8DB432 4D0100>|lea esi, [edx+esi+14D] 00401425 |. 8B4D 0C |mov ecx, [ebp+C] ; [ebp+c]用户名len 00401428 |. 89DA |mov edx, ebx 0040142A |. 83C2 03 |add edx, 3 0040142D |. 0FAFCA |imul ecx, edx 00401430 |. 0FAFCF |imul ecx, edi 00401433 |. 89F0 |mov eax, esi 00401435 |. 01C8 |add eax, ecx 00401437 |. B9 0A000000 |mov ecx, 0A 0040143C |. 31D2 |xor edx, edx 0040143E |. F7F1 |div ecx 00401440 |. 83C2 30 |add edx, 30 00401443 |. 88941D FCFEFF>|mov [ebp+ebx-104], dl 0040144A |. 0FB6BC1D FCFE>|movzx edi, byte ptr [ebp+ebx-104] 00401452 |. 81F7 ACAD0000 |xor edi, 0ADAC 00401458 |. 89DE |mov esi, ebx 0040145A |. 83C6 02 |add esi, 2 0040145D |. 89F8 |mov eax, edi 0040145F |. 0FAFC6 |imul eax, esi 00401462 |. B9 0A000000 |mov ecx, 0A 00401467 |. 99 |cdq 00401468 |. F7F9 |idiv ecx 0040146A |. 83C2 30 |add edx, 30 0040146D |. 88941D FCFEFF>|mov [ebp+ebx-104], dl 00401474 |. 43 |inc ebx 00401475 |> 3B5D 0C cmp ebx, [ebp+C] 00401478 |.^ 0F8C 74FFFFFF \jl 004013F2 0040147E |. 8D85 FCFEFFFF lea eax, [ebp-104] ; 算出serial 00401484 |. 50 push eax 00401485 |. 6A 54 push 54 00401487 |. 8D85 DCFBFFFF lea eax, [ebp-424] 0040148D |. 50 push eax ; |Format 0040148E |. 8D85 E1FBFFFF lea eax, [ebp-41F] ; | 00401494 |. 50 push eax ; |算出来的中间serial1 00401495 |. E8 CE020000 call <jmp.&USER32.wsprintfA> ; \wsprintfA 0040149A |. 8B7D 0C mov edi, [ebp+C] ; 用户名Len 0040149D |. 89F8 mov eax, edi 0040149F |. 0FAF45 FC imul eax, [ebp-4] ; sum1 004014A3 |. B9 64000000 mov ecx, 64 004014A8 |. 99 cdq 004014A9 |. F7F9 idiv ecx 004014AB |. 89D7 mov edi, edx 004014AD |. 83C7 30 add edi, 30 004014B0 |. 57 push edi 004014B1 |. 8DBD E1FBFFFF lea edi, [ebp-41F] 004014B7 |. 57 push edi 004014B8 |. 8DBD D6FBFFFF lea edi, [ebp-42A] 004014BE |. 57 push edi ; |Format 004014BF |. 8DBD E1FDFFFF lea edi, [ebp-21F] ; | 004014C5 |. 57 push edi ; |算出来的中间serial2 004014C6 |. E8 9D020000 call <jmp.&USER32.wsprintfA> ; \wsprintfA 004014CB |. 83C4 20 add esp, 20 004014CE |. 8D8D E1FDFFFF lea ecx, [ebp-21F] ; 算出来的serial 004014D4 |. 83C8 FF or eax, FFFFFFFF 004014D7 |> 40 /inc eax ; 计算serial的len 004014D8 |. 803C01 00 |cmp byte ptr [ecx+eax], 0 004014DC |.^ 75 F9 \jnz short 004014D7 004014DE |. 50 push eax ; /Arg3 004014DF |. 8D85 E1FCFFFF lea eax, [ebp-31F] ; |我们输入的serial 004014E5 |. 50 push eax ; |Arg2 004014E6 |. 8D85 E1FDFFFF lea eax, [ebp-21F] ; |算出来的中间serial 004014EC |. 50 push eax ; |Arg1 004014ED |. E8 D0FDFFFF call 004012C2 ; \比对serial
004012C2处的比对算法如下:
004012C2 /$ 55 push ebp 004012C3 |. 89E5 mov ebp, esp 004012C5 |. 53 push ebx 004012C6 |. 56 push esi 004012C7 |. 57 push edi 004012C8 |. 8B5D 10 mov ebx, [ebp+10] ; 算出来的serial的len 004012CB |. 31F6 xor esi, esi 004012CD |. 46 inc esi 004012CE |. EB 29 jmp short 004012F9 004012D0 |> 8B55 08 /mov edx, [ebp+8] ; 算出来的serial 004012D3 |. 0FBE3C32 |movsx edi, byte ptr [edx+esi] ; 取每一位进行异或再取余 004012D7 |. 89F8 |mov eax, edi 004012D9 |. 83F0 20 |xor eax, 20 004012DC |. B9 0A000000 |mov ecx, 0A 004012E1 |. 99 |cdq 004012E2 |. F7F9 |idiv ecx 004012E4 |. 89D7 |mov edi, edx 004012E6 |. 83C7 30 |add edi, 30 004012E9 |. 8B55 0C |mov edx, [ebp+C] ; 用户输入的serial 004012EC |. 0FBE1432 |movsx edx, byte ptr [edx+esi] 004012F0 |. 39D7 |cmp edi, edx ; 按位比对 004012F2 |. 74 04 |je short 004012F8 004012F4 |. 31C0 |xor eax, eax 004012F6 |. EB 08 |jmp short 00401300 004012F8 |> 46 |inc esi 004012F9 |> 39DE cmp esi, ebx 004012FB |.^ 7C D3 \jl short 004012D0 004012FD |. 31C0 xor eax, eax 004012FF |. 40 inc eax 00401300 |> 5F pop edi 00401301 |. 5E pop esi 00401302 |. 5B pop ebx 00401303 |. 5D pop ebp 00401304 \. C3 retn
用户名:solver
中间serial: T022501-50
正确serial: 6688167316
我用go写了个keygen,代码如下:
package main
import (
"fmt"
)
var username string="solver"
var ascii string="ABCDEFGHIJKLMNOPQRSTUVWXYZ"
var keystr string
func main(){
fmt.Printf("--=== TheBigMan's CrackMe #6 keygen ===---\n")
fmt.Printf("-- keygen by [solver] 2020-10-19 --\n")
fmt.Printf("== solver9@163.com ==\n")
fmt.Printf("==--------------------------------------==\n")
fmt.Printf("Please input username: ");
fmt.Scanf("%s",&username)
if(len(username)<3 || len(username)>9){
fmt.Printf("username must be 3-9 bytes length")
return
}
keygen()
}
func keygen(){
var sum1 uint32 = 0
var m int32 = 0
var n uint32 =0
var val1 uint32 =0
var ch,a,mid1 byte
var sn []byte
var ulen uint32=0
var serial2 uint32=0
var keystrlen uint32=0
var keybytes []byte
ulen=uint32(len(username))
sn = []byte(username)
for n=0;n<ulen;n++{
sum1+=uint32(username[n])
}
for n=0;n<ulen;n++{
ch=username[n]
m=int32(n*4-(n+1))
if(m<0){
a=0
}else{
a=ascii[m]
}
mid1=ch^a
val1=0x14d+uint32(mid1)+((sum1*n-sum1)^0xffffffff)
sn[n]=byte(0x30+((val1+(n+3)*ulen*uint32(ch))%10))
sn[n]=byte(0x30+(((n+2)*((uint32(sn[n])^0x0adac)))%10))
}
keystr=fmt.Sprintf("%c%s",0x54,sn)
serial2=(ulen*sum1)%0x64+0x30
keystr=fmt.Sprintf("%s-%d",keystr,serial2)
keystrlen=uint32(len(keystr))
keybytes = []byte(keystr)
for n=0;n<keystrlen;n++{
keybytes[n]=(keystr[n]^0x20)%10+0x30
}
fmt.Printf("Your serial number: %s\n",keybytes);
}

浙公网安备 33010602011771号