Beispiel #1
0
int
pe_relocate(vm_offset_t imgbase)
{
	image_section_header	sect;
	image_base_reloc	*relhdr;
	uint16_t		rel, *sloc;
	uint32_t		base, delta, *lloc;
	int			i, count;
	vm_offset_t		txt;

	base = pe_imagebase(imgbase);
	pe_get_section(imgbase, &sect, ".text");
	txt = pe_translate_addr(imgbase, sect.ish_vaddr);
	delta = (uint32_t)(txt) - base - sect.ish_vaddr;

	pe_get_section(imgbase, &sect, ".reloc");

	relhdr = (image_base_reloc *)(imgbase + sect.ish_rawdataaddr);

	do {
		count = (relhdr->ibr_blocksize -
		    (sizeof(uint32_t) * 2)) / sizeof(uint16_t);
		for (i = 0; i < count; i++) {
			rel = relhdr->ibr_rel[i];
			switch (IMR_RELTYPE(rel)) {
			case IMAGE_REL_BASED_ABSOLUTE:
				break;
			case IMAGE_REL_BASED_HIGHLOW:
				lloc = (uint32_t *)pe_translate_addr(imgbase,
				    relhdr->ibr_vaddr + IMR_RELOFFSET(rel));
				*lloc = pe_translate_addr(imgbase,
				    (*lloc - base));
				break;
			case IMAGE_REL_BASED_HIGH:
				sloc = (uint16_t *)pe_translate_addr(imgbase,
				    relhdr->ibr_vaddr + IMR_RELOFFSET(rel));
				*sloc += (delta & 0xFFFF0000) >> 16;
				break;
			case IMAGE_REL_BASED_LOW:
				sloc = (uint16_t *)pe_translate_addr(imgbase,
				    relhdr->ibr_vaddr + IMR_RELOFFSET(rel));
				*sloc += (delta & 0xFFFF);
				break;
			default:
				kprintf ("[%d]reloc type: %d\n",i,
				    IMR_RELTYPE(rel));
				break;
			}
		}
		relhdr = (image_base_reloc *)((vm_offset_t)relhdr +
		    relhdr->ibr_blocksize);
	} while (relhdr->ibr_blocksize);

	return(0);
}
BOOL CRemoteLoader::ProcessRelocation( INT ImageBaseDelta, WORD Data, PBYTE RelocationBase )
{
	BOOL bReturn = TRUE;

	switch( IMR_RELTYPE( Data ) )
	{
	case IMAGE_REL_BASED_ABSOLUTE:
		{
			DebugShout( "[ProcessRelocation] IMAGE_REL_BASED_ABSOLUTE" );

			break;
		}
	case IMAGE_REL_BASED_HIGH:
		{
			SHORT* Raw		= reinterpret_cast< SHORT* >( RelocationBase + IMR_RELOFFSET( Data ) );
			SHORT Backup	= *Raw;

			*Raw += HIWORD( ImageBaseDelta );

			DebugShout( "[ProcessRelocation] IMAGE_REL_BASED_HIGH (0x%X) -> (0x%X)", 
				Backup, *Raw );

			break;
		}
	case IMAGE_REL_BASED_LOW:
		{
			SHORT* Raw		= reinterpret_cast< SHORT* >( RelocationBase + IMR_RELOFFSET( Data ) );
			SHORT Backup	= *Raw;

			*Raw += LOWORD( ImageBaseDelta );

			DebugShout( "[ProcessRelocation] IMAGE_REL_BASED_LOW (0x%X) -> (0x%X)", 
				Backup, *Raw );

			break;
		}
	case IMAGE_REL_BASED_HIGHLOW:
		{
			DWORD32* Raw	= reinterpret_cast< DWORD32* >( RelocationBase + IMR_RELOFFSET( Data ) );
			DWORD32 Backup	= *Raw;

			*Raw += ImageBaseDelta;

			DebugShout( "[ProcessRelocation] IMAGE_REL_BASED_HIGHLOW (0x%X) -> (0x%X)", 
				Backup, *Raw );

			break;
		}
	case IMAGE_REL_BASED_DIR64:
		{
			DWORD64* Raw	= reinterpret_cast< DWORD64* >( RelocationBase + IMR_RELOFFSET( Data ) );
			DWORD64 Backup	= *Raw;

			*Raw += ImageBaseDelta;

			DebugShout( "[ProcessRelocation] IMAGE_REL_BASED_DIR64 (0x%X) -> (0x%X)", 
				Backup, *Raw );

			break;
		}
	case IMAGE_REL_BASED_HIGHADJ:
		{
			DebugShout( "[ProcessRelocation] IMAGE_REL_BASED_HIGHADJ" );

			break;
		}
	default:
		{
			DebugShout( "[ProcessRelocation] UNKNOWN RELOCATION (0x%X)", IMR_RELTYPE( Data ) );

			bReturn = FALSE;

			break;
		}
	}

	return bReturn;
}