A priori, c'est un binaire win32 normal, apparemment packé mais PeiD ne trouve pas de signature.

On commence par l'ouvrir sous OllyDbg v2, la version 1 ayant du mal à l'analyser. On tombe directement sur l'instruction PUSHAD, qui fait penser à un packer UPX-like. Une recherche de la commande POPAD confirme cette intuition, et il suffit de mettre un breakpoint à l'adresse 00466F1B puis F9 pour unpacker l’exécutable.

rce100_pic1

Une analyse de la table des appels inter-modulaires ne nous révèle pas d'appels intéressants concernant une éventuelle comparaison de serial, on va donc breaker sur les appels à SendMessageA (sauf celui avec WM_MOUSELEAVE) pour intercepter les évènements de clicks et autres sur la fenêtre.

rce100_pic2

On run avec F9, et on entre un serial bidon (abcdef). On est interrompu après avoir entré le premier caractère car Olly a breaké sur un appel à SendMessageA. Après être entré dans le CALL suivant l'appel et quelques F8 plus tard on tombe sur une boucle qui semble compter le nombre de caractères entrés dans la textbox (en 4042F5)

rce100_pic4

Enfait la fonction dans laquelle on se trouve est chargée de dessiner la textbox avec les caractères qu'on a entrés, donc useless pour ce qu'on veut faire. Néanmoins, elle permet de récupérer l'adresse mémoire de l'emplacement de la chaîne, contenue dans EDX à ce moment là (soit 9866E8 ici).

On note cette adresse précieusement, elle servira plus tard :)

Maintenant on enlève le breakpoint en 404657 sinon on va être interrompu après chaque nouveau caractère entré dans la textbox, et on tape notre serial bidon : abcdefg, puis on clique sur Login. Olly break une fois de plus sur un appel à SendMessageA. Pour trouver la routine de vérification, on place un breakpoint mémoire à l'adresse du serial 9866E8, puis F9 pour relancer le programme. Olly break en 403F76.

rce100_pic5

Quelques F8 plus loin, on tombe sur cette fonction :

rce100_pic6

On remarques quelques lignes plus haut le CALL 0041EC50, puis la comparaison entre EAX et un une constante hexadécimale. Regardons cette fonction de plus près :

rce100_pic7

On voit ici que cette fonction génère un hash avec les caractères du serial, il reste donc plus qu'à recoder la fonction en C et lancer un bruteforce jusqu'à obtenir le bon checksum. Pour viser large on prend comme charset la plage ascii 48;122.

#include <stdio.h>
#include <stdlib.h>
 
#define MIN 48
#define MAX 122
 
void bf(char* input,int lenght)
{
	int i;
	int eax;
	int esi = 0xdeadbeef;
	for(i=0;i<lenght;i++)
	{
		eax = input[i];
		esi = esi*0x38271606;
		eax = eax*0x5b86affe;
		esi = eax - esi;
	}
 
	if(esi==0xc4b1801c)
	{
		printf("Password : %s",input);
		exit(0);
	}
}
 
void construct(char* input,int i,int j)
{
	if(i==j)
	{
		bf(input,j);
	}
	else
	{
		int k;
 
		for(k=MIN;k<=MAX;k++)
		{
			input[i]=k;
			construct(input,i+1,j);
		}
	}
}
 
int main()
{
 
	char pass[1024];
 
	int i;
 
	for(i=1;i<20;i++)
	{
		construct(pass,0,i);
		printf("Lenght : %d\n",i);
	}
 
	return 0;
}

Après quelques secondes, on trouve pWn3D.