BINDER D'EXE DE DÉBUTANT

Neo_Fr Messages postés 653 Date d'inscription mardi 6 décembre 2005 Statut Membre Dernière intervention 10 novembre 2014 - 25 mai 2008 à 23:07
cs_badrbadr Messages postés 475 Date d'inscription jeudi 19 juin 2003 Statut Membre Dernière intervention 3 novembre 2008 - 26 mai 2008 à 19:08
Cette discussion concerne un article du site. Pour la consulter dans son contexte d'origine, cliquez sur le lien ci-dessous.

https://codes-sources.commentcamarche.net/source/46759-binder-d-exe-de-debutant

cs_badrbadr Messages postés 475 Date d'inscription jeudi 19 juin 2003 Statut Membre Dernière intervention 3 novembre 2008 1
26 mai 2008 à 19:08
Ok merci, je vois plus clair.
Y a ce site que j'ai trouvé qui explique le principe graphiquement :
http://dn.codegear.com/article/27979
Apparemment, ça pourrait même fonctionner sous Linux :)
BruNews Messages postés 21040 Date d'inscription jeudi 23 janvier 2003 Statut Modérateur Dernière intervention 21 août 2019
26 mai 2008 à 19:02
Pas du tout, le loader ne lit pas un exe comme un quelconque fichier.
Va lire les specs du format PE, tu verras que ne sont lus que les octets utiles définis dans les structures internes, tout ce qui est au delà est ignoré.
Cette méthode est très utile par exemple pour embarquer une DLL dans l'exe, on la dépose à l'exécution dans le dossier TEMP et on la supprime en quittant.
cs_badrbadr Messages postés 475 Date d'inscription jeudi 19 juin 2003 Statut Membre Dernière intervention 3 novembre 2008 1
26 mai 2008 à 18:55
Oui, sauf que le fichier au quel on colle des octets à la fin est un executable (assez délicat). Le format(age) de l'exe est d'une certaine manière compromis. Un futur loader des applications win32 peut décider d'interrompre le chargement de l'exe s'il trouve que sa taille ne concorde pas avec celle indiquée (j'imagine qu'il y a un tel champ) dans le header PE (pour je ne sais quel raison).
J'ignore si Microsoft a documenté comme quoi l'ajout de données supplémentaires à la fin d'un fichier executable est permis. S'ils l'ont fait, ça voudra dire qu'ils grantissent que ça ne causera pas de problèmes dans le futur.
BruNews Messages postés 21040 Date d'inscription jeudi 23 janvier 2003 Statut Modérateur Dernière intervention 21 août 2019
26 mai 2008 à 18:46
Sans tenir compte du code de la source que je n'ai pas lu entièrement mais juste sur le principe, il n'y a aucune raison que ça ne fonctionne pas, le format PE n'entre pour rien dans l'affaire.
On colle des octets à la fin d'un fichier (quel qu'il soit) puis un DWORD à la fin indiquant le nombre d'octets, on doit retrouver les octets originaux en les relisant.
cs_badrbadr Messages postés 475 Date d'inscription jeudi 19 juin 2003 Statut Membre Dernière intervention 3 novembre 2008 1
26 mai 2008 à 17:48
Je suis surpris que ce programme fonctionne. Vous ajoutez simplement deux fichiers .exe à la fin d'un autre fichier .exe (le binder) en prenant soin de spécifier la taille avant.
Je ne connais pas très bien le format .exe de Windows (appelé PE) ni à quel point est documenté, mais est-ce que ce programme ne risque pas de cesser de fonctionner sur des versions futures de Windows?
Il me semble que le moyen le mieux documenté est d'utiliser l'API Win32 pour ce genre de programme auto-extractable (voir UpdateResoource());
TorTukiTu Messages postés 31 Date d'inscription samedi 22 avril 2006 Statut Membre Dernière intervention 18 avril 2011 1
26 mai 2008 à 12:39
Merci de tous vos commentaires ^^ c super pr progresser longue vie a CodeSSourceS
cs_jfrancois Messages postés 482 Date d'inscription vendredi 26 août 2005 Statut Membre Dernière intervention 5 décembre 2009 2
25 mai 2008 à 23:43
Surtout que dans : char *file1_name=calloc(256,sizeof(char));
le calloc ne sert à rien, et dans : file1_name=argv[2];
ça ne copie rien d'autre que l'adresse qui est dans argv[2] (argv est un tableau de pointeurs), c'est à dire que cela ne fait que créer une sorte d'alias pour argv[2] !
Il suffit de faire : char *file1_name = argv[2];

Pour copier il aurait fallu faire : strcpy(file1_name,argv[2]);
Neo_Fr Messages postés 653 Date d'inscription mardi 6 décembre 2005 Statut Membre Dernière intervention 10 novembre 2014 2
25 mai 2008 à 23:41
Tant qua inclure windows.h autant ne pas le faire pour rien ;)

#include <windows.h>
#include <stdio.h>

DWORD __stdcall FileConcat(LPSTR lpszDstFile, LPSTR lpszSrcFile)
{
HANDLE hSrcFile, hDstFile;
DWORD dwRet = 1, dwFileSize, br, bw;
BYTE* lpBuffer;
hSrcFile = CreateFile(lpszSrcFile, GENERIC_READ, 0, 0, OPEN_EXISTING, 0, 0);
if(hSrcFile == INVALID_HANDLE_VALUE) return 1;
hDstFile = CreateFile(lpszDstFile, GENERIC_WRITE, 0, 0, OPEN_ALWAYS, 0, 0);
if(hDstFile == INVALID_HANDLE_VALUE) goto _Error;
lpBuffer = (BYTE*) HeapAlloc(GetProcessHeap(), HEAP_NO_SERIALIZE, 0x100000); // 1mo
if(!lpBuffer) goto _Error;
dwFileSize = GetFileSize(hDstFile, 0);
SetFilePointer(hDstFile, dwFileSize, 0, FILE_BEGIN);
while(1)
{
if(!ReadFile(hSrcFile, lpBuffer, 0x100000, &br, 0)) goto _Error;
if(!br) break;
if(!WriteFile(hDstFile, lpBuffer, br, &bw, 0)) goto _Error;
}
dwRet = 0;
_Error:
if(lpBuffer) HeapFree(GetProcessHeap(), HEAP_NO_SERIALIZE, lpBuffer);
if(hDstFile) CloseHandle(hDstFile);
if(hSrcFile) CloseHandle(hSrcFile);
return dwRet;
}

/*
Voici comment se presente le fichier:
|----"self-extractor"----|---donnes sur la tailles des exe --|--------EXE1------|-------EXE2------|
*/
DWORD __stdcall FormatFile(LPSTR lpszFilePath, DWORD dwFile1Size, DWORD dwFile2Size)
{
HANDLE hFile;
DWORD bw;
FileConcat(lpszFilePath, "header.bin");
hFile = CreateFile(lpszFilePath, GENERIC_WRITE, 0, 0, CREATE_ALWAYS, 0, 0);
if(hFile == INVALID_HANDLE_VALUE) return 1;
WriteFile(hFile, &dwFile1Size, sizeof(DWORD), &bw, 0);
WriteFile(hFile, &dwFile2Size, sizeof(DWORD), &bw, 0);
CloseHandle(hFile);
return 0;
}

DWORD __stdcall GetSizeOfFile(LPSTR lpszFile)
{
HANDLE hFile;
DWORD dwFileSize;
hFile = CreateFile(lpszFile, GENERIC_READ, 0, 0, OPEN_EXISTING, 0, 0);
if(hFile == INVALID_HANDLE_VALUE) return 0;
dwFileSize = GetFileSize(hFile, 0);
CloseHandle(hFile);
return dwFileSize;
}

int main(int argc, LPSTR* argv)
{
HANDLE hFile;
LPSTR lpszFile1, *lpszFile2, *lpszBindedFile;
if(argc != 4)
{
printf("Syntaxe: binded_name.exe file1.exe file2.exe\n");
system("PAUSE");
return 0;
}
lpszFile1 = argv[2];
lpszFile2 = argv[3];
lpszBindedFile = argv[1];
FileConcat("tmp.exe", lpszFile1);
FileConcat("tmp.exe", lpszFile2);
FormatFile(lpszBindedFile, GetSizeOfFile(lpszFile1), GetSizeOfFile(lpszFile2));
system("PAUSE");
return 0;
}

Neo_Fr
BruNews Messages postés 21040 Date d'inscription jeudi 23 janvier 2003 Statut Modérateur Dernière intervention 21 août 2019
25 mai 2008 à 23:10
NEO_FR m'a devancé.
BruNews Messages postés 21040 Date d'inscription jeudi 23 janvier 2003 Statut Modérateur Dernière intervention 21 août 2019
25 mai 2008 à 23:09
char *c=calloc(1,sizeof(char));
On n'appelle pas une alloc dynamique pour 1 octet.
char c;
allait tout aussi bien en utilisant idem 4 octets (ici sur la pile) mais sans appel au memory manager.
D'ailleurs dans ta fonction forma(...) tu oublies de libérer la mémoire.
TorTukiTu Messages postés 31 Date d'inscription samedi 22 avril 2006 Statut Membre Dernière intervention 18 avril 2011 1
25 mai 2008 à 23:08
Merci des tes conseils =) je fait ça
Neo_Fr Messages postés 653 Date d'inscription mardi 6 décembre 2005 Statut Membre Dernière intervention 10 novembre 2014 2
25 mai 2008 à 23:07
On utilise pas calloc pour 1 octet ni meme pour 256(surtout que quelque lignes plus bas tu fait pointer le pointeur sur autre chose, puis quand tu copie un fichier ne le copie pas octet par octet c'est la cata niveau perfs creer plutot un buffer et tu copie par passe de 1 mo.

Neo_Fr
Rejoignez-nous