コード例 #1
0
ファイル: frommem.c プロジェクト: hoangduit/reactos
BOOLEAN
RosSymCreateFromMem(PVOID ImageStart, ULONG_PTR ImageSize, PROSSYM_INFO *RosSymInfo)
{
	ANSI_STRING AnsiNameString = { };
	PIMAGE_DOS_HEADER DosHeader;
	PIMAGE_NT_HEADERS NtHeaders;
	PIMAGE_SECTION_HEADER SectionHeaders;
	ULONG SectionIndex;
	unsigned SymbolTable, NumSymbols;
	
	/* Check if MZ header is valid */
	DosHeader = (PIMAGE_DOS_HEADER) ImageStart;
	if (ImageSize < sizeof(IMAGE_DOS_HEADER)
		|| ! ROSSYM_IS_VALID_DOS_HEADER(DosHeader))
    {
		DPRINT1("Image doesn't have a valid DOS header\n");
		return FALSE;
    }
	
	/* Locate NT header  */
	NtHeaders = (PIMAGE_NT_HEADERS)((char *) ImageStart + DosHeader->e_lfanew);
	if (ImageSize < DosHeader->e_lfanew + sizeof(IMAGE_NT_HEADERS)
		|| ! ROSSYM_IS_VALID_NT_HEADERS(NtHeaders))
    {
		DPRINT1("Image doesn't have a valid PE header\n");
		return FALSE;
    }
	
	SymbolTable = NtHeaders->FileHeader.PointerToSymbolTable;
	NumSymbols = NtHeaders->FileHeader.NumberOfSymbols;
	
	/* Search for the section header */
	ULONG SectionHeaderSize = NtHeaders->FileHeader.NumberOfSections * sizeof(IMAGE_SECTION_HEADER);
	SectionHeaders = RosSymAllocMem(SectionHeaderSize);
	RtlCopyMemory(SectionHeaders, IMAGE_FIRST_SECTION(NtHeaders), SectionHeaderSize);
	
	// Convert names to ANSI_STRINGs
	for (SectionIndex = 0; SectionIndex < NtHeaders->FileHeader.NumberOfSections;
		 SectionIndex++) 
	{
		if (SectionHeaders[SectionIndex].Name[0] != '/') {
			AnsiNameString.Buffer = RosSymAllocMem(IMAGE_SIZEOF_SHORT_NAME);
			RtlCopyMemory(AnsiNameString.Buffer, SectionHeaders[SectionIndex].Name, IMAGE_SIZEOF_SHORT_NAME);
			AnsiNameString.MaximumLength = IMAGE_SIZEOF_SHORT_NAME;
			AnsiNameString.Length = GetStrnlen(AnsiNameString.Buffer, IMAGE_SIZEOF_SHORT_NAME);
		} else {
			UNICODE_STRING intConv;
			NTSTATUS Status;
			ULONG StringOffset;
			
			if (!RtlCreateUnicodeStringFromAsciiz(&intConv, (PCSZ)SectionHeaders[SectionIndex].Name + 1))
				goto freeall;
			Status = RtlUnicodeStringToInteger(&intConv, 10, &StringOffset);
			RtlFreeUnicodeString(&intConv);
			if (!NT_SUCCESS(Status)) goto freeall;
			ULONG VirtualOffset = pefindrva(SectionHeaders, NtHeaders->FileHeader.NumberOfSections, SymbolTable+(NumSymbols*SYMBOL_SIZE)+StringOffset);
			if (!VirtualOffset) goto freeall;
			AnsiNameString.Buffer = RosSymAllocMem(MAXIMUM_DWARF_NAME_SIZE);
			if (!AnsiNameString.Buffer) goto freeall;
			PCHAR StringTarget = ((PCHAR)ImageStart)+VirtualOffset;
			PCHAR EndOfImage = ((PCHAR)ImageStart) + NtHeaders->OptionalHeader.SizeOfImage;
			if (StringTarget >= EndOfImage) goto freeall;
			ULONG PossibleStringLength = EndOfImage - StringTarget;
			if (PossibleStringLength > MAXIMUM_DWARF_NAME_SIZE)
				PossibleStringLength = MAXIMUM_DWARF_NAME_SIZE;
			RtlCopyMemory(AnsiNameString.Buffer, StringTarget, PossibleStringLength);
			AnsiNameString.Length = strlen(AnsiNameString.Buffer);
			AnsiNameString.MaximumLength = MAXIMUM_DWARF_NAME_SIZE;		  
		}
		memcpy
			(&SectionHeaders[SectionIndex],
			 &AnsiNameString,
			 sizeof(AnsiNameString));
	}
	
	Pe *pe = RosSymAllocMem(sizeof(*pe));
	pe->fd = ImageStart;
	pe->e2 = peget2;
	pe->e4 = peget4;
	pe->e8 = peget8;
	pe->loadbase = (ULONG)ImageStart;
	pe->imagebase = NtHeaders->OptionalHeader.ImageBase;
	pe->imagesize = NtHeaders->OptionalHeader.SizeOfImage;
	pe->nsections = NtHeaders->FileHeader.NumberOfSections;
	pe->sect = SectionHeaders;
	pe->nsymbols = NtHeaders->FileHeader.NumberOfSymbols;
	pe->symtab = malloc(pe->nsymbols * sizeof(CoffSymbol));
	PSYMENT SymbolData = (PSYMENT)
		(((PCHAR)ImageStart) + 
		 pefindrva
		 (pe->sect, 
		  pe->nsections, 
		  NtHeaders->FileHeader.PointerToSymbolTable));
	int i, j;
	for (i = 0, j = 0; i < pe->nsymbols; i++) {
		if ((SymbolData[i].e_scnum < 1) || 
			(SymbolData[i].e_sclass != C_EXT &&
			 SymbolData[i].e_sclass != C_STAT))
			continue;
		int section = SymbolData[i].e_scnum - 1;
		if (SymbolData[i].e.e.e_zeroes) {
			pe->symtab[j].name = malloc(sizeof(SymbolData[i].e.e_name)+1);
			strcpy(pe->symtab[j].name, SymbolData[i].e.e_name);
		} else {
			PCHAR SymbolName = ((PCHAR)ImageStart) + 
				pefindrva
				(pe->sect, 
				 pe->nsections, 
				 NtHeaders->FileHeader.PointerToSymbolTable + 
				 (NtHeaders->FileHeader.NumberOfSymbols * 18) + 
				 SymbolData[i].e.e.e_offset);
			pe->symtab[j].name = malloc(strlen(SymbolName)+1);
			strcpy(pe->symtab[j].name, SymbolName);
		}
		if (pe->symtab[j].name[0] == '.') {
			free(pe->symtab[j].name);
			continue;
		}
		pe->symtab[j].address = pe->sect[section].VirtualAddress + SymbolData[i].e_value;
		j++;
	}
	pe->nsymbols = j;
	pe->loadsection = loadmemsection;
	*RosSymInfo = dwarfopen(pe);  

	return !!*RosSymInfo;
	
freeall:
	if (AnsiNameString.Buffer) RosSymFreeMem(AnsiNameString.Buffer);
	for (SectionIndex = 0; SectionIndex < NtHeaders->FileHeader.NumberOfSections;
		 SectionIndex++)
		RtlFreeAnsiString(ANSI_NAME_STRING(&SectionHeaders[SectionIndex]));
	RosSymFreeMem(SectionHeaders);
	
	return FALSE;
}
コード例 #2
0
ファイル: fromfile.c プロジェクト: HBelusca/NasuTek-Odyssey
BOOLEAN
RosSymCreateFromFile(PVOID FileContext, PROSSYM_INFO *RosSymInfo)
{
    IMAGE_DOS_HEADER DosHeader;
    IMAGE_NT_HEADERS NtHeaders;
    PIMAGE_SECTION_HEADER SectionHeaders;
    unsigned SectionIndex;
    unsigned SymbolTable, NumSymbols;

    /* Load DOS header */
    if (! RosSymSeekFile(FileContext, 0))
    {
        werrstr("Could not rewind file\n");
        return FALSE;
    }
    if (! RosSymReadFile(FileContext, &DosHeader, sizeof(IMAGE_DOS_HEADER)))
    {
        werrstr("Failed to read DOS header %x\n", RosSymStatus);
        return FALSE;
    }
    if (! ROSSYM_IS_VALID_DOS_HEADER(&DosHeader))
    {
        werrstr("Image doesn't have a valid DOS header\n");
        return FALSE;
    }

    /* Load NT headers */
    if (! RosSymSeekFile(FileContext, DosHeader.e_lfanew))
    {
        werrstr("Failed seeking to NT headers\n");
        return FALSE;
    }
    if (! RosSymReadFile(FileContext, &NtHeaders, sizeof(IMAGE_NT_HEADERS)))
    {
        werrstr("Failed to read NT headers\n");
        return FALSE;
    }
    if (! ROSSYM_IS_VALID_NT_HEADERS(&NtHeaders))
    {
        werrstr("Image doesn't have a valid PE header\n");
        return FALSE;
    }

    SymbolTable = NtHeaders.FileHeader.PointerToSymbolTable;
    NumSymbols = NtHeaders.FileHeader.NumberOfSymbols;

    if (!NumSymbols)
    {
        werrstr("Image doesn't have debug symbols\n");
        return FALSE;
    }

    DPRINT("SymbolTable %x NumSymbols %x\n", SymbolTable, NumSymbols);

    /* Load section headers */
    if (! RosSymSeekFile(FileContext, (char *) IMAGE_FIRST_SECTION(&NtHeaders) -
                         (char *) &NtHeaders + DosHeader.e_lfanew))
    {
        werrstr("Failed seeking to section headers\n");
        return FALSE;
    }
    DPRINT("Alloc section headers\n");
    SectionHeaders = RosSymAllocMem(NtHeaders.FileHeader.NumberOfSections
                                    * sizeof(IMAGE_SECTION_HEADER));
    if (NULL == SectionHeaders)
    {
        werrstr("Failed to allocate memory for %u section headers\n",
                NtHeaders.FileHeader.NumberOfSections);
        return FALSE;
    }
    if (! RosSymReadFile(FileContext, SectionHeaders,
                         NtHeaders.FileHeader.NumberOfSections
                         * sizeof(IMAGE_SECTION_HEADER)))
    {
        RosSymFreeMem(SectionHeaders);
        werrstr("Failed to read section headers\n");
        return FALSE;
    }

    // Convert names to ANSI_STRINGs
    for (SectionIndex = 0; SectionIndex < NtHeaders.FileHeader.NumberOfSections;
         SectionIndex++) 
    {
        ANSI_STRING astr;
        if (SectionHeaders[SectionIndex].Name[0] != '/') {
            DPRINT("Short name string %d, %s\n", SectionIndex, SectionHeaders[SectionIndex].Name);
            astr.Buffer = RosSymAllocMem(IMAGE_SIZEOF_SHORT_NAME);
            memcpy(astr.Buffer, SectionHeaders[SectionIndex].Name, IMAGE_SIZEOF_SHORT_NAME);
            astr.MaximumLength = IMAGE_SIZEOF_SHORT_NAME;
            astr.Length = GetStrnlen(astr.Buffer, IMAGE_SIZEOF_SHORT_NAME);
        } else {
            UNICODE_STRING intConv;
            NTSTATUS Status;
            ULONG StringOffset;

            Status = RtlCreateUnicodeStringFromAsciiz(&intConv, (PCSZ)SectionHeaders[SectionIndex].Name + 1);
            if (!NT_SUCCESS(Status)) goto freeall;
            Status = RtlUnicodeStringToInteger(&intConv, 10, &StringOffset);
            RtlFreeUnicodeString(&intConv);
            if (!NT_SUCCESS(Status)) goto freeall;
            if (!RosSymSeekFile(FileContext, SymbolTable + NumSymbols * SYMBOL_SIZE + StringOffset))
                goto freeall;
            astr.Buffer = RosSymAllocMem(MAXIMUM_DWARF_NAME_SIZE);
            if (!RosSymReadFile(FileContext, astr.Buffer, MAXIMUM_DWARF_NAME_SIZE))
                goto freeall;
            astr.Length = GetStrnlen(astr.Buffer, MAXIMUM_DWARF_NAME_SIZE);
            astr.MaximumLength = MAXIMUM_DWARF_NAME_SIZE;		  
            DPRINT("Long name %d, %s\n", SectionIndex, astr.Buffer);
        }
        *ANSI_NAME_STRING(&SectionHeaders[SectionIndex]) = astr;
    }

    DPRINT("Done with sections\n");
    Pe *pe = RosSymAllocMem(sizeof(*pe));
    pe->fd = FileContext;
    pe->e2 = peget2;
    pe->e4 = peget4;
    pe->e8 = peget8;
    pe->nsections = NtHeaders.FileHeader.NumberOfSections;
    pe->sect = SectionHeaders;
    pe->imagebase = pe->loadbase = NtHeaders.OptionalHeader.ImageBase;
    pe->imagesize = NtHeaders.OptionalHeader.SizeOfImage;
    pe->codestart = NtHeaders.OptionalHeader.BaseOfCode;
    pe->datastart = NtHeaders.OptionalHeader.BaseOfData;
    pe->loadsection = loaddisksection;
    *RosSymInfo = dwarfopen(pe);

    return TRUE;

freeall:
    for (SectionIndex = 0; SectionIndex < NtHeaders.FileHeader.NumberOfSections;
         SectionIndex++)
        RtlFreeAnsiString(ANSI_NAME_STRING(&SectionHeaders[SectionIndex]));
    RosSymFreeMem(SectionHeaders);

    return FALSE;
}