evbunpack/example/PackerTestApp/PackerTestApp.c
2024-06-07 00:13:22 +08:00

107 lines
No EOL
3.9 KiB
C
Raw Permalink Blame History

// PackerTestApp.cpp : Generic testing PE for packers
// by mos9527, 2022
/* References:
https://learn.microsoft.com/en-us/cpp/parallel/multithreading-with-c-and-win32
https://bidouillesecurity.com/tutorial-writing-a-pe-packer-part-1/
https://github.com/jeremybeaume/packer-tutorial
*/
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <Psapi.h>
#include <stdio.h>
#define EXIT_OK 0
#define EXIT_INVALID_FS 1
#define EXIT_INVALID_TLS 2
#define EXIT_INVALID_OVERLAY 3
const char* MAGIC = "El Psy Kongroo.";
__declspec(thread) int tls_value = 0;
int WINAPI thread_job(int no) {
printf("TLS run #%d: tls_value before thread job:%d\n", no, tls_value);
if (tls_value != 0) {
printf(">>> Bad TLS initial value. Early out.\n");
ExitProcess(EXIT_INVALID_TLS);
}
tls_value = no;
printf("TLS run #%d: tls_value after thread job:%d\n", no, tls_value);
return 0;
}
int main()
{
printf("TLS - Thread Local Storage\n");
for (int i = 1; i <= 2; i++) {
HANDLE thread = _beginthread(thread_job, 0, i);
WaitForSingleObject(thread, INFINITE);
}
printf(">>> TLS Checks OK.\n");
HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE);
char BUFFER[1024] = { 0 };
DWORD bytesRead;
if (handle) {
printf("Win32 API Hook - CreateFile,ReadFile (README.txt)\n");
HANDLE file = CreateFileA(
"README.txt", GENERIC_READ, NULL, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL
);
if (file == INVALID_HANDLE_VALUE) {
printf("Cannot open file for reading!\n");
ExitProcess(EXIT_INVALID_FS);
}
else {
if (ReadFile(file, BUFFER, 1024, &bytesRead, NULL)) {
if (memcmp(BUFFER, MAGIC, strlen(MAGIC)) != 0) {
printf(">>> Invalid README.txt content!\n");
ExitProcess(EXIT_INVALID_FS);
}
else {
printf(">>> README.txt content OK.\n");
}
}
}
printf("PE Modification - Sections\n");
/** Parse header **/
char* VA = (char*)GetModuleHandleA(NULL);
IMAGE_DOS_HEADER* p_DOS_HDR = (IMAGE_DOS_HEADER*)VA;
IMAGE_NT_HEADERS* p_NT_HDR = (IMAGE_NT_HEADERS*)(((char*)p_DOS_HDR) + p_DOS_HDR->e_lfanew);
// Note: We<57>re manipulating pointers, so be very, very carefull with pointer arithmetic:
// pointer + 1 actually adds size_of(type of the pointer), hence the cast in char*. Easy mistake to make here!
IMAGE_SECTION_HEADER* sections = (IMAGE_SECTION_HEADER*)(p_NT_HDR + 1);
DWORD hdr_image_base = p_NT_HDR->OptionalHeader.ImageBase;
DWORD size_of_image = p_NT_HDR->OptionalHeader.SizeOfImage;
DWORD entry_point_RVA = p_NT_HDR->OptionalHeader.AddressOfEntryPoint;
DWORD size_of_headers = p_NT_HDR->OptionalHeader.SizeOfHeaders;
DWORD number_of_sections = p_NT_HDR->FileHeader.NumberOfSections;
for (DWORD i = 0; i < number_of_sections; i++) {
printf("%s VA=0x%x RawPtr=0x%x RawSize=0x%x\n", sections[i].Name,sections[i].VirtualAddress,sections[i].PointerToRawData,sections[i].SizeOfRawData);
}
printf("Misc - Overlay\n");
DWORD start_of_overlay = sections[number_of_sections - 1].PointerToRawData + sections[number_of_sections - 1].SizeOfRawData;
// Overlays are not memory-mapped. Read them from the exe
memset(BUFFER, 0, 1024);
if (GetModuleFileNameA(NULL,BUFFER,1024)) {
// GetProcessImageFileNameA gives us NT paths which we can only use by calling internal APIs
printf("Name %s\n", BUFFER);
file = CreateFileA(BUFFER, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (file == INVALID_HANDLE_VALUE) {
printf("Cannot open file for reading!\n");
}
else {
if (SetFilePointer(file, LOWORD(start_of_overlay),0 , FILE_BEGIN)) {
if (ReadFile(file, BUFFER, 1024, &bytesRead, NULL))
if (memcmp(BUFFER, MAGIC, strlen(MAGIC)) != 0) {
printf(">>> Invalid Overlay content!\n");
ExitProcess(EXIT_INVALID_OVERLAY);
}
else {
printf(">>> Overlay content OK. %s\n", BUFFER);
}
}
}
}
else {
printf("Cannot acquire filename for self!\n");
}
}
return 0;
}