-
-
Save hasherezade/657975ca7e988b4aa1538324ace87588 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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