Esempio n. 1
0
static int fixup_reloc(void *image, struct nt_header *nt_hdr)
{
	struct section_header *sect_hdr;
	int base = nt_hdr->opt_hdr.opt_nt_hdr.image_base;
	int size;
	struct coffpe_relocs *fixup_block;

	sect_hdr = get_section(nt_hdr, ".reloc");
	if (sect_hdr == NULL)
		return -EINVAL;
	fixup_block = (struct coffpe_relocs *)(image + sect_hdr->rawdata_addr);

	do
	{
		int i;
		uint16_t fixup, offset;

		size = (fixup_block->block_size - (2 * sizeof(uint32_t))) /
			sizeof(uint16_t);
		for (i = 0; i < size; i++)
		{
			uint32_t *loc;
			uint32_t addr;
			fixup = fixup_block->fixup[i];
			offset = fixup & 0xfff;
			loc = RVA2VA(image, fixup_block->page_rva + offset,
				   uint32_t *);

			switch ((fixup >> 12) & 0x0f)
			{
			case COFF_FIXUP_ABSOLUTE:
				break;
			case COFF_FIXUP_HIGHLOW:
				addr = RVA2VA(image, (*loc - base), uint32_t);
				*loc = addr;
				break;
			default:
				ERROR("unknown fixup: %08X", fixup);
				return -EOPNOTSUPP;
				break;
			}
		}
		fixup_block = (struct coffpe_relocs *)
			((size_t)fixup_block + fixup_block->block_size);
	} while (fixup_block->block_size);

	return 0;
}
Esempio n. 2
0
LPVOID search_exp(LPVOID base, DWORD hash)
{
  PIMAGE_DOS_HEADER       dos;
  PIMAGE_NT_HEADERS       nt;
  DWORD                   cnt, rva, dll_h;
  PIMAGE_DATA_DIRECTORY   dir;
  PIMAGE_EXPORT_DIRECTORY exp;
  PDWORD                  adr;
  PDWORD                  sym;
  PWORD                   ord;
  PCHAR                   api, dll;
  LPVOID                  api_adr=NULL;
  
  dos = (PIMAGE_DOS_HEADER)base;
  nt  = RVA2VA(PIMAGE_NT_HEADERS, base, dos->e_lfanew);
  dir = (PIMAGE_DATA_DIRECTORY)nt->OptionalHeader.DataDirectory;
  rva = dir[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress;
  
  // if no export table, return NULL
  if (rva==0) return NULL;
  
  exp = (PIMAGE_EXPORT_DIRECTORY) RVA2VA(ULONG_PTR, base, rva);
  cnt = exp->NumberOfNames;
  
  // if no api names, return NULL
  if (cnt==0) return NULL;
  
  adr = RVA2VA(PDWORD,base, exp->AddressOfFunctions);
  sym = RVA2VA(PDWORD,base, exp->AddressOfNames);
  ord = RVA2VA(PWORD, base, exp->AddressOfNameOrdinals);
  
  do {
    // calculate hash of api string
    api = RVA2VA(PCHAR, base, sym[cnt-1]);
    // add to DLL hash and compare
    if (crc32c(api) + dll_h == hash) {
      // return address of function
      api_adr = RVA2VA(LPVOID, base, adr[ord[cnt-1]]);
      return api_adr;
    }
  } while (--cnt && api_adr==0);
  return api_adr;
}
Esempio n. 3
0
static int fixup_reloc(void *image, IMAGE_NT_HEADERS *nt_hdr)
{
	ULONG_PTR base;
	ULONG_PTR size;
	IMAGE_BASE_RELOCATION *fixup_block;
	IMAGE_DATA_DIRECTORY *base_reloc_data_dir;
	PIMAGE_OPTIONAL_HEADER opt_hdr;

	opt_hdr = &nt_hdr->OptionalHeader;
	base = opt_hdr->ImageBase;
	base_reloc_data_dir =
		&opt_hdr->DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC];
	if (base_reloc_data_dir->Size == 0)
		return 0;

	fixup_block = RVA2VA(image, base_reloc_data_dir->VirtualAddress,
			     IMAGE_BASE_RELOCATION *);
	DBGLINKER("fixup_block=%p, image=%p", fixup_block, image);
	DBGLINKER("fixup_block info: %x %d",
		  fixup_block->VirtualAddress, fixup_block->SizeOfBlock);

	while (fixup_block->SizeOfBlock) {
		int i;
		WORD fixup, offset;

		size = (fixup_block->SizeOfBlock -
			sizeof(IMAGE_BASE_RELOCATION)) / sizeof(WORD);
		DBGLINKER("found %Lu relocations in this block",
			  (uint64_t)size);

		for (i = 0; i < size; i++) {
			fixup = fixup_block->TypeOffset[i];
			offset = fixup & 0xfff;
			switch ((fixup >> 12) & 0x0f) {
			case IMAGE_REL_BASED_ABSOLUTE:
				break;

			case IMAGE_REL_BASED_HIGHLOW: {
				uint32_t addr;
				uint32_t *loc =
					RVA2VA(image,
					       fixup_block->VirtualAddress +
					       offset, uint32_t *);
				addr = RVA2VA(image, (*loc - base), uint32_t);
				DBGLINKER("relocation: *%p (Val:%X)= %X",
					  loc, *loc, addr);
				*loc = addr;
			}
				break;

			case IMAGE_REL_BASED_DIR64: {
				uint64_t addr;
				uint64_t *loc =
					RVA2VA(image,
					       fixup_block->VirtualAddress +
					       offset, uint64_t *);
				addr = RVA2VA(image, (*loc - base), uint64_t);
				DBGLINKER("relocation: *%p (Val:%llX)= %llx",
					  loc, *loc, addr);
				*loc = addr;
			}
				break;

			default:
				ERROR("unknown fixup: %08X",
				      (fixup >> 12) & 0x0f);
				return -EOPNOTSUPP;
				break;
			}
		}
		DBGLINKER("finished relocating block");

		fixup_block = (IMAGE_BASE_RELOCATION *)
			((void *)fixup_block + fixup_block->SizeOfBlock);
	};
	DBGLINKER("done relocating all");

	return 0;
}