
악성코드 분석 및 리버스 엔지니어링을 위해 수동 매핑, IAT 후킹, 메모리 덤핑, 그리고 임포트 재구축을 지원하는 사용자 정의 PE 로딩 및 조작 라이브러리.
PE 파일을 로드하고 조작하기 위한 라이브러리입니다.
libPEConv의 목표는 PE 파일의 사용자 정의 로딩을 위한 "스위스 아미 나이프"를 만드는 것이었습니다. 이 라이브러리는 자체 로더에 빠르게 통합할 수 있는 다양한 헬퍼 함수를 모아 놓았습니다. 예를 들어: 섹션 재매핑, 재배치 적용, 임포트 로딩, 리소스 파싱 등이 있습니다.
PE 파일을 로드할 수 있을 뿐만 아니라 일부 단계를 사용자 정의할 수도 있습니다. 즉, IAT 후킹(사용자 정의 IAT 해석기 제공) 및 함수 리디렉션을 지원합니다. 그러나 인라인 후킹에 초점을 맞추지 않으므로 MS Detours나 MinHook과 같은 라이브러리와 혼동해서는 안 됩니다.
LibPeConv는 리소스에서 PE를 직접 로드하고 로컬 코드인 것처럼 통합할 수 있으므로 PE 바인더를 만드는 데 사용할 수 있습니다.
또한 메모리에서 PE를 덤프하고 해당 IAT를 재구성하는 데 도움이 될 수 있습니다.
경고: MUI를 사용하는 애플리케이션은 지원되지 않습니다.
가장 간단한 사용 사례: libPeConv를 사용하여 원하는 EXE를 수동으로 로드하고 실행합니다.
#include <Windows.h>
#include <iostream>
#include <peconv.h> // include libPeConv header
int main(int argc, char *argv[])
{
if (argc < 2) {
std::cout << "Args: <path to the exe>" << std::endl;
return 0;
}
LPCSTR pe_path = argv[1];
// manually load the PE file using libPeConv:
size_t v_size = 0;
#ifdef LOAD_FROM_PATH
//if the PE is dropped on the disk, you can load it from the file:
BYTE* my_pe = peconv::load_pe_executable(pe_path, v_size);
#else
size_t bufsize = 0;
BYTE *buffer = peconv::load_file(pe_path, bufsize);
// if the file is NOT dropped on the disk, you can load it directly from a memory buffer:
BYTE* my_pe = peconv::load_pe_executable(buffer, bufsize, v_size);
#endif
if (!my_pe) {
return -1;
}
// if the loaded PE needs to access resources, you may need to connect it to the PEB:
peconv::set_main_module_in_peb((HMODULE)my_pe);
// load delayed imports (if present):
const ULONGLONG load_base = (ULONGLONG)my_pe;
peconv::load_delayed_imports(my_pe, load_base);
// if needed, you can run TLS callbacks before the Entry Point:
peconv::run_tls_callbacks(my_pe, v_size);
//calculate the Entry Point of the manually loaded module
DWORD ep_rva = peconv::get_entry_point_rva(my_pe);
if (!ep_rva) {
return -2;
}
ULONG_PTR ep_va = ep_rva + (ULONG_PTR) my_pe;
//assuming that the payload is an EXE file (not DLL) this will be the simplest prototype of the main:
int (*new_main)() = (int(*)())ep_va;
//call the Entry Point of the manually loaded PE:
return new_main();
}
참고: https://github.com/hasherezade/libpeconv_tpl/blob/master/project_template/main.cpp