NO

Author Topic: PellesC 9 dbg  (Read 795 times)

Offline TimoVJL

  • Global Moderator
  • Member
  • *****
  • Posts: 1850
PellesC 9 dbg
« on: June 21, 2018, 12:51:28 pm »
This small test project use mspdbcore.dll (v12->) to write pdb.
It reads test2.dbg in test.
Use temporary files in tests.

Code: [Select]
SYMSRV:  C:\code\x64dbg\x64\symbols\hello-msvcrt64.pdb\5BEB47315BE54758B90D5ED6BBE9CD131\hello-msvcrt64.pdb not found
DBGHELP: hello-msvcrt64 - public symbols 
        C:\code\PellesC\V9\mspdb\test\temp\hello-msvcrt64.pdb
EDIT: another version that needs msobjxx.dll too.

EDIT: analyze pdb with this code:
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;

typedef struct PdbStreamHeader {
  uint32_t Version; // VC70 20000404 1312E94h
  uint32_t Signature;
  uint32_t Age;
  GUID UniqueId;
}PDBSTREAMHEADER,*PPDBSTREAMHEADER;

typedef struct DbiStreamHeader {
  int32_t VersionSignature;
  uint32_t VersionHeader;
  uint32_t Age;
  uint16_t GlobalStreamIndex;
  uint16_t BuildNumber;
  uint16_t PublicStreamIndex;
  uint16_t PdbDllVersion;
  uint16_t SymRecordStream;
  uint16_t PdbDllRbld;
  int32_t ModInfoSize;
  int32_t SectionContributionSize;
  int32_t SectionMapSize;
  int32_t SourceInfoSize;
  int32_t TypeServerSize;
  uint32_t MFCTypeServerIndex;
  int32_t OptionalDbgHeaderSize;
  int32_t ECSubstreamSize;
  uint16_t Flags;
  uint16_t Machine;
  uint32_t Padding;
}DBISTREAMHEADER, *PDBISTREAMHEADER;

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;
}

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 *pDW = (DWORD*)&pStreamDir->StreamSizes;
DWORD *pStreamSizes = &pStreamDir->StreamSizes;
printf("StreamSizes[] = ");
for (DWORD nC=0; nC<nStreams; nC++)
printf("%d ", pStreamSizes[nC]);
printf("\nStreamBlocks[] = ");
DWORD *pStreamBlocks = &pStreamDir->StreamSizes;
pStreamBlocks += nStreams;
for (DWORD nC=0; nC<nStreams; nC++)
printf("%d ", pStreamBlocks[nC]);
printf("\n");
printf("Version VC70 20000404 %Xh\n", 20000404);
for (DWORD nC=0; nC<nStreams; nC++) {
if (pStreamBlocks[nC] && pStreamSizes[nC]) {
DWORD nBlock = pStreamBlocks[nC]*pMsfHdr->BlockSize;
//printf("%p\n", pStreamBlocks[nC]*pMsfHdr->BlockSize);
printf("%02u %p %Xh\n", pStreamBlocks[nC], nBlock, *(DWORD*)(pMem+nBlock));
if (*(DWORD*)(pMem+nBlock) == 0x1312E94) {
PPDBSTREAMHEADER pStreamheader = (PPDBSTREAMHEADER)(pMem+nBlock);
printf("\tPdbStreamHeader Version: %u\n", pStreamheader->Version);
}
if (*(DWORD*)(pMem+nBlock) == 0xFFFFFFFF) {
printf("\t%Xh\n", *(DWORD*)(pMem+nBlock+4));
if (*(DWORD*)(pMem+nBlock+4) == 0x1310977) {
PDBISTREAMHEADER pDBIHdr = (PDBISTREAMHEADER)(pMem+nBlock);
printf("\tDBI V70\n");
printf("\tVersionSignature: %Xh\n", pDBIHdr->VersionSignature);
printf("\tVersionHeader: %Xh\n", pDBIHdr->VersionHeader);
printf("\tGlobalStreamIndex: %u -> %Xh\n", pDBIHdr->GlobalStreamIndex,
pDBIHdr->GlobalStreamIndex*pMsfHdr->BlockSize);
printf("\tPublicStreamIndex: %u -> %Xh\n", pDBIHdr->PublicStreamIndex,
pDBIHdr->PublicStreamIndex*pMsfHdr->BlockSize);
printf("\tSymRecordStream: %u -> %Xh\n", pDBIHdr->SymRecordStream,
pDBIHdr->SymRecordStream*pMsfHdr->BlockSize);
printf("\tFlags: %Xh\n", pDBIHdr->Flags);
printf("\tMachine: %Xh\n", pDBIHdr->Machine);
}
}
}
}
return 0;
}
« Last Edit: June 25, 2018, 12:35:26 pm by TimoVJL »
May the source be with you