Exemple #1
0
void addDir32NBReloc(COFFBaseDefinedAtom *atom, const Atom *target,
                     llvm::COFF::MachineTypes machine, size_t offsetInAtom) {
  switch (machine) {
  case llvm::COFF::IMAGE_FILE_MACHINE_I386:
    addReloc(atom, target, offsetInAtom, Reference::KindArch::x86,
             llvm::COFF::IMAGE_REL_I386_DIR32NB);
    return;
  case llvm::COFF::IMAGE_FILE_MACHINE_AMD64:
    addReloc(atom, target, offsetInAtom, Reference::KindArch::x86_64,
             llvm::COFF::IMAGE_REL_AMD64_ADDR32NB);
    return;
  default:
    llvm_unreachable("unsupported machine type");
  }
}
Exemple #2
0
static void doReloc( asm_reloc *reloc, ins_operand *op, owl_reloc_type rtype, uint_32 *offset ) {
//***********************************************************************************************

    if( op == NULL ) return;
    if( !( OP_HAS_RELOC( op ) ) ) return;
    addReloc( reloc, op->reloc.target, relocType( op->reloc.type, rtype ),
              (unsigned)( (char *)offset - (char *)result ), ( op->flags & RELOC ) );
}
Exemple #3
0
HOOKINFO *hookAPIFunction(const char *lib, const char *func, unsigned char *hookFunction)
{
	HOOKINFO *hook = NULL;
	int routineCodeSize = 0;
	unsigned char *originalProc = NULL;
	unsigned char *codeBytePtr = NULL;
	HMODULE hlib = NULL;
	DWORD oldProtection = 0;
	int maxCodeLength = 1024;

	unsigned char opCode;
	
	void *newFunc = NULL;

	void *requiredFunctionAddress = NULL;

	if (!hookInit)
		is64BitProcess();

	hlib = LoadLibraryA(lib);

	originalProc = (unsigned char *)GetProcAddress(hlib, func);

	codeBytePtr = originalProc;

	int off;

	hook = allocStructMem(HOOKINFO);

	if (!hook)
		return NULL;

	while (routineCodeSize == 0)
	{
		if (maxCodeLength-- <= 0)
			return NULL;

		switch (*codeBytePtr)
		{
			case OC_RET:
			{
				opCode = *(codeBytePtr + 1);

				//bak bakalim gercekten rutin sonunda miyiz?
				if (opCode == 0x90 || opCode == 0xcc || opCode == 0x00)
				{
					routineCodeSize = ((codeBytePtr + 1) - originalProc);

					if (verbose)
						xprintf("+ RET\n\n");
				}
			}
			break;
			case OC_RET_N:
			{
				opCode = *(codeBytePtr + 2);

				if (opCode == 0x90 || opCode == 0xcc || opCode == 0x00)
				{
					routineCodeSize = ((codeBytePtr + 3) - originalProc); //ret + 2 byte rel16 byte ret val
					
					if (verbose)
						xprintf("+ RET X\n\n");
				}
			}
			break;
			case OC_CALL_REL:
			{
				if (isMov(*(codeBytePtr - 1)))
					break;

				off = *((int *)(codeBytePtr + 1));
				addReloc(hook,codeBytePtr + 1, off,4);

				if (verbose)
					xprintf("CALL_R8 found at 0x%p -> RELOFFSET: %x (%d)\n\n", codeBytePtr, off,off);

				codeBytePtr += 4;

			}
			break;
			case OC_CALL_MODRM:
			{
				//check previous opcode is one of the MOV opcode.
				//0xFF is EDI,EDI operand for MOV
				if (isMov(*(codeBytePtr - 1)))
					break;

				if (getInstrByModrm(*(codeBytePtr + 1)) == OCX_CALL)
				{
					off = *((int *)(codeBytePtr + 2));
					addReloc(hook,codeBytePtr + 2, off, 4);

					if (verbose)
						xprintf("MODRM based CALL found at 0x%p -> RELOFFSET: %x (%d)\n\n", codeBytePtr, off,off);

					//detect size
				}
			}
			break;
			case OC_JCC_NEAR: //two byte len
			{
				//0x80 - 0x8F kosullu dallanma komutlari

				opCode = *(codeBytePtr + 1);

				if (opCode >= OC_JCC_BEGIN && opCode <= OC_JCC_END)
				{
					off = *((int *)(codeBytePtr + 1 + 1));

					addReloc(hook,codeBytePtr + 2, off, 4);

					if (verbose)
						xprintf("REL_JCC found at 0x%p -> RELOFFSET: %x (%d)\n\n", codeBytePtr, off, off);
					
					
					codeBytePtr += 6;
				}
			}
			break;
		}

		codeBytePtr++;
	}

	
	
	requiredFunctionAddress = originalProc - routineCodeSize - 1024;

	newFunc = NULL;

	while (newFunc == NULL)
	{
		//nop alani icin ekstradan 32 byte bellek iste
		newFunc = VirtualAlloc(requiredFunctionAddress, routineCodeSize + 32, MEM_RESERVE | MEM_COMMIT, PAGE_EXECUTE_READWRITE);
		
		requiredFunctionAddress = ((unsigned char *)requiredFunctionAddress) - 0x1000;

	}

	//Yeni kod bellek bolgesini Nop ile dolduralim cop opcode kalmasin.
	memset(newFunc, 0x90, routineCodeSize + 32);
	
	//orjinal fonksiyon kodunu yeni alana tasiyoruz.
	memcpy(newFunc, originalProc, routineCodeSize);

	//orjinal kod bellek bolgesinin readonly modunu readwrite yapiyoruz.
	if (!VirtualProtect(originalProc, routineCodeSize, PAGE_EXECUTE_READWRITE, &oldProtection))
	{
		xprintf("original code page could not switch to r/w mode");
		VirtualFree(newFunc, routineCodeSize + 32, MEM_RELEASE);

		return NULL;
	}
	
	//orjinal bellek bolgesini nopluyoruz. guvenli olmasi icin
	memset(originalProc, 0x90, routineCodeSize);

	//x64

	//64 bit ise hook fonksiyonumuzun yeri 64 bit araligina giren bir noktada
	//olabilir. o yuzden 64 bit bir registera adresi alip oraya zipliyoruz
	if (is64bit)
	{
		//64 bit trambolin fonksiyon cagrisi

		//mov rax, 64BIT_FUNCTION_ADDRESS
		//jmp rax

		*originalProc = (unsigned char)0x48;
		*(originalProc + 1) = (unsigned char)0xB8;
		*((long long int *)(originalProc + 2)) = (long long int)hookFunction;

		*((unsigned short *)(originalProc + 10)) = 0xe0ff;

	}
	else
	{ 
		//32 bit tramboline cagri
		//32 bit ise normal bir jump ile bolgeye ziplayabiliriz.
		
		//JMP NEW_RELATIVE_OFFSET

		int jmpOffset = ((unsigned char *)originalProc) - hookFunction;


		jmpOffset = -jmpOffset;
		jmpOffset -= 5; //our jmp instruction size


		*originalProc = (unsigned char)0xE9;

		*((int *)(originalProc + 1)) = jmpOffset;
	}

	VirtualProtect(originalProc, routineCodeSize, oldProtection, &oldProtection);


	xprintf("Original Function Location: 0x%p\n", originalProc);
	xprintf("New Function Location: 0x%p\n", newFunc);

	for (relocBranchList *beg = hook->relocList->head; beg != NULL; beg = beg->next)
	{
		recalculateAndPatch(originalProc, (unsigned char *)newFunc, beg->rbi);
	}

	hook->originalApi = newFunc;
	hook->hookFunction = hookFunction;

	return hook;
}