ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

frommem.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 doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.