summaryrefslogtreecommitdiffstats
path: root/src/pdb.c
diff options
context:
space:
mode:
authorQuentin LADEVIE <qladevie@wanadev.fr>2024-11-20 08:46:32 +0100
committerQuentin LADEVIE <qladevie@wanadev.fr>2024-11-20 08:46:32 +0100
commit65b3c69b4be9f826d71cffe3d333397adee5d4fd (patch)
treee640b55868f61db6257756e960756a0bba1e62e7 /src/pdb.c
parent09d761b30a579b0282185c1db9e91e981f2f3a27 (diff)
Store loaded modules info
Add command to list loaded modules Add command to print callstack Load modules of pdb files
Diffstat (limited to 'src/pdb.c')
-rw-r--r--src/pdb.c132
1 files changed, 114 insertions, 18 deletions
diff --git a/src/pdb.c b/src/pdb.c
index dfa4c74..a28a201 100644
--- a/src/pdb.c
+++ b/src/pdb.c
@@ -1,8 +1,26 @@
+#include "cvinfo.h"
+
+enum STREAM_INDEX {
+ OLD_DIRECTORY,
+ PDB,
+ TPI,
+ DBI,
+ IPI,
+};
+
+enum SYMBOL_KIND {
+ OBJNAME = 0x1101,
+ PUBLIC = 0x110e,
+ GPROC32 = 0x1110,
+ COMPIL3 = 0x113C,
+};
+
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());
+ return;
}
// MSF superblock
@@ -24,24 +42,27 @@ void open_pdb(const char* pdb_path) {
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);
+
+ // Loog through streams
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* stream_blocks_indices[1024U] = { 0U };
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) {
+ print("PDB stream blocks : NONE\n");
+ continue;
+ }
+
+ if (stream_sizes[stream_id] == 0U) {
continue;
}
+
+ stream_blocks_indices[stream_id] = &stream_blocks[block_index];
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++;
@@ -57,12 +78,11 @@ void open_pdb(const char* pdb_path) {
};
struct pdb_info_stream pdb_info_stream = { 0U };
- SetFilePointer(pdb_file, pdb_info_stream_blocks[0U] * sizeof(block), NULL, FILE_BEGIN);
+ SetFilePointer(pdb_file, stream_blocks_indices[PDB][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 {
+ struct DBI_stream_header {
i32 version_signature;
u32 version_header;
u32 age;
@@ -84,13 +104,89 @@ void open_pdb(const char* pdb_path) {
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;
+
+ struct mod_info {
+ u32 Unused1;
+ struct SectionContribEntry {
+ u16 Section;
+ u8 Padding1[2];
+ i32 Offset;
+ i32 Size;
+ u32 Characteristics;
+ u16 ModuleIndex;
+ u8 Padding2[2];
+ u32 DataCrc;
+ u32 RelocCrc;
+ } SectionContr;
+ u16 Flags;
+ u16 ModuleSymStream;
+ u32 SymByteSize;
+ u32 C11ByteSize;
+ u32 C13ByteSize;
+ u16 SourceFileCount;
+ u8 Padding[2];
+ u32 Unused2;
+ u32 SourceFileNameIndex;
+ u32 PdbFilePathNameIndex;
+ } *modules_info[64U];
+ u8* modules_name[64U] = { 0U };
+ u8* obj_files_name[64U] = { 0U };
+ u8 DBI_block[4096U] = { 0U };
+ SetFilePointer(pdb_file, stream_blocks_indices[DBI][0U] * sizeof(block), NULL, FILE_BEGIN);
+ ReadFile(pdb_file, (void*)&DBI_block, sizeof(DBI_block), (LPDWORD)&b_read, NULL);
+ struct DBI_stream_header* DBI_stream_header = (struct DBI_stream_header*)DBI_block;
+
+ i32 byte_index = sizeof(*DBI_stream_header);
+ for (u32 module_index = 0U; byte_index < DBI_stream_header->mod_info_size; module_index++) {
+ modules_info[module_index] = (struct mod_info*)&DBI_block[byte_index];
+ modules_name[module_index] = &DBI_block[byte_index + sizeof(struct mod_info)];
+ print("Module symbole stream index %xu\n", modules_info[module_index]->ModuleSymStream);
+ print("%s\n", modules_name[module_index]);
+ size_t module_name_length = 0U;
+ StringCchLengthA((STRSAFE_LPSTR)modules_name[module_index], STRSAFE_MAX_CCH, &module_name_length);
+ obj_files_name[module_index] = &DBI_block[byte_index + sizeof(struct mod_info) + module_name_length + 1U];
+
+ print("%s\n", obj_files_name[module_index]);
+ size_t obj_file_name_length = 0U;
+ StringCchLengthA((STRSAFE_LPSTR)obj_files_name[module_index], STRSAFE_MAX_CCH, &obj_file_name_length);
+
+ u32 module_info_size = sizeof(*modules_info[0U]) + (i32)module_name_length + 1 + (i32)obj_file_name_length + 1;
+ module_info_size = ((module_info_size + 3U) * 4U) / 4U;
+ byte_index += module_info_size;
+
+ // Module Info Stream
+ u8 module_info_block[4096U] = { 0U };
+ SetFilePointer(pdb_file, stream_blocks_indices[modules_info[module_index]->ModuleSymStream][0U] * sizeof(module_info_block), NULL, FILE_BEGIN);
+ ReadFile(pdb_file, (void*)&module_info_block, sizeof(module_info_block), (LPDWORD)&b_read, NULL);
+
+ u8* symbols = &module_info_block[4U];
+ u8* cur_sym = symbols;
+ while ((u32)(cur_sym - symbols) < modules_info[module_index]->SymByteSize) {
+ struct SYMTYPE* rec = (struct SYMTYPE*)cur_sym;
+ if (rec->rectyp == OBJNAME) {
+ struct OBJNAMESYM* objname = (struct OBJNAMESYM*)cur_sym;
+ print("OBJNAME SYMBOL %s\n", objname->name);
+ } else if (rec->rectyp == PUBLIC) {
+ struct PUBSYM32* pub = (struct PUBSYM32*)cur_sym;
+ print("PUBLIC SYMBOL %s\n", pub->name);
+ } else if (rec->rectyp == GPROC32) {
+ struct PROCSYM32* proc = (struct PROCSYM32*)cur_sym;
+ print("PROC32 SYMBOL %s\n", proc->name);
+ } else if (rec->rectyp == COMPIL3) {
+ struct COMPILESYM3* com = (struct COMPILESYM3*)cur_sym;
+ print("COMPILER SYMBOL %s\n", com->verSz);
+ } else {
+ print("Unkown symbole kind %xu\n", rec->rectyp);
+ }
+ cur_sym += rec->reclen + 2U;
+ }
+ }
// 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);
+ SetFilePointer(pdb_file, stream_blocks_indices[DBI_stream_header->global_stream_index][0U] * sizeof(block), NULL, FILE_BEGIN);
+ ReadFile(pdb_file, (void*)&block, sizeof(DBI_stream_header), (LPDWORD)&b_read, NULL);
+
+ // Public Symbol Stream
+ SetFilePointer(pdb_file, stream_blocks_indices[DBI_stream_header->public_stream_index][0U] * sizeof(block), NULL, FILE_BEGIN);
+ ReadFile(pdb_file, (void*)&block, sizeof(block), (LPDWORD)&b_read, NULL);
}