Skip to content

Instantly share code, notes, and snippets.

@hasherezade
Last active December 26, 2023 13:40
Show Gist options
  • Save hasherezade/657975ca7e988b4aa1538324ace87588 to your computer and use it in GitHub Desktop.
Save hasherezade/657975ca7e988b4aa1538324ace87588 to your computer and use it in GitHub Desktop.
#include <Windows.h>
#include <iostream>
#include <tchar.h>
#include <peconv.h> // include libPeConv header
BYTE* g_Payload = nullptr;
size_t g_PayloadSize = 0;
HACCEL _stdcall my_LoadAcceleratorsW(
HINSTANCE hInstance,
LPCWSTR lpTableName
)
{
HACCEL res = LoadAcceleratorsW(hInstance, lpTableName);
if (res) {
return res;
}
std::wcout << "Failed to load: " << lpTableName << " for: " << std::hex << (ULONG_PTR)hInstance << std::endl;
return (HACCEL)0x1337;
}
// manually load the PE file using libPeConv
bool load_payload(LPCTSTR pe_path)
{
if (g_Payload) {
std::cerr << "[!] The payload is already loaded!\n";
return false;
}
peconv::hooking_func_resolver my_res;
my_res.add_hook("LoadAcceleratorsW", (FARPROC)&my_LoadAcceleratorsW);
// if the PE is dropped on the disk, you can load it from the file:
g_Payload = peconv::load_pe_executable(pe_path, g_PayloadSize, (peconv::t_function_resolver*)&my_res);
if (!g_Payload) {
return false;
}
// if the loaded PE needs to access resources, you may need to connect it to the PEB:
peconv::set_main_module_in_peb((HMODULE)g_Payload);
// load delayed imports (if present):
const ULONGLONG loadBase = (ULONGLONG)g_Payload;
peconv::load_delayed_imports(g_Payload, loadBase, (peconv::t_function_resolver*)&my_res);
return true;
}
int run_payload()
{
if (!g_Payload) {
std::cerr << "[!] The payload is not loaded!\n";
return -1;
}
// if needed, you can run TLS callbacks before the Entry Point:
peconv::run_tls_callbacks(g_Payload, g_PayloadSize);
//calculate the Entry Point of the manually loaded module
DWORD ep_rva = peconv::get_entry_point_rva(g_Payload);
if (!ep_rva) {
std::cerr << "[!] Cannot fetch EP!\n";
return -2;
}
const ULONG_PTR ep_va = ep_rva + (ULONG_PTR)g_Payload;
// run payload's main:
int ret = 0;
//the simplest prototype of the main fuction:
int basic_main(void);
auto new_main = reinterpret_cast<decltype(&basic_main)>(ep_va);
//call the Entry Point of the manually loaded PE:
ret = new_main();
return ret;
}
int _tmain(int argc, LPTSTR argv[])
{
if (argc < 2) {
std::cout << "Args: <path to the exe>" << std::endl;
return 0;
}
const LPTSTR pe_path = argv[1];
if (!load_payload(pe_path)) {
return -1;
}
std::cout << "Payload loaded at: " << std::hex << (ULONG_PTR)g_Payload << "\n";
return run_payload();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment