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, ...
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.