I wrote a shellcode in C that pops a messagebox. I have compiled two variations of it. One says "Hello World!" (shellcodeA) and the other one says "Goodbye World!" (shellcodeB).
#define WIN32_LEAN_AND_MEAN
#pragma warning( disable : 4201 ) // Disable warning about 'nameless struct/union'
#include "GetProcAddressWithHash.h"
#include <Windows.h>
/** NOTE: module hashes are computed using all-caps unicode strings */
#define LDRLOADDLL_HASH 0xbdbf9c13
#define LDRGETPROCADDRESS_HASH 0x5ed941b5
typedef int (WINAPI* MESSAGEBOXW)(HWND, LPCWSTR, LPCWSTR, UINT);
typedef NTSTATUS(WINAPI* LDRLOADDLL)(PWCHAR, ULONG, PUNICODE_STRING, PHANDLE);
typedef NTSTATUS(WINAPI* LDRGETPROCADDRESS)(HMODULE, PANSI_STRING, WORD, PVOID*);
#define FILL_STRING_WITH_BUF(string, buffer) \
string.Length = sizeof(buffer); \
string.MaximumLength = string.Length; \
string.Buffer = (PCHAR)buffer
VOID Run()
{
#pragma warning( push )
#pragma warning( disable : 4055 ) // Ignore cast warnings
// Function pointers
LDRLOADDLL pLdrLoadDll = NULL;
LDRGETPROCADDRESS pLdrGetProcAddress = NULL;
MESSAGEBOXW pMessageBoxW = NULL;
// General
HANDLE hUser32;
// String
UNICODE_STRING uString = { 0 };
STRING aString = { 0 };
WCHAR sUser32[] = { 'u', 's', 'e', 'r', '3', '2', '.', 'd', 'l', 'l' };
BYTE sMessageBoxW[] = { 'M', 'e', 's', 's', 'a', 'g', 'e', 'B', 'o', 'x', 'W', 0 };
WCHAR sMsgContent[] = { 'H', 'e', 'l', 'l', 'o', ' ', 'W', 'o', 'r', 'l', 'd', '!', 0 };
WCHAR sMsgTitle[] = { 'D', 'e', 'm', 'o', '!', 0 };
///
// STEP 1: locate all the required functions
///
pLdrLoadDll = (LDRLOADDLL)GetProcAddressWithHash(LDRLOADDLL_HASH);
pLdrGetProcAddress = (LDRGETPROCADDRESS)GetProcAddressWithHash(LDRGETPROCADDRESS_HASH);
uString.Buffer = sUser32;
uString.MaximumLength = sizeof(sUser32);
uString.Length = sizeof(sUser32);
pLdrLoadDll(NULL, 0, &uString, &hUser32);
FILL_STRING_WITH_BUF(aString, sMessageBoxW);
pLdrGetProcAddress(hUser32, &aString, 0, (PVOID*)&pMessageBoxW);
///
// STEP 2: pop messagebox
///
pMessageBoxW(NULL, sMsgContent, sMsgTitle, 0x00000000L);
}
Now i am trying to write a c++ program that generates a third piece of shellcode that is glueing shellcode A and B together. The way im doing this is having a piece of bootstrap asm that makes a call to shellcodeA and then to shellcodeB. So it will look like this in memory:
// Bootstrap shellcode
// shellCodeA
// shellCodeB
Here is the program:
#include <cstdio>
#include <fstream>
#include "Windows.h"
BOOL ConvertToShellcode(LPSTR& outBytes, DWORD& outLength)
{
//MARKER:S
LPSTR shellCodeA32 = const_cast<LPSTR>("\x83\xEC\x60\x53\x55\x56\x57\x6A\x75\x58\x6A\x73\x59\x6A\x65\x5B\x6A\x72\x5F\x6A\x33\x66\x89\x44\x24\x44\x58\x6A\x32\x66\x89\x44\x24\x4C\x58\x6A\x2E\x66\x89\x44\x24\x4E\x58\x6A\x64\x5E\x6A\x6C\x5A\x6A\x6F\x83\x64\x24\x14\x00\x66\x89\x5C\x24\x48\x88\x5C\x24\x2D\x88\x5C\x24\x32\x5B\x6A\x57\x66\x89\x4C\x24\x46\x66\x89\x44\x24\x50\x88\x4C\x24\x2E\x88\x4C\x24\x2F\x59\x6A\x48\x58\x6A\x65\x5D\x6A\x20\x66\x89\x44\x24\x58\x58\x6A\x21\x66\x89\x44\x24\x62\x33\xC0\x88\x4C\x24\x36\x66\x89\x4C\x24\x64\x59\x6A\x44\x66\x89\x44\x24\x70\x58\x66\x89\x44\x24\x34\x6A\x6D\x58\x66\x89\x44\x24\x38\x33\xC0\x66\x89\x7C\x24\x46\x66\x89\x74\x24\x4E\x66\x89\x54\x24\x50\x66\x89\x54\x24\x52\xC6\x44\x24\x28\x4D\x66\xC7\x44\x24\x2C\x61\x67\xC6\x44\x24\x2F\x42\x88\x5C\x24\x30\xC6\x44\x24\x31\x78\xC6\x44\x24\x33\x00\x66\x89\x6C\x24\x56\x66\x89\x54\x24\x58\x66\x89\x54\x24\x5A\x66\x89\x5C\x24\x5C\x66\x89\x5C\x24\x62\x66\x89\x7C\x24\x64\x66\x89\x54\x24\x66\x66\x89\x74\x24\x68\x66\x89\x4C\x24\x6A\x66\x89\x6C\x24\x36\x66\x89\x5C\x24\x3A\x66\x89\x4C\x24\x3C\x66\x89\x44\x24\x3E\xB9\x13\x9C\xBF\xBD\xE8\x71\x00\x00\x00\xB9\xB5\x41\xD9\x5E\x8B\xF0\xE8\x65\x00\x00\x00\x8B\xF8\x33\xDB\x6A\x14\x8D\x44\x24\x44\x89\x44\x24\x20\x58\x66\x89\x44\x24\x1A\x66\x89\x44\x24\x18\x8D\x44\x24\x14\x50\x8D\x44\x24\x1C\x50\x53\x53\xFF\xD6\x6A\x0C\x58\x66\x89\x44\x24\x20\x66\x89\x44\x24\x22\x8D\x44\x24\x28\x89\x44\x24\x24\x8D\x44\x24\x10\x50\x53\x8D\x44\x24\x28\x50\xFF\x74\x24\x20\xFF\xD7\x53\x8D\x44\x24\x38\x50\x8D\x44\x24\x5C\x50\x53\xFF\x54\x24\x20\x5F\x5E\x5D\x5B\x83\xC4\x60\xC3\x83\xEC\x14\x64\xA1\x30\x00\x00\x00\x53\x55\x56\x8B\x40\x0C\x57\x89\x4C\x24\x1C\x8B\x78\x0C\xE9\xA5\x00\x00\x00\x8B\x47\x30\x33\xF6\x8B\x5F\x2C\x8B\x3F\x89\x44\x24\x10\x8B\x42\x3C\x89\x7C\x24\x14\x8B\x6C\x10\x78\x89\x6C\x24\x18\x85\xED\x0F\x84\x80\x00\x00\x00\xC1\xEB\x10\x33\xC9\x85\xDB\x74\x2F\x8B\x7C\x24\x10\x0F\xBE\x2C\x0F\xC1\xCE\x0D\x80\x3C\x0F\x61\x89\x6C\x24\x10\x7C\x09\x8B\xC5\x83\xC0\xE0\x03\xF0\xEB\x04\x03\x74\x24\x10\x41\x3B\xCB\x72\xDD\x8B\x7C\x24\x14\x8B\x6C\x24\x18\x8B\x44\x2A\x20\x33\xDB\x8B\x4C\x2A\x18\x03\xC2\x89\x4C\x24\x10\x85\xC9\x74\x34\x8B\x38\x33\xED\x03\xFA\x83\xC0\x04\x89\x44\x24\x20\x8A\x0F\xC1\xCD\x0D\x0F\xBE\xC1\x03\xE8\x47\x84\xC9\x75\xF1\x8B\x7C\x24\x14\x8D\x04\x2E\x3B\x44\x24\x1C\x74\x20\x8B\x44\x24\x20\x43\x3B\x5C\x24\x10\x72\xCC\x8B\x57\x18\x85\xD2\x0F\x85\x50\xFF\xFF\xFF\x33\xC0\x5F\x5E\x5D\x5B\x83\xC4\x14\xC3\x8B\x74\x24\x18\x8B\x44\x16\x24\x8D\x04\x58\x0F\xB7\x0C\x10\x8B\x44\x16\x1C\x8D\x04\x88\x8B\x04\x10\x03\xC2\xEB\xDB");
LPSTR shellCodeA64 = const_cast<LPSTR>("\x48\x89\x5C\x24\x18\x48\x89\x7C\x24\x20\x55\x48\x8D\x6C\x24\xA9\x48\x81\xEC\xA0\x00\x00\x00\x33\xDB\xC7\x45\x17\x75\x00\x73\x00\xB9\x13\x9C\xBF\xBD\x48\x89\x5D\x67\x89\x5D\xFB\x89\x5D\x0B\x66\x89\x5D\x47\xC7\x45\x1B\x65\x00\x72\x00\xC7\x45\x1F\x33\x00\x32\x00\xC7\x45\x23\x2E\x00\x64\x00\xC7\x45\x27\x6C\x00\x6C\x00\xC7\x45\xD7\x4D\x65\x73\x73\xC7\x45\xDB\x61\x67\x65\x42\xC7\x45\xDF\x6F\x78\x57\x00\xC7\x45\x2F\x48\x00\x65\x00\xC7\x45\x33\x6C\x00\x6C\x00\xC7\x45\x37\x6F\x00\x20\x00\xC7\x45\x3B\x57\x00\x6F\x00\xC7\x45\x3F\x72\x00\x6C\x00\xC7\x45\x43\x64\x00\x21\x00\xC7\x45\xE7\x44\x00\x65\x00\xC7\x45\xEB\x6D\x00\x6F\x00\xC7\x45\xEF\x21\x00\x00\x00\xE8\x74\x00\x00\x00\xB9\xB5\x41\xD9\x5E\x48\x8B\xD8\xE8\x67\x00\x00\x00\x48\x8B\xF8\xC7\x45\xF7\x14\x00\x14\x00\x48\x8D\x45\x17\x33\xD2\x4C\x8D\x4D\x6F\x48\x89\x45\xFF\x4C\x8D\x45\xF7\x33\xC9\xFF\xD3\x48\x8B\x4D\x6F\x48\x8D\x45\xD7\x45\x33\xC0\x48\x89\x45\x0F\x4C\x8D\x4D\x67\xC7\x45\x07\x0C\x00\x0C\x00\x48\x8D\x55\x07\xFF\xD7\x45\x33\xC9\x4C\x8D\x45\xE7\x48\x8D\x55\x2F\x33\xC9\xFF\x55\x67\x4C\x8D\x9C\x24\xA0\x00\x00\x00\x49\x8B\x5B\x20\x49\x8B\x7B\x28\x49\x8B\xE3\x5D\xC3\xCC\xCC\x48\x8B\xC4\x48\x89\x58\x08\x48\x89\x68\x10\x48\x89\x70\x18\x48\x89\x78\x20\x41\x56\x48\x83\xEC\x10\x65\x48\x8B\x04\x25\x60\x00\x00\x00\x8B\xE9\x45\x33\xF6\x48\x8B\x50\x18\x4C\x8B\x4A\x10\x4D\x8B\x41\x30\x4D\x85\xC0\x0F\x84\xB3\x00\x00\x00\x41\x0F\x10\x41\x58\x49\x63\x40\x3C\x41\x8B\xD6\x4D\x8B\x09\xF3\x0F\x7F\x04\x24\x46\x8B\x9C\x00\x88\x00\x00\x00\x45\x85\xDB\x74\xD2\x48\x8B\x04\x24\x48\xC1\xE8\x10\x66\x44\x3B\xF0\x73\x22\x48\x8B\x4C\x24\x08\x44\x0F\xB7\xD0\x0F\xBE\x01\xC1\xCA\x0D\x80\x39\x61\x7C\x03\x83\xC2\xE0\x03\xD0\x48\xFF\xC1\x49\x83\xEA\x01\x75\xE7\x4F\x8D\x14\x18\x45\x8B\xDE\x41\x8B\x7A\x20\x49\x03\xF8\x45\x39\x72\x18\x76\x8E\x8B\x37\x41\x8B\xDE\x49\x03\xF0\x48\x8D\x7F\x04\x0F\xBE\x0E\x48\xFF\xC6\xC1\xCB\x0D\x03\xD9\x84\xC9\x75\xF1\x8D\x04\x13\x3B\xC5\x74\x0E\x41\xFF\xC3\x45\x3B\x5A\x18\x72\xD5\xE9\x5E\xFF\xFF\xFF\x41\x8B\x42\x24\x43\x8D\x0C\x1B\x49\x03\xC0\x0F\xB7\x14\x01\x41\x8B\x4A\x1C\x49\x03\xC8\x8B\x04\x91\x49\x03\xC0\xEB\x02\x33\xC0\x48\x8B\x5C\x24\x20\x48\x8B\x6C\x24\x28\x48\x8B\x74\x24\x30\x48\x8B\x7C\x24\x38\x48\x83\xC4\x10\x41\x5E\xC3");
LPSTR shellCodeB32 = const_cast<LPSTR>("\x83\xEC\x64\x53\x55\x56\x57\x6A\x75\x58\x6A\x73\x59\x6A\x65\x5B\x6A\x72\x5F\x6A\x33\x66\x89\x44\x24\x44\x58\x6A\x32\x66\x89\x44\x24\x4C\x58\x6A\x2E\x66\x89\x44\x24\x4E\x58\x6A\x64\x5E\x6A\x6C\x5A\x6A\x6F\x83\x64\x24\x14\x00\x66\x89\x5C\x24\x48\x88\x5C\x24\x2D\x88\x5C\x24\x32\x5B\x6A\x57\x66\x89\x4C\x24\x46\x66\x89\x44\x24\x50\x88\x4C\x24\x2E\x88\x4C\x24\x2F\x59\x6A\x47\x58\x6A\x62\x66\x89\x44\x24\x58\x58\x6A\x79\x66\x89\x44\x24\x60\x58\x6A\x65\x5D\x6A\x20\x66\x89\x44\x24\x62\x58\x6A\x21\x88\x4C\x24\x36\x66\x89\x44\x24\x66\x33\xC0\x66\x89\x4C\x24\x68\x59\x6A\x44\x66\x89\x44\x24\x74\x58\x66\x89\x7C\x24\x46\x66\x89\x74\x24\x4E\x66\x89\x54\x24\x50\x66\x89\x54\x24\x52\xC6\x44\x24\x28\x4D\x66\xC7\x44\x24\x2C\x61\x67\xC6\x44\x24\x2F\x42\x88\x5C\x24\x30\xC6\x44\x24\x31\x78\xC6\x44\x24\x33\x00\x66\x89\x5C\x24\x56\x66\x89\x5C\x24\x58\x66\x89\x74\x24\x5A\x66\x89\x6C\x24\x60\x66\x89\x5C\x24\x66\x66\x89\x7C\x24\x68\x66\x89\x54\x24\x6A\x66\x89\x74\x24\x6C\x66\x89\x4C\x24\x6E\x66\x89\x44\x24\x34\x66\x89\x6C\x24\x36\x6A\x6D\x58\x66\x89\x44\x24\x38\x33\xC0\x66\x89\x4C\x24\x3C\xB9\x13\x9C\xBF\xBD\x66\x89\x5C\x24\x3A\x66\x89\x44\x24\x3E\xE8\x71\x00\x00\x00\xB9\xB5\x41\xD9\x5E\x8B\xF0\xE8\x65\x00\x00\x00\x8B\xF8\x33\xDB\x6A\x14\x8D\x44\x24\x44\x89\x44\x24\x20\x58\x66\x89\x44\x24\x1A\x66\x89\x44\x24\x18\x8D\x44\x24\x14\x50\x8D\x44\x24\x1C\x50\x53\x53\xFF\xD6\x6A\x0C\x58\x66\x89\x44\x24\x20\x66\x89\x44\x24\x22\x8D\x44\x24\x28\x89\x44\x24\x24\x8D\x44\x24\x10\x50\x53\x8D\x44\x24\x28\x50\xFF\x74\x24\x20\xFF\xD7\x53\x8D\x44\x24\x38\x50\x8D\x44\x24\x5C\x50\x53\xFF\x54\x24\x20\x5F\x5E\x5D\x5B\x83\xC4\x64\xC3\x83\xEC\x14\x64\xA1\x30\x00\x00\x00\x53\x55\x56\x8B\x40\x0C\x57\x89\x4C\x24\x1C\x8B\x78\x0C\xE9\xA5\x00\x00\x00\x8B\x47\x30\x33\xF6\x8B\x5F\x2C\x8B\x3F\x89\x44\x24\x10\x8B\x42\x3C\x89\x7C\x24\x14\x8B\x6C\x10\x78\x89\x6C\x24\x18\x85\xED\x0F\x84\x80\x00\x00\x00\xC1\xEB\x10\x33\xC9\x85\xDB\x74\x2F\x8B\x7C\x24\x10\x0F\xBE\x2C\x0F\xC1\xCE\x0D\x80\x3C\x0F\x61\x89\x6C\x24\x10\x7C\x09\x8B\xC5\x83\xC0\xE0\x03\xF0\xEB\x04\x03\x74\x24\x10\x41\x3B\xCB\x72\xDD\x8B\x7C\x24\x14\x8B\x6C\x24\x18\x8B\x44\x2A\x20\x33\xDB\x8B\x4C\x2A\x18\x03\xC2\x89\x4C\x24\x10\x85\xC9\x74\x34\x8B\x38\x33\xED\x03\xFA\x83\xC0\x04\x89\x44\x24\x20\x8A\x0F\xC1\xCD\x0D\x0F\xBE\xC1\x03\xE8\x47\x84\xC9\x75\xF1\x8B\x7C\x24\x14\x8D\x04\x2E\x3B\x44\x24\x1C\x74\x20\x8B\x44\x24\x20\x43\x3B\x5C\x24\x10\x72\xCC\x8B\x57\x18\x85\xD2\x0F\x85\x50\xFF\xFF\xFF\x33\xC0\x5F\x5E\x5D\x5B\x83\xC4\x14\xC3\x8B\x74\x24\x18\x8B\x44\x16\x24\x8D\x04\x58\x0F\xB7\x0C\x10\x8B\x44\x16\x1C\x8D\x04\x88\x8B\x04\x10\x03\xC2\xEB\xDB");
LPSTR shellCodeB64 = const_cast<LPSTR>("\x48\x89\x5C\x24\x18\x48\x89\x7C\x24\x20\x55\x48\x8D\x6C\x24\xA9\x48\x81\xEC\xA0\x00\x00\x00\x33\xDB\xC7\x45\x17\x75\x00\x73\x00\xB9\x13\x9C\xBF\xBD\x48\x89\x5D\x67\x89\x5D\xFB\x89\x5D\x0B\x66\x89\x5D\x4B\xC7\x45\x1B\x65\x00\x72\x00\xC7\x45\x1F\x33\x00\x32\x00\xC7\x45\x23\x2E\x00\x64\x00\xC7\x45\x27\x6C\x00\x6C\x00\xC7\x45\xD7\x4D\x65\x73\x73\xC7\x45\xDB\x61\x67\x65\x42\xC7\x45\xDF\x6F\x78\x57\x00\xC7\x45\x2F\x47\x00\x6F\x00\xC7\x45\x33\x6F\x00\x64\x00\xC7\x45\x37\x62\x00\x79\x00\xC7\x45\x3B\x65\x00\x20\x00\xC7\x45\x3F\x57\x00\x6F\x00\xC7\x45\x43\x72\x00\x6C\x00\xC7\x45\x47\x64\x00\x21\x00\xC7\x45\xE7\x44\x00\x65\x00\xC7\x45\xEB\x6D\x00\x6F\x00\xC7\x45\xEF\x21\x00\x00\x00\xE8\x75\x00\x00\x00\xB9\xB5\x41\xD9\x5E\x48\x8B\xD8\xE8\x68\x00\x00\x00\x48\x8B\xF8\xC7\x45\xF7\x14\x00\x14\x00\x48\x8D\x45\x17\x33\xD2\x4C\x8D\x4D\x6F\x48\x89\x45\xFF\x4C\x8D\x45\xF7\x33\xC9\xFF\xD3\x48\x8B\x4D\x6F\x48\x8D\x45\xD7\x45\x33\xC0\x48\x89\x45\x0F\x4C\x8D\x4D\x67\xC7\x45\x07\x0C\x00\x0C\x00\x48\x8D\x55\x07\xFF\xD7\x45\x33\xC9\x4C\x8D\x45\xE7\x48\x8D\x55\x2F\x33\xC9\xFF\x55\x67\x4C\x8D\x9C\x24\xA0\x00\x00\x00\x49\x8B\x5B\x20\x49\x8B\x7B\x28\x49\x8B\xE3\x5D\xC3\xCC\xCC\xCC\x48\x8B\xC4\x48\x89\x58\x08\x48\x89\x68\x10\x48\x89\x70\x18\x48\x89\x78\x20\x41\x56\x48\x83\xEC\x10\x65\x48\x8B\x04\x25\x60\x00\x00\x00\x8B\xE9\x45\x33\xF6\x48\x8B\x50\x18\x4C\x8B\x4A\x10\x4D\x8B\x41\x30\x4D\x85\xC0\x0F\x84\xB3\x00\x00\x00\x41\x0F\x10\x41\x58\x49\x63\x40\x3C\x41\x8B\xD6\x4D\x8B\x09\xF3\x0F\x7F\x04\x24\x46\x8B\x9C\x00\x88\x00\x00\x00\x45\x85\xDB\x74\xD2\x48\x8B\x04\x24\x48\xC1\xE8\x10\x66\x44\x3B\xF0\x73\x22\x48\x8B\x4C\x24\x08\x44\x0F\xB7\xD0\x0F\xBE\x01\xC1\xCA\x0D\x80\x39\x61\x7C\x03\x83\xC2\xE0\x03\xD0\x48\xFF\xC1\x49\x83\xEA\x01\x75\xE7\x4F\x8D\x14\x18\x45\x8B\xDE\x41\x8B\x7A\x20\x49\x03\xF8\x45\x39\x72\x18\x76\x8E\x8B\x37\x41\x8B\xDE\x49\x03\xF0\x48\x8D\x7F\x04\x0F\xBE\x0E\x48\xFF\xC6\xC1\xCB\x0D\x03\xD9\x84\xC9\x75\xF1\x8D\x04\x13\x3B\xC5\x74\x0E\x41\xFF\xC3\x45\x3B\x5A\x18\x72\xD5\xE9\x5E\xFF\xFF\xFF\x41\x8B\x42\x24\x43\x8D\x0C\x1B\x49\x03\xC0\x0F\xB7\x14\x01\x41\x8B\x4A\x1C\x49\x03\xC8\x8B\x04\x91\x49\x03\xC0\xEB\x02\x33\xC0\x48\x8B\x5C\x24\x20\x48\x8B\x6C\x24\x28\x48\x8B\x74\x24\x30\x48\x8B\x7C\x24\x38\x48\x83\xC4\x10\x41\x5E\xC3");
DWORD shellCodeA32Length = 629, shellCodeA64Length = 552;
DWORD shellCodeB32Length = 645, shellCodeB64Length = 560;
//MARKER:E
LPSTR shellcodeA = shellCodeA32;
LPSTR shellcodeB = shellCodeB32;
DWORD shellcodeALength = shellCodeA32Length;
DWORD shellcodeBLength = shellCodeB32Length;
if (shellcodeA == NULL || shellcodeALength == 0) return FALSE;
BYTE bootstrap[12] = { 0 };
DWORD i = 0;
// call - Transfer execution to shellCodeA
bootstrap[i++] = 0xe8;
bootstrap[i++] = sizeof(bootstrap) - i - 4; // Skip the remainder of instructions
bootstrap[i++] = 0x00;
bootstrap[i++] = 0x00;
bootstrap[i++] = 0x00;
// leave
//bootstrap[i++] = 0xc9;
// ret - return to caller
//bootstrap[i++] = 0xc3;
// call - Transfer execution to shellCodeB
bootstrap[i++] = 0xe8;
bootstrap[i++] = sizeof(bootstrap) + shellcodeALength - i - 4; // Skip the remainder of instructions
bootstrap[i++] = 0x00;
bootstrap[i++] = 0x00;
bootstrap[i++] = 0x00;
// leave
bootstrap[i++] = 0xc9;
// ret - return to caller
bootstrap[i++] = 0xc3;
// Ends up looking like this in memory:
// Bootstrap shellcode
// shellCodeA
// shellCodeB
outLength = sizeof(bootstrap) + shellcodeALength + shellcodeBLength;
outBytes = (LPSTR)malloc(outLength);
MoveMemory(outBytes, bootstrap, sizeof(bootstrap));
MoveMemory(outBytes + sizeof(bootstrap), shellcodeA, shellcodeALength);
MoveMemory(outBytes + sizeof(bootstrap) + shellcodeALength, shellcodeB, shellcodeBLength);
return TRUE;
}
typedef UINT_PTR(WINAPI* SHC)();
int main()
{
LPSTR finalShellcode = NULL;
DWORD finalSize;
DWORD dwOldProtect1 = 0;
SYSTEM_INFO sysInfo;
BOOL status;
std::fstream outFile;
DWORD dLastError;
status = ConvertToShellcode(finalShellcode, finalSize);
if (!status) {
printf("[!] Failed to convert shellcode\n");
goto Cleanup;
}
outFile = std::fstream(R"(../bin/FinalShellcode_x86.bin)",
std::ios::out | std::ios::binary);
outFile.write(finalShellcode, finalSize);
outFile.close();
GetNativeSystemInfo(&sysInfo);
status = VirtualProtect(finalShellcode, sysInfo.dwPageSize, PAGE_EXECUTE_READWRITE, &dwOldProtect1);
if (status) {
SHC shc = (SHC)(finalShellcode);
printf("[+] Executing shell code\n");
HMODULE hLoadedShc = (HMODULE)shc(); // Excute shellcode
status = 1;
goto Cleanup;
}
dLastError = GetLastError();
Cleanup:
if (finalShellcode)
free(finalShellcode);
return !status;
}
So when i run the shellcode the ConvertToShellcode
function produces shellcodeA gets called and i see a messagebox with "Hello world!". But when its time to call shellcodeB i get an access violation error. When i checked the buffer where the shellcode got allocated in IDA using blobrunner i found this:
I can see that the first call points to a valid function. But the second call points somewhere within the first shellcode and not to the second one. I saw the subroutine for shellcodeA started at 0x6A000C. ShellcodeA is 629 bytes long so shellcodeB should start at 0x6A0281. And not at 0x6A007E.
0x6A0281 looks about right. I can see the user32.dll array.
If we now take a look again at the cpp program. If i debug it using msvc:
I can see that the value for
sizeof(bootstrap) + shellcodeALength - i - 4
equals 0x119 which is 281 This cant be true since ShellcodeA is around 600 bytes long. If i manually calculate sizeof(bootstrap) + shellcodeALength - i - 4
i get 631 which is 0x277 in hex. I have a feeling im confusing hex and ints at this point but the outcomes are totally different. Could anyone here please point me in the right direction since i have no idea what to do anymore. I have also already tried manually setting the call to the right offset but i didnt get different results.
EDIT: here is a link to the github project so you can compile the program and shellcodes if you want. https://github.com/11philip22/asmGlue/