Пример #1
0
int main(int argc, char **argv)
{
	int ret = 0;

	if(process_args(argc, argv))
	{
		if(load_mapfile(g_mapfile) && load_elf(g_infile))
		{
			if(fixup_imports() && fixup_nidmap())
			{
				FILE *fp;

				fp = fopen(g_outfile, "wb");
				if(fp != NULL)
				{
					(void) fwrite(g_elfdata, 1, g_elfsize, fp);
					fclose(fp);
				}
				else
				{
					fprintf(stderr, "Error, couldn't open %s for writing\n", g_outfile);
					return 0;
				}
			}
			else
			{
				ret = 1;
			}
			free_data();
		}
		else
		{
			ret = 1;
		}
	}
	else
	{
		print_help();
		ret = 1;
	}

	return ret;
}
Пример #2
0
/**********************************************************************
 *                 PE_CreateModule
 *
 * Create WINE_MODREF structure for loaded HMODULE32, link it into
 * process modref_list, and fixup all imports.
 *
 * Note: hModule must point to a correctly allocated PE image,
 *       with base relocations applied; the 16-bit dummy module
 *       associated to hModule must already exist.
 *
 * Note: This routine must always be called in the context of the
 *       process that is to own the module to be created.
 */
WINE_MODREF *PE_CreateModule( HMODULE hModule,
                              LPCSTR filename, DWORD flags, WIN_BOOL builtin )
{
    DWORD load_addr = (DWORD)hModule;
    IMAGE_NT_HEADERS *nt = PE_HEADER(hModule);
    IMAGE_DATA_DIRECTORY *dir;
    IMAGE_IMPORT_DESCRIPTOR *pe_import = NULL;
    IMAGE_EXPORT_DIRECTORY *pe_export = NULL;
    IMAGE_RESOURCE_DIRECTORY *pe_resource = NULL;
    WINE_MODREF *wm;




    dir = nt->OptionalHeader.DataDirectory+IMAGE_DIRECTORY_ENTRY_EXPORT;
    if (dir->Size)
        pe_export = (PIMAGE_EXPORT_DIRECTORY)RVA(dir->VirtualAddress);

    dir = nt->OptionalHeader.DataDirectory+IMAGE_DIRECTORY_ENTRY_IMPORT;
    if (dir->Size)
        pe_import = (PIMAGE_IMPORT_DESCRIPTOR)RVA(dir->VirtualAddress);

    dir = nt->OptionalHeader.DataDirectory+IMAGE_DIRECTORY_ENTRY_RESOURCE;
    if (dir->Size)
        pe_resource = (PIMAGE_RESOURCE_DIRECTORY)RVA(dir->VirtualAddress);

    dir = nt->OptionalHeader.DataDirectory+IMAGE_DIRECTORY_ENTRY_EXCEPTION;
    if (dir->Size) FIXME("Exception directory ignored\n" );

    dir = nt->OptionalHeader.DataDirectory+IMAGE_DIRECTORY_ENTRY_SECURITY;
    if (dir->Size) FIXME("Security directory ignored\n" );




    dir = nt->OptionalHeader.DataDirectory+IMAGE_DIRECTORY_ENTRY_DEBUG;
    if (dir->Size) TRACE("Debug directory ignored\n" );

    dir = nt->OptionalHeader.DataDirectory+IMAGE_DIRECTORY_ENTRY_COPYRIGHT;
    if (dir->Size) FIXME("Copyright string ignored\n" );

    dir = nt->OptionalHeader.DataDirectory+IMAGE_DIRECTORY_ENTRY_GLOBALPTR;
    if (dir->Size) FIXME("Global Pointer (MIPS) ignored\n" );



    dir = nt->OptionalHeader.DataDirectory+IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG;
    if (dir->Size) FIXME("Load Configuration directory ignored\n" );

    dir = nt->OptionalHeader.DataDirectory+IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT;
    if (dir->Size) TRACE("Bound Import directory ignored\n" );

    dir = nt->OptionalHeader.DataDirectory+IMAGE_DIRECTORY_ENTRY_IAT;
    if (dir->Size) TRACE("Import Address Table directory ignored\n" );

    dir = nt->OptionalHeader.DataDirectory+IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT;
    if (dir->Size)
    {
		TRACE("Delayed import, stub calls LoadLibrary\n" );
		/*
		 * Nothing to do here.
		 */

#ifdef ImgDelayDescr
		/*
		 * This code is useful to observe what the heck is going on.
		 */
		{
		ImgDelayDescr *pe_delay = NULL;
        pe_delay = (PImgDelayDescr)RVA(dir->VirtualAddress);
        TRACE_(delayhlp)("pe_delay->grAttrs = %08x\n", pe_delay->grAttrs);
        TRACE_(delayhlp)("pe_delay->szName = %s\n", pe_delay->szName);
        TRACE_(delayhlp)("pe_delay->phmod = %08x\n", pe_delay->phmod);
        TRACE_(delayhlp)("pe_delay->pIAT = %08x\n", pe_delay->pIAT);
        TRACE_(delayhlp)("pe_delay->pINT = %08x\n", pe_delay->pINT);
        TRACE_(delayhlp)("pe_delay->pBoundIAT = %08x\n", pe_delay->pBoundIAT);
        TRACE_(delayhlp)("pe_delay->pUnloadIAT = %08x\n", pe_delay->pUnloadIAT);
        TRACE_(delayhlp)("pe_delay->dwTimeStamp = %08x\n", pe_delay->dwTimeStamp);
        }
#endif
	}

    dir = nt->OptionalHeader.DataDirectory+IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR;
    if (dir->Size) FIXME("Unknown directory 14 ignored\n" );

    dir = nt->OptionalHeader.DataDirectory+15;
    if (dir->Size) FIXME("Unknown directory 15 ignored\n" );




    wm = (WINE_MODREF *)HeapAlloc( GetProcessHeap(),
                                   HEAP_ZERO_MEMORY, sizeof(*wm) );
    wm->module = hModule;

    if ( builtin )
        wm->flags |= WINE_MODREF_INTERNAL;
    if ( flags & DONT_RESOLVE_DLL_REFERENCES )
        wm->flags |= WINE_MODREF_DONT_RESOLVE_REFS;
    if ( flags & LOAD_LIBRARY_AS_DATAFILE )
        wm->flags |= WINE_MODREF_LOAD_AS_DATAFILE;

    wm->type = MODULE32_PE;
    wm->binfmt.pe.pe_export = pe_export;
    wm->binfmt.pe.pe_import = pe_import;
    wm->binfmt.pe.pe_resource = pe_resource;
    wm->binfmt.pe.tlsindex = -1;

    wm->filename = malloc(strlen(filename)+1);
    strcpy(wm->filename, filename );
    wm->modname = strrchr( wm->filename, '\\' );
    if (!wm->modname) wm->modname = wm->filename;
    else wm->modname++;

    if ( pe_export )
        dump_exports( hModule );

    /* Fixup Imports */

    if (    pe_import
         && !( wm->flags & WINE_MODREF_LOAD_AS_DATAFILE )
         && !( wm->flags & WINE_MODREF_DONT_RESOLVE_REFS )
         && fixup_imports( wm ) )
    {
        /* remove entry from modref chain */
         return NULL;
    }

    return wm;
}
Пример #3
0
/* map a builtin dll in memory and fixup RVAs */
static void *map_dll( const IMAGE_NT_HEADERS *nt_descr )
{
#ifdef HAVE_MMAP
    IMAGE_DATA_DIRECTORY *dir;
    IMAGE_DOS_HEADER *dos;
    IMAGE_NT_HEADERS *nt;
    IMAGE_SECTION_HEADER *sec;
    BYTE *addr;
    DWORD code_start, data_start, data_end;
    const size_t page_size = getpagesize();
    const size_t page_mask = page_size - 1;
    int delta, nb_sections = 2;  /* code + data */
    unsigned int i;

    size_t size = (sizeof(IMAGE_DOS_HEADER)
                   + sizeof(IMAGE_NT_HEADERS)
                   + nb_sections * sizeof(IMAGE_SECTION_HEADER));

    assert( size <= page_size );

    /* module address must be aligned on 64K boundary */
    addr = (BYTE *)((nt_descr->OptionalHeader.ImageBase + 0xffff) & ~0xffff);
    if (wine_anon_mmap( addr, page_size, PROT_READ|PROT_WRITE, MAP_FIXED ) != addr) return NULL;

    dos    = (IMAGE_DOS_HEADER *)addr;
    nt     = (IMAGE_NT_HEADERS *)(dos + 1);
    sec    = (IMAGE_SECTION_HEADER *)(nt + 1);

    /* Build the DOS and NT headers */

    dos->e_magic    = IMAGE_DOS_SIGNATURE;
    dos->e_cblp     = 0x90;
    dos->e_cp       = 3;
    dos->e_cparhdr  = (sizeof(*dos)+0xf)/0x10;
    dos->e_minalloc = 0;
    dos->e_maxalloc = 0xffff;
    dos->e_ss       = 0x0000;
    dos->e_sp       = 0x00b8;
    dos->e_lfarlc   = sizeof(*dos);
    dos->e_lfanew   = sizeof(*dos);

    *nt = *nt_descr;

    delta      = (const BYTE *)nt_descr - addr;
    code_start = page_size;
    data_start = delta & ~page_mask;
    data_end   = (nt->OptionalHeader.SizeOfImage + delta + page_mask) & ~page_mask;

    fixup_rva_ptrs( &nt->OptionalHeader.AddressOfEntryPoint, addr, 1 );

    nt->FileHeader.NumberOfSections                = nb_sections;
    nt->OptionalHeader.BaseOfCode                  = code_start;
#ifndef _WIN64
    nt->OptionalHeader.BaseOfData                  = data_start;
#endif
    nt->OptionalHeader.SizeOfCode                  = data_start - code_start;
    nt->OptionalHeader.SizeOfInitializedData       = data_end - data_start;
    nt->OptionalHeader.SizeOfUninitializedData     = 0;
    nt->OptionalHeader.SizeOfImage                 = data_end;
    nt->OptionalHeader.ImageBase                   = (ULONG_PTR)addr;

    /* Build the code section */

    memcpy( sec->Name, ".text", sizeof(".text") );
    sec->SizeOfRawData = data_start - code_start;
    sec->Misc.VirtualSize = sec->SizeOfRawData;
    sec->VirtualAddress   = code_start;
    sec->PointerToRawData = code_start;
    sec->Characteristics  = (IMAGE_SCN_CNT_CODE | IMAGE_SCN_MEM_EXECUTE | IMAGE_SCN_MEM_READ);
    sec++;

    /* Build the data section */

    memcpy( sec->Name, ".data", sizeof(".data") );
    sec->SizeOfRawData = data_end - data_start;
    sec->Misc.VirtualSize = sec->SizeOfRawData;
    sec->VirtualAddress   = data_start;
    sec->PointerToRawData = data_start;
    sec->Characteristics  = (IMAGE_SCN_CNT_INITIALIZED_DATA |
                             IMAGE_SCN_MEM_WRITE | IMAGE_SCN_MEM_READ);
    sec++;

    for (i = 0; i < nt->OptionalHeader.NumberOfRvaAndSizes; i++)
        fixup_rva_dwords( &nt->OptionalHeader.DataDirectory[i].VirtualAddress, delta, 1 );

    /* Build the import directory */

    dir = &nt->OptionalHeader.DataDirectory[IMAGE_FILE_IMPORT_DIRECTORY];
    if (dir->Size)
    {
        IMAGE_IMPORT_DESCRIPTOR *imports = (void *)(addr + dir->VirtualAddress);
        fixup_imports( imports, addr, delta );
    }

    /* Build the resource directory */

    dir = &nt->OptionalHeader.DataDirectory[IMAGE_FILE_RESOURCE_DIRECTORY];
    if (dir->Size)
    {
        void *ptr = (void *)(addr + dir->VirtualAddress);
        fixup_resources( ptr, ptr, delta );
    }

    /* Build the export directory */

    dir = &nt->OptionalHeader.DataDirectory[IMAGE_FILE_EXPORT_DIRECTORY];
    if (dir->Size)
    {
        IMAGE_EXPORT_DIRECTORY *exports = (void *)(addr + dir->VirtualAddress);
        fixup_exports( exports, addr, delta );
    }
    return addr;
#else  /* HAVE_MMAP */
    return NULL;
#endif  /* HAVE_MMAP */
}
Пример #4
0
int load_pe_images(struct pe_image *pe_image, int n)
{
	struct nt_header *nt_hdr;
	unsigned int nt_hdr_offset;
	int i = 0;
	void *image;
	int size;
	struct optional_header *opt_hdr;

	for (i = 0; i < n; i++)
	{
		image = pe_image[i].image;
		size = pe_image[i].size;

		/* The PE header is found at the RVA specified at offset 3c. */
		if (size < 0x3c + 4)
			return -EINVAL;
		nt_hdr_offset =  *(unsigned int *)(image+0x3c);
		nt_hdr = (struct nt_header *)((char *)image + nt_hdr_offset);
		pe_image[i].type = check_nt_hdr(nt_hdr);
		if (pe_image[i].type <= 0)
			return -EINVAL;

		if (read_exports(image, nt_hdr, pe_image[i].name))
			return -EINVAL;
	}

	for (i = 0; i < n; i++)
	{
		image = pe_image[i].image;
		size = pe_image[i].size;

		nt_hdr_offset =  *(unsigned int *)(image+0x3c);
		nt_hdr = (struct nt_header *)((char *)image + nt_hdr_offset);
		opt_hdr = &nt_hdr->opt_hdr;

		if (fixup_reloc(image, nt_hdr))
			return -EINVAL;
		if (fixup_imports(image, nt_hdr))
			return -EINVAL;
		flush_icache_range(image, pe_image[i].size);

		pe_image[i].entry = RVA2VA(image,
					   opt_hdr->opt_std_hdr.entry_rva,
					   void *);
		DBGTRACE1("entry is at %p, rva at %08X", pe_image[i].entry, 
		     (unsigned int)opt_hdr->opt_std_hdr.entry_rva);
	}
	for (i = 0; i < n; i++)
	{
		image = pe_image[i].image;
		size = pe_image[i].size;

		nt_hdr_offset =  *(unsigned int *)(image+0x3c);
		nt_hdr = (struct nt_header *)((char *)image + nt_hdr_offset);
		opt_hdr = &nt_hdr->opt_hdr;

		if (pe_image[i].type == COFF_CHAR_DLL)
		{
			struct ustring ustring;
			char *buf = "0\0t0m0p00";
			int (*dll_entry)(struct ustring *ustring) STDCALL;

			memset(&ustring, 0, sizeof(ustring));
			ustring.buf = buf;
			dll_entry = (void *)get_dll_init(pe_image[i].name);

			DBGTRACE1("calling dll_init at %p", dll_entry);
			if (!dll_entry || dll_entry(&ustring))
				ERROR("DLL initialize failed for %s",
				      pe_image[i].name);
		}
		else if (pe_image[i].type == COFF_CHAR_IMAGE)
			;
		else
			ERROR("illegal image type: %d", pe_image[i].type);
	}
Пример #5
0
int load_pe_images(struct pe_image *pe_image, int n)
{
	int i;
	struct pe_image *pe;

#ifdef DEBUG
	/* Sanity checkings */
	CHECK_SZ(IMAGE_SECTION_HEADER, IMAGE_SIZEOF_SECTION_HEADER);
	CHECK_SZ(IMAGE_FILE_HEADER, IMAGE_SIZEOF_FILE_HEADER);
	CHECK_SZ(IMAGE_OPTIONAL_HEADER, IMAGE_SIZEOF_NT_OPTIONAL_HEADER);
	CHECK_SZ(IMAGE_NT_HEADERS, 4 + IMAGE_SIZEOF_FILE_HEADER +
		 IMAGE_SIZEOF_NT_OPTIONAL_HEADER);
	CHECK_SZ(IMAGE_DOS_HEADER, 0x40);
	CHECK_SZ(IMAGE_EXPORT_DIRECTORY, 40);
	CHECK_SZ(IMAGE_BASE_RELOCATION, 8);
	CHECK_SZ(IMAGE_IMPORT_DESCRIPTOR, 20);
#endif

	for (i = 0; i < n; i++) {
		IMAGE_DOS_HEADER *dos_hdr;
		pe = &pe_image[i];
		dos_hdr = pe->image;

		if (pe->size < sizeof(IMAGE_DOS_HEADER)) {
			DBGTRACE1("image too small: %d", pe->size);
			return -EINVAL;
		}

		pe->nt_hdr =
			(IMAGE_NT_HEADERS *)(pe->image + dos_hdr->e_lfanew);
		pe->opt_hdr = &pe->nt_hdr->OptionalHeader;

		pe->type = check_nt_hdr(pe->nt_hdr);
		if (pe->type <= 0) {
			DBGTRACE1("type <= 0");
			return -EINVAL;
		}

		if (fix_pe_image(pe)) {
			DBGTRACE1("bad PE image");
			return -EINVAL;
		}

		if (read_exports(pe)) {
			DBGTRACE1("read exports failed");
			return -EINVAL;
		}
	}

	for (i = 0; i < n; i++) {
	        pe = &pe_image[i];

		if (fixup_reloc(pe->image, pe->nt_hdr)) {
			DBGTRACE1("fixup reloc failed");
			return -EINVAL;
		}
		if (fixup_imports(pe->image, pe->nt_hdr)) {
			DBGTRACE1("fixup imports failed");
			return -EINVAL;
		}
#if defined(CONFIG_X86_64)
		INFO("fixing KI_USER_SHARED_DATA address in the driver");
		fix_user_shared_data_addr(pe_image[i].image, pe_image[i].size);
#endif
		flush_icache_range(pe->image, pe->size);

		pe->entry =
			RVA2VA(pe->image,
			       pe->opt_hdr->AddressOfEntryPoint, void *);
		DBGTRACE1("entry is at %p, rva at %08X", pe->entry,
			  pe->opt_hdr->AddressOfEntryPoint);
	}

	for (i = 0; i < n; i++) {
	        pe = &pe_image[i];

		if (pe->type == IMAGE_FILE_DLL) {
			struct unicode_string ustring;
			char *buf = "0/0t0m0p00";
			int (*dll_entry)(struct unicode_string *ustring)
				wstdcall;

			memset(&ustring, 0, sizeof(ustring));
			ustring.buf = (wchar_t *)buf;
			dll_entry = (void *)get_dll_init(pe->name);

			DBGTRACE1("calling dll_init at %p", dll_entry);
			if (!dll_entry || dll_entry(&ustring))
				ERROR("DLL initialize failed for %s",
				      pe->name);
		}
		else if (pe->type != IMAGE_FILE_EXECUTABLE_IMAGE)
			ERROR("illegal image type: %d", pe->type);
	}