Skip to content

Instantly share code, notes, and snippets.

@litao3rd
Created June 6, 2016 07:31
Show Gist options
  • Save litao3rd/67e478644b03eeeff74dcba2ec1d6d0d to your computer and use it in GitHub Desktop.
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 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