Esempio n. 1
0
DWORD_PTR IATSearch::findNextFunctionAddress()
{
#ifdef DEBUG_COMMENTS
    _DecodedInst inst;
#endif

    for (unsigned int i = 0; i < decomposerInstructionsCount; i++)
    {

        if (decomposerResult[i].flags != FLAG_NOT_DECODABLE)
        {
            if (META_GET_FC(decomposerResult[i].meta) == FC_CALL || META_GET_FC(decomposerResult[i].meta) == FC_UNC_BRANCH)
            {
                if (decomposerResult[i].size >= 5)
                {
                    if (decomposerResult[i].ops[0].type == O_PC)
                    {
#ifdef DEBUG_COMMENTS
                        distorm_format(&decomposerCi, &decomposerResult[i], &inst);
                        Scylla::debugLog.log(L"%S %S %d %d - target address: " PRINTF_DWORD_PTR_FULL, inst.mnemonic.p, inst.operands.p, decomposerResult[i].ops[0].type, decomposerResult[i].size, INSTRUCTION_GET_TARGET(&decomposerResult[i]));
#endif
                        return (DWORD_PTR)INSTRUCTION_GET_TARGET(&decomposerResult[i]);
                    }
                }
            }
        }
    }

    return 0;
}
Esempio n. 2
0
// - 'call dword ptr [0xC0DEC0DE]' (6 bytes)
// - 'call dword ptr <reg + 32bit_displacement>' (6 bytes)
// - 'call 0xC0DEC0DE' (5 bytes)
// - 'call dword ptr <reg>' (2 bytes)
// - 'call dword ptr <reg + 8bit_displacement>' (3 bytes)
// - 'call dword ptr <reg1 + reg2 + 8bit_displacement>' (4 bytes)
// - 'call dword ptr <reg1 + reg2 + 32bit_displacement>' (7 bytes)
// 
// bExactCheck decides whether we checks target of the call instruction
// matches critical function.
BOOL
CheckCaller(
	IN ULONG_PTR lpReturningAddress,
	IN BOOL bExactCheck,
	IN ROP_CALLEE RopCallee,
	IN ULONG *pGeneralRegisters)
{
	CONST DWORD CallInstructionLength[] = {6, 5, 2, 3, 4, 7};
	CONST DWORD dwMaxInstructions = 7;
	_DInst DecodedInstructions[dwMaxInstructions]; /* There might be 7 instructions in all */
	DWORD dwDecodedInstructionsCount = 0;
	_CodeInfo ci;

	for(DWORD i = 0; 
		i < sizeof(CallInstructionLength) / sizeof(DWORD); 
		++i)
	{
		ci.code = (BYTE*)(lpReturningAddress - CallInstructionLength[i]);
		ci.codeLen = CallInstructionLength[i];
		ci.codeOffset = 0;
		ci.dt = Decode32Bits;
		ci.features = DF_NONE;
		distorm_decompose(&ci, 
			DecodedInstructions, 
			dwMaxInstructions,
			(unsigned int*)&dwDecodedInstructionsCount);

		if(dwDecodedInstructionsCount != 1 ||
			DecodedInstructions[0].flags == FLAG_NOT_DECODABLE)
		{
			continue;
		}

		ULONG_PTR lpCallingTarget = 0;

		if(DecodedInstructions[0].opcode == I_CALL)
		{
			if(!bExactCheck)
			{
				return TRUE;
			}
			else
			{
				_DInst* pInstr = &DecodedInstructions[0];
				/* Single operand only for call instructions */
				switch(pInstr->ops[0].type)
				{
				case O_REG:
					lpCallingTarget = GENERAL_REGISTER(pInstr->ops[0].index);
					break;
				case O_SMEM:
					lpCallingTarget = 
						*(ULONG_PTR*)(GENERAL_REGISTER(pInstr->ops[0].index) + pInstr->disp);
					break;
				case O_MEM:
					lpCallingTarget = *(ULONG_PTR*)
						(
						GENERAL_REGISTER(pInstr->base) /* base */
						+ GENERAL_REGISTER(pInstr->ops[0].index) * pInstr->scale /* index and scale */
						+ pInstr->disp /* displacement */
						);
					break;
				case O_PC:
					lpCallingTarget = (ULONG_PTR)INSTRUCTION_GET_TARGET(pInstr);
					break;
				case O_DISP:
					lpCallingTarget = *(ULONG_PTR*)(pInstr->disp);
					break;
				default:
					DEBUG_PRINTF(LDBG, NULL, "Error occurs in CALL_VALIDATION. Operand type = %x.\n",
						pInstr->ops[0].type);
					break;
				}
			}

			if(lpCallingTarget == 
				(ULONG_PTR)GetCriticalFunctionAddress(RopCallee))
			{
				return TRUE;
			}
		}

		/* TODO: Handle those more complicated cases, like jmp and so on */
	}

	return FALSE;
}