Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenfrommem.c
Go to the documentation of this file.
00001 /* 00002 * COPYRIGHT: See COPYING in the top level directory 00003 * PROJECT: ReactOS kernel 00004 * FILE: lib/rossym/frommem.c 00005 * PURPOSE: Creating rossym info from an in-memory image 00006 * 00007 * PROGRAMMERS: Ge van Geldorp (gvg@reactos.com) 00008 */ 00009 00010 #define NTOSAPI 00011 #include <ntifs.h> 00012 #include <ndk/ntndk.h> 00013 #include <reactos/rossym.h> 00014 #include "rossympriv.h" 00015 #include <ntimage.h> 00016 00017 #define NDEBUG 00018 #include <debug.h> 00019 00020 #include "dwarf.h" 00021 #include "pe.h" 00022 00023 BOOLEAN 00024 RosSymCreateFromMem(PVOID ImageStart, ULONG_PTR ImageSize, PROSSYM_INFO *RosSymInfo) 00025 { 00026 ANSI_STRING AnsiNameString = { }; 00027 PIMAGE_DOS_HEADER DosHeader; 00028 PIMAGE_NT_HEADERS NtHeaders; 00029 PIMAGE_SECTION_HEADER SectionHeaders; 00030 ULONG SectionIndex; 00031 unsigned SymbolTable, NumSymbols; 00032 00033 /* Check if MZ header is valid */ 00034 DosHeader = (PIMAGE_DOS_HEADER) ImageStart; 00035 if (ImageSize < sizeof(IMAGE_DOS_HEADER) 00036 || ! ROSSYM_IS_VALID_DOS_HEADER(DosHeader)) 00037 { 00038 DPRINT1("Image doesn't have a valid DOS header\n"); 00039 return FALSE; 00040 } 00041 00042 /* Locate NT header */ 00043 NtHeaders = (PIMAGE_NT_HEADERS)((char *) ImageStart + DosHeader->e_lfanew); 00044 if (ImageSize < DosHeader->e_lfanew + sizeof(IMAGE_NT_HEADERS) 00045 || ! ROSSYM_IS_VALID_NT_HEADERS(NtHeaders)) 00046 { 00047 DPRINT1("Image doesn't have a valid PE header\n"); 00048 return FALSE; 00049 } 00050 00051 SymbolTable = NtHeaders->FileHeader.PointerToSymbolTable; 00052 NumSymbols = NtHeaders->FileHeader.NumberOfSymbols; 00053 00054 /* Search for the section header */ 00055 ULONG SectionHeaderSize = NtHeaders->FileHeader.NumberOfSections * sizeof(IMAGE_SECTION_HEADER); 00056 SectionHeaders = RosSymAllocMem(SectionHeaderSize); 00057 RtlCopyMemory(SectionHeaders, IMAGE_FIRST_SECTION(NtHeaders), SectionHeaderSize); 00058 00059 // Convert names to ANSI_STRINGs 00060 for (SectionIndex = 0; SectionIndex < NtHeaders->FileHeader.NumberOfSections; 00061 SectionIndex++) 00062 { 00063 if (SectionHeaders[SectionIndex].Name[0] != '/') { 00064 AnsiNameString.Buffer = RosSymAllocMem(IMAGE_SIZEOF_SHORT_NAME); 00065 RtlCopyMemory(AnsiNameString.Buffer, SectionHeaders[SectionIndex].Name, IMAGE_SIZEOF_SHORT_NAME); 00066 AnsiNameString.MaximumLength = IMAGE_SIZEOF_SHORT_NAME; 00067 AnsiNameString.Length = GetStrnlen(AnsiNameString.Buffer, IMAGE_SIZEOF_SHORT_NAME); 00068 } else { 00069 UNICODE_STRING intConv; 00070 NTSTATUS Status; 00071 ULONG StringOffset; 00072 00073 Status = RtlCreateUnicodeStringFromAsciiz(&intConv, (PCSZ)SectionHeaders[SectionIndex].Name + 1); 00074 if (!NT_SUCCESS(Status)) goto freeall; 00075 Status = RtlUnicodeStringToInteger(&intConv, 10, &StringOffset); 00076 RtlFreeUnicodeString(&intConv); 00077 if (!NT_SUCCESS(Status)) goto freeall; 00078 ULONG VirtualOffset = pefindrva(SectionHeaders, NtHeaders->FileHeader.NumberOfSections, SymbolTable+(NumSymbols*SYMBOL_SIZE)+StringOffset); 00079 if (!VirtualOffset) goto freeall; 00080 AnsiNameString.Buffer = RosSymAllocMem(MAXIMUM_DWARF_NAME_SIZE); 00081 if (!AnsiNameString.Buffer) goto freeall; 00082 PCHAR StringTarget = ((PCHAR)ImageStart)+VirtualOffset; 00083 PCHAR EndOfImage = ((PCHAR)ImageStart) + NtHeaders->OptionalHeader.SizeOfImage; 00084 if (StringTarget >= EndOfImage) goto freeall; 00085 ULONG PossibleStringLength = EndOfImage - StringTarget; 00086 if (PossibleStringLength > MAXIMUM_DWARF_NAME_SIZE) 00087 PossibleStringLength = MAXIMUM_DWARF_NAME_SIZE; 00088 RtlCopyMemory(AnsiNameString.Buffer, StringTarget, PossibleStringLength); 00089 AnsiNameString.Length = strlen(AnsiNameString.Buffer); 00090 AnsiNameString.MaximumLength = MAXIMUM_DWARF_NAME_SIZE; 00091 } 00092 memcpy 00093 (&SectionHeaders[SectionIndex], 00094 &AnsiNameString, 00095 sizeof(AnsiNameString)); 00096 } 00097 00098 Pe *pe = RosSymAllocMem(sizeof(*pe)); 00099 pe->fd = ImageStart; 00100 pe->e2 = peget2; 00101 pe->e4 = peget4; 00102 pe->e8 = peget8; 00103 pe->loadbase = (ULONG)ImageStart; 00104 pe->imagebase = NtHeaders->OptionalHeader.ImageBase; 00105 pe->imagesize = NtHeaders->OptionalHeader.SizeOfImage; 00106 pe->nsections = NtHeaders->FileHeader.NumberOfSections; 00107 pe->sect = SectionHeaders; 00108 pe->nsymbols = NtHeaders->FileHeader.NumberOfSymbols; 00109 pe->symtab = malloc(pe->nsymbols * sizeof(CoffSymbol)); 00110 PSYMENT SymbolData = (PSYMENT) 00111 (((PCHAR)ImageStart) + 00112 pefindrva 00113 (pe->sect, 00114 pe->nsections, 00115 NtHeaders->FileHeader.PointerToSymbolTable)); 00116 int i, j; 00117 for (i = 0, j = 0; i < pe->nsymbols; i++) { 00118 if ((SymbolData[i].e_scnum < 1) || 00119 (SymbolData[i].e_sclass != C_EXT && 00120 SymbolData[i].e_sclass != C_STAT)) 00121 continue; 00122 int section = SymbolData[i].e_scnum - 1; 00123 if (SymbolData[i].e.e.e_zeroes) { 00124 pe->symtab[j].name = malloc(sizeof(SymbolData[i].e.e_name)+1); 00125 strcpy(pe->symtab[j].name, SymbolData[i].e.e_name); 00126 } else { 00127 PCHAR SymbolName = ((PCHAR)ImageStart) + 00128 pefindrva 00129 (pe->sect, 00130 pe->nsections, 00131 NtHeaders->FileHeader.PointerToSymbolTable + 00132 (NtHeaders->FileHeader.NumberOfSymbols * 18) + 00133 SymbolData[i].e.e.e_offset); 00134 pe->symtab[j].name = malloc(strlen(SymbolName)+1); 00135 strcpy(pe->symtab[j].name, SymbolName); 00136 } 00137 if (pe->symtab[j].name[0] == '.') { 00138 free(pe->symtab[j].name); 00139 continue; 00140 } 00141 pe->symtab[j].address = pe->sect[section].VirtualAddress + SymbolData[i].e_value; 00142 j++; 00143 } 00144 pe->nsymbols = j; 00145 pe->loadsection = loadmemsection; 00146 *RosSymInfo = dwarfopen(pe); 00147 00148 return !!*RosSymInfo; 00149 00150 freeall: 00151 if (AnsiNameString.Buffer) RosSymFreeMem(AnsiNameString.Buffer); 00152 for (SectionIndex = 0; SectionIndex < NtHeaders->FileHeader.NumberOfSections; 00153 SectionIndex++) 00154 RtlFreeAnsiString(ANSI_NAME_STRING(&SectionHeaders[SectionIndex])); 00155 RosSymFreeMem(SectionHeaders); 00156 00157 return FALSE; 00158 } 00159 00160 /* EOF */ Generated on Sat May 26 2012 04:35:19 for ReactOS by
1.7.6.1
|