solved new crackme

This commit is contained in:
Chenx221 2024-11-25 15:33:52 +08:00
parent ac3699fa78
commit b3a531b8a0
Signed by: chenx221
GPG Key ID: D7A9EC07024C3021
13 changed files with 904 additions and 0 deletions

31
clone/RaedMe.txt Normal file
View File

@ -0,0 +1,31 @@
------ clone -------
Author: haggar
Type: keygenme
Level: 2
Objective:
You must create working keygen. No patching!!
Algorithm is simple and very clear, easy to understand, but I hope not dumb. First intend was to throw in some arrays which would bring need of bruting serial, but I tought that it would be extra job for nothing. Maybe in next version :)
About:
This crackme is based on one FHCF template which I got from potsmoke and I thank him for sharing it with me. That is why I gave it name "clone". Altough from visual side crackme is same as template, algorithm is completly mine.

BIN
clone/clone.exe Normal file

Binary file not shown.

View File

@ -0,0 +1,23 @@
{
"runtimeTarget": {
"name": ".NETCoreApp,Version=v8.0",
"signature": ""
},
"compilationOptions": {},
"targets": {
".NETCoreApp,Version=v8.0": {
"sp_keygen/1.0.0": {
"runtime": {
"sp_keygen.dll": {}
}
}
}
},
"libraries": {
"sp_keygen/1.0.0": {
"type": "project",
"serviceable": false,
"sha512": ""
}
}
}

BIN
clone/keygen/sp_keygen.dll Normal file

Binary file not shown.

BIN
clone/keygen/sp_keygen.exe Normal file

Binary file not shown.

View File

@ -0,0 +1,13 @@
{
"runtimeOptions": {
"tfm": "net8.0",
"framework": {
"name": "Microsoft.NETCore.App",
"version": "8.0.0"
},
"configProperties": {
"System.Reflection.Metadata.MetadataUpdater.IsSupported": false,
"System.Runtime.Serialization.EnableUnsafeBinaryFormatterSerialization": false
}
}
}

271
clone/solve.md Normal file
View File

@ -0,0 +1,271 @@
算serial
先上一组可用密钥:
```
Name: chenx221
Serial: 6237A3FB
```
检查逻辑c#实现):
未给出的自定义函数见keygen源码
```c#
public static bool Check(string user, string serial)
{
if (!(CheckStrLen(serial, 8, 8) && CheckStrLen(user, 5, 0)))
return false;
uint eax, ebx, ecx;
ushort cx;
byte cl, ch, dl = 0, bl;
byte[] userBytes, serialBytes;
foreach (char c in user[4..])
{
dl += (byte)c;
}
ecx = (uint)(dl << 24) | (uint)(dl << 16) | (uint)(dl << 8) | dl;
userBytes = Encoding.ASCII.GetBytes(user[..4]);
eax = BitConverter.ToUInt32(userBytes, 0);
ecx ^= eax;
ecx = BSwap(ecx);
ecx += 0x3022006;
ecx = BSwap(ecx);
ecx -= 0xDEADC0DE;
ecx = BSwap(ecx);
cl = (byte)((ecx & 0xFF) + 1);
ecx = (ecx & 0xFFFFFF00) | cl;
ch = (byte)(((ecx >> 8) & 0xFF) + 1);
ecx = (ecx & 0xFFFF00FF) | ((uint)ch << 8);
ecx = BSwap(ecx);
cl = (byte)((ecx & 0xFF) - 1);
ecx = (ecx & 0xFFFFFF00) | cl;
ch = (byte)(((ecx >> 8) & 0xFF) - 1);
ecx = (ecx & 0xFFFF00FF) | ((uint)ch << 8);
ecx = BSwap(ecx);
ecx ^= 0xEDB88320;
ecx = BSwap(ecx);
ecx += 0xD76AA478;
ecx = BSwap(ecx);
ecx -= 0xB00BFACE;
ecx = BSwap(ecx);
ecx += 0xBADBEEF;
ecx = BSwap(ecx);
ecx++;
ecx = BSwap(ecx);
ecx--;
ecx = BSwap(ecx);
ecx += eax;
ecx = BSwap(ecx);
cx = (ushort)((ecx & 0xFFFF) + 1);
ecx = (ecx & 0xFFFF0000) | cx;
ecx = BSwap(ecx);
cx = (ushort)((ecx & 0xFFFF) + 1);
ecx = (ecx & 0xFFFF0000) | cx;
ecx = BSwap(ecx); //true serial result
serialBytes = ParseHstr(serial);
ebx = (uint)(serialBytes[0] * 0x10 + serialBytes[1]);
bl = (byte)(ebx & 0xFF);
bl = (byte)((bl ^ 0x12) + 0x34);
ebx = bl;
eax = ebx;
eax <<= 8;
ebx = (uint)(serialBytes[2] * 0x10 + serialBytes[3]);
bl = (byte)(ebx & 0xFF);
bl = (byte)((bl ^ 0x56) + 0x78);
ebx = bl;
eax += ebx;
eax <<= 8;
ebx = (uint)(serialBytes[4] * 0x10 + serialBytes[5]);
bl = (byte)(ebx & 0xFF);
bl = (byte)((bl ^ 0x90) + 0xAB);
ebx = bl;
eax += ebx;
eax <<= 8;
ebx = (uint)(serialBytes[6] * 0x10 + serialBytes[7]);
bl = (byte)(ebx & 0xFF);
bl = (byte)((bl ^ 0xCD) + 0xEF);
ebx = bl;
eax += ebx;
eax = BSwap(eax); //user input serial result
return eax == ecx; //ecx<->ebx(crackme)
}
```
反向计算c#实现):
```c#
public static void CalcSerial(string user)
{
...
... //这部分与Check相同故省略
...
ecx = BSwap(ecx); //true serial result
eax = BSwap(ecx);
int[] key = [0x12, 0x34, 0x56, 0x78, 0x90, 0xAB, 0xCD, 0xEF];
int keyIndex = key.Length - 1;
byte[] byteArray = new byte[4];
for (int i = 3; i >= 0; i--)
{
byte temp = (byte)(eax & 0xFF);
temp = (byte)(temp - key[keyIndex--]);
temp = (byte)(temp ^ key[keyIndex--]);
byteArray[i] = temp;
eax >>= 8;
}
Console.WriteLine($"Serial: {BitConverter.ToString(byteArray).Replace("-", "")}");
}
```
细节:
```assembly
004011DB | 6A 19 | push 19 | event
004011DD | 68 9A304000 | push clone.40309A | 40309A:"123456" (serial)
004011E2 | 6A 66 | push 66 |
004011E4 | FF75 08 | push dword ptr ss:[ebp+8] |
004011E7 | E8 F4010000 | call <JMP.&GetDlgItemTextA> |
004011EC | 83F8 08 | cmp eax,8 | serial length == 8
004011EF | 0F85 A9010000 | jne <clone.Fail> |
004011F5 | 6A 1E | push 1E |
004011F7 | 68 7C304000 | push clone.40307C | 40307C:"chenx221" (user)
004011FC | 6A 65 | push 65 |
004011FE | FF75 08 | push dword ptr ss:[ebp+8] |
00401201 | E8 DA010000 | call <JMP.&GetDlgItemTextA> |
00401206 | 83F8 05 | cmp eax,5 | user length >=5
00401209 | 0F82 8F010000 | jb <clone.Fail> |
0040120F | 8D05 7C304000 | lea eax,dword ptr ds:[40307C] | user
00401215 | 8D48 04 | lea ecx,dword ptr ds:[eax+4] | user去前四位
00401218 | 33D2 | xor edx,edx |
0040121A | 0211 | add dl,byte ptr ds:[ecx] | 累加user去前四位后每位asc(注意:dl)
0040121C | 41 | inc ecx |
0040121D | 8039 00 | cmp byte ptr ds:[ecx],0 |
00401220 | 75 F8 | jne clone.40121A |
00401222 | 33C9 | xor ecx,ecx |
00401224 | 8ACA | mov cl,dl | 上一步的结果(ex:ab)
00401226 | 8AEA | mov ch,dl | 上一步的结果
00401228 | 0FC9 | bswap ecx | 1
0040122A | 8ACA | mov cl,dl |
0040122C | 8AEA | mov ch,dl | (ex: ecx=abababab)
0040122E | 8B00 | mov eax,dword ptr ds:[eax] | user
00401230 | 33C8 | xor ecx,eax | abababab ^ user前四位(小端序
00401232 | 0FC9 | bswap ecx | 2
00401234 | 81C1 06200203 | add ecx,3022006 |
0040123A | 0FC9 | bswap ecx | 3
0040123C | 81E9 DEC0ADDE | sub ecx,DEADC0DE |
00401242 | 0FC9 | bswap ecx | 4
00401244 | FEC1 | inc cl |
00401246 | FEC5 | inc ch |
00401248 | 0FC9 | bswap ecx | 5
0040124A | FEC9 | dec cl |
0040124C | FECD | dec ch |
0040124E | 0FC9 | bswap ecx | 6
00401250 | 81F1 2083B8ED | xor ecx,EDB88320 |
00401256 | 0FC9 | bswap ecx | ...
00401258 | 81C1 78A46AD7 | add ecx,D76AA478 |
0040125E | 0FC9 | bswap ecx |
00401260 | 81E9 CEFA0BB0 | sub ecx,B00BFACE |
00401266 | 0FC9 | bswap ecx |
00401268 | 81C1 EFBEAD0B | add ecx,BADBEEF |
0040126E | 0FC9 | bswap ecx |
00401270 | 41 | inc ecx |
00401271 | 0FC9 | bswap ecx |
00401273 | 49 | dec ecx |
00401274 | 0FC9 | bswap ecx |
00401276 | 03C8 | add ecx,eax | 还是user
00401278 | 0FC9 | bswap ecx |
0040127A | 66:41 | inc cx |
0040127C | 0FC9 | bswap ecx |
0040127E | 66:41 | inc cx |
00401280 | 0FC9 | bswap ecx |
00401282 | 890D C8304000 | mov dword ptr ds:[4030C8],ecx |
00401288 | 33C9 | xor ecx,ecx |
0040128A | 8D05 9A304000 | lea eax,dword ptr ds:[40309A] | serial
00401290 | 33DB | xor ebx,ebx | 十六进制字符转实际数值
00401292 | 8A18 | mov bl,byte ptr ds:[eax] |
00401294 | 80FB 00 | cmp bl,0 |
00401297 | 74 3A | je clone.4012D3 | serial读完了?
00401299 | 80FB 30 | cmp bl,30 | 30:'0'
0040129C | 0F82 FC000000 | jb <clone.Fail> |
004012A2 | 80FB 39 | cmp bl,39 | 39:'9'
004012A5 | 77 0D | ja clone.4012B4 |
004012A7 | 80EB 30 | sub bl,30 | 0~9数字处理部分(str2int)
004012AA | 8899 B8304000 | mov byte ptr ds:[ecx+4030B8], |
004012B0 | 40 | inc eax |
004012B1 | 41 | inc ecx |
004012B2 | EB DC | jmp clone.401290 |
004012B4 | 80FB 41 | cmp bl,41 | 41:'A'
004012B7 | 0F82 E1000000 | jb <clone.Fail> |
004012BD | 80FB 46 | cmp bl,46 | 46:'F'
004012C0 | 0F87 D8000000 | ja <clone.Fail> |
004012C6 | 80EB 37 | sub bl,37 | 只接受A~F
004012C9 | 8899 B8304000 | mov byte ptr ds:[ecx+4030B8], | A~F处理部分(str2int)
004012CF | 40 | inc eax |
004012D0 | 41 | inc ecx |
004012D1 | EB BD | jmp clone.401290 |
004012D3 | 33C0 | xor eax,eax |
004012D5 | 33DB | xor ebx,ebx |
004012D7 | 33C9 | xor ecx,ecx | 0
004012D9 | 33D2 | xor edx,edx |
004012DB | 0FB699 B8304000 | movzx ebx,byte ptr ds:[ecx+40 | 读取第一位
004012E2 | C1E3 04 | shl ebx,4 | <<4
004012E5 | 41 | inc ecx | 1
004012E6 | 0FB691 B8304000 | movzx edx,byte ptr ds:[ecx+40 |
004012ED | 03DA | add ebx,edx | +=第二位
004012EF | 80F3 12 | xor bl,12 |
004012F2 | 80C3 34 | add bl,34 |
004012F5 | 81E3 FF000000 | and ebx,FF |
004012FB | 41 | inc ecx | 2
004012FC | 03C3 | add eax,ebx |
004012FE | C1E0 08 | shl eax,8 |
00401301 | 0FB699 B8304000 | movzx ebx,byte ptr ds:[ecx+40 |
00401308 | C1E3 04 | shl ebx,4 |
0040130B | 41 | inc ecx | 3
0040130C | 0FB691 B8304000 | movzx edx,byte ptr ds:[ecx+40 |
00401313 | 03DA | add ebx,edx |
00401315 | 80F3 56 | xor bl,56 |
00401318 | 80C3 78 | add bl,78 |
0040131B | 81E3 FF000000 | and ebx,FF |
00401321 | 41 | inc ecx | 4
00401322 | 03C3 | add eax,ebx |
00401324 | C1E0 08 | shl eax,8 |
00401327 | 0FB699 B8304000 | movzx ebx,byte ptr ds:[ecx+40 |
0040132E | C1E3 04 | shl ebx,4 |
00401331 | 41 | inc ecx | 5
00401332 | 0FB691 B8304000 | movzx edx,byte ptr ds:[ecx+40 |
00401339 | 03DA | add ebx,edx |
0040133B | 80F3 90 | xor bl,90 |
0040133E | 80C3 AB | add bl,AB |
00401341 | 81E3 FF000000 | and ebx,FF |
00401347 | 41 | inc ecx | 6
00401348 | 03C3 | add eax,ebx |
0040134A | C1E0 08 | shl eax,8 |
0040134D | 0FB699 B8304000 | movzx ebx,byte ptr ds:[ecx+40 |
00401354 | C1E3 04 | shl ebx,4 |
00401357 | 41 | inc ecx | 7
00401358 | 0FB691 B8304000 | movzx edx,byte ptr ds:[ecx+40 |
0040135F | 03DA | add ebx,edx |
00401361 | 80F3 CD | xor bl,CD |
00401364 | 80C3 EF | add bl,EF |
00401367 | 81E3 FF000000 | and ebx,FF |
0040136D | 41 | inc ecx | 8
0040136E | 03C3 | add eax,ebx |
00401370 | 0FC8 | bswap eax |
00401372 | 8B1D C8304000 | mov ebx,dword ptr ds:[4030C8] |
00401378 | 3BD8 | cmp ebx,eax | eax是用户输入serial计算结果,ebx是正确的结果
0040137A | 75 22 | jne <clone.Fail> |
0040137C | 6A 40 | push 40 | Success
0040137E | 68 50304000 | push clone.403050 | 403050:"Bravo!"
00401383 | 68 19304000 | push clone.403019 | 403019:"Well done! Now make good tutorial :)"
00401388 | 6A 00 | push 0 |
0040138A | E8 75000000 | call clone.401404 |
0040138F | 68 3E304000 | push clone.40303E | 40303E:"clone - defeated!"
00401394 | FF75 08 | push dword ptr ss:[ebp+8] |
00401397 | E8 86000000 | call <JMP.&SetWindowTextA> |
0040139C | EB 00 | jmp <clone.Fail> |
0040139E | EB 15 | jmp clone.4013B5 |
```

163
clone/source/keygen1.sln Normal file
View File

@ -0,0 +1,163 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.11.35303.130
MinimumVisualStudioVersion = 10.0.40219.1
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "keygen1", "keygen1\keygen1.csproj", "{D0E162E3-FC99-4405-BEE1-AB85D9D41DA9}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "keygen2", "keygen2\keygen2.csproj", "{2446CB50-1882-4219-9DB0-E7F5517E6E20}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "keygen3", "keygen3\keygen3.csproj", "{BC47A6DE-7F9D-4D65-A996-69FB778C95F3}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "GiveMeSerial", "GiveMeSerial\GiveMeSerial.vcxproj", "{E3604156-7DF2-4B5F-AECA-64786B92F38C}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DllInjector", "DllInjector\DllInjector.csproj", "{A5A24406-1296-457B-91A3-60E67511D807}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "GetSerial", "GetSerial\GetSerial.vcxproj", "{85044A5C-C4A3-4C79-9AD5-6895F61F8515}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "GuessSerial", "GuessSerial\GuessSerial.csproj", "{7B2D3886-A213-4F99-89F7-D0D7DDAA97D9}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Validator", "Validator\Validator.csproj", "{6BE1ED72-6CA9-4442-B529-C867A9D6904C}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FindKey", "FindKey\FindKey.csproj", "{D5E3C871-EA87-48E7-9287-E96B8410EB18}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "sp_keygen", "sp_keygen\sp_keygen.csproj", "{D6614743-D01E-4899-A5E7-B4E45BD1B033}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Debug|x64 = Debug|x64
Debug|x86 = Debug|x86
Release|Any CPU = Release|Any CPU
Release|x64 = Release|x64
Release|x86 = Release|x86
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{D0E162E3-FC99-4405-BEE1-AB85D9D41DA9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{D0E162E3-FC99-4405-BEE1-AB85D9D41DA9}.Debug|Any CPU.Build.0 = Debug|Any CPU
{D0E162E3-FC99-4405-BEE1-AB85D9D41DA9}.Debug|x64.ActiveCfg = Debug|Any CPU
{D0E162E3-FC99-4405-BEE1-AB85D9D41DA9}.Debug|x64.Build.0 = Debug|Any CPU
{D0E162E3-FC99-4405-BEE1-AB85D9D41DA9}.Debug|x86.ActiveCfg = Debug|x86
{D0E162E3-FC99-4405-BEE1-AB85D9D41DA9}.Debug|x86.Build.0 = Debug|x86
{D0E162E3-FC99-4405-BEE1-AB85D9D41DA9}.Release|Any CPU.ActiveCfg = Release|Any CPU
{D0E162E3-FC99-4405-BEE1-AB85D9D41DA9}.Release|Any CPU.Build.0 = Release|Any CPU
{D0E162E3-FC99-4405-BEE1-AB85D9D41DA9}.Release|x64.ActiveCfg = Release|x64
{D0E162E3-FC99-4405-BEE1-AB85D9D41DA9}.Release|x64.Build.0 = Release|x64
{D0E162E3-FC99-4405-BEE1-AB85D9D41DA9}.Release|x86.ActiveCfg = Release|x86
{D0E162E3-FC99-4405-BEE1-AB85D9D41DA9}.Release|x86.Build.0 = Release|x86
{2446CB50-1882-4219-9DB0-E7F5517E6E20}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{2446CB50-1882-4219-9DB0-E7F5517E6E20}.Debug|Any CPU.Build.0 = Debug|Any CPU
{2446CB50-1882-4219-9DB0-E7F5517E6E20}.Debug|x64.ActiveCfg = Debug|x64
{2446CB50-1882-4219-9DB0-E7F5517E6E20}.Debug|x64.Build.0 = Debug|x64
{2446CB50-1882-4219-9DB0-E7F5517E6E20}.Debug|x86.ActiveCfg = Debug|x86
{2446CB50-1882-4219-9DB0-E7F5517E6E20}.Debug|x86.Build.0 = Debug|x86
{2446CB50-1882-4219-9DB0-E7F5517E6E20}.Release|Any CPU.ActiveCfg = Release|Any CPU
{2446CB50-1882-4219-9DB0-E7F5517E6E20}.Release|Any CPU.Build.0 = Release|Any CPU
{2446CB50-1882-4219-9DB0-E7F5517E6E20}.Release|x64.ActiveCfg = Release|x64
{2446CB50-1882-4219-9DB0-E7F5517E6E20}.Release|x64.Build.0 = Release|x64
{2446CB50-1882-4219-9DB0-E7F5517E6E20}.Release|x86.ActiveCfg = Release|x86
{2446CB50-1882-4219-9DB0-E7F5517E6E20}.Release|x86.Build.0 = Release|x86
{BC47A6DE-7F9D-4D65-A996-69FB778C95F3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{BC47A6DE-7F9D-4D65-A996-69FB778C95F3}.Debug|Any CPU.Build.0 = Debug|Any CPU
{BC47A6DE-7F9D-4D65-A996-69FB778C95F3}.Debug|x64.ActiveCfg = Debug|Any CPU
{BC47A6DE-7F9D-4D65-A996-69FB778C95F3}.Debug|x64.Build.0 = Debug|Any CPU
{BC47A6DE-7F9D-4D65-A996-69FB778C95F3}.Debug|x86.ActiveCfg = Debug|x86
{BC47A6DE-7F9D-4D65-A996-69FB778C95F3}.Debug|x86.Build.0 = Debug|x86
{BC47A6DE-7F9D-4D65-A996-69FB778C95F3}.Release|Any CPU.ActiveCfg = Release|Any CPU
{BC47A6DE-7F9D-4D65-A996-69FB778C95F3}.Release|Any CPU.Build.0 = Release|Any CPU
{BC47A6DE-7F9D-4D65-A996-69FB778C95F3}.Release|x64.ActiveCfg = Release|x64
{BC47A6DE-7F9D-4D65-A996-69FB778C95F3}.Release|x64.Build.0 = Release|x64
{BC47A6DE-7F9D-4D65-A996-69FB778C95F3}.Release|x86.ActiveCfg = Release|x86
{BC47A6DE-7F9D-4D65-A996-69FB778C95F3}.Release|x86.Build.0 = Release|x86
{E3604156-7DF2-4B5F-AECA-64786B92F38C}.Debug|Any CPU.ActiveCfg = Debug|x64
{E3604156-7DF2-4B5F-AECA-64786B92F38C}.Debug|Any CPU.Build.0 = Debug|x64
{E3604156-7DF2-4B5F-AECA-64786B92F38C}.Debug|x64.ActiveCfg = Debug|x64
{E3604156-7DF2-4B5F-AECA-64786B92F38C}.Debug|x64.Build.0 = Debug|x64
{E3604156-7DF2-4B5F-AECA-64786B92F38C}.Debug|x86.ActiveCfg = Debug|Win32
{E3604156-7DF2-4B5F-AECA-64786B92F38C}.Debug|x86.Build.0 = Debug|Win32
{E3604156-7DF2-4B5F-AECA-64786B92F38C}.Release|Any CPU.ActiveCfg = Release|x64
{E3604156-7DF2-4B5F-AECA-64786B92F38C}.Release|Any CPU.Build.0 = Release|x64
{E3604156-7DF2-4B5F-AECA-64786B92F38C}.Release|x64.ActiveCfg = Release|x64
{E3604156-7DF2-4B5F-AECA-64786B92F38C}.Release|x64.Build.0 = Release|x64
{E3604156-7DF2-4B5F-AECA-64786B92F38C}.Release|x86.ActiveCfg = Release|Win32
{E3604156-7DF2-4B5F-AECA-64786B92F38C}.Release|x86.Build.0 = Release|Win32
{A5A24406-1296-457B-91A3-60E67511D807}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{A5A24406-1296-457B-91A3-60E67511D807}.Debug|Any CPU.Build.0 = Debug|Any CPU
{A5A24406-1296-457B-91A3-60E67511D807}.Debug|x64.ActiveCfg = Debug|Any CPU
{A5A24406-1296-457B-91A3-60E67511D807}.Debug|x64.Build.0 = Debug|Any CPU
{A5A24406-1296-457B-91A3-60E67511D807}.Debug|x86.ActiveCfg = Debug|Any CPU
{A5A24406-1296-457B-91A3-60E67511D807}.Debug|x86.Build.0 = Debug|Any CPU
{A5A24406-1296-457B-91A3-60E67511D807}.Release|Any CPU.ActiveCfg = Release|Any CPU
{A5A24406-1296-457B-91A3-60E67511D807}.Release|Any CPU.Build.0 = Release|Any CPU
{A5A24406-1296-457B-91A3-60E67511D807}.Release|x64.ActiveCfg = Release|x64
{A5A24406-1296-457B-91A3-60E67511D807}.Release|x64.Build.0 = Release|x64
{A5A24406-1296-457B-91A3-60E67511D807}.Release|x86.ActiveCfg = Release|x86
{A5A24406-1296-457B-91A3-60E67511D807}.Release|x86.Build.0 = Release|x86
{85044A5C-C4A3-4C79-9AD5-6895F61F8515}.Debug|Any CPU.ActiveCfg = Debug|x64
{85044A5C-C4A3-4C79-9AD5-6895F61F8515}.Debug|Any CPU.Build.0 = Debug|x64
{85044A5C-C4A3-4C79-9AD5-6895F61F8515}.Debug|x64.ActiveCfg = Debug|x64
{85044A5C-C4A3-4C79-9AD5-6895F61F8515}.Debug|x64.Build.0 = Debug|x64
{85044A5C-C4A3-4C79-9AD5-6895F61F8515}.Debug|x86.ActiveCfg = Debug|Win32
{85044A5C-C4A3-4C79-9AD5-6895F61F8515}.Debug|x86.Build.0 = Debug|Win32
{85044A5C-C4A3-4C79-9AD5-6895F61F8515}.Release|Any CPU.ActiveCfg = Release|x64
{85044A5C-C4A3-4C79-9AD5-6895F61F8515}.Release|Any CPU.Build.0 = Release|x64
{85044A5C-C4A3-4C79-9AD5-6895F61F8515}.Release|x64.ActiveCfg = Release|x64
{85044A5C-C4A3-4C79-9AD5-6895F61F8515}.Release|x64.Build.0 = Release|x64
{85044A5C-C4A3-4C79-9AD5-6895F61F8515}.Release|x86.ActiveCfg = Release|Win32
{85044A5C-C4A3-4C79-9AD5-6895F61F8515}.Release|x86.Build.0 = Release|Win32
{7B2D3886-A213-4F99-89F7-D0D7DDAA97D9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{7B2D3886-A213-4F99-89F7-D0D7DDAA97D9}.Debug|Any CPU.Build.0 = Debug|Any CPU
{7B2D3886-A213-4F99-89F7-D0D7DDAA97D9}.Debug|x64.ActiveCfg = Debug|Any CPU
{7B2D3886-A213-4F99-89F7-D0D7DDAA97D9}.Debug|x64.Build.0 = Debug|Any CPU
{7B2D3886-A213-4F99-89F7-D0D7DDAA97D9}.Debug|x86.ActiveCfg = Debug|Any CPU
{7B2D3886-A213-4F99-89F7-D0D7DDAA97D9}.Debug|x86.Build.0 = Debug|Any CPU
{7B2D3886-A213-4F99-89F7-D0D7DDAA97D9}.Release|Any CPU.ActiveCfg = Release|Any CPU
{7B2D3886-A213-4F99-89F7-D0D7DDAA97D9}.Release|Any CPU.Build.0 = Release|Any CPU
{7B2D3886-A213-4F99-89F7-D0D7DDAA97D9}.Release|x64.ActiveCfg = Release|x64
{7B2D3886-A213-4F99-89F7-D0D7DDAA97D9}.Release|x64.Build.0 = Release|x64
{7B2D3886-A213-4F99-89F7-D0D7DDAA97D9}.Release|x86.ActiveCfg = Release|x86
{7B2D3886-A213-4F99-89F7-D0D7DDAA97D9}.Release|x86.Build.0 = Release|x86
{6BE1ED72-6CA9-4442-B529-C867A9D6904C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{6BE1ED72-6CA9-4442-B529-C867A9D6904C}.Debug|Any CPU.Build.0 = Debug|Any CPU
{6BE1ED72-6CA9-4442-B529-C867A9D6904C}.Debug|x64.ActiveCfg = Debug|Any CPU
{6BE1ED72-6CA9-4442-B529-C867A9D6904C}.Debug|x64.Build.0 = Debug|Any CPU
{6BE1ED72-6CA9-4442-B529-C867A9D6904C}.Debug|x86.ActiveCfg = Debug|Any CPU
{6BE1ED72-6CA9-4442-B529-C867A9D6904C}.Debug|x86.Build.0 = Debug|Any CPU
{6BE1ED72-6CA9-4442-B529-C867A9D6904C}.Release|Any CPU.ActiveCfg = Release|Any CPU
{6BE1ED72-6CA9-4442-B529-C867A9D6904C}.Release|Any CPU.Build.0 = Release|Any CPU
{6BE1ED72-6CA9-4442-B529-C867A9D6904C}.Release|x64.ActiveCfg = Release|x64
{6BE1ED72-6CA9-4442-B529-C867A9D6904C}.Release|x64.Build.0 = Release|x64
{6BE1ED72-6CA9-4442-B529-C867A9D6904C}.Release|x86.ActiveCfg = Release|x86
{6BE1ED72-6CA9-4442-B529-C867A9D6904C}.Release|x86.Build.0 = Release|x86
{D5E3C871-EA87-48E7-9287-E96B8410EB18}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{D5E3C871-EA87-48E7-9287-E96B8410EB18}.Debug|Any CPU.Build.0 = Debug|Any CPU
{D5E3C871-EA87-48E7-9287-E96B8410EB18}.Debug|x64.ActiveCfg = Debug|Any CPU
{D5E3C871-EA87-48E7-9287-E96B8410EB18}.Debug|x64.Build.0 = Debug|Any CPU
{D5E3C871-EA87-48E7-9287-E96B8410EB18}.Debug|x86.ActiveCfg = Debug|Any CPU
{D5E3C871-EA87-48E7-9287-E96B8410EB18}.Debug|x86.Build.0 = Debug|Any CPU
{D5E3C871-EA87-48E7-9287-E96B8410EB18}.Release|Any CPU.ActiveCfg = Release|Any CPU
{D5E3C871-EA87-48E7-9287-E96B8410EB18}.Release|Any CPU.Build.0 = Release|Any CPU
{D5E3C871-EA87-48E7-9287-E96B8410EB18}.Release|x64.ActiveCfg = Release|x64
{D5E3C871-EA87-48E7-9287-E96B8410EB18}.Release|x64.Build.0 = Release|x64
{D5E3C871-EA87-48E7-9287-E96B8410EB18}.Release|x86.ActiveCfg = Release|x86
{D5E3C871-EA87-48E7-9287-E96B8410EB18}.Release|x86.Build.0 = Release|x86
{D6614743-D01E-4899-A5E7-B4E45BD1B033}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{D6614743-D01E-4899-A5E7-B4E45BD1B033}.Debug|Any CPU.Build.0 = Debug|Any CPU
{D6614743-D01E-4899-A5E7-B4E45BD1B033}.Debug|x64.ActiveCfg = Debug|Any CPU
{D6614743-D01E-4899-A5E7-B4E45BD1B033}.Debug|x64.Build.0 = Debug|Any CPU
{D6614743-D01E-4899-A5E7-B4E45BD1B033}.Debug|x86.ActiveCfg = Debug|Any CPU
{D6614743-D01E-4899-A5E7-B4E45BD1B033}.Debug|x86.Build.0 = Debug|Any CPU
{D6614743-D01E-4899-A5E7-B4E45BD1B033}.Release|Any CPU.ActiveCfg = Release|Any CPU
{D6614743-D01E-4899-A5E7-B4E45BD1B033}.Release|Any CPU.Build.0 = Release|Any CPU
{D6614743-D01E-4899-A5E7-B4E45BD1B033}.Release|x64.ActiveCfg = Release|Any CPU
{D6614743-D01E-4899-A5E7-B4E45BD1B033}.Release|x64.Build.0 = Release|Any CPU
{D6614743-D01E-4899-A5E7-B4E45BD1B033}.Release|x86.ActiveCfg = Release|Any CPU
{D6614743-D01E-4899-A5E7-B4E45BD1B033}.Release|x86.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {01ED3EE8-E89A-4A27-AF68-EF2490CB6BD7}
EndGlobalSection
EndGlobal

View File

@ -0,0 +1,206 @@
using System.Globalization;
using System.Text;
class Program
{
static void Main()
{
//Check("chenx221", "12345678"); // debug
Console.Write("Enter name: ");
string? name = Console.ReadLine();
if (name == null)
throw new ArgumentNullException(nameof(name), "Name cannot be null.");
CalcSerial(name);
Console.ReadKey();
}
public static void CalcSerial(string user)
{
if (!CheckStrLen(user, 5, 0))
throw new ArgumentException("Invalid user string length.");
uint eax, ecx;
ushort cx;
byte cl, ch, dl = 0;
byte[] userBytes;
foreach (char c in user[4..])
{
dl += (byte)c;
}
ecx = (uint)(dl << 24) | (uint)(dl << 16) | (uint)(dl << 8) | dl;
userBytes = Encoding.ASCII.GetBytes(user[..4]);
eax = BitConverter.ToUInt32(userBytes, 0);
ecx ^= eax;
ecx = BSwap(ecx);
ecx += 0x3022006;
ecx = BSwap(ecx);
ecx -= 0xDEADC0DE;
ecx = BSwap(ecx);
cl = (byte)((ecx & 0xFF) + 1);
ecx = (ecx & 0xFFFFFF00) | cl;
ch = (byte)(((ecx >> 8) & 0xFF) + 1);
ecx = (ecx & 0xFFFF00FF) | ((uint)ch << 8);
ecx = BSwap(ecx);
cl = (byte)((ecx & 0xFF) - 1);
ecx = (ecx & 0xFFFFFF00) | cl;
ch = (byte)(((ecx >> 8) & 0xFF) - 1);
ecx = (ecx & 0xFFFF00FF) | ((uint)ch << 8);
ecx = BSwap(ecx);
ecx ^= 0xEDB88320;
ecx = BSwap(ecx);
ecx += 0xD76AA478;
ecx = BSwap(ecx);
ecx -= 0xB00BFACE;
ecx = BSwap(ecx);
ecx += 0xBADBEEF;
ecx = BSwap(ecx);
ecx++;
ecx = BSwap(ecx);
ecx--;
ecx = BSwap(ecx);
ecx += eax;
ecx = BSwap(ecx);
cx = (ushort)((ecx & 0xFFFF) + 1);
ecx = (ecx & 0xFFFF0000) | cx;
ecx = BSwap(ecx);
cx = (ushort)((ecx & 0xFFFF) + 1);
ecx = (ecx & 0xFFFF0000) | cx;
ecx = BSwap(ecx); //true serial result
//开始反向计算Serial
eax = BSwap(ecx);
int[] key = [0x12, 0x34, 0x56, 0x78, 0x90, 0xAB, 0xCD, 0xEF];
int keyIndex = key.Length - 1;
byte[] byteArray = new byte[4];
for (int i = 3; i >= 0; i--)
{
byte temp = (byte)(eax & 0xFF);
temp = (byte)(temp - key[keyIndex--]);
temp = (byte)(temp ^ key[keyIndex--]);
byteArray[i] = temp;
eax >>= 8;
}
Console.WriteLine($"Serial: {BitConverter.ToString(byteArray).Replace("-", "")}");
}
public static bool Check(string user, string serial)
{
if (!(CheckStrLen(serial, 8, 8) && CheckStrLen(user, 5, 0)))
return false;
uint eax, ebx, ecx;
ushort cx;
byte cl, ch, dl = 0, bl;
byte[] userBytes, serialBytes;
foreach (char c in user[4..])
{
dl += (byte)c;
}
ecx = (uint)(dl << 24) | (uint)(dl << 16) | (uint)(dl << 8) | dl;
userBytes = Encoding.ASCII.GetBytes(user[..4]);
eax = BitConverter.ToUInt32(userBytes, 0);
ecx ^= eax;
ecx = BSwap(ecx);
ecx += 0x3022006;
ecx = BSwap(ecx);
ecx -= 0xDEADC0DE;
ecx = BSwap(ecx);
cl = (byte)((ecx & 0xFF) + 1);
ecx = (ecx & 0xFFFFFF00) | cl;
ch = (byte)(((ecx >> 8) & 0xFF) + 1);
ecx = (ecx & 0xFFFF00FF) | ((uint)ch << 8);
ecx = BSwap(ecx);
cl = (byte)((ecx & 0xFF) - 1);
ecx = (ecx & 0xFFFFFF00) | cl;
ch = (byte)(((ecx >> 8) & 0xFF) - 1);
ecx = (ecx & 0xFFFF00FF) | ((uint)ch << 8);
ecx = BSwap(ecx);
ecx ^= 0xEDB88320;
ecx = BSwap(ecx);
ecx += 0xD76AA478;
ecx = BSwap(ecx);
ecx -= 0xB00BFACE;
ecx = BSwap(ecx);
ecx += 0xBADBEEF;
ecx = BSwap(ecx);
ecx++;
ecx = BSwap(ecx);
ecx--;
ecx = BSwap(ecx);
ecx += eax;
ecx = BSwap(ecx);
cx = (ushort)((ecx & 0xFFFF) + 1);
ecx = (ecx & 0xFFFF0000) | cx;
ecx = BSwap(ecx);
cx = (ushort)((ecx & 0xFFFF) + 1);
ecx = (ecx & 0xFFFF0000) | cx;
ecx = BSwap(ecx); //true serial result
serialBytes = ParseHstr(serial);
ebx = (uint)(serialBytes[0] * 0x10 + serialBytes[1]);
bl = (byte)(ebx & 0xFF);
bl = (byte)((bl ^ 0x12) + 0x34);
ebx = bl;
eax = ebx;
eax <<= 8;
ebx = (uint)(serialBytes[2] * 0x10 + serialBytes[3]);
bl = (byte)(ebx & 0xFF);
bl = (byte)((bl ^ 0x56) + 0x78);
ebx = bl;
eax += ebx;
eax <<= 8;
ebx = (uint)(serialBytes[4] * 0x10 + serialBytes[5]);
bl = (byte)(ebx & 0xFF);
bl = (byte)((bl ^ 0x90) + 0xAB);
ebx = bl;
eax += ebx;
eax <<= 8;
ebx = (uint)(serialBytes[6] * 0x10 + serialBytes[7]);
bl = (byte)(ebx & 0xFF);
bl = (byte)((bl ^ 0xCD) + 0xEF);
ebx = bl;
eax += ebx;
eax = BSwap(eax); //user input serial result
return eax == ecx; //ecx<->ebx(crackme)
}
public static string ReverseString(string input)
{
if (input == null)
throw new ArgumentNullException(nameof(input), "Input string cannot be null.");
return new string(input.Reverse().ToArray());
}
public static bool CheckStrLen(string input, int min, int max)
{
int l = input.Length;
if (min > 0 && l < min)
return false;
if (max > 0 && l > max)
return false;
return true;
}
public static uint BSwap(uint value)
{
byte[] bytes = BitConverter.GetBytes(value);
Array.Reverse(bytes);
return BitConverter.ToUInt32(bytes, 0);
}
public static byte[] ParseHstr(string hexString)
{
byte[] bytes = new byte[hexString.Length];
for (int i = 0; i < hexString.Length; i++)
{
if (byte.TryParse(hexString[i].ToString(), NumberStyles.HexNumber, null, out byte value))
bytes[i] = value;
else
throw new FormatException("Invalid hex string.");
}
return bytes;
}
}

View File

@ -0,0 +1,63 @@
//------------------------------------------------------------------------------
// <auto-generated>
// 此代码由工具生成。
// 运行时版本:4.0.30319.42000
//
// 对此文件的更改可能会导致不正确的行为,并且如果
// 重新生成代码,这些更改将会丢失。
// </auto-generated>
//------------------------------------------------------------------------------
namespace sp_keygen.Properties {
using System;
/// <summary>
/// 一个强类型的资源类,用于查找本地化的字符串等。
/// </summary>
// 此类是由 StronglyTypedResourceBuilder
// 类通过类似于 ResGen 或 Visual Studio 的工具自动生成的。
// 若要添加或移除成员,请编辑 .ResX 文件,然后重新运行 ResGen
// (以 /str 作为命令选项),或重新生成 VS 项目。
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
internal class Resources {
private static global::System.Resources.ResourceManager resourceMan;
private static global::System.Globalization.CultureInfo resourceCulture;
[global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
internal Resources() {
}
/// <summary>
/// 返回此类使用的缓存的 ResourceManager 实例。
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Resources.ResourceManager ResourceManager {
get {
if (object.ReferenceEquals(resourceMan, null)) {
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("sp_keygen.Properties.Resources", typeof(Resources).Assembly);
resourceMan = temp;
}
return resourceMan;
}
}
/// <summary>
/// 重写当前线程的 CurrentUICulture 属性,对
/// 使用此强类型资源类的所有资源查找执行重写。
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Globalization.CultureInfo Culture {
get {
return resourceCulture;
}
set {
resourceCulture = value;
}
}
}
}

View File

@ -0,0 +1,101 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 1.3
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">1.3</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1">this is my long string</data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
[base64 mime encoded serialized .NET Framework object]
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
[base64 mime encoded string representing a byte array form of the .NET Framework object]
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>1.3</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.3500.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.3500.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
</root>

View File

@ -0,0 +1,8 @@
{
"profiles": {
"sp_keygen": {
"commandName": "Project",
"commandLineArgs": "chenx221\r\n123-456-789-X"
}
}
}

View File

@ -0,0 +1,25 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<Compile Update="Properties\Resources.Designer.cs">
<DesignTime>True</DesignTime>
<AutoGen>True</AutoGen>
<DependentUpon>Resources.resx</DependentUpon>
</Compile>
</ItemGroup>
<ItemGroup>
<EmbeddedResource Update="Properties\Resources.resx">
<Generator>ResXFileCodeGenerator</Generator>
<LastGenOutput>Resources.Designer.cs</LastGenOutput>
</EmbeddedResource>
</ItemGroup>
</Project>