コード例 #1
0
ファイル: HDTools.cpp プロジェクト: AloneFallen/wog
DWORD HDTools::GetFunctionLength(LPVOID begin)
{
	size_t end = GetFunctionEnd((size_t)begin);
	DWORD delta = (DWORD)((DWORD_PTR)end - (DWORD_PTR)begin);
	delta    += hde_disasm((void*)end);
	return delta;
}
コード例 #2
0
ファイル: khook.cpp プロジェクト: 12019/apilogger
//Creates stub function. And jump to target+5 bytes
void* GetSafeFuncStartOrig(void *addr){
	//malloc for code
	void *p = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, 32);
	if(!p) return 0;

	//Damn antivirals trick
	PFN_VirtualProtectEx pVirtualProtectEx = (PFN_VirtualProtectEx)(GetProcAddress( g_hKernel32, "VirtualProtectEx" ) );

	DWORD dwTemp;
	pVirtualProtectEx((HANDLE)(-1), (LPVOID)p, 32, PAGE_EXECUTE_READWRITE, &dwTemp);	

	BYTE *pcode=(BYTE*)addr;
	DWORD code_len=0;
	while(code_len<5){
		HDE_STRUCT hdestr={0};
		DWORD instr_len=hde_disasm(pcode, &hdestr);
		code_len+=instr_len;
		pcode+=instr_len;
		//FIX: opcode tests here
	}
	memcpy((void*)p, addr, code_len);
	pcode=(BYTE*)p+code_len;
	*pcode=0xE9;
	*(DWORD*)(pcode+1)=(DWORD)((DWORD)((BYTE*)addr+code_len)-(DWORD)pcode-5);
	return p;
}
コード例 #3
0
ファイル: HDTools.cpp プロジェクト: AloneFallen/wog
size_t GetBranchListFromBlock(size_t block, size_t* branchList, DWORD& branchIdx)
{
	unsigned char* ptr = (unsigned char* )block;

	//	If we reach an end-point, then this block is complete
	while(!IsEndPoint(ptr, block))
	{
		//	Record all branching instructions that we encounter
		size_t address = GetBranchAddress(ptr);
		if(address)
			branchList[branchIdx++] = address;

		//	Next instruction
		ptr += hde_disasm(ptr);
	}

	return (size_t)(ptr);
}
コード例 #4
0
ファイル: khook.cpp プロジェクト: 12019/apilogger
int IsShortFunc(LPVOID addr){
	int res=0;

	DWORD code_len=0;
	BYTE* pcode = (BYTE*)addr;

	while(code_len<5){
		HDE_STRUCT hdestr={0};
		DWORD instr_len=hde_disasm(pcode, &hdestr);
		BYTE Opcode = *pcode;
		code_len += instr_len;
		pcode    += instr_len;
		if(Opcode==0xC3 || Opcode==0xC2){//retn , retn NN
			res=1;
			break;
		}
	}

	if( res == 0 ){//Long function
		return 0;
	}

	if( code_len >= 5 ){//5 bytes len function
		return 0;
	}

	DWORD CheckLen = 5 - code_len;
	DWORD FilledWithCC = 1;
	for( DWORD i = 0; i < CheckLen; i++ ){
		if( (pcode[i] != 0xCC) && (pcode[i] != 0x90) ){//Check for 0xCC or 0x90 after RETN -> compiler code alignment
			FilledWithCC = 0;
		}
	}
	if( FilledWithCC ){
		res = 0;
	}
	return res;
}
コード例 #5
0
ファイル: khook.cpp プロジェクト: 12019/apilogger
//Creates stub function. And jump to target+5 bytes
void* GetSafeFuncStart(void *addr){
	//malloc for code
	void *p=MemAlloc(32);
	if(!p) return 0;

	DWORD dwTemp;
	safe_VirtualProtectEx((HANDLE)(-1), (LPVOID)p, 32, PAGE_EXECUTE_READWRITE, &dwTemp);	
	
	BYTE *pcode=(BYTE*)addr;
	DWORD code_len=0;
	while(code_len<5){
		HDE_STRUCT hdestr={0};
		DWORD instr_len=hde_disasm(pcode, &hdestr);
		code_len+=instr_len;
		pcode+=instr_len;
		//FIX: opcode tests here
	}
	memcpy((void*)p, addr, code_len);
	pcode=(BYTE*)p+code_len;
	*pcode=0xE9;
	*(DWORD*)(pcode+1)=(DWORD)((DWORD)((BYTE*)addr+code_len)-(DWORD)pcode-5);
	return p;
}
コード例 #6
0
	bool CreateTrampolineFunction(CREATE_TREMPOLINE_T& ct)
	{
		assert(("CreateTrampolineFunction", ct.pTarget != NULL));

#if defined _M_X64
		CALL_ABS call = { 0x15FF, 0x00000000 };
		JMP_ABS  jmp  = { 0x25FF, 0x00000000 };
		JCC_ABS  jcc  = { 0x70, 0x02, 0xEB, 0x06, 0x25FF, 0x00000000 };
#elif defined _M_IX86
		CALL_REL call = { 0xE8, 0x00000000 };
		JMP_REL  jmp  = { 0xE9, 0x00000000 };
		JCC_REL  jcc  = { 0x800F, 0x00000000 };
#endif

		size_t    oldPos = 0;
		size_t    newPos = 0;
		uintptr_t jmpDest = 0;		// 関数内ジャンプの飛び先アドレス(分岐中判定に使用)
		bool      finished = false;	// 関数終了フラグ
		while (!finished)
		{
			uint8_t *pInst = reinterpret_cast<uint8_t*>(ct.pTarget) + oldPos;
			hde_t hs;
			hde_disasm(pInst, &hs);
			if ((hs.flags & F_ERROR) == F_ERROR)
			{
				return false;
			}

			void*  pCopySrc = pInst;
			size_t copySize = hs.len;

			if (pInst - reinterpret_cast<uint8_t*>(ct.pTarget) >= sizeof(JMP_REL))
			{
				// ターゲット関数へのジャンプを書き込み、関数を終了
				AppendTempAddress(reinterpret_cast<uintptr_t>(pInst), newPos, jmp, ct);

				pCopySrc = &jmp;
				copySize = sizeof(jmp);

				finished = true;
			}
#if defined _M_X64
			// RIP相対アドレッシングを使用している命令 (ModR/M = 00???101B)
			else if ((hs.modrm & 0xC7) == 0x05)
			{
				// RIP相対アドレスのみ書き換え
				AppendRipRelativeAddress(pInst, newPos, hs, ct);

				// JMP (FF /4)なら関数を終了
				if (hs.opcode == 0xFF && hs.modrm_reg == 4)
				{
					finished = true;
				}
			}
#endif
			// 相対直接CALL
			else if (hs.opcode == 0xE8)
			{
				AppendTempAddress(GetRelativeBranchDestination(pInst, hs, false), newPos, call, ct);
				pCopySrc = &call;
				copySize = sizeof(call);
			}
			// 相対直接JMP (EB or E9)
			else if ((hs.opcode & 0xFD) == 0xE9)
			{
				uintptr_t dest = GetRelativeBranchDestination(pInst, hs, hs.opcode == 0xEB);

				// 関数内へのジャンプはそのままコピー(ジャンプ中は命令長が変わるような操作は不可)
				if (IsInternalJump(ct.pTarget, dest))
				{
					jmpDest = std::max<uintptr_t>(jmpDest, dest);
				}
				else
				{
					AppendTempAddress(dest, newPos, jmp, ct);
					pCopySrc = &jmp;
					copySize = sizeof(jmp);

					// 分岐中でなければ関数を終了
					finished = (reinterpret_cast<uintptr_t>(pInst) >= jmpDest);
				}
			}
			// 相対直接Jcc
			else if ((hs.opcode & 0xF0) == 0x70 || (hs.opcode & 0xFC) == 0xE0 || (hs.opcode2 & 0xF0) == 0x80)
			{
				uintptr_t dest = GetRelativeBranchDestination(pInst, hs, (hs.opcode & 0xF0) == 0x70 || (hs.opcode & 0xFC) == 0xE0);

				// 関数内へのジャンプはそのままコピー(分岐中は命令長が変わるような操作は不可)
				if (IsInternalJump(ct.pTarget, dest))
				{
					jmpDest = std::max<uintptr_t>(jmpDest, dest);
				}
				else if ((hs.opcode & 0xFC) == 0xE0) // 関数外へのJCXZ, JECXZ には対応しない
				{
					return false;
				}
				else
				{
					AppendTempAddress(dest, newPos, jcc, ct);
					SetJccOpcode(hs, jcc);
					pCopySrc = &jcc;
					copySize = sizeof(jcc);
				}
			}
			// RET (C2 or C3)
			else if ((hs.opcode & 0xFE) == 0xC2)
			{
				// 分岐中でなければトランポリン関数を終了
				finished = (reinterpret_cast<uintptr_t>(pInst) >= jmpDest);
			}

			// 分岐中は命令長が変わるような操作は不可
			if (reinterpret_cast<uintptr_t>(pInst) < jmpDest && copySize != hs.len)
			{
				return false;
			}

			ct.trampoline.resize(newPos + copySize);
			memcpy(&ct.trampoline[ newPos ], pCopySrc, copySize);

			ct.oldIPs.push_back(oldPos);
			oldPos += hs.len;
			ct.newIPs.push_back(newPos);
			newPos += copySize;
		}

		// Is there enough place for a long jump?
		if (oldPos < sizeof(JMP_REL) && !IsCodePadding(reinterpret_cast<uint8_t*>(ct.pTarget) + oldPos, sizeof(JMP_REL) - oldPos))
		{
			// Is there enough place for a short jump?
			if (oldPos < sizeof(JMP_REL_SHORT) && !IsCodePadding(reinterpret_cast<uint8_t*>(ct.pTarget) + oldPos, sizeof(JMP_REL_SHORT) - oldPos))
			{
				return false;
			}

			// Can we place the long jump above the function?
			if (!IsExecutableAddress(reinterpret_cast<uint8_t*>(ct.pTarget) - sizeof(JMP_REL)))
			{
				return false;
			}

			if (!IsCodePadding(reinterpret_cast<uint8_t*>(ct.pTarget) - sizeof(JMP_REL), sizeof(JMP_REL)))
			{
				return false;
			}

			ct.patchAbove = true;
		}

		return true;
	}
コード例 #7
0
ファイル: khook.cpp プロジェクト: 12019/apilogger
void* KHOOK::operator new(size_t size, LPCVOID addr, LPCVOID stub, int *pError, DWORD PushID){
	
	if(IsShortFunc((LPVOID)addr)){
		*pError=LESS_5_BYTE;
		return 0;
	}

	DWORD dwTemp=0;
	if(!safe_VirtualProtectEx((HANDLE)(-1), (LPVOID)addr, 32, PAGE_EXECUTE_READWRITE, &dwTemp)){
		*pError=KHOOK::PAGE_PROT_ERR;
		return 0;
	}

	KHOOK *pHook=(KHOOK*)MemAlloc(sizeof(KHOOK));
	if(!pHook){
		*pError=MEMALLOC_ERR;
		return 0;
	}
	
	pHook->addr=addr;
	pHook->stub=stub;
	pHook->code_len=0;
	pHook->ReassembledCodeLen = 0;

	BYTE* pDst  = (BYTE*)pHook->exec_buf;//dst
	BYTE *pcode = (BYTE*)addr;			//src

	while(pHook->code_len < 5){
		HDE_STRUCT hdestr = {0};
		DWORD instr_len = hde_disasm(pcode, &hdestr);
		
		//reassemble copy
		DWORD NewInstrLen = pHook->ReAssembleInstr((BYTE*)addr, pcode, pDst, instr_len);

		pHook->code_len += instr_len;
		pHook->ReassembledCodeLen += NewInstrLen;
		pcode += instr_len;
		pDst  += NewInstrLen;
	}

	//Save original bytes for restore hook
	memcpy((void*)pHook->orig_bytes, addr, pHook->code_len);


	//push id
	//jmp Stub
	pHook->push_id[0] = 0x68;	//PUSH opcode
	*(DWORD*)&pHook->push_id[1] = PushID;

	pHook->push_id[5] = 0xE9;	//JMP opcode
	*(DWORD*)&pHook->push_id[6] = (DWORD)((BYTE*)stub - ((BYTE*)&pHook->push_id[5] + 5));


	//EXEC_BUFFER...JMP FUNC_ADDR+LEN
	BYTE *dst=pHook->exec_buf + pHook->ReassembledCodeLen;
	*(BYTE*)dst = 0xE9;//JMP opcode
	*(DWORD*)(dst+1) = (DWORD)((DWORD)((BYTE*)addr + pHook->code_len) - (DWORD)dst - 5);


	//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
	//Set hook
	//Write jmp stub to function begin address
	*(BYTE*)addr=0xE9;
	if(PushID==0xFFFFFFFF){//jmp to exec_buf
		*(DWORD*)((BYTE*)addr + 1)=(DWORD)((BYTE*)stub - ((BYTE*)addr + 5));
	}
	else{// jmp to pushid
		*(DWORD*)((BYTE*)addr + 1)=(DWORD)((BYTE*)(BYTE*)pHook->push_id - ((BYTE*)addr + 5));
	}
	
	
	if(!safe_VirtualProtectEx((HANDLE)(-1), (LPVOID)pHook->exec_buf, 32, PAGE_EXECUTE_READWRITE, &dwTemp)){
		*pError=KHOOK::PAGE_PROT_ERR;
		return 0;
	}

	if(!safe_VirtualProtectEx((HANDLE)(-1), (LPVOID)pHook->push_id, 16, PAGE_EXECUTE_READWRITE, &dwTemp)){
		*pError=KHOOK::PAGE_PROT_ERR;
		return 0;
	}

	//safe_FlushInstructionCache((HANDLE)-1, 0, 0);
	return pHook;
}