Creer un fake code assembleur (v2)

Description

meme principe que la version precedente, a part quelques modifications:
- recursivité et tables d'instructions pour une meilleur création
- creation du resultat dans un fichier include avec une macro #define pour eviter d'allourdir le code utilisateur
- le nom du fichier .h est aleatoire pour pouvoir creer plusieur fake code dans le meme programme
- affichage de la position de la pile avant et apres celle utilisé par le fake pour pouvoir l'utiliser par vous
- affichage des registres non utilisés pour chaque instruction, pour inserer du code facilement
- mise dans une procedure pour la creation de code, ce qui permet de lutiliser pour dautre chose en creant une table specifique
- ajustement de la taille de la pile utilisé pour le fake par le #define TAILLEPILE
- amelioration dans la vitesse de creation (100000 ligne de code crées en 3econdes sur un p3 800 en debug)
                        • pour voir un exemple du resultat, voir le fichier zip (fichier fakeasm811.h) **************

Source / Exemple :


#include "stdafx.h"
#include <stdlib.h> 
#include <windows.h>
#include <time.h>
#include <string.h>
#include <stdio.h>
#pragma warning(disable: 4102) //pas de label
#include <iostream> 
#include <fstream.h>

#define TAILLEPILE 300

bool listepile[TAILLEPILE];

struct regdestdef
{
	char nom[255];
	bool use; //indique si on vient decrire dedans, remis a false quand on le lit en source
	bool donttouch; //c'est un registre alloue pour vous, mettre a true si vous voulez vous reserver le registre en ecriture
};

regdestdef registre[]={
	{"eax",false,false},
	{"ebx",false,false},
	{"ecx",false,false},
	{"edx",false,false},
	{"esi",false,false},
	{"edi",false,false}
};

char tablefs[][255]={"0h","1ch","20h","28h","2ch","30h","34h","38h","124h"};

struct insdescription
{
	char ins[255];
	char format[255];
	char param[6][3];
	int pourcentage;
	insdescription *table;
	int tailletable;
	unsigned long nbligne;
};

insdescription nivo2[];

insdescription nivo1[] = {
	{"je","%s %s",{"b ","b ","b ","b ","b ","b "},100,nivo2,19,25},
	{"jne","%s %s",{"b ","b ","b ","b ","b ","b "},100,nivo2,19,25},
	{"jb","%s %s",{"b ","b ","b ","b ","b ","b "},100,nivo2,19,25},
	{"jbe","%s %s",{"b ","b ","b ","b ","b ","b "},100,nivo2,19,25},
	{"jnb","%s %s",{"b ","b ","b ","b ","b ","b "},100,nivo2,19,25},
	{"jnbe","%s %s",{"b ","b ","b ","b ","b ","b "},100,nivo2,19,25}
};

insdescription nivo2[] = {
	{"mul","%s %s %s",{"m ","r ","m ","r ","m ","r "},30,NULL,0,0}, 
	{"sub","%s %s,%s",{"mr","rm","rr","ri","mi","rr"},85,NULL,0,0}, 
	{"and","%s %s,%s",{"mr","rm","rr","ri","mi","rr"},85,NULL,0,0}, 
	{"or","%s %s,%s",{"mr","rm","rr","ri","mi","rr"},80,NULL,0,0}, 
	{"test","%s %s,%s",{"mr","rm","rr","ri","mi","rr"},15,nivo1,6,1}, 
	{"shl","%s %s,%s",{"ml","rl","ml","rl","ml","rl"},30,NULL,0,0}, 
	{"cmp","%s %s,%s",{"mr","rm","rr","ri","mi","rr"},15,nivo1,6,1}, 
	{"shr","%s %s,%s",{"ml","rl","ml","rl","ml","rl"},30,NULL,0,0}, 
	{"mov","%s %s,%s",{"mr","rm","rr","ri","mi","rf"},85,NULL,0,0}, 
	{"xor","%s %s,%s",{"mr","rm","rr","ri","mi","rr"},85,NULL,0,0}, 
	{"add","%s %s,%s",{"mr","rr","ri","mi","rm","rr"},85,NULL,0,0}, 
	{"sal","%s %s,%s",{"ml","rl","ml","rl","ml","rl"},30,NULL,0,0},
	{"dec","%s %s %s",{"m ","r ","m ","r ","m ","r "},50,NULL,0,0}, 
	{"neg","%s %s %s",{"m ","r ","m ","r ","m ","r "},60,NULL,0,0}, 
	{"sar","%s %s,%s",{"ml","rl","ml","rl","ml","rl"},30,NULL,0,0}, 
	{"rol","%s %s,%s",{"ml","rl","ml","rl","ml","rl"},43,NULL,0,0},					 
	{"inc","%s %s %s",{"m ","r ","m ","r ","m ","r "},50,NULL,0,0}, 
	{"not","%s %s %s",{"m ","r ","m ","r ","m ","r "},50,NULL,0,0}, 
	{"int 3","%s %s %s",{"  ","  ","  ","  ","  ","  "},50,NULL,0,0},
};

insdescription nivo0[] = {
	{"push","%s %s %s",{" m"," r"," i"," r"," m"," i"},90,NULL,0,0},
	{"mul","%s %s %s",{"m ","r ","m ","r ","m ","r "},30,NULL,0,0}, 
	{"sub","%s %s,%s",{"mr","rm","rr","ri","mi","rr"},85,NULL,0,0}, 
	{"and","%s %s,%s",{"mr","rm","rr","ri","mi","rr"},85,NULL,0,0}, 
	{"or","%s %s,%s",{"mr","rm","rr","ri","mi","rr"},80,NULL,0,0}, 
	{"pop","%s %s %s",{"r ","r ","r ","r ","r ","r "},100,NULL,0,0}, // on lui interdit les acces memoire
	{"test","%s %s,%s",{"mr","rm","rr","ri","mi","rr"},15,nivo1,6,1}, 
	{"shl","%s %s,%s",{"ml","rl","ml","rl","ml","rl"},30,NULL,0,0}, 
	{"cmp","%s %s,%s",{"mr","rm","rr","ri","mi","rr"},15,nivo1,6,1}, 
	{"shr","%s %s,%s",{"ml","rl","ml","rl","ml","rl"},30,NULL,0,0}, 
	{"mov","%s %s,%s",{"mr","rm","rr","ri","mi","rf"},85,NULL,0,0}, 
	{"xor","%s %s,%s",{"mr","rm","rr","ri","mi","rr"},85,NULL,0,0}, 
	{"add","%s %s,%s",{"mr","rr","ri","mi","rm","rr"},85,NULL,0,0}, 
	{"sal","%s %s,%s",{"ml","rl","ml","rl","ml","rl"},30,NULL,0,0},
	{"dec","%s %s %s",{"m ","r ","m ","r ","m ","r "},50,NULL,0,0}, 
	{"neg","%s %s %s",{"m ","r ","m ","r ","m ","r "},60,NULL,0,0}, 
	{"sar","%s %s,%s",{"ml","rl","ml","rl","ml","rl"},30,NULL,0,0}, 
	{"rol","%s %s,%s",{"ml","rl","ml","rl","ml","rl"},43,NULL,0,0},					 
	{"inc","%s %s %s",{"m ","r ","m ","r ","m ","r "},50,NULL,0,0}, 
	{"not","%s %s %s",{"m ","r ","m ","r ","m ","r "},50,NULL,0,0}, 
	{"int 3","%s %s %s",{"  ","  ","  ","  ","  ","  "},50,NULL,0,0},
};

char label[255],oldins[255],regoqp[255];
int pile=0;	
ofstream sortie;
int toucheme;
unsigned long nblignereel,maxreel;
int profondeur;

void assembleur(unsigned long ligne,insdescription *table,int taille)
{

int ins=0;
int keltyp;
int constante=0;
int valeurpiles=0;
int valeurpiled=0;
int regd=0,regs=0;
int fs=0;
bool trouve;

char sregd[255],sregs[255],sins[255];

while (ligne>0 && maxreel>0) 
{
	do {

		strcpy(sregd,"");
		strcpy(sregs,"");
		strcpy(sins,"");
		trouve=true;
		valeurpiles=-1;
		valeurpiled=-1;

		ins = rand()%taille; 

		if (table[ins].pourcentage <= rand()%100) continue;
		if (!stricmp(table[ins].ins,"pop") && pile<=0) continue; // pas de pop si ya pas eu de pile

		do {
			keltyp= rand()%6;
		}
		while (table[ins].param[keltyp][0] == 'm' && pile==0); // pas de [esp+x] en destination si ya pas eu de pile

		
		// on cree la destination
		if (table[ins].param[keltyp][0] == 'm') { // memoire    [esp+%s]
			int ab=0; //anti boucle infini
			do {
				if (pile>4) valeurpiled = rand()%pile;
				else valeurpiled=0;
				valeurpiled = (valeurpiled/4)*4; //on creer un multiple de 4
				ab++;
				if (ab>10) goto autre; //on tente une autre instruction
			} while (listepile[pile-valeurpiled]);
			listepile[pile-valeurpiled] = true;
			if (valeurpiled)
				sprintf(sregd,"dword ptr[esp+%d]",valeurpiled);
			else
				strcpy(sregd,"dword ptr[esp]");
		}
		else if (table[ins].param[keltyp][0] == 'i') { // constante
			constante = rand()%0x7fffffff;
			sprintf(sregd,"%d",constante);
		}
		else if (table[ins].param[keltyp][0] == 'l') { // constante de 0 a 7
			constante = rand()%7+1;
			sprintf(sregd,"%d",constante);
		}
		else if (table[ins].param[keltyp][0] == 'r') { // registre
			int ab=0; //anti boucle infini
			do {
				regd = rand()%((sizeof(registre)/sizeof(regdestdef)));
				ab++;
				if (ab>10) goto autre; //on tente une autre instruction
			} //ici on va verifie que le registre soit pas alouee ou que on a pas deja ecrit dedans sans lecture par la suite
			while (registre[regd].donttouch || (registre[regd].use && (!stricmp(table[ins].ins,"pop") || !stricmp(table[ins].ins,"mov")))); // on eviter lecriture dans le registre alloue
			
			registre[regd].use = true; //dit kon ecrit dedans
			strcpy(sregd,registre[regd].nom);
		}
		else if (table[ins].param[keltyp][0] == ' ') { // pas de destination
			strcpy(sregd,"");
		}
		else if (table[ins].param[keltyp][0] == 'b') { // label
			if (strlen(label)) {
				strcpy(sregd,label);
			}
			else
			{
				sprintf(sregd,"L%d",nblignereel);
				strcpy(label,sregd);
			}
		}
		else { //erreur
			continue; // on recree une autre instruction
		}

		// on cree la source
		if (table[ins].param[keltyp][1] == 'm') { // memoire    [esp+%s] 
			if (pile) valeurpiles = rand()%(pile);
			else valeurpiles=0;
			valeurpiles = (valeurpiles/4)*4; //on creer un multiple de 4
			listepile[pile-valeurpiles] = false;
			if (valeurpiles)
				sprintf(sregs,"dword ptr[esp+%d]",valeurpiles);
			else
				strcpy(sregs,"dword ptr[esp]");
		}
		else if (table[ins].param[keltyp][1] == 'f') { // registre fs
			fs=rand()%9; // si le registre est fs
			sprintf(sregs,"fs:[%s]",&tablefs[fs]);
		}
		else if (table[ins].param[keltyp][1] == 'r') { // registre
			do
			{
				regs = rand()%((sizeof(registre)/sizeof(regdestdef)));
			} while (!stricmp(registre[regs].nom,sregd)); //evite la meme source et destination

			registre[regs].use=false;
			strcpy(sregs,registre[regs].nom);
		}
		else if (table[ins].param[keltyp][1] == 'i') { // constante
			constante = rand()%0x7084fff;
			sprintf(sregs,"%d",constante);
		}
		else if (table[ins].param[keltyp][1] == 'l') { // constante de 0 a 7
			constante = rand()%7+1;
			sprintf(sregs,"%d",constante);
		}
		else if (table[ins].param[keltyp][1] == ' ') { // pas de destination
			strcpy(sregs,"");
		}
		else { //erreur
			exit(0); // ciao erreur grave
		}

		trouve=false;
autre:
	;
	}
	while (trouve); 

	// cas particuliers
	if (!stricmp(table[ins].ins,"pop")) pile-=4;	
	if (!stricmp(table[ins].ins,"push"))
	{
		if (pile >= TAILLEPILE) continue;//on limite la taille de la pile, tampis on saute l'instruction
		pile+=4;
	}

	strcpy(oldins,table[ins].ins);
	sprintf(sins,table[ins].format,table[ins].ins,sregd,sregs); // on crée linstruction finale
	

	strcat(sins,"/*"); //pour le #define

	int nbroqp=0;
	for (int rr=0;rr<6;rr++)
	{
		if (registre[rr].use)	nbroqp++;
	}

	if (nbroqp>5 || profondeur!=0)	strcat(sins," ----- NE RIEN INSERER APRES -----");
	else
	{
		char tmp[255];
		sprintf(tmp," pile +%d -%d",pile,TAILLEPILE-pile);
		strcat(sins,tmp);
	}

	if (nbroqp<=5 && profondeur==0)
	{
		while (strlen(sins) <75) strcat(sins," ");
		strcat(sins,"reg libre:");

		for (int rr=0;rr<6;rr++)
		{
			if (!registre[rr].use)	{
				strcat(sins," ");
				strcat(sins,registre[rr].nom);
			}
			else strcat(sins,"    ");
		}
	}
	
	sortie << "_asm " << sins << "*/\\" << endl;

	nblignereel++; // on incremente le nombre de ligne totale

	if (table[ins].table !=NULL && profondeur<=3) { //vive le recursif
		unsigned long b=rand()%table[ins].nbligne+1;
		profondeur++;
		assembleur(b,table[ins].table,table[ins].tailletable);
		profondeur--;
		if (strlen(label)>0 && profondeur==0) {
			sortie << "_asm " << label << ":\\" << endl;
			strcpy(label,"");
		}

	}
	maxreel--;
	ligne--;
}

}

int main(int argc, char* argv[])
{
	char nom[255];
	char fichier[255];
	srand ( time(NULL) );
	sprintf(nom,"fakeasm%d",rand()%1000+1);
	strcpy(fichier,nom);
	strcat(fichier,".h");
	sortie.open(fichier);

strcpy(label,"");
strcpy(oldins,"");

profondeur=0;

for (int jj=0;jj<TAILLEPILE/4;jj++) listepile[jj]=false;

	

toucheme = (toucheme/4)*4; 
nblignereel=0;

sortie << "//---------- debut code factice ----------" <<endl;
sortie << "// a mettre entre _asm { }" << endl;
sortie << "// rajouter /Zm400 a la compilation, 400=400% de memoire en +" << endl;

sortie << "#define " << nom << " \\" <<endl;

maxreel=100000; // nb de ligne maximum a creer
assembleur(100000,nivo0,21);// ici on indique le nimbre de ligne a creer pour le niveau 0 de profondeur

if (strlen(label)>0) //on a pas eu le temps de le poser?
	sortie << "_asm " << label << ":\\" << endl;

if (pile) { //on remet la pile au debut
sortie << "_asm add esp," << pile << " //on restaure la pile"  <<endl;
}

sortie << "//---------- fin code factice ----------" <<endl;
sortie.close();
	return 0;
}

Conclusion :


il me manque a gerer certaines choses comme (on verra bien si je le fais):
- les jmp (pour embrouiller encore plus le tracage)
- pouvoir injecter du code (fournit dans un .txt) aleatoirement en fonction des registres non utilisés par le fake
- creer des macros crées aléatoirement pour faire des antidebug, ...

Codes Sources

A voir également

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.