Find the Serial when the Name is CodeEngn
(Difficulty : ☆☆☆☆☆ / Keygen : ★★★☆☆)
Analysis...
Solution and Coding...
Unnecessary
Result...
Omake...
Attachment is 'KeyGen' of Advance RCE level 03
Please feel free to test it.
For testing purpose, you can use following values. (one of working Name and Serial)
Serial : 1867703930
(Compiled with Windows SDK)
//
// Reverse2L03_keygen.cpp - Key Generator of Advance RCE level 03
// Made by 3735943886
// Lisence : GPL
//
#include <iostream>
#include <string>
using namespace std;
class RCE2L03
{
public:
unsigned __int32 KeyGen(string *pName)
{
// Length check
if(pName->length() < 3)
return 0;
Name = pName;
Serial = 0;
NamePointer = 0;
SUB401277();
return Serial;
}
private:
string *Name;
unsigned __int32 Serial, eax, ebx, ecx, NamePointer;
void SUB4011D5(unsigned __int32 u)
{
// Dumped from 4011D5 to 40123E
// .text:004011E4 mov eax, u
if(Serial & 2)
{
// .text:004011E7 movzx ecx, word ptr Serial
// .text:004011EE add ecx, 1538h
// .text:004011F4 and ecx, 7A2B36FFh
// .text:004011FA xor eax, ecx
// .text:004011FC imul eax, Serial
ecx = ((Serial & 0xffff) + 0x1538) & 0x7a2b36ff;
eax = (u ^ ecx) * Serial;
}
else
{
// .text:004011E7 add eax, dword ptr Serial
// .text:004011ED movzx ecx, byte ptr Serial
// .text:004011F4 imul eax, 2099h
// .text:004011FA shr eax, 3
eax = ((u + Serial) * 0x2099) >> 3;
ecx = Serial & 0xff;
// .text:004011FD sub eax, 3
// .text:00401200 loop 4011fd
// .text:00401202 nop
do
{
eax -= 3;
ecx--;
} while(ecx);
}
if(Serial & 4)
{
// .text:00401203 sub eax, ecx
// .text:00401205 shl eax, 7
// .text:00401208 add eax, 17F4Bh
eax = ((eax - ecx) << 7) + 0x17f4b;
// .text:0040120D movzx ecx, ax
ecx = eax & 0xffff;
// .text:00401210 ror cx, 5
ecx = (((ecx & 0xffff) >> 5) | ((ecx & 0xffff) << 11)) & 0xffff;
// .text:00401214 add eax, ecx
eax += ecx;
}
else
{
// .text:00401203 xor eax, 1AFh
eax ^= 0x1af;
// .text:00401208 mov ebx, eax
// .text:0040120A rol eax, 6
eax = eax << 6 | eax >> 26;
// .text:0040120D bswap eax
// .text:0040120F or eax, 66Ah
eax = ((eax << 24) | ((eax << 8) & 0xff0000) | ((eax >> 8) & 0xff00) | (eax >> 24)) | 0x66a;
// .text:00401214 nop
// .text:00401215 nop
}
if(Serial & 8)
{
// .text:00401216 movzx ecx, ax
// .text:00401219 not cx
ecx = (~eax) & 0xffff;
// .text:0040121C sub eax, b9h
// .text:00401221 xor eax, ecx
// .text:00401223 loop
do
{
eax = (eax - 0xb9) ^ ecx;
ecx--;
} while(ecx);
// .text:00401225 |. 90 NOP
// .text:00401226 |. 90 NOP
}
else
{
// .text:00401216 mov ebx, 11h
// .text:0040121B mov ecx, eax
ecx = eax;
// .text:0040121D cdq
// .text:0040121E idiv ebx
// .text:00401220 bt ecx, edx
// .text:00401223 xchg eax, ecx
// .text:00401224 adc eax, 2
// .text:00401227 mov Serial, eax
eax = ecx + 2;
if(ecx & (1 << ((__int32)ecx % 0x11))) eax++;
}
// Before return, it calls 401277 to modify Serial and 4011d5
Serial = eax - 0x7f9;
return;
}
unsigned __int32 SUB401241(unsigned __int32 u1, unsigned __int32 u2)
{
// Dumped from 401241 to 401274
if(!u2) return u1;
SUB4011D5(u1);
return SUB401241(u2, (__int32)u1 % u2);
}
void SUB401277()
{
// Dumped from 401277 to 40138F
Serial -= 0x7f9;
ebx = Name->at(NamePointer);
ecx = Name->at(NamePointer + 1);
ebx = (((ebx << 5) + 0x2328 + ecx) * 0xd) ^ 0x15587;
ecx ^= 0xbc614e;
Serial ^= SUB401241(ebx, ecx);
NamePointer++;
if(NamePointer == Name->length() - 1)
return;
else
SUB401277();
}
};
int main()
{
string *Name = new string;
RCE2L03 *k = new RCE2L03;
// Logo
cout << endl << "Reverse2L03_keygen.cpp - Key Generator of Advance RCE level 03"
<< endl << "Made by 3735943886" << endl << "Lisence : GPL" << endl << endl;
// Get Name
cout << "Name : "; getline(cin, *Name);
if(Name->length())
cout << "Serial : " << dec << k->KeyGen(Name) << endl;
delete k;
delete Name;
return 0;
}