Vous ne trouvez pas de réponse à votre problème ? Alors posez la question dans le forum. Souvenez-vous qu'il n'y a jamais de question bête, mais rester dans l'ignorance parce que l'on n'ose pas poser une question, ça c'est une erreur !

CHAINE EN HEXA (WIN32)


Information sur la source

Catégorie :Chaîne de caractères Classé sous : chaine, hexa, API, ASM Niveau : Débutant Date de création : 11/03/2008 Vu / téléchargé: 4 426 / 133

Note :
10 / 10 - par 2 personnes
10,00 / 10

  • 1

  • 2

  • 3

  • 4

  • 5

  • 6

  • 7

  • 8

  • 9

  • 10

Commentaire sur cette source (17)
Ajouter un commentaire et/ou une note


Description

Cliquez pour voir la capture en taille normale
Pour question récurrente sur forum.

char* __fastcall bnStrToHex(char *szsrc, char* szdst);
retourne pointeur sur fin d'écriture pour chainage direct si besoin.

Prêt à l'emploi, il n'y a plus qu'à utiliser.
 

Fichier Zip

Pour les "Membres Club", vous pouvez télécharger directement un fichier contenu dans le zip sans télécharger le zip en entier !

Télécharger le zip

Commentaires et avis

signaler à un administrateur
Commentaire de Neo_Fr le 11/03/2008 22:50:22

J'allais le faire =), pour ceux que ca interesse une version en C qui encode et decode c'est ici: http://Neo_Fr.fr.nf/Bin2Hex.zip

Neo_Fr

signaler à un administrateur
Commentaire de exar le 12/03/2008 09:38:48

En fait, cette source aurait plus sa place dans la partie "assembler"...  Ce n'est plus du C, si ?

signaler à un administrateur
Commentaire de max12 le 12/03/2008 17:10:08 administrateur CS 10/10

Ça ferais un excellent snippet :P Bon certains aurait de l'urticaire a cause de l'ASM mais tant qu'a avoir du code aussi bien qu'il soit optimisé.

signaler à un administrateur
Commentaire de exar le 12/03/2008 20:20:07 10/10

MAX12: tout-à-fait d'accord, mais sur un code qui ne fait que transformer une chaîne de caractères en hexadécimal, je ne vois pas bien où se situe la gain par rapport au C classique...
J'approuve aussi ta note, parce que techniquement, c'est le top !  Mais je ne vois pas bien l'utilité...
J'utilise aussi parfois l'ASM (bien que rarement), mais pas directement dans le code C (ou C++, que j'utilise plus).
Allez, je vais aussi mettre une excellente note, parce que ce n'est pas la première fois que je vois des codes de BruNews, j'ai vu pas mal de ses commentaires et conseils, et je dois dire que je ne connais PERSONNE qui code aussi bien et aussi proprement.  Je rêverai d'avoir des collègues comme lui ;o)  Au moins, j'apprendrais pas mal de choses, je pense, contrairement aux développeurs chez le client chez qui je suis pour l'instant, qui me font recoder pas mal de choses (code qui fonctionne), simplement parce que, malgré les commentaires, ils ne comprennent rien...  Alors, si je mettais de l'ASM...  Ils m'ont demandé ce que c'était une classe et un objet, parce que j'en ai parlé dans des specs.  Ils n'avaient jamais entendu ce terme...
Bon, j'arrête de causer...  Je suis trop bavard... ;o)
Bonne continuation !

signaler à un administrateur
Commentaire de Ahryman40k le 25/03/2008 10:30:52

Je tente d'utiliser ta fonction assembleur pour convertir une chaine en code hexa, mais il semble y avoir un soucis.

__declspec(naked) char* __fastcall bnStrToHex(char *szsrc, char* szdst)

Mon projet est une application MFC sous VS2003.

lorsque je passe mon parametre szsrc, alloué et renseigné juste avant l'appel, son contenu est "dégradé", au point qu'un delete juste apres l'appel a bnStrToHex fait tout explosé.
Qu'ais-je bien pu oublier ?

exemple :
        char* pHexStr = new char[size*2+1];
char* bufferCpy = new char[size];
::memcpy( bufferCpy, buffer, size ); // buffer est renseigné plus tot dans le code
bnStrToHex( bufferCpy, pHexStr );
// delete bufferCpy;   // fait tout crasher
// bufferCpy = NULL;


merci.

signaler à un administrateur
Commentaire de BruNews le 25/03/2008 10:46:13 administrateur CS

à tester: delete [] bufferCpy;

signaler à un administrateur
Commentaire de Ahryman40k le 25/03/2008 11:16:52

Ca ne change rien, il y a un probleme d'allocation sur le heap.
Mais le contenu de la memoire est etrange.

Je pense que l'attribut "naked", dixit la doc : enleve le prologue et l'epilogue de la fonction, fais que la fonction assembleur est directement executé au coeur même de la fonction appelante ( en clair a la compilation cela ne forme qu'un bloc ), par contre je ne connais pas l'influence du _fastcall.
La doc dis :
The __fastcall calling convention specifies that arguments to functions are to be passed in registers, when possible. The following list shows the implementation of this calling convention.
Le probleme est donc et lorsque ce n'est pas possible ??! :s

Et pourquoi mon delete crash et pourquoi j'ai une heap exception ? ><'' Y a t'il une methode ALL C/C++ qui pourrait me faire la même chose, car bien que le resultat attendue soit correct, ca bug dans mon code quand même :/

signaler à un administrateur
Commentaire de BruNews le 25/03/2008 11:39:52 administrateur CS

Les params passent en registre (ECX et EDX) à tout coup pour cette fonction, le prob ne peut pas venir de cela.
'naked' ne spécifie pas 'inline' donc pas d'exécution DANS l'appelant. Il empêche simplement le compilo d'y toucher (prologue, épilogue et autres arguties).

Dans tous les cas, faut trouver le prob dans ton code appelant. J'ai ce genre de fonction qui tourne en prod sur de gros serveurs depuis fort longtemps sans l'ombre d'un soucis.

signaler à un administrateur
Commentaire de Ahryman40k le 25/03/2008 14:02:55

En fait je genere un .reg à partir de plusieurs informations. T'as methode est donc utile pour creer une clef du genre :

"BB1"=hex:fc,03,d0,ac,05,89,47,d0,fe,62,00,2e,fa,64,82,20

Lorsque je debogue, quelque chose m'intrique, c'est que la le parametre szsrc n'a rien a voir avec le pointeur que je lui ai passé ... Soit le parametre bufferCpy qui est passé à ta methode.

Je te donne un exemple qui reproduit le crash
j'ai crée un simple projet console avec VS2003.
//***********************************************************************************//
#include <stdio.h>
#include <stdarg.h>
#include <ctime>
#include <string>
#include <tchar.h>
#include <map>
#include <set>
#include <assert.h>
#include <typeinfo.h>
#include <fstream>
#include <sstream>

__declspec(naked) char* __fastcall bnStrToHex(char *szsrc, char* szdst)
{ // ECX = szsrc, EDX = szdst
__asm
{
mov       [esp-4], esi
mov       esi, ecx
fromSRC:
mov       al, [esi]
test      al, al
je        short strEXIT
mov       cl, al
add       edx, 2
and       cl, 15
shr       al, 4
add       cl, 48
add       al, 48
cmp       cl, 57
jbe       short L1
add       cl, 7
L1:
cmp       al, 57
jbe       short L2
add       al, 7
L2:
add       esi, 1
mov       byte ptr[edx-2], al
mov       byte ptr[edx-1], cl
jmp       short fromSRC
strEXIT:
mov       byte ptr[edx], 0
mov       esi, [esp-4]
mov       eax, edx
ret       0
}
}



std::string string_hex
(
const char* buffer,
const size_t& size
)
{    
char* pHexStr = new char[size*2+1];
char* bufferCpy = new char[size];
::memcpy( bufferCpy, buffer, size );

bnStrToHex( bufferCpy, pHexStr );

// TODO !!
// Attention il faut deleter pHexStr et BufferCpy !!!!

(&*pHexStr)[size*2] = '\0';

std::ostringstream oss; //initialise un string stream qui stock la sortie de std::hex
unsigned int i = 0;
for
(
char* c = pHexStr;
i < size*2;
i++
)
{
if ( i != 0 )
oss << _T(",");

oss << c[i];
oss << c[++i];
}

return oss.str();
}



int _tmain(int argc, _TCHAR* argv[])
{
try
{
std::fstream stream( "C:\\Config.reg", std::ios_base::binary | std::ios_base::out | std::ios_base::trunc );  

std::string  header = _T("Windows Registry Editor Version 5.00\n");
stream.write( header.c_str(), header.size()  );

header = _T("\n");
stream.write( header.c_str(), header.size()  );

std::string  agentKey = _T("[HKEY_LOCAL_MACHINE\\SOFTWARE\\Medialive\\Agent]\n");
stream.write( agentKey.c_str(), agentKey.size()  );

std::ostringstream version;
version << _T("\"Version\"=\"") << "3.1" << _T("\"\n");
stream.write( version.str().c_str(), version.str().size()  );

std::ostringstream bbpath;
bbpath << _T("\"BBPath\"=\"") << "C:\\azerty.bb" << _T("\"\n");
stream.write( bbpath.str().c_str(), bbpath.str().size() );

std::ostringstream agentPath;
agentPath << _T("\"MedialiveAgent\"=\"") << "C:\\azerty.dll" << _T("\"\n");
stream.write( agentPath.str().c_str(), agentPath.str().size()  );

std::ostringstream gbbKey;

gbbKey << _T("\"BB1\"=hex:") << string_hex
(
"_Ahryman__40000_",
16
) << _T("\n");

stream.write( gbbKey.str().c_str(), gbbKey.str().size() );

std::ostringstream gbbChecksum;
gbbChecksum << _T("\"BB2\"=hex:") + string_hex
(
"_Ahryman__40000_",
16
) << _T("\n");
stream.write( gbbChecksum.str().c_str(), gbbChecksum.str().size()  );

std::string  initKey = _T("\"InitialKey\"=hex:00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00\n");
stream.write( initKey.c_str(), initKey.size()  );
std::string  defaultId = _T("\"DefaultID\"=hex:00,00,00,00\n");
stream.write( defaultId.c_str(), defaultId.size()  );

stream.close();
}
catch( ... )
{
assert ( false );
}

return 0;
}
//************************************************************************************//

signaler à un administrateur
Commentaire de BruNews le 25/03/2008 14:21:41 administrateur CS

Si tu me mets tout cela en PSEUDO code avec exemple de ce qu'il faut obtenir, je te le refais en vrai code (plus de stream, string et autres couches d'interprétation qui ont peu à faire dans du Windows).

signaler à un administrateur
Commentaire de BruNews le 25/03/2008 14:38:51 administrateur CS

OK j'ai décortiqué tout ce sabir, je te fais cela.

signaler à un administrateur
Commentaire de BruNews le 25/03/2008 15:38:15 administrateur CS

Windows Registry Editor Version 5.00

[HKEY_LOCAL_MACHINE\SOFTWARE\Medialive\Agent]
"Version"="3.1"
"BBPath"="C:\azerty.bb"
"MedialiveAgent"="C:\azerty.dll"
"BB1"=hex:string_hex("_Ahryman__40000_", 16)
"BB2"=hex:string_hex("_Ahryman__40000_", 16)
"InitialKey"=hex:00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00
"DefaultID"=hex:00,00,00,00

CODE POUR OBTENIR CELA:
const char szREGEDIT[] = "Windows Registry Editor Version 5.00\r\n\r\n"; // len = 40
const char szHKLMMDLV[] = "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Medialive\\Agent]\r\n"; // len = 47
const char szVERSION31[] = "\"Version\"=\"3.1\"\r\n"; // len = 17
const char szBBPATH[] = "\"BBPath\"=\"C:\\azerty.bb\"\r\n"; // len = 25
const char szMDLV[] = "\"MedialiveAgent\"=\"C:\\azerty.dll\"\r\n"; // len = 34
const char szBB1HEX[] = "\"BB1\"=hex:";

int __stdcall FaireFichierReg()
{
  HANDLE hfl;
  char szhex[36], buf[100], *c, *d;
  DWORD v, i;
  
  hfl = CreateFile("D:\\Config.reg", GENERIC_WRITE, 0, 0, CREATE_ALWAYS, 0, 0);
  if(hfl == INVALID_HANDLE_VALUE) return 0;
  WriteFile(hfl, szREGEDIT, 40, &v, 0);
  WriteFile(hfl, szHKLMMDLV, 47, &v, 0);
  WriteFile(hfl, szVERSION31, 17, &v, 0);
  WriteFile(hfl, szBBPATH, 25, &v, 0);
  WriteFile(hfl, szMDLV, 34, &v, 0);
  
  bnStrToHex("_Ahryman__40000_", szhex); // 1 SEULE FOIS, SORT 32 OCTETS ICI
  
  c = (char*) szBB1HEX;
  d = buf;
  while(*d = *c) {d++; c++;} // RECOPIE, d EST POINTEUR D'ECRITURE
  c = szhex;
  i = 16; // strlen("_Ahryman__40000_")
  do { // COPIE DE 2 OCTETS DE szhex A CHAQUE TOUR
    *d++ = *c++;
    *d++ = *c++;
    *d++ = ',';
  } while(--i);
  *(d-1) = '\r';  // ON SORT AVEC 1 VIRGULE EN TROP, ON ECRASE
  *d++ = '\n';
  WriteFile(hfl, buf, d - buf, &v, 0);
  
  // POUR BB2 QUI EST IDEM
  buf[3] = '2';
  WriteFile(hfl, buf, d - buf, &v, 0);
  
  // JE STOPPE ICI, LE RESTE EST TRIVIAL ET DEJA FAIT PLUS HAUT
  return CloseHandle(hfl);
}

En quoi est-ce plus compliqué de coder un peu ?
Quand on réalise qu'on peut tout maitriser et qu'il y a énorme benef de perfs et taille code, il n'y a plus à se poser la question.

signaler à un administrateur
Commentaire de BruNews le 25/03/2008 15:42:01 administrateur CS

OUPS, c'est

Windows Registry Editor Version 5.00

[HKEY_LOCAL_MACHINE\SOFTWARE\Medialive\Agent]
"Version"="3.1"
"BBPath"="C:\azerty.bb"
"MedialiveAgent"="C:\azerty.dll"
"BB1"=hex:5F,41,68,72,79,6D,61,6E,5F,5F,34,30,30,30,30,5F
"BB2"=hex:5F,41,68,72,79,6D,61,6E,5F,5F,34,30,30,30,30,5F

qu'on obtient avec code plus haut.

signaler à un administrateur
Commentaire de Ahryman40k le 25/03/2008 16:49:10

Merci, grace à ton exemple j'ai mis en evidence le probleme avec ta methode bnStrToHex.

Le premier exemple provient de ton exemple et fonctionne
//*******************************************************************//
char* szhex = new char[36];
char* buf = new char[100];
bnStrToHex("_Ahryman__40000_", szhex); // 1 SEULE FOIS, SORT 32 OCTETS ICI
delete[] szhex;
delete[] buf;
//*******************************************************************//

Celui-ci est pratiquement identique mis a part le fait que je ne passe pas une chaine constante mais un pointeur contenant ma chaine:
*******************************************************************//
char* szhex = new char[36];
char* bufferCpy = new char[16];
::memcpy( bufferCpy, "__Ahryman_40000_", 16 );
bnStrToHex( bufferCpy, szhex ); // Ici ma chaine n'est pas terminée par '\0' d'ou le crash !!! J'ai donc besoin d'un tableau de taille 17 et d'inserer le caractere de fin de chaine.
delete[] bufferCpy;
delete[] szhex;

Donc finalement pour que cela fonctionne correctement, il faut appeler la methode comme suis en s'assurant que le parametre d'entrée est bien une chaine avec caractere de fin.
//************************************************************************************//
char* szhex = new char[36];
char* bufferCpy = new char[17];
::memcpy( bufferCpy, "_Ahryman__40000_", 17 );
bufferCpy[16] = '\0';
bnStrToHex( bufferCpy, szhex );
delete[] bufferCpy; // ca ne pete plus -_-''
delete[] szhex;

J'ai donc une derniere question à te poser,
mon besoin final est d'avoir la même methode bnStrToHex prenant en plus la taille de la chaine que je veux traiter (plutot que de s'arreter au caracetre de fin de chaine). Dans mon prog bufferCpy pourra contenir en plein milieu ce caractere de fin de chaine, car c'est une valeur sur 16 caracteres generée aleatoirement. Or j'ai besoin de recuperer le code hexa de l'integralité de ces caracteres.

Merci.

signaler à un administrateur
Commentaire de Neo_Fr le 25/03/2008 17:03:38

Prend la taille du buffer en parametre:

void __stdcall Bin2Hex(BYTE* lpIn, DWORD dwInSize, BYTE* lpOut)
{
static const BYTE HexaTable[16] = { 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
                                            0x38, 0x39, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66 };
    DWORD i = (dwInSize-1);
    while(1)
{
        lpOut[2*i] = HexaTable[(lpIn[i] >> 4) & 0x0F];
        lpOut[2*i+1] = HexaTable[(lpIn[i]) & 0x0F];
if(!i--) break;
    }
}

Neo_Fr

signaler à un administrateur
Commentaire de BruNews le 25/03/2008 17:10:00 administrateur CS

A TESTER mais devrait aller:
__declspec(naked) char* __fastcall bnStrToHex(char *szsrc, char* szdst, DWORD lensrc)
{ // ECX = szsrc, EDX = szdst, [esp+4] = lensrc
  __asm {
    mov       [esp-4], esi
    mov       [esp-8], ebx
    mov       esi, ecx
    mov       ebx, [esp+4]
fromSRC:
    mov       al, [esi]
    mov       cl, al
    add       edx, 2
    and       cl, 15
    shr       al, 4
    add       cl, 48
    add       al, 48
    cmp       cl, 57
    jbe       short L1
    add       cl, 7
L1:
    cmp       al, 57
    jbe       short L2
    add       al, 7
L2:
    add       esi, 1
    mov       byte ptr[edx-2], al
    mov       byte ptr[edx-1], cl
    sub       ebx, 1
    jne       short fromSRC
strEXIT:
    mov       byte ptr[edx], 0
    mov       esi, [esp-4]
    mov       ebx, [esp-8]
    mov       eax, edx
    ret       4
  }
}

ATTENTION que je ne teste pas si lensrc > 0 en entrée.

signaler à un administrateur
Commentaire de Ahryman40k le 25/03/2008 17:19:52

Ha bein oui nickel,
ca marche tres bien ca.

Merci ^^

Ajouter un commentaire

Discussions en rapport avec ce code source dans le forum

chaine binaire en chaine hexa [ par thomas59553 ] bonjour a tous ;)je cherche une methode permettant de convertir une chaine binaire en une chaine hexale contenu de la chaine binaire est deja verifiee Copie d'une chaine Hexa dans une Chaine de caractères [ par lyde ] Bonjour,je souhaiterais copier la chaine hexa "010601AE0205040045" dans une variable de type TCHAR * qui est quasiment equivalente a un char *.Cependa API Windows récuperation de la taille d'une chaine pour ecrire [ par LouisJean ] Bonjour a tous je début en programmation. j'ai fait un peut en JAVA et maintenant DEV C++ Je n'arrive pas a faire marcher le «  GetTextExtentP conversion string (binaire) to string (hexa) [ par janiaut ] Bonjour, voila je susi toujours dans mon big programme, j'ai un petit problème sur une conversion d'un string (de mot binaire) en conversion de string Convertir chaine en hexa [ par cartes1 ] BonjourDébutant en C++ avec visual studio 6 sous windows je désire savoir s'il existe un moyen simple d'affecter à une variable le contenu en hexa d'u convertir une chaine de caractère (hexa) en int [ par MrDimanche ] Voila,Mon problème est simple.Dans une string (char[100]), j'ai ceci : E9876. Je voudrais obtenir sa valeur en int. Comment faire, j'ai beau chercher Lire et modifier la RAM [ par bilaloch ] Bonjour à tous,J'aimerais savoir s'il y a une possibilité pour que, à travers le C++ (ou l'ASM d'ailleurs, je poste ce message sur le forum de l'ASM é [API WIN32] Générer un pdf [ par tarretg ] Bonjour à tous, Je développe actuellement un exécutable en Win32 sous Visual C++. Je voudrais générer un rapport en pdf des calculs effectués par l'u Traitement de chaine de caractères [ par RoulianRoss ] Bonjour, j'ai une chaine de caractère du type PUSH_essai et je veux enlever le préfixe PUSH_ de cette chaine. comment puis-je faire???? Merci Différence Fichier - Dossier [ par Spoolega ] Bonjour,J'ai créé une fonction qui me permet de savoir si l'argument que je lui passe (c'est une chaine de caractères) est l'emplacement d'un fichier


Nos sponsors

Sondage...

CalendriCode

Juillet 2009
LMMJVSD
  12345
6789101112
13141516171819
20212223242526
2728293031  

Consulter la suite du CalendriCode

Téléchargements

Logiciels à télécharger sur le même thème :

Comparez les prix Nouvelle version

Photothèque Nouveau !



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
Temps d'éxécution de la page : 0,686 sec

Google Coop CodeS-SourceS Google Coop CodeS-SourceS


Certaines images présentes sur le site (notament certains avatars) sont issues des collections IconShock, donc si vous souhaitez utiliser ces icons vous devez les acheter, ne les copiez pas et ne utilisez pas dans vos sites et applications sans les avoir commandé.