lundi 29 mai 2017

Shellcode utilisant des Hash ROL3


Introduction


Nous avons trouvé plusieurs sources sur Internet de shellcode utilisant des hashs moins current basé sur ROL3
nous avons également trouver les deux variantes CallApi(...) et la fonction autonome de génération du hash en Rol3. Ainsi que la classique api GetProcAddrByRol3(...)

Nous avons prendre comme exemple la page  "http://bbs.pediy.com/thread-126839.htm"
qui fait l'équivalent de WinExec("E:\\2.EXE",SW_SHOW); pour notre analyse des HashRol3 et remonter à une fonction C.

Analyse par l'exemple


Exemple d'un bloc du shellcode qui nous intéresse plus particulièrement dans ce shellcode sera le suivant:

\x64\xA1\x30\x00\x00\x00\x8B\x40\x0C\x8B\x40\x1C\x8B\x00\x8B\x40
\x08\x68\x4B\xF7\x6E\x01\x50\xE8\x57\x00\x00\x00\x90\xE8\x0B\x00
\x00\x00\x45\x3A\x5c\x5c\x32\x2E\x65\x78\x65\x00\x00\x5D\x6A\x00
\x55\xFF\xD0

Nous l'avons transcrit en assembleur via un outil perso. Cela nous donne le code assembleur suivant:
 
00000000:   64 A1 30 00 00 00      MOV EAX,DWORD PTR FS:[00000030]
00000006:   8B 40 0C                  MOV EAX,[EAX+0Ch]
00000009:   8B 40 1C                  MOV EAX,[EAX+1Ch]
0000000C:   8B 00                      MOV EAX,DWORD PTR DS:[EAX]
0000000E:   8B 40 08                  MOV EAX,[EAX+08h]
00000011:   68 4B F7 6E 01          PUSH 016EF74Bh
00000016:   50                                PUSH EAX
00000017:   E8 57 00 00 00          CALL 00000057h
0000001C:   90                           NOP
0000001D:   E8 0B 00 00 00 CALL 0000000Bh
                                      db "E:\\2.exe"
00000022:  45 3A 5C 5C 32 2E 65 78 65 00
0000002C:   00                          
0000002D:   5D                          POP EBP
0000002E:   6A 00                      PUSH 0h
00000030:   55                           PUSH EBP
00000031:   FF D0                      CALL EAX

Mais vous pourrez voir que sur plusieurs autres site l'utilisation de hash Rol3 avec la même structure d'appel comme sur le blocs de code fournit par la page  "http://www.sgoldcn.com/simple/?t329.html" 

00408C58   . 55                  PUSH EBP
00408C59   . 8BEC              MOV EBP,ESP
00408C5B   . 83EC 20         SUB ESP,20
00408C5E   . 53                  PUSH EBX
00408C5F   . 56                  PUSH ESI
00408C60   . 57                  PUSH EDI
00408C61   . E8 22010000   CALL WRAR39~1.00408D88
00408C66   . 8BF0               MOV ESI,EAX
00408C68   . 68 89FD12A4   PUSH A412FD89
00408C6D   . 56                  PUSH ESI
00408C6E   . 8975 EC          MOV DWORD PTR SS:[EBP-14],ESI
00408C71   . E8 52010000   CALL WRAR39~1.00408DC8
00408C76   . 68 19D0D602   PUSH 2D6D019
00408C7B   . 56                   PUSH ESI
00408C7C   . 8BF8               MOV EDI,EAX
00408C7E   . E8 45010000   CALL WRAR39~1.00408DC8
00408C83   . BB 60A90010   MOV EBX,1000A960
00408C88   . 81EB 00A20010 SUB EBX,1000A200
00408C8E   . 53                   PUSH EBX
00408C8F   . 6A 40               PUSH 40
00408C91   . FFD0                CALL EAX
00408C93   . 8945 F8           MOV DWORD PTR SS:[EBP-8],EAX
00408C96   . E8 AD010000   CALL WRAR39~1.00408E48
00408C9B   . 8945 F0           MOV DWORD PTR SS:[EBP-10],EAX
00408C9E   . 90                   NOP
00408C9F   . 90                   NOP
00408CA0   . 90                   NOP
00408CA1   . B1 6C              MOV CL,6C
00408CA3   . 32C0               XOR AL,AL
00408CA5   . C645 E0 73      MOV BYTE PTR SS:[EBP-20],73
00408CA9   . C645 E1 68      MOV BYTE PTR SS:[EBP-1F],68
00408CAD   . 884D E2          MOV BYTE PTR SS:[EBP-1E],CL

 Nous avons mis en rouge les deux parties qui nous intéressent le plus avec le mode d'appel et les deux hashs 016EF74B  et  A412FD89

Extraction des APIs correspondant au Hash

Nous avons passer ces Hash dans notre outil ApiHashPredator.exe























Nous avons fait de même avec le hash A412FD89 qui nous a donné la Api correspondante  "LoadLibraryA"

Nous avons passer quelques fonctions qui sont souvent appeler dans des shellcodes pour crée un petit tableau de référence
Hash Value
Dll
Api Function
016EF74B
Kernel32.dll
WinExec
A412FD89
Kernel32.dll
LoadLibraryA
16118A5D
Urlmon.dll
URLDownloadToFileA
14D14C51
User32.dll
MessageBoxA

Maintenant regardons la façon dont est utilisé ses hashs dans ses deux shellcodes

68 4B F7 6E 01         PUSH 016EF74Bh
50                               PUSH EAX
E8 57 00 00 00         CALL 00000057h

Lorsque ces instruction sont exécutées, il en résulte que la pile lorsqu'elle arrive sur le code de la subroutine à l'adresse 0x00000057  ce compose comme suit



 Vu les deux shellcodes EAX contient le hModule de Kernel32.dll

Nous pouvons déduire de la que les deux calls sont sur  le même type de fonction qui est

DWORD GetProcAddressByHashRol3(HMODULE hMod,DWORD dwHashRol3 );

dans le bloc de la subroutine un call est également effectué vers une sur subroutine  que nous avons extrait du deuxième shellcode qui semble assez intéressante

\x55\x8B\xEC\x8B\x45\x08\x52\x33\xD2\xC1\xC2\x03\x32\x10\x40\x80
\x38\x00\x75\xF5\x8B\xC2\x5A\xC9\xC3

Nous l'avons transcrit en assembleur via un outil perso. Cela nous donne le code assembleur suivant:

00000000:   55                       PUSH EBP
00000001:   8B EC                MOV EBP,ESP
00000003:   8B 45 08                        MOV EAX,DWORD PTR [EBP+08h]
00000006:   52                       PUSH EDX
00000007:   33 D2                  XOR EDX,EDX
00000009:   C1 C2 03           ROL EDX,03h (3 en décimale)
0000000C:   32 10                  XOR DL,BYTE PTR[EAX]
0000000E:   40                       INC EAX
0000000F:   80 38 00             CMP BYTE PTR [EAX],00h
00000012:   75 F5                  JNZ F5h (rel8)(-0Bh ->:00000009)
00000014:   8B C2                 MOV EAX,EDX
00000016:   5A                      POP EDX
00000017:   C9                      LEAVE ( equivaut MOV ESP,EBP / POP EBP) en X86
00000018:   C3                       RET

Nous avons mis en bleu le prologue et épilogue de la fonction comme le bloc utilise le registre EDX pour travailler. Nous voyons la sauvegarde et restauration de sa valeur en début et fin de traitement de la fonction en orange.

La fonction n'a qu'un paramètre passé et renvoi un DWORD. Vu que le traitement étant sur des bytes on peut dire que le paramétres passer est un pointeur vers un char

donc la fonction est de la forme DWORD fonctionX(char* pC )

Test de la fonction en environnement C++

Nous avons porté ce code dans Visual Studio pour tester la fonction

DWORD __declspec(naked)GetHash_MalwareRef1_Asm_V2(const char* pFunction)
{
            __asm
            {
                        PUSH EBP
                        MOV EBP,ESP
                        MOV EAX,DWORD PTR[EBP+0x08]
                        PUSH EDX
                        XOR EDX, EDX
                        NextCharString:
                        ROL EDX,3  
                        XOR DL,[EAX]
                        INC EAX
                        CMP BYTE PTR[EAX],0x0
                        JNZ SHORT NextCharString
                        MOV EAX,EDX
                        POP EDX
                        LEAVE
                        RETN
            }
}

 voici le résultat du programme de test, après execution


 la transcription du code Assembleur en code C est assez simple dont voici la transposition

DWORD GetHash_MalwareRef1_C_V2(const char* pFunction)
{
      DWORD dwHashRol3 = 0x0;

         do
        {
            dwHashRol3 = ((dwHashRol3 << 3) & (DWORD)(-1))|(dwHashRol3 >> (32-3));
            dwHashRol3 = dwHashRol3 ^ (*pFunction);  // ^ est l'opérateur "ou exclusif binaire"
            pFunction++;
         }while(*pFunction);

      return dwHashRol3;
}

Il faut voir que l'utilisation du registre EDX correspond à l'utilisation d'une variable local à la fonction EDX correspond à notre dwHashRol3

que la boucle do / while est notre JNZ en assembleur

Revenons maintenant au premier shellcode initial  analyse, nous avons la fin du shellcode qui est proche de la fonction décoder du second. Comme vous pouvez le voir dans la capture écran.


Nous avons transcrit cette fonction dans Visual Studio pour évalué sont résultat

DWORD __declspec(naked)GetHash_MalwareRef1_Asm_V3(const char* pFunction)
{
        __asm
       {
            POP ECX
            POP EAX
            PUSH EAX     //> Rajouter pour éviter les soucis de Pile en sortie de fonction
            PUSH ECX
            PUSH ESI
            XOR EDX,EDX
            XCHG EAX,ESI
            CLD
NextCharString:
            LODSB
            TEST AL,AL
            JZ finish
            ROL EDX,03h
            XOR DL,AL
            JMP NextCharString
finish:
            XCHG EAX,EDX
            POP ESI
            RET
       }
}

Nous avons intégré au testeur des fonctions hash Rol3

Tableau de hash Rol3 détecté dans des shellcodes

Voilà cela nous a permit de faire un tour sur ce type de hash Rol3. Delà il vous sera facile de trouver différente source utilisant ce type de hash Rol3

Dont par exemple si vous regardé la page "http://www.52pojie.cn/thread-59301-1-1.html"

Vous aurez un panel de ce type de hash utilisé complétant notre tableaux initial

Hash Value
Dll
Api Function
016EF74B
Kernel32.dll
WinExec
A412FD89
Kernel32.dll
LoadLibraryA
16118A5D
Urlmon.dll
URLDownloadToFileA
14D14C51
User32.dll
MessageBoxA
C5FF2F46
Kernel32.dll
VirtualProtect
38C62A7A
Kernel32.dll
CreateFileA
9554EFE7
Kernel32.dll
GetFileSize
A9D1FD70
Kernel32.dll
SetFilePointer
0BE25545
Kernel32.dll
ReadFile
02D6D019
Kernel32.dll
LocalAlloc
C0D6D616
Kernel32.dll
CloseHandle
405AD3CD
Kernel32.dll
LocalFree

dimanche 14 mai 2017

Shellcode en X64 "MessageBoxA"

Nous allons utiliser les mêmes techniques que sous X32 en portant les fonctions en X64

Disposer d'une fonction pour obtenir le HMODULE sur Kernel32.dll
cela grâce à une GetKernel32(..) en X64 que l'on nommera GetKernel32InX64
pour la partie API obtention des APIs qui nous serons utile
nous utiliserons des HASH et la fonction GetProcAddressByHashROR13Additive(..) en X64
Que l'on nommera  GetProcAddressByHashROR13AdditiveInX64V1

le pseudo code du shellcode sera

// Obtention du HMODULE de kernel32.dll
RAX = GetKernel32InX64(void)
// Obtention de la fonction "LoadLibraryA"
RAX = GetProcAddressByHashROR13AdditiveX64(RAX,0xEC0E4E8E )
// Appeler la fonction charger "user32.dll" et obtenir son HMODULE
RAX = LoadLibraryA("user32.dll")
// Obtenir la fonction "MessageBoxA"
RAX = GetProcAddressByHashROR13AdditiveInX64V1(RAX,0xBC4DA2A8 )
// Enfin appeler la fonction
// MessageBoxA(NULL,">X64 Sample: MessageBoxA<","<9B113D1A>",MB_OK);

Pour cela nous avons besoin d'une fonction HMODULE GetKernel32InX64(void) en X64

Dont voici le code assemble en X64 ( Intel )

PUSH RSI
PUSH RDI
PUSH RBX
XOR RBX,RBX
PUSH 30h
POP RAX
MOV RSI,QWORD PTR gs:[RAX]
MOV RAX,QWORD PTR[RSI+60h]
MOV RAX,QWORD PTR[RAX+18h]
MOV RSI,qword ptr [RAX+10h]
NextModule:
MOV RDI,QWORD PTR[RSI+60h]
MOV RAX,QWORD PTR[RSI+30h]
MOV RSI,[RSI]
CMP BYTE PTR[RDI+18h], BL
JNZ NextModule
POP RBX
POP RDI
POP RSI
RET

Pour la fonction

DWORD64 GetProcAddressByHashROR13AdditiveInX64V1(HMODULE hMod,
                                                                                                              DWORD dwHash);

Nous expliquerons dans un autre article comment la crée, mais étant un peut longue l'intérêt assez limité. Pour le principe, elle a été généré à partir d'un code C via Microsoft Visual Studio qui est une technique très utilisé pour générer des bloques de Shellcode dans le monde Windows.

Nous avons mis le shellcode résultant globale dans un tableau en C avec des couleurs pour vous permettre de bien distinguer les différents blocs du Shellcode X64

unsigned char MessageBox64bitV1_sc[] =
"\x48\x83\xEC\x28"
"\x48\x83\xE4\xF0"
"\xE8\xE9\x01\x00\x00"
"\xBA\x8E\x4E\x0E\xEC"
"\x48\x89\xC1"
"\xE8\x68\x00\x00\x00"
"\xEB\x27"
"\x59"
"\xFF\xD0"
"\xBA\xA8\xA2\x4D\xBC"
"\x48\x89\xC1"
"\xE8\x56\x00\x00\x00"
"\x48\x89\xC3"
"\x4D\x31\xC9"
"\xEB\x1F"
"\x41\x58"
"\xEB\x3A"
"\x5A"
"\x48\x31\xC9"
"\xFF\xD3"
"\x48\x83\xC4\x28"
"\xC3"
"\xE8\xD4\xFF\xFF\xFF"
"\x75\x73\x65\x72\x33\x32\x2E\x64\x6C\x6C\x00"
"\xE8\xDC\xFF\xFF\xFF"
"\x3E\x58\x36\x34\x20\x53\x61\x6D\x70\x6C\x65\x3A\x20\x4D\x65\x73"
"\x73\x61\x67\x65\x42\x6F\x78\x41\x3C\x00"
"\xE8\xC1\xFF\xFF\xFF"
"\x3C\x39\x42\x31\x31\x33\x44\x31\x41\x3E\x00"
"\x89\x54\x24\x10\x48\x89\x4C\x24\x08\x48\x83\xEC\x68\x48\xC7\x44"
"\x24\x18\x00\x00\x00\x00\x48\x8B\x44\x24\x70\x48\x89\x44\x24\x08"
"\x48\x8B\x44\x24\x08\x48\x63\x48\x3C\x48\x8B\x44\x24\x08\x48\x03"
"\xC1\x48\x89\x04\x24\x48\x8B\x04\x24\x48\x05\x88\x00\x00\x00\x48"
"\x89\x44\x24\x10\x48\x8B\x44\x24\x10\x83\x38\x00\x0F\x84\x18\x01"
"\x00\x00\x48\x8B\x44\x24\x10\x8B\x08\x48\x8B\x44\x24\x08\x48\x03"
"\xC1\x48\x89\x44\x24\x20\x48\x8B\x44\x24\x20\x8B\x48\x20\x48\x8B"
"\x44\x24\x08\x48\x03\xC1\x48\x89\x44\x24\x30\x48\x8B\x44\x24\x20"
"\x8B\x48\x24\x48\x8B\x44\x24\x08\x48\x03\xC1\x48\x89\x44\x24\x28"
"\x48\x8B\x44\x24\x20\x8B\x48\x1C\x48\x8B\x44\x24\x08\x48\x03\xC1"
"\x48\x89\x44\x24\x38\xC7\x44\x24\x40\x00\x00\x00\x00\xEB\x0B\x8B"
"\x44\x24\x40\x83\xC0\x01\x89\x44\x24\x40\x48\x8B\x44\x24\x20\x8B"
"\x40\x18\x39\x44\x24\x40\x0F\x83\x9E\x00\x00\x00\x8B\x4C\x24\x40"
"\x48\x8B\x44\x24\x30\x8B\x0C\x88\x48\x8B\x44\x24\x08\x48\x03\xC1"
"\x48\x89\x44\x24\x48\xC7\x44\x24\x50\x00\x00\x00\x00\x48\x8B\x44"
"\x24\x48\x0F\xBE\x00\x85\xC0\x74\x3E\x48\x8B\x44\x24\x48\x0F\xBE"
"\x00\x89\x44\x24\x54\x48\x8B\x44\x24\x48\x48\x83\xC0\x01\x48\x89"
"\x44\x24\x48\x8B\x44\x24\x50\xC1\xE8\x0D\x8B\x4C\x24\x50\xC1\xE1"
"\x13\x0B\xC1\x89\x44\x24\x50\x8B\x4C\x24\x54\x8B\x44\x24\x50\x03"
"\xC1\x89\x44\x24\x50\xEB\xB6\x8B\x44\x24\x78\x39\x44\x24\x50\x75"
"\x24\x8B\x4C\x24\x40\x48\x8B\x44\x24\x28\x0F\xB7\x0C\x48\x48\x8B"
"\x44\x24\x38\x8B\x0C\x88\x48\x8B\x44\x24\x08\x48\x03\xC1\x48\x89"
"\x44\x24\x18\xEB\x05\xE9\x45\xFF\xFF\xFF\x48\x8B\x44\x24\x18\x48"
"\x83\xC4\x68\xC3"
"\x56\x57\x53\x48\x33\xDB\x6A\x30\x58\x65\x48\x8B\x30\x48\x8B\x46"
"\x60\x48\x8B\x40\x18\x48\x8B\x70\x10\x48\x8B\x7E\x60\x48\x8B\x46"
"\x30\x48\x8B\x36\x38\x5F\x18\x75\xF0\x5B\x5F\x5E\xC3";


 Nous avons passer dans un outil pour vous faire sortir les blocs de couleur

Pour le test du shellcode X64


Créer à partir de visual studio un projet "StarterShellcodeX64_MessageBoxA"

New Project\Win32 - Projet Win32 ( Projet Vide )

Puis ajouter un fichier code .cpp nommé "StarterShellcodeX64_MessageBoxA.cpp"

et copier le code dans le fichier

 

#define WIN32_LEAN_AND_MEAN             // Exclure les en-têtes Windows rarement utilisés
// Fichiers d'en-tête Windows :
#include <windows.h>

// Fichiers d'en-tête C RunTime
#include <stdlib.h>
#include <malloc.h>
#include <memory.h>
#include <tchar.h>

int APIENTRY _tWinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPTSTR lpCmdLine,int nCmdShow)
{
                unsigned char MessageBox64bitV1_sc[] =
                "\x48\x83\xEC\x28"
                "\x48\x83\xE4\xF0"
                "\xE8\xE9\x01\x00\x00"
                "\xBA\x8E\x4E\x0E\xEC"
                "\x48\x89\xC1"
                "\xE8\x68\x00\x00\x00"
                "\xEB\x27"
                "\x59"
                "\xFF\xD0"
                "\xBA\xA8\xA2\x4D\xBC"
                "\x48\x89\xC1"
                "\xE8\x56\x00\x00\x00"
                "\x48\x89\xC3"
                "\x4D\x31\xC9"
                "\xEB\x1F"
                "\x41\x58"
                "\xEB\x3A"
                "\x5A"
                "\x48\x31\xC9"
                "\xFF\xD3"
                "\x48\x83\xC4\x28"
                "\xC3"
                "\xE8\xD4\xFF\xFF\xFF"
                "\x75\x73\x65\x72\x33\x32\x2E\x64\x6C\x6C\x00"
                "\xE8\xDC\xFF\xFF\xFF"
                "\x3E\x58\x36\x34\x20\x53\x61\x6D\x70\x6C\x65\x3A\x20\x4D\x65\x73\x73\x61\x67\x65\x42\x6F\x78\x41\x3C\x00"
                "\xE8\xC1\xFF\xFF\xFF"
                "\x3C\x39\x42\x31\x31\x33\x44\x31\x41\x3E\x00"
                "\x89\x54\x24\x10\x48\x89\x4C\x24\x08\x48\x83\xEC\x68\x48\xC7\x44"
                "\x24\x18\x00\x00\x00\x00\x48\x8B\x44\x24\x70\x48\x89\x44\x24\x08"
                "\x48\x8B\x44\x24\x08\x48\x63\x48\x3C\x48\x8B\x44\x24\x08\x48\x03"
                "\xC1\x48\x89\x04\x24\x48\x8B\x04\x24\x48\x05\x88\x00\x00\x00\x48"
                "\x89\x44\x24\x10\x48\x8B\x44\x24\x10\x83\x38\x00\x0F\x84\x18\x01"
                "\x00\x00\x48\x8B\x44\x24\x10\x8B\x08\x48\x8B\x44\x24\x08\x48\x03"
                "\xC1\x48\x89\x44\x24\x20\x48\x8B\x44\x24\x20\x8B\x48\x20\x48\x8B"
                "\x44\x24\x08\x48\x03\xC1\x48\x89\x44\x24\x30\x48\x8B\x44\x24\x20"
                "\x8B\x48\x24\x48\x8B\x44\x24\x08\x48\x03\xC1\x48\x89\x44\x24\x28"
                "\x48\x8B\x44\x24\x20\x8B\x48\x1C\x48\x8B\x44\x24\x08\x48\x03\xC1"
                "\x48\x89\x44\x24\x38\xC7\x44\x24\x40\x00\x00\x00\x00\xEB\x0B\x8B"
                "\x44\x24\x40\x83\xC0\x01\x89\x44\x24\x40\x48\x8B\x44\x24\x20\x8B"
                "\x40\x18\x39\x44\x24\x40\x0F\x83\x9E\x00\x00\x00\x8B\x4C\x24\x40"
                "\x48\x8B\x44\x24\x30\x8B\x0C\x88\x48\x8B\x44\x24\x08\x48\x03\xC1"
                "\x48\x89\x44\x24\x48\xC7\x44\x24\x50\x00\x00\x00\x00\x48\x8B\x44"
                "\x24\x48\x0F\xBE\x00\x85\xC0\x74\x3E\x48\x8B\x44\x24\x48\x0F\xBE"
                "\x00\x89\x44\x24\x54\x48\x8B\x44\x24\x48\x48\x83\xC0\x01\x48\x89"
                "\x44\x24\x48\x8B\x44\x24\x50\xC1\xE8\x0D\x8B\x4C\x24\x50\xC1\xE1"
                "\x13\x0B\xC1\x89\x44\x24\x50\x8B\x4C\x24\x54\x8B\x44\x24\x50\x03"
                "\xC1\x89\x44\x24\x50\xEB\xB6\x8B\x44\x24\x78\x39\x44\x24\x50\x75"
                "\x24\x8B\x4C\x24\x40\x48\x8B\x44\x24\x28\x0F\xB7\x0C\x48\x48\x8B"
                "\x44\x24\x38\x8B\x0C\x88\x48\x8B\x44\x24\x08\x48\x03\xC1\x48\x89"
                "\x44\x24\x18\xEB\x05\xE9\x45\xFF\xFF\xFF\x48\x8B\x44\x24\x18\x48"
                "\x83\xC4\x68\xC3"
                "\x56\x57\x53\x48\x33\xDB\x6A\x30\x58\x65\x48\x8B\x30\x48\x8B\x46"
                "\x60\x48\x8B\x40\x18\x48\x8B\x70\x10\x48\x8B\x7E\x60\x48\x8B\x46"
                "\x30\x48\x8B\x36\x38\x5F\x18\x75\xF0\x5B\x5F\x5E\xC3";

                int len = sizeof(MessageBox64bitV1_sc);

                void *pvBuffer;
                pvBuffer = malloc(len);

                memcpy(pvBuffer,(void*)&(MessageBox64bitV1_sc[0]),len);

                DWORD oldProtect;
                if (VirtualProtect(pvBuffer, len, PAGE_EXECUTE_READWRITE, &oldProtect))
                {
                               (*((int (__stdcall *)(void))pvBuffer))();
                }       

                return 0;
}

 Vous devriez avoir une vue comme celle en dessous , configurer la compilation en X64


Suite à la compilation, vous aurez un executable X64 avec votre shellcode MessageBoxA