Skip to content

Instantly share code, notes, and snippets.

@RealNeGate
Last active June 17, 2023 01:37
Show Gist options
  • Select an option

  • Save RealNeGate/a27c830503d226829a1dc37e14c717d6 to your computer and use it in GitHub Desktop.

Select an option

Save RealNeGate/a27c830503d226829a1dc37e14c717d6 to your computer and use it in GitHub Desktop.
#define UNICODE
#include <stdio.h>
#include <stddef.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
static void free_pdb_path(wchar_t* path) {
free(path);
}
// freed with free_pdb_path
static wchar_t* find_pdb(char* image_base) {
if (image_base == NULL) {
return NULL;
}
// we expect a DOS header
char* ptr = image_base;
if (memcmp(ptr, "MZ", 2) == 0) {
// we'll find the pointer to the PE header at the end of the DOS header
ptr = image_base + *((uint32_t*) (ptr + 60));
}
if (memcmp(ptr, "PE\0\0", 4) != 0) {
fprintf(stderr, "error: no PE header! got %.*s\n", 4, ptr);
return NULL;
}
IMAGE_NT_HEADERS64* nt = (IMAGE_NT_HEADERS64*) ptr;
// debug directory is [6]
IMAGE_DEBUG_DIRECTORY* debug_dir = (IMAGE_DEBUG_DIRECTORY*) (image_base + nt->OptionalHeader.DataDirectory[6].VirtualAddress);
if (debug_dir->Type != IMAGE_DEBUG_TYPE_CODEVIEW) {
return NULL;
}
size_t debug_section_size = debug_dir->SizeOfData;
char* debug_section = image_base + debug_dir->AddressOfRawData;
if (debug_section_size <= 24) {
fprintf(stderr, "error: Executable image doesn't have a PDB file!");
return NULL;
}
char* path = debug_section + 24;
wchar_t* output = malloc(FILENAME_MAX * sizeof(wchar_t));
MultiByteToWideChar(CP_UTF8, 0, path, -1, output, FILENAME_MAX);
return output;
}
int wmain(int argc, wchar_t** argv) {
char* image_base = NULL;
if (argc >= 2) {
image_base = (char*) GetModuleHandle(argv[1]);
if (image_base == NULL) {
// if it wasn't loaded already, load it now
printf("Loading %S...\n", argv[1]);
image_base = (char*) LoadLibrary(argv[1]);
if (image_base == NULL) {
printf("Could not load %S\n", argv[1]);
return 1;
}
}
} else {
image_base = (char*) GetModuleHandle(NULL);
}
wchar_t* pdb_path = find_pdb(image_base);
if (pdb_path == NULL) {
printf("PDB path could not be found!");
return 1;
}
printf("PDB path is at: %S\n", pdb_path);
free_pdb_path(pdb_path);
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment