1 /* 2 * ReactOS log2lines 3 * Written by Jan Roeloffzen 4 * 5 * - Image functions for symbol info 6 */ 7 8 #include <errno.h> 9 #include <string.h> 10 #include <rsym.h> 11 12 #include "compat.h" 13 #include "util.h" 14 #include "options.h" 15 #include "log2lines.h" 16 #include <sys/types.h> 17 18 static PIMAGE_SECTION_HEADER 19 find_rossym_section(PIMAGE_FILE_HEADER PEFileHeader, PIMAGE_SECTION_HEADER PESectionHeaders) 20 { 21 size_t i; 22 for (i = 0; i < PEFileHeader->NumberOfSections; i++) 23 { 24 if (0 == strcmp((char *)PESectionHeaders[i].Name, ".rossym")) 25 return &PESectionHeaders[i]; 26 } 27 return NULL; 28 } 29 30 size_t 31 fixup_offset(size_t ImageBase, size_t offset) 32 { 33 if (offset > ABS_TRESHOLD) 34 offset -= ImageBase; 35 return offset; 36 } 37 38 PROSSYM_ENTRY 39 find_offset(void *data, size_t offset) 40 { 41 PSYMBOLFILE_HEADER RosSymHeader = (PSYMBOLFILE_HEADER)data; 42 PROSSYM_ENTRY Entries = (PROSSYM_ENTRY)((char *)data + RosSymHeader->SymbolsOffset); 43 size_t symbols = RosSymHeader->SymbolsLength / sizeof(ROSSYM_ENTRY); 44 size_t i; 45 46 for (i = 0; i < symbols; i++) 47 { 48 if (Entries[i].Address > offset) 49 { 50 if (!i--) 51 return NULL; 52 else 53 return &Entries[i]; 54 } 55 } 56 return NULL; 57 } 58 59 PIMAGE_SECTION_HEADER 60 get_sectionheader(const void *FileData) 61 { 62 PIMAGE_DOS_HEADER PEDosHeader; 63 PIMAGE_FILE_HEADER PEFileHeader; 64 PIMAGE_OPTIONAL_HEADER PEOptHeader; 65 PIMAGE_SECTION_HEADER PESectionHeaders; 66 PIMAGE_SECTION_HEADER PERosSymSectionHeader; 67 size_t ImageBase; 68 69 /* Check if MZ header exists */ 70 PEDosHeader = (PIMAGE_DOS_HEADER)FileData; 71 if (PEDosHeader->e_magic != IMAGE_DOS_MAGIC || PEDosHeader->e_lfanew == 0L) 72 { 73 l2l_dbg(0, "Input file is not a PE image.\n"); 74 summ.offset_errors++; 75 return NULL; 76 } 77 78 /* Locate PE file header */ 79 /* sizeof(ULONG) = sizeof(MAGIC) */ 80 PEFileHeader = (PIMAGE_FILE_HEADER)((char *)FileData + PEDosHeader->e_lfanew + sizeof(ULONG)); 81 82 /* Locate optional header */ 83 PEOptHeader = (PIMAGE_OPTIONAL_HEADER)(PEFileHeader + 1); 84 ImageBase = PEOptHeader->ImageBase; 85 86 /* Locate PE section headers */ 87 PESectionHeaders = (PIMAGE_SECTION_HEADER)((char *)PEOptHeader + PEFileHeader->SizeOfOptionalHeader); 88 89 /* find rossym section */ 90 PERosSymSectionHeader = find_rossym_section(PEFileHeader, PESectionHeaders); 91 if (!PERosSymSectionHeader) 92 { 93 l2l_dbg(0, "Couldn't find rossym section in executable\n"); 94 summ.offset_errors++; 95 return NULL; 96 } 97 98 return PERosSymSectionHeader; 99 } 100 101 int 102 get_ImageBase(char *fname, size_t *ImageBase) 103 { 104 IMAGE_DOS_HEADER PEDosHeader; 105 IMAGE_FILE_HEADER PEFileHeader; 106 IMAGE_OPTIONAL_HEADER PEOptHeader; 107 108 FILE *fr; 109 off_t readLen; 110 int res; 111 112 *ImageBase = INVALID_BASE; 113 fr = fopen(fname, "rb"); 114 if (!fr) 115 { 116 l2l_dbg(3, "get_ImageBase, cannot open '%s' (%s)\n", fname, strerror(errno)); 117 return 1; 118 } 119 120 readLen = fread(&PEDosHeader, sizeof(IMAGE_DOS_HEADER), 1, fr); 121 if (1 != readLen) 122 { 123 l2l_dbg(1, "get_ImageBase %s, read error IMAGE_DOS_HEADER (%s)\n", fname, strerror(errno)); 124 fclose(fr); 125 return 2; 126 } 127 128 /* Check if MZ header exists */ 129 if (PEDosHeader.e_magic != IMAGE_DOS_MAGIC || PEDosHeader.e_lfanew == 0L) 130 { 131 l2l_dbg(2, "get_ImageBase %s, MZ header missing\n", fname); 132 fclose(fr); 133 return 3; 134 } 135 136 /* Locate PE file header */ 137 res = fseek(fr, PEDosHeader.e_lfanew + sizeof(ULONG), SEEK_SET); 138 readLen = fread(&PEFileHeader, sizeof(IMAGE_FILE_HEADER), 1, fr); 139 if (1 != readLen) 140 { 141 l2l_dbg(1, "get_ImageBase %s, read error IMAGE_FILE_HEADER (%s)\n", fname, strerror(errno)); 142 fclose(fr); 143 return 4; 144 } 145 146 /* Locate optional header */ 147 readLen = fread(&PEOptHeader, sizeof(IMAGE_OPTIONAL_HEADER), 1, fr); 148 if (1 != readLen) 149 { 150 l2l_dbg(1, "get_ImageBase %s, read error IMAGE_OPTIONAL_HEADER (%s)\n", fname, strerror(errno)); 151 fclose(fr); 152 return 5; 153 } 154 155 /* Check if it's really an IMAGE_OPTIONAL_HEADER we are interested in */ 156 if (PEOptHeader.Magic != IMAGE_NT_OPTIONAL_HDR32_MAGIC && 157 PEOptHeader.Magic != IMAGE_NT_OPTIONAL_HDR64_MAGIC) 158 { 159 l2l_dbg(2, "get_ImageBase %s, not an IMAGE_NT_OPTIONAL_HDR 32/64 bit\n", fname); 160 fclose(fr); 161 return 6; 162 } 163 164 *ImageBase = PEOptHeader.ImageBase; 165 fclose(fr); 166 return 0; 167 } 168 169 /* EOF */ 170