mirror of
https://github.com/reactos/reactos.git
synced 2024-10-29 19:13:58 +00:00
169 lines
4.4 KiB
C
169 lines
4.4 KiB
C
/*
|
|
* ReactOS log2lines
|
|
* Written by Jan Roeloffzen
|
|
*
|
|
* - Image functions for symbol info
|
|
*/
|
|
|
|
#include <errno.h>
|
|
#include <string.h>
|
|
#include <rsym.h>
|
|
|
|
#include "compat.h"
|
|
#include "util.h"
|
|
#include "options.h"
|
|
#include "log2lines.h"
|
|
|
|
static PIMAGE_SECTION_HEADER
|
|
find_rossym_section(PIMAGE_FILE_HEADER PEFileHeader, PIMAGE_SECTION_HEADER PESectionHeaders)
|
|
{
|
|
size_t i;
|
|
for (i = 0; i < PEFileHeader->NumberOfSections; i++)
|
|
{
|
|
if (0 == strcmp((char *)PESectionHeaders[i].Name, ".rossym"))
|
|
return &PESectionHeaders[i];
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
size_t
|
|
fixup_offset(size_t ImageBase, size_t offset)
|
|
{
|
|
if (offset > ABS_TRESHOLD)
|
|
offset -= ImageBase;
|
|
return offset;
|
|
}
|
|
|
|
PROSSYM_ENTRY
|
|
find_offset(void *data, size_t offset)
|
|
{
|
|
PSYMBOLFILE_HEADER RosSymHeader = (PSYMBOLFILE_HEADER)data;
|
|
PROSSYM_ENTRY Entries = (PROSSYM_ENTRY)((char *)data + RosSymHeader->SymbolsOffset);
|
|
size_t symbols = RosSymHeader->SymbolsLength / sizeof(ROSSYM_ENTRY);
|
|
size_t i;
|
|
|
|
for (i = 0; i < symbols; i++)
|
|
{
|
|
if (Entries[i].Address > offset)
|
|
{
|
|
if (!i--)
|
|
return NULL;
|
|
else
|
|
return &Entries[i];
|
|
}
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
PIMAGE_SECTION_HEADER
|
|
get_sectionheader(const void *FileData)
|
|
{
|
|
PIMAGE_DOS_HEADER PEDosHeader;
|
|
PIMAGE_FILE_HEADER PEFileHeader;
|
|
PIMAGE_OPTIONAL_HEADER PEOptHeader;
|
|
PIMAGE_SECTION_HEADER PESectionHeaders;
|
|
PIMAGE_SECTION_HEADER PERosSymSectionHeader;
|
|
size_t ImageBase;
|
|
|
|
/* Check if MZ header exists */
|
|
PEDosHeader = (PIMAGE_DOS_HEADER)FileData;
|
|
if (PEDosHeader->e_magic != IMAGE_DOS_MAGIC || PEDosHeader->e_lfanew == 0L)
|
|
{
|
|
l2l_dbg(0, "Input file is not a PE image.\n");
|
|
summ.offset_errors++;
|
|
return NULL;
|
|
}
|
|
|
|
/* Locate PE file header */
|
|
/* sizeof(ULONG) = sizeof(MAGIC) */
|
|
PEFileHeader = (PIMAGE_FILE_HEADER)((char *)FileData + PEDosHeader->e_lfanew + sizeof(ULONG));
|
|
|
|
/* Locate optional header */
|
|
PEOptHeader = (PIMAGE_OPTIONAL_HEADER)(PEFileHeader + 1);
|
|
ImageBase = PEOptHeader->ImageBase;
|
|
|
|
/* Locate PE section headers */
|
|
PESectionHeaders = (PIMAGE_SECTION_HEADER)((char *)PEOptHeader + PEFileHeader->SizeOfOptionalHeader);
|
|
|
|
/* find rossym section */
|
|
PERosSymSectionHeader = find_rossym_section(PEFileHeader, PESectionHeaders);
|
|
if (!PERosSymSectionHeader)
|
|
{
|
|
l2l_dbg(0, "Couldn't find rossym section in executable\n");
|
|
summ.offset_errors++;
|
|
return NULL;
|
|
}
|
|
|
|
return PERosSymSectionHeader;
|
|
}
|
|
|
|
int
|
|
get_ImageBase(char *fname, size_t *ImageBase)
|
|
{
|
|
IMAGE_DOS_HEADER PEDosHeader;
|
|
IMAGE_FILE_HEADER PEFileHeader;
|
|
IMAGE_OPTIONAL_HEADER PEOptHeader;
|
|
|
|
FILE *fr;
|
|
off_t readLen;
|
|
int res;
|
|
|
|
*ImageBase = INVALID_BASE;
|
|
fr = fopen(fname, "rb");
|
|
if (!fr)
|
|
{
|
|
l2l_dbg(3, "get_ImageBase, cannot open '%s' (%s)\n", fname, strerror(errno));
|
|
return 1;
|
|
}
|
|
|
|
readLen = fread(&PEDosHeader, sizeof(IMAGE_DOS_HEADER), 1, fr);
|
|
if (1 != readLen)
|
|
{
|
|
l2l_dbg(1, "get_ImageBase %s, read error IMAGE_DOS_HEADER (%s)\n", fname, strerror(errno));
|
|
fclose(fr);
|
|
return 2;
|
|
}
|
|
|
|
/* Check if MZ header exists */
|
|
if (PEDosHeader.e_magic != IMAGE_DOS_MAGIC || PEDosHeader.e_lfanew == 0L)
|
|
{
|
|
l2l_dbg(2, "get_ImageBase %s, MZ header missing\n", fname);
|
|
fclose(fr);
|
|
return 3;
|
|
}
|
|
|
|
/* Locate PE file header */
|
|
res = fseek(fr, PEDosHeader.e_lfanew + sizeof(ULONG), SEEK_SET);
|
|
readLen = fread(&PEFileHeader, sizeof(IMAGE_FILE_HEADER), 1, fr);
|
|
if (1 != readLen)
|
|
{
|
|
l2l_dbg(1, "get_ImageBase %s, read error IMAGE_FILE_HEADER (%s)\n", fname, strerror(errno));
|
|
fclose(fr);
|
|
return 4;
|
|
}
|
|
|
|
/* Locate optional header */
|
|
readLen = fread(&PEOptHeader, sizeof(IMAGE_OPTIONAL_HEADER), 1, fr);
|
|
if (1 != readLen)
|
|
{
|
|
l2l_dbg(1, "get_ImageBase %s, read error IMAGE_OPTIONAL_HEADER (%s)\n", fname, strerror(errno));
|
|
fclose(fr);
|
|
return 5;
|
|
}
|
|
|
|
/* Check if it's really an IMAGE_OPTIONAL_HEADER we are interested in */
|
|
if (PEOptHeader.Magic != IMAGE_NT_OPTIONAL_HDR32_MAGIC &&
|
|
PEOptHeader.Magic != IMAGE_NT_OPTIONAL_HDR64_MAGIC)
|
|
{
|
|
l2l_dbg(2, "get_ImageBase %s, not an IMAGE_NT_OPTIONAL_HDR 32/64 bit\n", fname);
|
|
fclose(fr);
|
|
return 6;
|
|
}
|
|
|
|
*ImageBase = PEOptHeader.ImageBase;
|
|
fclose(fr);
|
|
return 0;
|
|
}
|
|
|
|
/* EOF */
|