begin process at 2008 05 16 06:34:22
1 173 219 membres
61 nouveaux aujourd'hui
13 970 membres club

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é: 2 135 / 70

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

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

  • 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

Appels d'offres

Pub



CalendriCode

Mai 2008
LMMJVSD
   1234
567891011
12131415161718
19202122232425
262728293031 

Téléchargements

Boutique

Boutique de goodies CodeS-SourceS