Created
June 6, 2016 07:31
-
-
Save litao3rd/67e478644b03eeeff74dcba2ec1d6d0d to your computer and use it in GitHub Desktop.
This is a C-style code for part of one crackme cycle.exe
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// This is a C-style code for part of one crackme cycle.exe | |
// crackme download address: http://bbs.pediy.com/attachment.php?attachmentid=503&d=1139931299 | |
#include <stdio.h> | |
#include <stdlib.h> | |
#include <string.h> | |
static unsigned int dword_402182 = 0xfedcba98; | |
static int gather_byte_msb(unsigned int value) | |
{ | |
int ret = 0; | |
int i; | |
for(i = 0; i < sizeof(value); ++i){ | |
ret |= ((value >> (i * 8)) & 0x80) >> (7-i); | |
} | |
return ret; | |
} | |
static int rol(unsigned int value, unsigned int shift) | |
{ | |
unsigned int mask; | |
unsigned int high; | |
if(shift > sizeof(value)*8) | |
shift %= sizeof(value) * 8; | |
if(shift == 0) | |
return value; | |
mask = ~(1 << shift); | |
high = (value >> (sizeof(value)*8 - shift)) & mask; | |
value = (value << shift) | high; | |
return value; | |
} | |
static int ror(unsigned int value, unsigned int shift) | |
{ | |
unsigned int mask; | |
unsigned int low; | |
if(shift > sizeof(value)*8) | |
shift %= sizeof(value)*8; | |
if(shift == 0) | |
return value; | |
mask = ~(1 << shift); | |
low = value & mask; | |
value = (value >> shift) | (low << (sizeof(value)*8 - shift)); | |
return value; | |
} | |
static void sub_4011f1(const char *name, const char *serial, unsigned int *eax, unsigned int *ebx) | |
{ | |
int i; | |
*eax = ((int *)name)[0]; | |
*ebx = ((int *)name)[1]; | |
*eax ^= ((int *)serial)[0]; | |
*ebx ^= ((int *)serial)[1]; | |
*eax &= 0x7f3f1f0f; | |
*ebx &= 0x7030100; | |
for(i = 0; i < 8; ++i){ | |
int esi = *eax; | |
int edi = *ebx; | |
int edx, tmp; | |
esi <<= i; | |
edi <<= i; | |
esi = gather_byte_msb(esi); | |
edi = gather_byte_msb(edi); | |
edi = (esi << 4) ^ edi; | |
edx = edi & 0xff; | |
tmp = 8; | |
if(i <= 3){ | |
tmp = 8 * i + 8; | |
*eax = rol(*eax, tmp); | |
*eax ^= edx; | |
*eax = ror(*eax, tmp); | |
}else{ | |
tmp = 8 * (i-3); | |
*ebx = rol(*ebx, tmp); | |
*ebx ^= edx; | |
*ebx = ror(*ebx, tmp); | |
} | |
} | |
} | |
static void sub_401190(unsigned int *ecx, unsigned int eax, unsigned int ebx) | |
{ | |
unsigned int tmp; | |
unsigned int edi, esi; | |
if(*ecx <= 0x80) | |
return ; | |
tmp = *ecx; | |
esi = *ecx; | |
*ecx &= 0xff; | |
if(*ecx > 8){ | |
edi = ebx; | |
*ecx >>= 4; | |
}else{ | |
edi = eax; | |
} | |
do{ | |
edi = rol(edi, 8); | |
*ecx >>= 1; | |
}while(*ecx != 0); | |
esi >>= 8; | |
edi &= esi; | |
edi &= 0xff; | |
*ecx = tmp; | |
restart: | |
esi = 0x80; | |
while(esi){ | |
if((esi & edi) == 0){ | |
esi >>= 1; | |
continue; | |
} | |
edi ^= esi; | |
*ecx &= 0xff00; | |
((char *)&esi)[1] ^= ((char *)&esi)[0]; | |
*ecx ^= esi; | |
dword_402182++; | |
sub_401190(ecx, eax, ebx); | |
goto restart; | |
} | |
} | |
static int verification(const char *name, const char *serial) | |
{ | |
unsigned int eax = *((int *)(&name[8])); | |
unsigned int ebx = *((int *)(&name[12])); | |
eax ^= ebx; | |
eax ^= dword_402182; | |
eax |= 0x40404040; | |
eax &= 0x77777777; | |
eax ^= *((int *)(&serial[8])); | |
eax ^= *((int *)(&serial[12])); | |
if(eax == 0){ | |
printf("[!] name and serial number passed !\n"); | |
}else{ | |
printf("[*] name and serial number failed !\n"); | |
} | |
} | |
#define NAME_LEN 16 | |
#define BUFFSIZE (NAME_LEN + 1) // one for terminate character | |
static void fullfill_name(char *name, size_t size) | |
{ | |
int i; | |
size_t len = strlen(name) - 1; // one for '\n' character | |
for(i = 0; i < size-len; ++i){ | |
name[i+len] = name[i]; | |
} | |
name[size] = '\0'; | |
} | |
int main(void) | |
{ | |
//char name[BUFFSIZE]; | |
unsigned int eax, ebx; | |
unsigned int ecx = 0xff01; | |
const char *name = "litao3rdlitao3rd"; | |
const char *serial = "123456782332ASaA"; | |
#if 0 | |
fgets(name, BUFFSIZE, stdin); | |
fullfill_name(name, NAME_LEN); | |
#endif // 0 | |
sub_4011f1(name, serial, &eax, &ebx); | |
sub_401190(&ecx, eax, ebx); | |
if(ecx != 1){ | |
fprintf(stderr, "sub_401190 failure! ecx = %#x\n", ecx); | |
exit(-1); | |
} | |
verification(name, serial); | |
return 0; | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment