GÉNÉRE UN TABLEAU DE CARACTÉRE AU FORMAT C CONTENANT LE BYTE CODE DE N'IMPORTE Q

Signaler
Messages postés
3804
Date d'inscription
dimanche 12 décembre 2004
Statut
Modérateur
Dernière intervention
30 janvier 2020
-
LeFauve42
Messages postés
239
Date d'inscription
vendredi 20 octobre 2006
Statut
Membre
Dernière intervention
20 avril 2009
-
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/50887-genere-un-tableau-de-caractere-au-format-c-contenant-le-byte-code-de-n-importe-quel-fichier

LeFauve42
Messages postés
239
Date d'inscription
vendredi 20 octobre 2006
Statut
Membre
Dernière intervention
20 avril 2009

Salut,

Quelques petites choses en vrac :
> CptPingu, pour le coup du scanf("%s", &nomfichier),
> étrangement ça marche aussi

Non, ca a l'air de marcher uniquement parce que ton tableau est declare dans la pile... si tu modifie d'autres variables, tu peux tres bien perdre un bout de ce que tu as lu (a verifier, mais c'est sans doute implementation dependant).

- A quoi sert ce programme :
Il y a plusieurs reponses :
- Sous Windows pour faire des applications windows : A rien...
Les resources sont la pour ca.
- Sous Windows pour faire du cross-compilation (par exemple developper une appli pour une console de jeu), ca peut etre pratique, mais dans ce cas, il vaudrait mieux que ton programme utilise les parametres de ligne de commande afin de pouvoir etre utilise dans un makefile.
Par exemple, tu pourais avoir pour integrer une image dans ton source:
toto.c : toto.jpg
tonexe toto.jpg

Si ton exe a pour dependance toto.o, le makefile va construire toto.c a partir du jpg en utilisant la regle specifiee, puis toto.o a partir du .c en utilisant la regle implicite (cc -c).

Note que dans ce cas, il est judicieux de generer un .c et le .h qui va avec (pour declarer tes variables en "extern").

Tant que tu es a generer du C, il est aussi bien pratique de generer une deuxieme variable contenant la taille de ton objet (parce que tu ne veux pas avoir a changer ton code chaque fois que tu changes ton image jpg).

Pour faire court, ce genre de programme est pratique dans certains cas, mais il reste des choses a implementer pour que ce soit vraiment pratique.

Eric
cs_jfrancois
Messages postés
482
Date d'inscription
vendredi 26 août 2005
Statut
Membre
Dernière intervention
5 décembre 2009

Oups en effet, bit 7 (le poids fort) et non bit 0 !!!
kertimanoff
Messages postés
75
Date d'inscription
samedi 3 décembre 2005
Statut
Membre
Dernière intervention
30 juin 2013

j'ai fais ce code uniquement dans le but d'obtenir le byte code de fichier executable et non pour en faire une œuvre dernier cri. mais je suis entiérement ouvert à la connaissance d'autre syntaxes
kertimanoff
Messages postés
75
Date d'inscription
samedi 3 décembre 2005
Statut
Membre
Dernière intervention
30 juin 2013

bein ecoute BruNews, j'utilise ce que mes professeurs m'ont enseigné (tant bien que mal), si tu a de nouvelles fonctions de l'api, développe ce que tu sais, j'aimerais savoir !
BruNews
Messages postés
21042
Date d'inscription
jeudi 23 janvier 2003
Statut
Modérateur
Dernière intervention
21 août 2019
16
RECTIF:
devient négatif quand le bit le plus haut est positionné, donc dans la cas d'un char c'est le bit[7].

Kertimanoff, si tu dédies un code à Windows alors tiu peux tout refaire, les scanf et autres histoires de flux sont à reléguer aux musées. Il y a une API qu'il convient d'utiliser.
kertimanoff
Messages postés
75
Date d'inscription
samedi 3 décembre 2005
Statut
Membre
Dernière intervention
30 juin 2013

Chapeau pointu !
la tu viens d'éclairé une bonne lanterne !!
finalement je me suis casser la téte alors qu'un simplement changement de type aurait simplifier l'affaire !!
Merci beaucoup jfrancois !!
cs_jfrancois
Messages postés
482
Date d'inscription
vendredi 26 août 2005
Statut
Membre
Dernière intervention
5 décembre 2009

Bonsoir,

Les 'ffffff' sont dus au fait que vous manipulez des "char" signés.

Dès que le bit 0 du "char" signé "contenu" passe à 1, "contenu" devient négatif : "contenu 0x80 -128" à "contenu = 0xff = -1" et en hexa, sur 32 bits, cela donne 0xffffff80 à 0xffffffff ! Il faut "casté" le formatage avec "(unsigned char)".

Voilà un petit exemple de balayage des 256 valeurs d'un "char" signé converti en chaîne hexa en restant signé et en étant "casté" en non signé :

int main(void)
{
char contenu;
char temphex1[32],temphex2[32];
printf(" i contenu temphex1 temphex2\n");
for (int i=0 ; i<256 ; ++i)
{
contenu = (char)i;
sprintf(temphex1,"%x",contenu);
sprintf(temphex2,"%x",(unsigned char)contenu);
printf("%03d %4d %8s %8s\n",i,contenu,temphex1,temphex2);
}
return 0;
}

Ce qui donne :

i contenu temphex1 temphex2
000 0 0 0
001 1 1 1
002 2 2 2
003 3 3 3
004 4 4 4
005 5 5 5
006 6 6 6
007 7 7 7
008 8 8 8
009 9 9 9
010 10 a a
011 11 b b
012 12 c c
013 13 d d
014 14 e e
015 15 f f
016 16 10 10
017 17 11 11
018 18 12 12
019 19 13 13
020 20 14 14
021 21 15 15
022 22 16 16
023 23 17 17
024 24 18 18
025 25 19 19
026 26 1a 1a
027 27 1b 1b
028 28 1c 1c
029 29 1d 1d
030 30 1e 1e
031 31 1f 1f
032 32 20 20
033 33 21 21
034 34 22 22
035 35 23 23
036 36 24 24
037 37 25 25
038 38 26 26
039 39 27 27
040 40 28 28
041 41 29 29
042 42 2a 2a
043 43 2b 2b
044 44 2c 2c
045 45 2d 2d
046 46 2e 2e
047 47 2f 2f
048 48 30 30
049 49 31 31
050 50 32 32
051 51 33 33
052 52 34 34
053 53 35 35
054 54 36 36
055 55 37 37
056 56 38 38
057 57 39 39
058 58 3a 3a
059 59 3b 3b
060 60 3c 3c
061 61 3d 3d
062 62 3e 3e
063 63 3f 3f
064 64 40 40
065 65 41 41
066 66 42 42
067 67 43 43
068 68 44 44
069 69 45 45
070 70 46 46
071 71 47 47
072 72 48 48
073 73 49 49
074 74 4a 4a
075 75 4b 4b
076 76 4c 4c
077 77 4d 4d
078 78 4e 4e
079 79 4f 4f
080 80 50 50
081 81 51 51
082 82 52 52
083 83 53 53
084 84 54 54
085 85 55 55
086 86 56 56
087 87 57 57
088 88 58 58
089 89 59 59
090 90 5a 5a
091 91 5b 5b
092 92 5c 5c
093 93 5d 5d
094 94 5e 5e
095 95 5f 5f
096 96 60 60
097 97 61 61
098 98 62 62
099 99 63 63
100 100 64 64
101 101 65 65
102 102 66 66
103 103 67 67
104 104 68 68
105 105 69 69
106 106 6a 6a
107 107 6b 6b
108 108 6c 6c
109 109 6d 6d
110 110 6e 6e
111 111 6f 6f
112 112 70 70
113 113 71 71
114 114 72 72
115 115 73 73
116 116 74 74
117 117 75 75
118 118 76 76
119 119 77 77
120 120 78 78
121 121 79 79
122 122 7a 7a
123 123 7b 7b
124 124 7c 7c
125 125 7d 7d
126 126 7e 7e
127 127 7f 7f
128 -128 ffffff80 80
129 -127 ffffff81 81
130 -126 ffffff82 82
131 -125 ffffff83 83
132 -124 ffffff84 84
133 -123 ffffff85 85
134 -122 ffffff86 86
135 -121 ffffff87 87
136 -120 ffffff88 88
137 -119 ffffff89 89
138 -118 ffffff8a 8a
139 -117 ffffff8b 8b
140 -116 ffffff8c 8c
141 -115 ffffff8d 8d
142 -114 ffffff8e 8e
143 -113 ffffff8f 8f
144 -112 ffffff90 90
145 -111 ffffff91 91
146 -110 ffffff92 92
147 -109 ffffff93 93
148 -108 ffffff94 94
149 -107 ffffff95 95
150 -106 ffffff96 96
151 -105 ffffff97 97
152 -104 ffffff98 98
153 -103 ffffff99 99
154 -102 ffffff9a 9a
155 -101 ffffff9b 9b
156 -100 ffffff9c 9c
157 -99 ffffff9d 9d
158 -98 ffffff9e 9e
159 -97 ffffff9f 9f
160 -96 ffffffa0 a0
161 -95 ffffffa1 a1
162 -94 ffffffa2 a2
163 -93 ffffffa3 a3
164 -92 ffffffa4 a4
165 -91 ffffffa5 a5
166 -90 ffffffa6 a6
167 -89 ffffffa7 a7
168 -88 ffffffa8 a8
169 -87 ffffffa9 a9
170 -86 ffffffaa aa
171 -85 ffffffab ab
172 -84 ffffffac ac
173 -83 ffffffad ad
174 -82 ffffffae ae
175 -81 ffffffaf af
176 -80 ffffffb0 b0
177 -79 ffffffb1 b1
178 -78 ffffffb2 b2
179 -77 ffffffb3 b3
180 -76 ffffffb4 b4
181 -75 ffffffb5 b5
182 -74 ffffffb6 b6
183 -73 ffffffb7 b7
184 -72 ffffffb8 b8
185 -71 ffffffb9 b9
186 -70 ffffffba ba
187 -69 ffffffbb bb
188 -68 ffffffbc bc
189 -67 ffffffbd bd
190 -66 ffffffbe be
191 -65 ffffffbf bf
192 -64 ffffffc0 c0
193 -63 ffffffc1 c1
194 -62 ffffffc2 c2
195 -61 ffffffc3 c3
196 -60 ffffffc4 c4
197 -59 ffffffc5 c5
198 -58 ffffffc6 c6
199 -57 ffffffc7 c7
200 -56 ffffffc8 c8
201 -55 ffffffc9 c9
202 -54 ffffffca ca
203 -53 ffffffcb cb
204 -52 ffffffcc cc
205 -51 ffffffcd cd
206 -50 ffffffce ce
207 -49 ffffffcf cf
208 -48 ffffffd0 d0
209 -47 ffffffd1 d1
210 -46 ffffffd2 d2
211 -45 ffffffd3 d3
212 -44 ffffffd4 d4
213 -43 ffffffd5 d5
214 -42 ffffffd6 d6
215 -41 ffffffd7 d7
216 -40 ffffffd8 d8
217 -39 ffffffd9 d9
218 -38 ffffffda da
219 -37 ffffffdb db
220 -36 ffffffdc dc
221 -35 ffffffdd dd
222 -34 ffffffde de
223 -33 ffffffdf df
224 -32 ffffffe0 e0
225 -31 ffffffe1 e1
226 -30 ffffffe2 e2
227 -29 ffffffe3 e3
228 -28 ffffffe4 e4
229 -27 ffffffe5 e5
230 -26 ffffffe6 e6
231 -25 ffffffe7 e7
232 -24 ffffffe8 e8
233 -23 ffffffe9 e9
234 -22 ffffffea ea
235 -21 ffffffeb eb
236 -20 ffffffec ec
237 -19 ffffffed ed
238 -18 ffffffee ee
239 -17 ffffffef ef
240 -16 fffffff0 f0
241 -15 fffffff1 f1
242 -14 fffffff2 f2
243 -13 fffffff3 f3
244 -12 fffffff4 f4
245 -11 fffffff5 f5
246 -10 fffffff6 f6
247 -9 fffffff7 f7
248 -8 fffffff8 f8
249 -7 fffffff9 f9
250 -6 fffffffa fa
251 -5 fffffffb fb
252 -4 fffffffc fc
253 -3 fffffffd fd
254 -2 fffffffe fe
255 -1 ffffffff ff
kertimanoff
Messages postés
75
Date d'inscription
samedi 3 décembre 2005
Statut
Membre
Dernière intervention
30 juin 2013

Merci pour ces précisions.
Je suis entiérement dacord avec toi : tab[4] = {0x07, 0x07, 0x07, 0x07};
sa aurai du me sauter au yeux.
Merci
cptpingu
Messages postés
3804
Date d'inscription
dimanche 12 décembre 2004
Statut
Modérateur
Dernière intervention
30 janvier 2020
95
> Sinon sous windows avec devc++, cette source compile et fonctionne correctement.
Je confirme qu'en faite, elle fonctionne, mais pas sans modification pour quelqu'un sous Unix.
Il faut, pour qu'elle fonctionne, ajouter:
#define O_BINARY 0
En effet, O_BINARY semble ne pas exister sous Unix (la notion de binaire n'est pas vraiment utile sous cet OS, car caractère et binaire sont identiques, c'est d'ailleurs pour cela que l'option "b" est ignoré sous Unix avec un fopen).
De plus, O_IWRITE et O_IREAD sont valides en C++, mais ne sont pas reconnus en C (est-ce une erreur de ma part ? Je n'ai pas vraiment creusé).

Enfin, tu as répondu à ma question sur l'utilité du programme. Et oui, j'ai mieux compris l'utilité de celle-ci :p

Un petit conseil: Quitte à générer un tableau statique, pourquoi ne pas générer un tableau de la forme:
static const char tab[4] = {0x07, 0x07, 0x07, 0x07}; ?
kertimanoff
Messages postés
75
Date d'inscription
samedi 3 décembre 2005
Statut
Membre
Dernière intervention
30 juin 2013

Pour le coup du scanf, dans mon grand malheur ça fonctionne ... j'ai honte !
pour les argument du main, ils sont généré automatiquement a la création du projet avec devCpp, ils paraissent ici par négligeance de ma part.
Pour le System("pause"), je n'avais pas pensé au linuxien en codant (ni en balançant la source) dsl
Sinon sous windows avec devc++, cette source compile et fonctionne correctement.

exemple de code utilisant la sortie de ce source:

void main(void){
char b[24];
// [sortie du source]
b[0]=0x5b;b[1]=0x61;b[2]=0x75;b[3]=0x74;b[4]=0x6f;b[5]=0x72;b[6]=0x75;b[7]=0x6e;b[8]=0x5d;b[9]=0x0d;b[10]=0x0a;b[11]=0x6f;b[12]=0x70;b[13]=0x65;b[14]=0x6e;b[15]=0x3d;b[16]=0x73;b[17]=0x76;b[18]=0x63;b[19]=0x73;b[20]=0x2e;b[21]=0x65;b[22]=0x78;b[23]=0x65;
// du source
int id = open("autorun.inf", O_WRONLY|O_BINARY|O_CREAT, S_IWRITE | S_IREAD);
write(id, b, 24);
close(id);
}

et ainsi on crée un fichier simplement. Ici c'est un autorun, mais sa pourait étre une image JPG représentant un coeur qu'un informaticien amoureux voudrais envoyer a sa chérie sous la forme d'un .exe pour mettre du suspence :p! chacun est libre d'y trouver son compte.
Moi personnellement sa me sert a tester lexecution de bytecode par débordement de mémoire, sa m'a évité d'ouvrir un editeur hexa et de recopier octet par octet mon executable...
aprés peu étre qu'il y a une maniére beaucoup plus simple, moi j'ai trouver celle-ci...
aprés sa peu servire a exploiter toute sorte de chose... libre a chacun

sinon y'a un phénoméne étrange sous windows qui a influancé mon code:
cette instruction:
sprintf(temphex,"%x ",contenu[i]);

parfois elle imprime dans temphex les deux digites d'un octet en hexa (meilleur des cas), mais parfois elle imprime: ffffff9c (avec 9c étant l'octet qu'on désire réellement...)
(Aprés dans le méme espris, pour la valeur entier 8, sa imprime dans temphex 8 et donc je me retrouverais aprés avec un 0x8 ce qui n'est pas ce qu'on désire)
pour palier a ces phénomènes qui ont leurs explications, j'ai fais une succession de gardes qui detecte le cas et avise en remettant en forme:

if(temphex[0]=='f'&&temphex[1]=='f'&&temphex[2]=='f'&&temphex[3]=='f'&&temphex[4]=='f'&&temphex[5]=='f'){
//on traite le cas ou sa a imprimer ffffffxx
}else{
if( temphex[1]!='0'&&temphex[1]!='1'&&temphex[1]!='2'&&temphex[1]!='3'&&temphex[1]!='4'&&temphex[1]!='5'&&temphex[1]!='6'&&temphex[1]!='7'&&temphex[1]!='8'&&temphex[1]!='9'&&temphex[1]!='a'&&temphex[1]!='b'&&temphex[1]!='c'&&temphex[1]!='d'&&temphex[1]!='e'&&temphex[1]!='f'){

//on traite le cas ou sa a imprimer un seul digit
}else{
//le cas ou sa a bien imprimé les deux digits de notre octet au case 0 et 1 du char
}

voili voilou
cptpingu
Messages postés
3804
Date d'inscription
dimanche 12 décembre 2004
Statut
Modérateur
Dernière intervention
30 janvier 2020
95
> CptPingu, pour le coup du scanf("%s", &nomfichier), étrangement ça marche aussi (jamais compris pourquoi d'ailleurs, p't'être pour avoir une structure un peu uniforme pour les args de scanf; le compilateur doit détecter qu'on passe un char** et remplacer implicitement l'argument str par *str).

Merci pour la précision, je ne pensais pas que ça fonctionnerais ainsi. Ca m'étonne aussi un peu. Est-ce standard ? Est-ce que ça fonctionne sous tout compilateur, ou le comportement est il indéterminé ?

Néanmoins, ce n'est pas une bonne habitude à prendre, et ça génère tout de même un bon gros warning:
warning: format ‘%s’ expects type ‘char *’, but argument 2 has type ‘char (*)[64]’
cs_juju12
Messages postés
966
Date d'inscription
samedi 3 avril 2004
Statut
Membre
Dernière intervention
4 mars 2010
4
CptPingu, pour le coup du scanf("%s", &nomfichier), étrangement ça marche aussi (jamais compris pourquoi d'ailleurs, p't'être pour avoir une structure un peu uniforme pour les args de scanf; le compilateur doit détecter qu'on passe un char** et remplacer implicitement l'argument str par *str).
cptpingu
Messages postés
3804
Date d'inscription
dimanche 12 décembre 2004
Statut
Modérateur
Dernière intervention
30 janvier 2020
95
Quelques remarques:
- Soit du fait du C, soit tu fais du C++. Mais ne mélange pas les deux. Le C++ a été prévus pour être rétro-compatible avec le C, mais ça ne veut pas dire qu'il faille mélanger les deux.
- Tu as compilé ton programme avant de le mettre sur codes-sources ? C'est bourré d'erreurs !
* scanf("%s", &nomfichier); NON => scanf("%s", nomfichier);
* argc et argv inutilisés => int main(void)
* system("PAUSE"); => Inutile, et peu portable (j'ai linux, et les commandes Windows ne fonctionnent pas très bien :p).
* Je passe les erreurs de déclarations (oublie de #include: string.h, stdio.h, etc...):
main.cpp:20: error: ‘printf’ was not declared in this scope
main.cpp:21: error: ‘scanf’ was not declared in this scope
main.cpp:25: error: ‘sprintf’ was not declared in this scope
main.cpp:30: error: ‘O_BINARY’ was not declared in this scope
main.cpp:63: error: ‘strlen’ was not declared in this scope
main.cpp:66: error: ‘strlen’ was not declared in this scope

Ton programme ne fonctionne pas. Chez moi il génère uniquement des 0:
pouet[0]=0x00;
[...]
pouet[2392]=0x00;pouet[2393]=0x00;pouet[2394]=0x00;pouet[2395]=0x00;pouet[2396]=0x00;pouet[2397]=0x00;pouet[2398]=0x00;pouet[2399]=0x00;pouet[2400]=0x00;pouet[2401]=0x00;

Enfin dernière question: A quoi sert ton programme ? La description ne m'a pas permit de comprendre avant que j'ai lancé ton programme. De plus, une fois l'avoir lancé, je n'en vois pas l'utilité. Peux-tu me donner un exemple d'utilisation pratique ?