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