NO

Author Topic: some fun with pdb  (Read 509 times)

Offline TimoVJL

  • Global Moderator
  • Member
  • *****
  • Posts: 1742
some fun with pdb
« on: June 25, 2018, 04:56:27 pm »
How about reading pdb?
llvm offers some info about it, The PDB File Format

I hope that we can discuss about it in here and we find out what it can offer to PellesC users.
An open discussion about it.

EDIT:
Code: [Select]
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <stdio.h>
#include <stdint.h>
//#include "msf.h"

// https://llvm.org/docs/PDB/MsfFile.html

const char Magic[] = "Microsoft C/C++ MSF 7.00\r\n\x1a\x44\x53\0\0";

typedef struct SuperBlock {
  char FileMagic[32]; //sizeof(Magic)];
  uint32_t BlockSize;
  uint32_t FreeBlockMapBlock;
  uint32_t NumBlocks;
  uint32_t NumDirectoryBytes;
  uint32_t Unknown;
  uint32_t BlockMapAddr;
}SUPERBLOCK,*PSUPERBLOCK;

typedef struct StreamDirectory {
  uint32_t NumStreams;
  uint32_t StreamSizes; //[NumStreams];
  uint32_t StreamBlocks[]; //[NumStreams][];
}STREAMDIRECTORY,*PSTREAMDIRECTORY;

int ProcessFile(PBYTE pMem);

int main(int argc, char **argv)
{
HANDLE hFile, hMapping;
VOID *pMem;

if (argc < 2) {
puts("Usage: TestMsf.exe <file>");
return 1;
}

hFile = CreateFile(argv[1], GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
if (hFile != INVALID_HANDLE_VALUE)
{
hMapping = CreateFileMapping(hFile, NULL, PAGE_READONLY, 0, 0, NULL);
if (hMapping)
{
pMem = MapViewOfFile(hMapping, FILE_MAP_READ, 0, 0, 0);
if (pMem)
{
ProcessFile(pMem);
UnmapViewOfFile(pMem);
} else
puts("File open error");
CloseHandle(hMapping);
} else
puts("FileMapping error");
CloseHandle(hFile);
}
else
puts("File open error");
return 0;
}

/*
Old Directory Fixed Stream Index 0 Previous MSF Stream Directory
PDB Stream Fixed Stream Index 1 Basic File Information
TPI Stream Fixed Stream Index 2 CodeView Type Records
DBI Stream Fixed Stream Index 3 Module/Compiland Information
IPI Stream Fixed Stream Index 4 CodeView Type Records
*/
int ProcessFile(PBYTE pMem)
{
SUPERBLOCK *pMsfHdr = (SUPERBLOCK*)pMem;
printf("FileMagic: %s\n", pMsfHdr->FileMagic);
printf("BlockSize: %u\n", pMsfHdr->BlockSize);
printf("FreeBlockMapBlock: %u -> %Xh\n", pMsfHdr->FreeBlockMapBlock,
pMsfHdr->FreeBlockMapBlock*pMsfHdr->BlockSize);
printf("NumBlocks: %u\n", pMsfHdr->NumBlocks);
printf("NumDirectoryBytes: %u\n", pMsfHdr->NumDirectoryBytes);
printf("Unknown: %u\n", pMsfHdr->Unknown);
printf("BlockMapAddr: %u -> %Xh\n", pMsfHdr->BlockMapAddr,
pMsfHdr->BlockMapAddr*pMsfHdr->BlockSize);
printf("\nfilesize: %u\n", pMsfHdr->BlockSize*pMsfHdr->NumBlocks);
DWORD *pIndexes = (DWORD*)(pMem+pMsfHdr->BlockMapAddr*pMsfHdr->BlockSize);
DWORD *pIndex = pIndexes; // the first Index Block
printf("\nStreamDir indexes:");
while (*pIndex)
printf("%04Xh", *pIndex++);
pIndex = pIndexes; // the first Index Block
printf("\nStreamDir Block %u -> %Xh\n", *pIndex, *pIndex*pMsfHdr->BlockSize);
PSTREAMDIRECTORY pStreamDir = (PSTREAMDIRECTORY)(pMem+*pIndex*pMsfHdr->BlockSize);
printf("NumStreams %u\n", pStreamDir->NumStreams);
DWORD nStreams = pStreamDir->NumStreams;
DWORD nStreamBlocks = pMsfHdr->NumDirectoryBytes/4-1-pStreamDir->NumStreams;
printf("Number of stream blocks %u\n", nStreamBlocks);
//DWORD *pDW = (DWORD*)&pStreamDir->StreamSizes;
DWORD *pStreamSizes = &pStreamDir->StreamSizes;
printf("StreamSizes[%u] = ", nStreams);
for (DWORD nC=0; nC<nStreams; nC++)
printf("%d ", pStreamSizes[nC]);
printf("\nStreamBlocks[%u] =", nStreamBlocks);
DWORD *pStreamBlocks = &pStreamDir->StreamSizes;
pStreamBlocks += nStreams;
for (DWORD nC=0; nC<nStreamBlocks; nC++)
printf(" %2d", pStreamBlocks[nC]);
printf("\n                 ");
for (DWORD nC=0; nC<nStreams; nC++) {
//int nBlocks = pStreamSizes[nC]/nBlockSize+(pStreamSizes[nC]%nBlockSize?1:0);
int nBlocks;
if (pStreamSizes[nC]>0 && pStreamSizes[nC]<0xFFFFFFFF) // -1 free block
nBlocks = (pStreamSizes[nC]-1)/nBlockSize+1;
else nBlocks = 0;
if (nBlocks) {
printf("%2d %u {", nStream, nBlocks);
int nBlk1 = nBlkCnt;
for (int i=0; i<nBlocks; i++) {
if (i) printf(",");
printf("%d", pStreamBlocks[nBlkCnt++]);
}
printf("} %u bytes -> %Xh\n", pStreamSizes[nC], pStreamBlocks[nBlk1]*nBlockSize);
} else printf("%2d %u\n", nStream, nBlocks);
nStream++;
}
return 0;
}

EDIT 2018-07-05: TestPdb_a2 avoid to show wrong stream blocks.
EDIT 2018-07-06: TestPdb_a2 fixed streams.
« Last Edit: July 26, 2018, 01:47:12 pm by TimoVJL »
May the source be with you

Offline Vortex

  • Member
  • *
  • Posts: 508
    • http://www.vortex.masmcode.com
Re: some fun with pdb
« Reply #1 on: July 04, 2018, 10:11:01 pm »
Hi Timo,

Nice work, thanks. It shows all the sections of .pdb files.
Code it... That's all...

Offline TimoVJL

  • Global Moderator
  • Member
  • *****
  • Posts: 1742
Re: some fun with pdb
« Reply #2 on: July 05, 2018, 09:04:24 am »
Examples don't read blocks correctly, if they are not sequential :(
The hex-viewer works only with sequential data.

EDIT: a fix with a hex-viewer2
« Last Edit: July 06, 2018, 02:41:57 pm by TimoVJL »
May the source be with you

Offline TimoVJL

  • Global Moderator
  • Member
  • *****
  • Posts: 1742
Re: some fun with pdb
« Reply #3 on: July 07, 2018, 02:58:38 pm »
I hope that at least someone is interest of exploring PDB and gives a some info about it.
If you know good links for PDB internals, let us know about it.
May the source be with you

Offline frankie

  • Global Moderator
  • Member
  • *****
  • Posts: 1653
Re: some fun with pdb
« Reply #4 on: July 25, 2018, 03:47:54 pm »
Try if this work.
Actually it only read and extract files.
There is no codeview support, it only process the Multi Stream File format.
I'll publish source when my MSF lib is somewhat more solid.
« Last Edit: July 25, 2018, 04:43:28 pm by frankie »

Offline TimoVJL

  • Global Moderator
  • Member
  • *****
  • Posts: 1742
Re: some fun with pdb
« Reply #5 on: July 25, 2018, 04:19:40 pm »
Sure i test it :)
Good to know that you explore pdb too.
May the source be with you

Offline frankie

  • Global Moderator
  • Member
  • *****
  • Posts: 1653
Re: some fun with pdb
« Reply #6 on: July 25, 2018, 04:44:54 pm »
Just a mind exercise.  ;)
It is more close to my attitude, system code, drivers ...