Esempio n. 1
0
int Hook::getCompleteInstructions(const int bytes_needed, char *out_buffer, int *out_size)
{
	if ((bytes_needed == 0) || !source_function)
		return -1;

	_DInst *decodedInstructions = nullptr;
	unsigned int decodedInstructionsCount = 0;

	decodedInstructions = static_cast<_DInst *>(HeapAlloc(hHeap, HEAP_ZERO_MEMORY, bytes_needed*sizeof(_DInst)));
	if (!decodedInstructions)
		return -1;

	// Dissasamble the function ...
	_CodeInfo ci;
	ci.code = reinterpret_cast<const uint8_t *>(source_function);
	ci.codeLen = bytes_needed*2;
	ci.codeOffset = 0;
#if defined(_X86_)	// Defined on the command line by a linker variable.
    // the target architecture is x86
	ci.dt = Decode32Bits;
#elif defined(_AMD64_)
    // the target architecture is AMD x86-64
	ci.dt = Decode64Bits;
#endif
	ci.features = DF_NONE;
	distorm_decompose(&ci, decodedInstructions, bytes_needed, &decodedInstructionsCount);

	// Get the size of the fewest instructions ... bytes_needed <= instruction_size
	int current_size = 0;
	for (int i = 0; i < bytes_needed; ++i)
	{
		if (current_size < bytes_needed)
			current_size += (decodedInstructions+i)->size;
		else
			break;
	}

	HeapFree(hHeap, 0, decodedInstructions);

	if (!out_buffer || (*out_size < current_size))
	{
		// Not enough space in output buffer
		*out_size = current_size;
		return 0;
	}

	CopyMemory(out_buffer, reinterpret_cast<void *>(source_function), current_size);

	return current_size;
}
Esempio n. 2
0
blockinfo get_block_stats(const uint8_t *buf, unsigned long pc, size_t size, bool use64bit){

  blockinfo retval = {0,0};
   
#if defined(TARGET_I386)
   
    _DInst dec[256]; 
    unsigned int dec_count = 0;
    _DecodeType dt = use64bit ? Decode64Bits : Decode32Bits;

    _CodeInfo ci;
    ci.code = buf;
    ci.codeLen = size;
    ci.codeOffset = pc;
    ci.dt = dt;
    ci.features = DF_NONE;
    distorm_decompose(&ci, dec, 256, &dec_count);
    
    for (int i = dec_count - 1; i >= 0; i--) {
      _DecodedInst inst; 
        if (dec[i].flags == FLAG_NOT_DECODABLE) {
          printf("Instruction not decodable %lX\n", dec[i].addr);
          break;
        }
        switch(icls[dec[i].opcode]){
        case ICLS_NORMAL:
          retval.total_instr++;
          break;
        case ICLS_WARN:
          distorm_format(&ci, &dec[i], &inst);
          
          fprintf(stderr,"Could not classify instruction %s %s\n", inst.mnemonic.p, inst.operands.p);
          retval.total_instr++;
          break;
        case ICLS_BITARITH:
          retval.arith_instr++;
          retval.total_instr++;
          break;
        case ICLS_MOV:
          break;
        }
    }
#else
    fprintf(stderr, "Architecture not supported\n");
#endif
    return retval;

}
Esempio n. 3
0
bool ProcessAccessHelp::decomposeMemory(BYTE * dataBuffer, SIZE_T bufferSize, DWORD_PTR startAddress)
{

    ZeroMemory(&decomposerCi, sizeof(_CodeInfo));
    decomposerCi.code = dataBuffer;
    decomposerCi.codeLen = (int)bufferSize;
    decomposerCi.dt = dt;
    decomposerCi.codeOffset = startAddress;

    decomposerInstructionsCount = 0;

    if (distorm_decompose(&decomposerCi, decomposerResult, sizeof(decomposerResult)/sizeof(decomposerResult[0]), &decomposerInstructionsCount) == DECRES_INPUTERR)
    {
#ifdef DEBUG_COMMENTS
        Scylla::debugLog.log(L"decomposeMemory :: distorm_decompose == DECRES_INPUTERR");
#endif
        return false;
    }
    else
    {
        return true;
    }
}
Esempio n. 4
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;
}