summaryrefslogtreecommitdiffstats
path: root/src/pdb.c
diff options
context:
space:
mode:
authorQuentin LADEVIE <qladevie@wanadev.fr>2024-09-09 08:28:11 +0200
committerQuentin LADEVIE <qladevie@wanadev.fr>2024-09-09 08:28:11 +0200
commit09d761b30a579b0282185c1db9e91e981f2f3a27 (patch)
tree6050453c03502e0eee84c8d90b8e7da92d63d61e /src/pdb.c
parente61b27e6c699ae175d7704ddaaee0d39b6d14382 (diff)
Load public symbols for dll
Initial code for pdb loading
Diffstat (limited to 'src/pdb.c')
-rw-r--r--src/pdb.c96
1 files changed, 96 insertions, 0 deletions
diff --git a/src/pdb.c b/src/pdb.c
new file mode 100644
index 0000000..dfa4c74
--- /dev/null
+++ b/src/pdb.c
@@ -0,0 +1,96 @@
+void open_pdb(const char* pdb_path) {
+ HANDLE pdb_file = CreateFileA(pdb_path, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
+
+ if (pdb_file == INVALID_HANDLE_VALUE) {
+ print("Cannot open pdb file at path %s due to error %u\n", pdb_path, GetLastError());
+ }
+
+ // MSF superblock
+ struct msf_superblock {
+ u8 magic[32U];
+ u32 block_size;
+ u32 free_block_map_block;
+ u32 num_blocks;
+ u32 num_directory_bytes;
+ u32 unknown;
+ u32 block_map_addr;
+ };
+ struct msf_superblock superblock = { 0U };
+ u8 block[4096U] = { 0U };
+ u32 b_read = 0U;
+ ReadFile(pdb_file, (void*)&superblock, sizeof(superblock), (LPDWORD)&b_read, NULL);
+
+ // Stream directory
+ u32 dir_addr = (superblock.block_map_addr - 1U) * sizeof(block);
+ SetFilePointer(pdb_file, dir_addr, NULL, FILE_BEGIN);
+ ReadFile(pdb_file, (void*)block, superblock.num_directory_bytes, (LPDWORD)&b_read, NULL);
+ u32 num_streams = ((u32*)block)[0U];
+ u32* stream_sizes = &((u32*)block)[1U];
+ u32* stream_blocks = stream_sizes + num_streams;
+ u32* pdb_info_stream_blocks = NULL;
+ u32* pdb_DBI_stream_blocks = NULL;
+
+ u32 block_index = 0U;
+ for(u32 stream_id = 0u; stream_id < num_streams; stream_id++) {
+ print("PDB stream size : %u\n", stream_sizes[stream_id]);
+ if (stream_id == 1U) {
+ pdb_info_stream_blocks = &stream_blocks[block_index];
+ }
+ if (stream_id == 3U) {
+ pdb_DBI_stream_blocks = &stream_blocks[block_index];
+ }
+ if (stream_sizes[stream_id] == (u32)-1) {
+ continue;
+ }
+ for(u32 id = 0u; id < (stream_sizes[stream_id] / sizeof(block)) + 1U; id++) {
+ print("PDB stream blocks : %u\n", stream_blocks[block_index]);
+ block_index++;
+ }
+ }
+
+ // PDB Info Stream
+ struct pdb_info_stream {
+ u32 version;
+ u32 signature;
+ u32 age;
+ u32 guid[4u];
+ };
+
+ struct pdb_info_stream pdb_info_stream = { 0U };
+ SetFilePointer(pdb_file, pdb_info_stream_blocks[0U] * sizeof(block), NULL, FILE_BEGIN);
+ ReadFile(pdb_file, (void*)&pdb_info_stream, sizeof(pdb_info_stream), (LPDWORD)&b_read, NULL);
+ pdb_info_stream;
+
+ // DBI Stream
+ struct pdb_DBI_stream {
+ i32 version_signature;
+ u32 version_header;
+ u32 age;
+ u16 global_stream_index;
+ u16 build_number;
+ u16 public_stream_index;
+ u16 pdb_dll_version;
+ u16 sym_record_stream;
+ u16 pdb_dll_rbld;
+ i32 mod_info_size;
+ i32 section_contribution_size;
+ i32 section_map_size;
+ i32 source_info_size;
+ i32 type_server_map_size;
+ u32 mfc_type_server_index;
+ i32 optional_dbg_header_size;
+ i32 ec_substream_size;
+ u16 flags;
+ u16 machine;
+ u32 padding;
+ };
+ struct pdb_DBI_stream pdb_DBI_stream = { 0U };
+ SetFilePointer(pdb_file, pdb_DBI_stream_blocks[0U] * sizeof(block), NULL, FILE_BEGIN);
+ ReadFile(pdb_file, (void*)&pdb_DBI_stream, sizeof(pdb_DBI_stream), (LPDWORD)&b_read, NULL);
+ print("");
+ pdb_DBI_stream;
+
+ // Global Symbol Stream
+ SetFilePointer(pdb_file, pdb_DBI_stream.global_stream_index * sizeof(block), NULL, FILE_BEGIN);
+ ReadFile(pdb_file, (void*)&pdb_DBI_stream, sizeof(pdb_DBI_stream), (LPDWORD)&b_read, NULL);
+}