⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pe_linker.c

📁 ndis在linux下的无线网卡驱动源码
💻 C
📖 第 1 页 / 共 2 页
字号:
/* *  Copyright (C) 2003-2005 Pontus Fuchs, Giridhar Pemmasani * *  This program is free software; you can redistribute it and/or modify *  it under the terms of the GNU General Public License as published by *  the Free Software Foundation; either version 2 of the License, or *  (at your option) any later version. * *  This program is distributed in the hope that it will be useful, *  but WITHOUT ANY WARRANTY; without even the implied warranty of *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *  GNU General Public License for more details. * */#ifdef TEST_LOADER#include "usr_linker.h"#else#include <linux/types.h>#include <asm/errno.h>//#define DEBUGLINKER 2#include "ntoskernel.h"#endifstruct pe_exports {	char *dll;	char *name;	generic_func addr;};static struct pe_exports pe_exports[40];static int num_pe_exports;#if defined(CONFIG_X86_64)extern struct kuser_shared_data kuser_shared_data;#endif#define RVA2VA(image, rva, type) (type)(ULONG_PTR)((void *)image + rva)#define CHECK_SZ(a,b) { if (sizeof(a) != b) {				\			ERROR("%s is bad, got %zd, expected %d",	\			      #a , sizeof(a), (b)); return -EINVAL; } }#if defined(DEBUGLINKER) && DEBUGLINKER > 0#define DBGLINKER(fmt, ...) printk(KERN_INFO "%s (%s:%d): " fmt "\n",	\				   DRIVER_NAME, __FUNCTION__,		\				   __LINE__ , ## __VA_ARGS__);static const char *image_directory_name[] = {	"EXPORT",	"IMPORT",	"RESOURCE",	"EXCEPTION",	"SECURITY",	"BASERELOC",	"DEBUG",	"COPYRIGHT",	"GLOBALPTR",	"TLS",	"LOAD_CONFIG",	"BOUND_IMPORT",	"IAT",	"DELAY_IMPORT",	"COM_DESCRIPTOR" };#else#define DBGLINKER(fmt, ...) do { } while (0)#endif#ifndef TEST_LOADERextern struct wrap_export ntoskernel_exports[], ntoskernel_io_exports[],	ndis_exports[], crt_exports[], hal_exports[], rtl_exports[];#ifdef CONFIG_USBextern struct wrap_export usb_exports[];#endifstatic char *get_export(char *name){	int i;	for (i = 0 ; ntoskernel_exports[i].name != NULL; i++)		if (strcmp(ntoskernel_exports[i].name, name) == 0)			return (char *)ntoskernel_exports[i].func;	for (i = 0 ; ntoskernel_io_exports[i].name != NULL; i++)		if (strcmp(ntoskernel_io_exports[i].name, name) == 0)			return (char *)ntoskernel_io_exports[i].func;	for (i = 0 ; ndis_exports[i].name != NULL; i++)		if (strcmp(ndis_exports[i].name, name) == 0)			return (char *)ndis_exports[i].func;	for (i = 0 ; crt_exports[i].name != NULL; i++)		if (strcmp(crt_exports[i].name, name) == 0)			return (char *)crt_exports[i].func;	for (i = 0 ; hal_exports[i].name != NULL; i++)		if (strcmp(hal_exports[i].name, name) == 0)			return (char *)hal_exports[i].func;	for (i = 0 ; rtl_exports[i].name != NULL; i++)		if (strcmp(rtl_exports[i].name, name) == 0)			return (char *)rtl_exports[i].func;#ifdef CONFIG_USB	for (i = 0 ; usb_exports[i].name != NULL; i++)		if (strcmp(usb_exports[i].name, name) == 0)			return (char *)usb_exports[i].func;#endif	for (i = 0; i < num_pe_exports; i++)		if (strcmp(pe_exports[i].name, name) == 0)			return (char *)pe_exports[i].addr;	return NULL;}#endif // TEST_LOADERstatic void *get_dll_init(char *name){	int i;	for (i = 0; i < num_pe_exports; i++)		if ((strcmp(pe_exports[i].dll, name) == 0) &&		    (strcmp(pe_exports[i].name, "DllInitialize") == 0))			return (void *)pe_exports[i].addr;	return NULL;}/* * Find and validate the coff header * */static int check_nt_hdr(IMAGE_NT_HEADERS *nt_hdr){	int i;	WORD attr;	PIMAGE_OPTIONAL_HEADER opt_hdr;	/* Validate the "PE\0\0" signature */	if (nt_hdr->Signature != IMAGE_NT_SIGNATURE) {		ERROR("is this driver file? bad signature %08x",		      nt_hdr->Signature);		return -EINVAL;	}	opt_hdr = &nt_hdr->OptionalHeader;	/* Make sure Image is PE32 or PE32+ */#ifdef CONFIG_X86_64	if (opt_hdr->Magic != IMAGE_NT_OPTIONAL_HDR64_MAGIC) {		ERROR("kernel is 64-bit, but Windows driver is not 64-bit;"		      "bad magic: %04X", opt_hdr->Magic);		return -EINVAL;	}#else	if (opt_hdr->Magic != IMAGE_NT_OPTIONAL_HDR32_MAGIC) {		ERROR("kernel is 32-bit, but Windows driver is not 32-bit;"		      "bad magic: %04X", opt_hdr->Magic);		return -EINVAL;	}#endif	/* Validate the image for the current architecture. */#ifdef CONFIG_X86_64	if (nt_hdr->FileHeader.Machine != IMAGE_FILE_MACHINE_AMD64) {		ERROR("kernel is 64-bit, but Windows driver is not 64-bit;"		      " (PE signature is %04X)", nt_hdr->FileHeader.Machine);		return -EINVAL;	}#else	if (nt_hdr->FileHeader.Machine != IMAGE_FILE_MACHINE_I386) {		ERROR("kernel is 32-bit, but Windows driver is not 32-bit;"		      " (PE signature is %04X)", nt_hdr->FileHeader.Machine);		return -EINVAL;	}#endif	/* Must have attributes */#ifdef CONFIG_X86_64	attr = IMAGE_FILE_EXECUTABLE_IMAGE | IMAGE_FILE_LARGE_ADDRESS_AWARE;#else	attr = IMAGE_FILE_EXECUTABLE_IMAGE | IMAGE_FILE_32BIT_MACHINE;#endif	if ((nt_hdr->FileHeader.Characteristics & attr) != attr)		return -EINVAL;	/* Must be relocatable */	attr = IMAGE_FILE_RELOCS_STRIPPED;	if ((nt_hdr->FileHeader.Characteristics & attr))		return -EINVAL;	/* Make sure we have at least one section */	if (nt_hdr->FileHeader.NumberOfSections == 0)		return -EINVAL;	if (opt_hdr->SectionAlignment < opt_hdr->FileAlignment) {		ERROR("alignment mismatch: secion: 0x%x, file: 0x%x",		      opt_hdr->SectionAlignment, opt_hdr->FileAlignment);		return -EINVAL;	}	DBGLINKER("number of datadictionary entries %d",		  opt_hdr->NumberOfRvaAndSizes);	for (i = 0; i < opt_hdr->NumberOfRvaAndSizes; i++) {		DBGLINKER("datadirectory %s RVA:%X Size:%d",			  (i<=IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR)?			  image_directory_name[i] : "unknown",			  opt_hdr->DataDirectory[i].VirtualAddress,			  opt_hdr->DataDirectory[i].Size);	}	if ((nt_hdr->FileHeader.Characteristics & IMAGE_FILE_DLL))		return IMAGE_FILE_DLL;	if ((nt_hdr->FileHeader.Characteristics & IMAGE_FILE_EXECUTABLE_IMAGE))		return IMAGE_FILE_EXECUTABLE_IMAGE;	return -EINVAL;}static int import(void *image, IMAGE_IMPORT_DESCRIPTOR *dirent, char *dll){	ULONG_PTR *lookup_tbl, *address_tbl;	char *symname = NULL;	int i;	int ret = 0;	void *adr;	lookup_tbl  = RVA2VA(image, dirent->u.OriginalFirstThunk, ULONG_PTR *);	address_tbl = RVA2VA(image, dirent->FirstThunk, ULONG_PTR *);	for (i = 0; lookup_tbl[i]; i++) {		if (IMAGE_SNAP_BY_ORDINAL(lookup_tbl[i])) {			ERROR("ordinal import not supported: %Lu",			      (uint64_t)lookup_tbl[i]);			return -1;		}		else {			symname = RVA2VA(image,					 ((lookup_tbl[i] &					   ~IMAGE_ORDINAL_FLAG) + 2), char *);		}		adr = get_export(symname);		if (adr == NULL) {			ERROR("unknown symbol: %s:'%s'", dll, symname);			ret = -1;		} else {			DBGLINKER("found symbol: %s:%s: addr: %p, rva = %Lu",				  dll, symname, adr, (uint64_t)address_tbl[i]);			address_tbl[i] = (ULONG_PTR)adr;		}	}	return ret;}static int read_exports(struct pe_image *pe){	IMAGE_EXPORT_DIRECTORY *export_dir_table;	uint32_t *export_addr_table;	int i;	uint32_t *name_table;	PIMAGE_OPTIONAL_HEADER opt_hdr;	IMAGE_DATA_DIRECTORY *export_data_dir;	opt_hdr = &pe->nt_hdr->OptionalHeader;	export_data_dir =		&opt_hdr->DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT];	if (export_data_dir->Size == 0) {		DBGLINKER("no exports");		return 0;	}	export_dir_table =		RVA2VA(pe->image, export_data_dir->VirtualAddress,		       IMAGE_EXPORT_DIRECTORY *);	name_table = (unsigned int *)(pe->image +				      export_dir_table->AddressOfNames);	export_addr_table = (uint32_t *)		(pe->image + export_dir_table->AddressOfFunctions);	for (i = 0; i < export_dir_table->NumberOfNames; i++) {		if (export_data_dir->VirtualAddress <= *export_addr_table ||		    *export_addr_table >= (export_data_dir->VirtualAddress +					   export_data_dir->Size))			DBGLINKER("forwarder rva");		DBGLINKER("export symbol: %s, at %p",			  (char *)(pe->image + *name_table),			  pe->image + *export_addr_table);		pe_exports[num_pe_exports].dll = pe->name;		pe_exports[num_pe_exports].name = pe->image + *name_table;		pe_exports[num_pe_exports].addr =			pe->image + *export_addr_table;		num_pe_exports++;		name_table++;		export_addr_table++;	}	return 0;}static int fixup_imports(void *image, IMAGE_NT_HEADERS *nt_hdr)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -