program Keygen;
{$APPTYPE CONSOLE}
uses
Windows,
SysUtils,
MessageDigest_5;
type
TKey = packed record
Key: Int64;
function toString: AnsiString;
end;
PKey = ^TKey;
TKeyData = packed record
SaveSettings, SplashOK, RemoveBuyMenu, StoreFile: TKey;
procedure Swap();
end;
PKeyData = ^TKeyData;
const
SaveSettings: AnsiString = #$5B#$88#$A7#$0C#$2F#$DB#$E6#$E6#$8C#$1F#$17#$59;
SaveSettings_PW: TKey = (Key: 5137726410356843158);
SplashOK: AnsiString = #$5A#$1B#$F8#$DD#$07#$20#$E1#$8F;
SplashOK_PW: TKey = (Key: 683507419627418371);
RemoveBuyMenu: AnsiString = #$C9#$59#$9F#$99#$92#$F9#$6E#$15#$AD#$DB#$CB#$2C#$16;
RemoveBuyMenu_PW: TKey = (Key: -5742440621766567094);
StoreFile: AnsiString = #$B0#$43#$B0#$84#$44#$BE#$8C#$48#$A5;
StoreFile_PW: TKey = (Key: 549173212267554849);
procedure TKeyData.Swap;
function Int64Swap(A : int64):int64;
asm
mov edx,dword ptr [A]
mov eax,dword ptr [A+4]
bswap edx
bswap eax
end;
begin
SaveSettings.Key := Int64Swap(SaveSettings.Key);
SplashOK.Key := Int64Swap(SplashOK.Key);
RemoveBuyMenu.Key := Int64Swap(RemoveBuyMenu.Key);
StoreFile.Key := Int64Swap(StoreFile.Key);
end;
function TKey.toString: AnsiString;
begin
result := IntToHex(Key, SizeOf(Key) * 2);
end;
procedure Crypt(Table, Source, Dest: Pointer; Len: Integer); assembler;
asm
// PUSH EBP
// MOV EBP, ESP
SUB ESP,020h
MOV DWORD PTR SS:[EBP-020h],EBX
MOV DWORD PTR SS:[EBP-01Ch],ESI
MOV DWORD PTR SS:[EBP-4],EAX
MOV DWORD PTR SS:[EBP-8],EDX
MOV DWORD PTR SS:[EBP-0Ch],ECX
MOV EAX,DWORD PTR SS:[EBP+8]
DEC EAX
MOV DWORD PTR SS:[EBP-010h],0
CMP EAX,DWORD PTR SS:[EBP-010h]
JL @iNootePa_00421C44
DEC DWORD PTR SS:[EBP-010h]
@iNootePa_00421BAC:
INC DWORD PTR SS:[EBP-010h]
MOV EDX,DWORD PTR SS:[EBP-4]
INC BYTE PTR DS:[EDX+0100h]
MOV ECX,DWORD PTR SS:[EBP-4]
MOV EDX,DWORD PTR SS:[EBP-4]
MOVZX EDX,BYTE PTR DS:[EDX+0100h]
MOV DL,BYTE PTR DS:[ECX+EDX]
MOV BYTE PTR SS:[EBP-014h],DL
MOV EDX,DWORD PTR SS:[EBP-4]
MOV CL,BYTE PTR SS:[EBP-014h]
ADD BYTE PTR DS:[EDX+0101h],CL
MOV ESI,DWORD PTR SS:[EBP-4]
MOV EDX,DWORD PTR SS:[EBP-4]
MOVZX EDX,BYTE PTR DS:[EDX+0101h]
MOV ECX,DWORD PTR SS:[EBP-4]
MOV EBX,DWORD PTR SS:[EBP-4]
MOVZX EBX,BYTE PTR DS:[EBX+0100h]
MOV DL,BYTE PTR DS:[ESI+EDX]
MOV BYTE PTR DS:[ECX+EBX],DL
MOV EBX,DWORD PTR SS:[EBP-4]
MOV EDX,DWORD PTR SS:[EBP-4]
MOVZX EDX,BYTE PTR DS:[EDX+0101h]
MOV CL,BYTE PTR SS:[EBP-014h]
MOV BYTE PTR DS:[EBX+EDX],CL
MOV ECX,DWORD PTR SS:[EBP-4]
MOV EDX,DWORD PTR SS:[EBP-4]
MOVZX EDX,BYTE PTR DS:[EDX+0100h]
MOV DL,BYTE PTR DS:[ECX+EDX]
ADD BYTE PTR SS:[EBP-014h],DL
MOV ESI,DWORD PTR SS:[EBP-8]
MOV ECX,DWORD PTR SS:[EBP-010h]
MOV EBX,DWORD PTR SS:[EBP-4]
MOVZX EDX,BYTE PTR SS:[EBP-014h]
MOV CL,BYTE PTR DS:[ESI+ECX]
MOV DL,BYTE PTR DS:[EBX+EDX]
XOR CL,DL
MOV EBX,DWORD PTR SS:[EBP-0Ch]
MOV EDX,DWORD PTR SS:[EBP-010h]
MOV BYTE PTR DS:[EBX+EDX],CL
CMP EAX,DWORD PTR SS:[EBP-010h]
JG @iNootePa_00421BAC
@iNootePa_00421C44:
MOV EBX,DWORD PTR SS:[EBP-020h]
MOV ESI,DWORD PTR SS:[EBP-01Ch]
LEAVE
RET 4
end;
procedure CreateCryptTable(Dest: Pointer; Password: AnsiString); assembler;
asm
PUSH EBP
MOV EBP, ESP
SUB ESP,024h
MOV DWORD PTR SS:[EBP-024h],EBX
MOV DWORD PTR SS:[EBP-4],EAX
MOV DWORD PTR SS:[EBP-8],EDX
MOV EAX,DWORD PTR SS:[EBP-8]
TEST EAX,EAX
JE @loc_421AB9
MOV EAX,DWORD PTR DS:[EAX-4]
@loc_421AB9:
MOV DWORD PTR SS:[EBP-020h],EAX
MOV EAX,DWORD PTR SS:[EBP-4]
MOV BYTE PTR DS:[EAX+0100h],0
MOV EAX,DWORD PTR SS:[EBP-4]
MOV BYTE PTR DS:[EAX+0101h],0
MOV BYTE PTR SS:[EBP-010h],0
DEC BYTE PTR SS:[EBP-010h]
NOP
@loc_421AD8:
INC BYTE PTR SS:[EBP-010h]
MOV EDX,DWORD PTR SS:[EBP-4]
MOVZX EAX,BYTE PTR SS:[EBP-010h]
MOV CL,BYTE PTR SS:[EBP-010h]
MOV BYTE PTR DS:[EDX+EAX],CL
CMP BYTE PTR SS:[EBP-010h],0FFh
JB @loc_421AD8
MOV BYTE PTR SS:[EBP-0Ch],0
MOV DWORD PTR SS:[EBP-01Ch],0
MOV BYTE PTR SS:[EBP-010h],0
DEC BYTE PTR SS:[EBP-010h]
@loc_421B00:
INC BYTE PTR SS:[EBP-010h]
MOV EAX,DWORD PTR SS:[EBP-01Ch]
MOV EDX,DWORD PTR SS:[EBP-020h]
CMP EAX,EDX
JGE @loc_421B1B
MOV EAX,DWORD PTR SS:[EBP-8]
MOV EDX,DWORD PTR SS:[EBP-01Ch]
MOV AL,BYTE PTR DS:[EAX+EDX]
MOV BYTE PTR SS:[EBP-018h],AL
JMP @loc_421B1F
@loc_421B1B:
MOV BYTE PTR SS:[EBP-018h],0
@loc_421B1F:
INC DWORD PTR SS:[EBP-01Ch]
MOV EAX,DWORD PTR SS:[EBP-01Ch]
MOV EDX,DWORD PTR SS:[EBP-020h]
CMP EAX,EDX
JL @loc_421B33
MOV DWORD PTR SS:[EBP-01Ch],0
@loc_421B33:
MOV EDX,DWORD PTR SS:[EBP-4]
MOVZX EAX,BYTE PTR SS:[EBP-010h]
MOVZX EAX,BYTE PTR DS:[EDX+EAX]
MOVZX EDX,BYTE PTR SS:[EBP-018h]
ADD EAX,EDX
ADD BYTE PTR SS:[EBP-0Ch],AL
MOV EDX,DWORD PTR SS:[EBP-4]
MOVZX EAX,BYTE PTR SS:[EBP-010h]
MOV AL,BYTE PTR DS:[EDX+EAX]
MOV BYTE PTR SS:[EBP-014h],AL
MOV ECX,DWORD PTR SS:[EBP-4]
MOVZX EAX,BYTE PTR SS:[EBP-0Ch]
MOV EBX,DWORD PTR SS:[EBP-4]
MOVZX EDX,BYTE PTR SS:[EBP-010h]
MOV AL,BYTE PTR DS:[ECX+EAX]
MOV BYTE PTR DS:[EBX+EDX],AL
MOV EDX,DWORD PTR SS:[EBP-4]
MOVZX EAX,BYTE PTR SS:[EBP-0Ch]
MOV CL,BYTE PTR SS:[EBP-014h]
MOV BYTE PTR DS:[EDX+EAX],CL
CMP BYTE PTR SS:[EBP-010h],0FFh
JB @loc_421B00
MOV EBX,DWORD PTR SS:[EBP-024h]
LEAVE
RETN
end;
function CryptWrapper(Table: Pointer; s: AnsiString): AnsiString;
begin
result := s;
Crypt(Table, @result[1], @result[1], length(s));
end;
function DecryptString(s, Key: AnsiString): AnsiString;
var
CT: array [0..257] of byte;
begin
CreateCryptTable(@CT, Key);
result := CryptWrapper(@CT, s);
end;
function CheckKey(HWID: AnsiString; pKeyData: PKeyData): Integer;
var
CT: array [0..257] of byte;
KeyData: TKeyData;
s: AnsiString;
i: Integer;
begin
CreateCryptTable(@CT, HWID);
Crypt(@CT, pKeyData, @KeyData, SizeOf(KeyData));
KeyData.Swap;
result := ((Integer(DecryptString(SaveSettings, KeyData.SaveSettings.toString()) = 'SaveSettings') shl 3) or
(Integer(DecryptString(SplashOK, KeyData.SplashOK.toString()) = 'SplashOK') shl 2) or
(Integer(DecryptString(RemoveBuyMenu, KeyData.RemoveBuyMenu.toString()) = 'RemoveBuyMenu') shl 1) or
(Integer(DecryptString(StoreFile, KeyData.StoreFile.toString()) = 'StoreFile')) shl 0);
end;
function CreateKey(HWID: AnsiString): TKeyData;
var
CT: array [0..257] of byte;
i: integer;
begin
result.SaveSettings.Key := SaveSettings_PW.Key;
result.SplashOK.Key := SplashOK_PW.Key;
result.RemoveBuyMenu.Key := RemoveBuyMenu_PW.Key;
result.StoreFile.Key := StoreFile_PW.Key;
result.Swap;
CreateCryptTable(@CT, HWID);
Crypt(@CT, @result, @result, SizeOf(result));
end;
function GetHardwareID(): AnsiString;
var
Buffer: array [0..MAX_PATH] of AnsiChar;
len: DWord;
Computer, User, s: AnsiString;
MD5: IMD5;
begin
len := length(buffer);
GetComputerNameA(Buffer, len);
SetString(Computer, Buffer, len);
len := length(buffer);
GetUserNameA(Buffer, Len);
SetString(User, Buffer, len);
s := trim(User) + trim(Computer);
MD5 := GetMD5;
MD5.Init;
MD5.Update(s);
result := copy(MD5.AsString, 1, 16);
end;
var
KeyData: TKeyData;
HWID, FileName: AnsiString;
h, written: DWord;
begin
if (ParamCount() = 1) then
HWID := ParamStr(1)
else
HWID := GetHardwareID();
writeln('Erstelle Keyfile fuer HWID: ', HWID);
KeyData := CreateKey(HWID);
if (CheckKey(HWID, @KeyData) = 15) then
begin
h := CreateFileA(PAnsiChar(AnsiString(ExtractFilePath(paramstr(0)) + 'key.dat')), GENERIC_WRITE, 0, nil, CREATE_ALWAYS, 0, 0);
if (h <> INVALID_HANDLE_VALUE) then
begin
WriteFile(h, KeyData, SizeOf(KeyData), written, nil);
CloseHandle(h);
writeln('Keyfile erstellt.');
end
else
writeln('Konnte Keyfile nicht erstellen.');
end
else
writeln('Konnte kein gueltiges Keyfile erstellen :(.');
readln;
end.