int x86_udis86_op(RAnal *anal, RAnalOp *op, ut64 addr, const ut8 *data, int len) {
	int oplen;
	struct ud u;
	ud_init (&u);
	ud_set_pc (&u, addr);
	ud_set_mode (&u, anal->bits);
	ud_set_syntax (&u, NULL);
	ud_set_input_buffer (&u, data, len);
	ud_disassemble (&u);
	memset (op, '\0', sizeof (RAnalOp));
	op->addr = addr;
	op->jump = op->fail = -1;
	op->ref = op->value = -1;
	oplen = op->length = ud_insn_len (&u);
	switch (u.mnemonic) {
	case UD_Ijmp:
		op->type = R_ANAL_OP_TYPE_JMP;
		op->jump = addr + oplen + getval (&u.operand[0]);
		break;
	case UD_Ijz:
	case UD_Ijnz:
	case UD_Ijb:
	case UD_Ijbe:
	case UD_Ija:
	case UD_Ijs:
	case UD_Ijns:
	case UD_Ijo:
	case UD_Ijno:
	case UD_Ijp:
	case UD_Ijnp:
	case UD_Ijl:
	case UD_Ijge:
	case UD_Ijle:
	case UD_Ijg:
	case UD_Ijcxz:
		op->type = R_ANAL_OP_TYPE_CJMP;
		op->jump = addr + oplen + getval (&u.operand[0]);
		op->fail = addr+oplen;
		break;
	case UD_Icall:
		op->type = R_ANAL_OP_TYPE_CALL;
		op->jump = oplen + getval (&u.operand[0]);
		op->fail = addr+oplen;
		break;
	case UD_Iret:
	case UD_Iretf:
	case UD_Isysret:
		op->type = R_ANAL_OP_TYPE_RET;
		break;
	case UD_Isyscall:
		op->type = R_ANAL_OP_TYPE_SWI;
		break;
	case UD_Inop:
		op->type = R_ANAL_OP_TYPE_NOP;
		break;
	default:
		break;
	}
	return oplen;
}
    /*
     * len must be aligned to the sizeof(long)
     */
    int cnt = len / sizeof(long);
    size_t memsz = 0;

    for (int x = 0; x < cnt; x++) {
        uint8_t *addr = (uint8_t *) pc + (int)(x * sizeof(long));
        long ret = ptrace(PT_READ_D, pid, addr, NULL);

        if (errno != 0) {
            LOGMSG_P(l_WARN, "Couldn't PT_READ_D on pid %d, addr: %p", pid, addr);
            break;
        }

        memsz += sizeof(long);
        memcpy(&buf[x * sizeof(long)], &ret, sizeof(long));
    }
    return memsz;
}

#if defined(__i386__) || defined(__x86_64__)
#ifndef MAX_OP_STRING
#define MAX_OP_STRING 32
#endif                          /* MAX_OP_STRING */
static void arch_getX86InstrStr(pid_t pid, char *instr, void *pc)
{
    /*
     * MAX_INSN_LENGTH is actually 15, but we need a value aligned to 8
     * which is sizeof(long) on 64bit CPU archs (on most of them, I hope;)
     */
    uint8_t buf[16];
    size_t memsz;

    if ((memsz = arch_getProcMem(pid, buf, sizeof(buf), pc)) == 0) {
        snprintf(instr, MAX_OP_STRING, "%s", "[NOT_MMAPED]");
        return;
    }

    ud_t ud_obj;
    ud_init(&ud_obj);
    ud_set_mode(&ud_obj, 64);
    ud_set_syntax(&ud_obj, UD_SYN_INTEL);
    ud_set_pc(&ud_obj, (uint64_t) (long)pc);
    ud_set_input_buffer(&ud_obj, buf, memsz);
    if (!ud_disassemble(&ud_obj)) {
        LOGMSG(l_WARN, "Couldn't disassemble the x86/x86-64 instruction stream");
        return;
    }

    snprintf(instr, MAX_OP_STRING, "%s", ud_insn_asm(&ud_obj));
    for (int x = 0; instr[x] && x < MAX_OP_STRING; x++) {
        if (instr[x] == '/' || instr[x] == '\\' || isspace(instr[x]) || !isprint(instr[x])) {
            instr[x] = '_';
        }
    }
}
Beispiel #3
0
void Analysis::set_label_address(pCodeBufferInfo pinfo,
                                 AddressArray & _addra,
                                 std::map<long,int> & _map)
{
  ud_t ud_obj;
  ud_init(&ud_obj);

#ifndef PROTECT_X64
  ud_set_mode(&ud_obj,32);
#else
  ud_set_mode(&ud_obj,64);
#endif
  ud_set_pc(&ud_obj,pinfo->addr);
  ud_set_input_buffer(&ud_obj, (uint8_t*)pinfo->buf, pinfo->size);
  ud_set_syntax(&ud_obj,UD_SYN_INTEL);
  std::vector <ud_t> ud_obj_array;
  
  int label = 0;
  while (ud_disassemble(&ud_obj) != 0)
  {
     if (ud_obj.insn_offset > _addra[label])
     {
       //printf("当前地址不可能比分支地址大");
     }
     if (ud_obj.insn_offset == _addra[label])
     {
       _map.insert(std::make_pair(ud_obj.insn_offset,label));
       //printf("地址:%08x,标签:%d\n",ud_obj.insn_offset,label);
       label++;
     }
  } 

}
Beispiel #4
0
static int disassemble(RAsm *a, RAsmOp *op, const ut8 *buf, int len) {
	int opsize;
	static ud_t d = {0};
	static int osyntax = 0;
	if (!d.dis_mode)
		ud_init (&d);
	if (osyntax != a->syntax) {
		ud_set_syntax (&d, (a->syntax==R_ASM_SYNTAX_ATT)?
				UD_SYN_ATT: UD_SYN_INTEL);
		osyntax = a->syntax;
	}
	ud_set_input_buffer (&d, (uint8_t*) buf, len);
	ud_set_pc (&d, a->pc);
	ud_set_mode (&d, a->bits);
	opsize = ud_disassemble (&d);
	strncpy (op->buf_asm, ud_insn_asm (&d), R_ASM_BUFSIZE-1);
	op->buf_asm[R_ASM_BUFSIZE-1] = 0;
	if (opsize<1 || strstr (op->buf_asm, "invalid"))
		opsize = 0;
	op->size = opsize;
	if (a->syntax == R_ASM_SYNTAX_JZ) {
		if (!strncmp (op->buf_asm, "je ", 3)) {
			memcpy (op->buf_asm, "jz", 2);
		} else if (!strncmp (op->buf_asm, "jne ", 4)) {
			memcpy (op->buf_asm, "jnz", 3);
		}
	}
	return opsize;
}
pCodeInformation EquivalentInstruct::code_equivalent_replacement(pCodeInformation info,unsigned long imagebase)
{
	ud_t ud_obj;
	ud_init(&ud_obj);
	ud_set_mode(&ud_obj, 32);
	ud_set_pc(&ud_obj,info->base);
	ud_set_input_buffer(&ud_obj, info->buf, info->size);
	ud_set_syntax(&ud_obj, UD_SYN_INTEL);

	char buff[0xFFF];
	int error;

	while (ud_disassemble(&ud_obj) != 0)
	{
		switch (ud_obj.mnemonic)
		{
		case UD_NONE:
				break;
		case UD_Imov:
			{
			//	dword_ptr()
			}
			break;
		}
	}
}
Beispiel #6
0
status_t
DisassemblerX8664::Init(target_addr_t address, const void* code, size_t codeSize)
{
	// unset old data
	delete fUdisData;
	fUdisData = NULL;

	// set new data
	fUdisData = new(std::nothrow) UdisData;
	if (fUdisData == NULL)
		return B_NO_MEMORY;

	fAddress = address;
	fCode = (const uint8*)code;
	fCodeSize = codeSize;

	// init udis
	ud_init(fUdisData);
	ud_set_input_buffer(fUdisData, (unsigned char*)fCode, fCodeSize);
	ud_set_mode(fUdisData, 64);
	ud_set_pc(fUdisData, (uint64_t)fAddress);
	ud_set_syntax(fUdisData, UD_SYN_ATT);
	ud_set_vendor(fUdisData, UD_VENDOR_INTEL);
		// TODO: Set the correct vendor!

	return B_OK;
}
Beispiel #7
0
void DisassembleEp(hadesmem::Process const& process,
                   hadesmem::PeFile const& pe_file,
                   std::uintptr_t ep_rva,
                   void* ep_va,
                   std::size_t tabs)
{
  if (!ep_va)
  {
    return;
  }

  std::wostream& out = GetOutputStreamW();

  // Get the number of bytes from the EP to the end of the file.
  std::size_t max_buffer_size = GetBytesToEndOfFile(pe_file, ep_va);
  // Clamp the amount of data read to the theoretical maximum.
  std::size_t const kMaxInstructions = 10U;
  std::size_t const kMaxInstructionLen = 15U;
  std::size_t const kMaxInstructionsBytes =
    kMaxInstructions * kMaxInstructionLen;
  max_buffer_size = (std::min)(max_buffer_size, kMaxInstructionsBytes);
  auto const disasm_buf =
    hadesmem::ReadVector<std::uint8_t>(process, ep_va, max_buffer_size);
  std::uint64_t const ip = hadesmem::GetRuntimeBase(process, pe_file) + ep_rva;

  ud_t ud_obj;
  ud_init(&ud_obj);
  ud_set_input_buffer(&ud_obj, disasm_buf.data(), max_buffer_size);
  ud_set_syntax(&ud_obj, UD_SYN_INTEL);
  ud_set_pc(&ud_obj, ip);
  ud_set_mode(&ud_obj, pe_file.Is64() ? 64 : 32);

  // Be pessimistic. Use the minimum theoretical amount of instrutions we could
  // fit in our buffer.
  std::size_t const instruction_count = max_buffer_size / kMaxInstructionLen;
  for (std::size_t i = 0U; i < instruction_count; ++i)
  {
    std::uint32_t const len = ud_disassemble(&ud_obj);
    if (len == 0)
    {
      WriteNormal(out, L"WARNING! Disassembly failed.", tabs);
      // If we can't disassemble at least 5 instructions there's probably
      // something strange about the function. Even in the case of a nullsub
      // there is typically some INT3 or NOP padding after it...
      WarnForCurrentFile(i < 5U ? WarningType::kUnsupported
                                : WarningType::kSuspicious);
      break;
    }

    char const* const asm_str = ud_insn_asm(&ud_obj);
    HADESMEM_DETAIL_ASSERT(asm_str);
    char const* const asm_bytes_str = ud_insn_hex(&ud_obj);
    HADESMEM_DETAIL_ASSERT(asm_bytes_str);
    auto const diasm_line =
      hadesmem::detail::MultiByteToWideChar(asm_str) + L" (" +
      hadesmem::detail::MultiByteToWideChar(asm_bytes_str) + L")";
    WriteNormal(out, diasm_line, tabs);
  }
}
Beispiel #8
0
/* =============================================================================
 * ud_init() - Initializes ud_t object.
 * =============================================================================
 */
extern void
ud_init (struct ud *u)
{
  memset ((void *) u, 0, sizeof (struct ud));
  ud_set_mode (u, 16);
  u->mnemonic = UD_Iinvalid;
  ud_set_pc (u, 0);
#ifndef __UD_STANDALONE__
  ud_set_input_file (u, stdin);
#endif /* __UD_STANDALONE__ */
}
    /**
        HookEngine_Disassemble

        Obtain the minimum number of instruction bytes that need to be copied
        from the target function, in order to accomodate our jump instruction
    */
    static DWORD HookEngine_Disassemble(DWORD cbRequired, LPVOID pTargetFunctionAddress, DISASSEMBLY_DATA& DisassemblyData )
    {
        CONST SIZE_T Page = 4096;

        ud_t ud_obj = { 0 };
        ud_init(&ud_obj);
#if defined(_M_IX86)
        ud_set_mode(&ud_obj, 32);
#elif defined(_M_X64)
        ud_set_mode(&ud_obj, 64);
#else
#error Unsuported platform 
#endif
        ud_set_pc(&ud_obj, uint64_t(pTargetFunctionAddress));
        ud_set_vendor(&ud_obj, UD_VENDOR_INTEL);
        ud_set_input_buffer(&ud_obj, (unsigned char*)pTargetFunctionAddress, Page);

        DWORD instrlen = 0;

        DisassemblyData.Count = 0;
        DisassemblyData.Length = 0;

        HookEngine_Memset(DisassemblyData.Instructions, 0, sizeof(DisassemblyData.Instructions));
        HookEngine_Memset(DisassemblyData.InstuctionBuffer, 0, sizeof(DisassemblyData.InstuctionBuffer));
        HookEngine_Memset(DisassemblyData.InstructionLengths, 0, sizeof(DisassemblyData.InstructionLengths));

        do
        {
            instrlen = ud_disassemble(&ud_obj);
          
            if (instrlen)
            {
                if ((DisassemblyData.Length + instrlen) < MAX_INSTRUCTION_BUFFER)
                {
                    DisassemblyData.Instructions[DisassemblyData.Count] = ud_obj;
                    DisassemblyData.InstructionLengths[DisassemblyData.Count] = instrlen;
                    DisassemblyData.Count++;
                    HookEngine_Memcpy(&DisassemblyData.InstuctionBuffer[DisassemblyData.Length], ((BYTE*)pTargetFunctionAddress) + DisassemblyData.Length, instrlen);
                    DisassemblyData.Length += instrlen;
                }
            }

        } while (DisassemblyData.Length < cbRequired &&
                 DisassemblyData.Count < MAX_INSTRUCTIONS &&
                 instrlen != 0);

        return DisassemblyData.Length;
    }
Beispiel #10
0
void Analysis::analysis_address_table(pCodeBufferInfo pinfo,
                                      std::vector<long> & addr_entry_table,
                                      long addr_min,
                                      long addr_max) //jmp [addr_table + reg] 查找addr_table里面的值
{
/*#define WINDOWS
#include <Windows.h>
    HMODULE module = LoadLibrary("");
#endif
*/
    ud_t ud_obj;
    ud_init(&ud_obj);

#ifndef PROTECT_X64
    ud_set_mode(&ud_obj,32);
#else
    ud_set_mode(&ud_obj,64);
#endif
    ud_set_pc(&ud_obj,pinfo->addr);
    ud_set_input_buffer(&ud_obj, (uint8_t*)pinfo->buf, pinfo->size);
    ud_set_syntax(&ud_obj,UD_SYN_INTEL);
    while(ud_disassemble(&ud_obj) != 0)
    {
        if (ud_obj.operand[0].type == UD_OP_MEM)
        {
            if (ud_obj.operand[0].offset == 32)
            {
                long addr = ud_obj.operand[0].lval.sdword;
                if (addr <= addr_max && addr >= addr_min)
                  addr_entry_table.push_back(addr);
            }
        }
        if (ud_obj.operand[1].type == UD_OP_MEM)
        {
            if (ud_obj.operand[1].offset == 32)
            {
                long addr = ud_obj.operand[1].lval.sdword;
                if (addr <= addr_max && addr >= addr_min)
                   addr_entry_table.push_back(addr);
            }
        }
        //if (ud_insn_mnemonic(&ud_obj) == UD_Ijmp && ud_obj.operand[0].type == UD_OP_MEM)
        //{
        //}
    }
}
Beispiel #11
0
Client::Client()
{
	base = (DWORD)GetModuleHandle(nullptr);
	auto idh = (PIMAGE_DOS_HEADER)base;
	auto inh = (PIMAGE_NT_HEADERS)(base + idh->e_lfanew);
	auto ioh = &inh->OptionalHeader;
	imports = (PIMAGE_IMPORT_DESCRIPTOR)(base + ioh->DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress);

	codeBase = (BYTE*)(base + ioh->BaseOfCode);
	codeEnd = codeBase + ioh->SizeOfCode;
	dataBase = (BYTE*)(base + ioh->BaseOfData);
	dataEnd = dataBase + ioh->SizeOfInitializedData;

	ud ud_obj;
	ud_init(&ud_obj);
	ud_set_mode(&ud_obj, 32);
	ud_set_syntax(&ud_obj, nullptr);
	ud_set_input_buffer(&ud_obj, codeBase, codeEnd - codeBase);
	ud_set_pc(&ud_obj, (UINT)codeBase);

	data.reserve(0x100000);
	while (ud_disassemble(&ud_obj))
	{
		if (ud_obj.mnemonic == UD_Iint3 || ud_obj.mnemonic == UD_Inop)//useless
			continue;

		ud_instr instr;
		instr.op = ud_obj.mnemonic | (ud_obj.inp_ctr << 16);
		for (int i = 0; i < 2; i++)
		{
			if ((instr.args[i].type = ud_obj.operand[i].type) == UD_NONE)
				break;

			if (instr.args[i].type == UD_OP_MEM)
				instr.args[i].size = ud_obj.operand[i].offset;
			else
				instr.args[i].size = ud_obj.operand[i].size;

			instr.args[i].base = ud_obj.operand[i].base;
			instr.args[i].lval = ud_obj.operand[i].lval.udword;
		}
		instr.offset = (LPVOID)ud_obj.insn_offset;
		data.push_back(instr);
	}
}
Beispiel #12
0
static int disassemble(RAsm *a, RAsmOp *op, const ut8 *buf, ut64 len) {
	static ud_t disasm_obj;
	ud_init (&disasm_obj);
	ud_set_syntax (&disasm_obj, 
		a->syntax==R_ASM_SYNTAX_ATT?
			UD_SYN_ATT: UD_SYN_INTEL);
	ud_set_mode (&disasm_obj, a->bits);
	ud_set_pc (&disasm_obj, a->pc);
	ud_set_input_buffer (&disasm_obj, buf, len);
	op->inst_len = ud_disassemble (&disasm_obj);
	//op->inst_len = ud_insn_len (&disasm_obj);
	snprintf (op->buf_asm, R_ASM_BUFSIZE, "%s", ud_insn_asm (&disasm_obj));
	if (!op->inst_len || strstr (op->buf_asm, "invalid"))
		op->inst_len = -1;
	if (op->inst_len<1)
		op->inst_len = -1;
	return op->inst_len;
}
Beispiel #13
0
int ludis86_ud_set_pc (lua_State * L)
{
    ud_t * ud_obj;
    uint64_t rip;
    
    ud_obj = ludis86_check_ud_t(L, 1);
    
    if (lua_isnumber(L, 2))
        rip = luaL_checkint(L, 2);
    else
        rip = strtoull(luaL_checkstring(L, 2), NULL, 0);
    
    lua_pop(L, 2);
    
    ud_set_pc(ud_obj, rip);
    
    return 0;
}
Beispiel #14
0
static int disassemble(RAsm *a, RAsmOp *op, const ut8 *buf, int len) {
	int opsize;
	static ud_t d = {0};
	static int osyntax = 0;
	if (!d.dis_mode)
		ud_init (&d);
	if (osyntax != a->syntax) {
		ud_set_syntax (&d, (a->syntax==R_ASM_SYNTAX_ATT)?
				UD_SYN_ATT: UD_SYN_INTEL);
		osyntax = a->syntax;
	}
	ud_set_input_buffer (&d, (uint8_t*) buf, len);
	ud_set_pc (&d, a->pc);
	ud_set_mode (&d, a->bits);
	opsize = ud_disassemble (&d);
	snprintf (op->buf_asm, R_ASM_BUFSIZE, "%s", ud_insn_asm (&d));
	op->size = opsize;
	if (opsize<1 || strstr (op->buf_asm, "invalid"))
		opsize = -1;
	return opsize;
}
Beispiel #15
0
int main(int argc, char *argv[]) {

    ud_t ud_obj;

    ud_init(&ud_obj);

    ud_set_input_buffer(&ud_obj, (unsigned char *)func, 100);

    ud_set_syntax(&ud_obj, UD_SYN_ATT);

    ud_set_mode(&ud_obj, 64);

    ud_set_pc(&ud_obj, (unsigned long)func);

    unsigned int pointer = 0, cur_insn_length = 0;
    while ( (cur_insn_length = ud_disassemble(&ud_obj)) != 0 ) {
        printf("func(%d): %s\n", pointer, ud_insn_asm(&ud_obj));
        pointer += cur_insn_length;
    }

    return EXIT_SUCCESS;
}
Beispiel #16
0
static const char *disassemble(unsigned char *insn, int len, uint64_t rip,
			       int cr0_pe, int eflags_vm,
			       int cs_d, int cs_l)
{
	int mode;

	if (!cr0_pe)
		mode = 16;
	else if (eflags_vm)
		mode = 16;
	else if (cs_l)
		mode = 64;
	else if (cs_d)
		mode = 32;
	else
		mode = 16;

	ud_set_pc(&ud, rip);
	ud_set_mode(&ud, mode);
	ud_set_input_buffer(&ud, insn, len);
	ud_disassemble(&ud);
	return ud_insn_asm(&ud);
}
bool tryToDisassemble(const MacroAssemblerCodePtr& codePtr, size_t size, const char* prefix, PrintStream& out)
{
    ud_t disassembler;
    ud_init(&disassembler);
    ud_set_input_buffer(&disassembler, static_cast<unsigned char*>(codePtr.executableAddress()), size);
#if CPU(X86_64)
    ud_set_mode(&disassembler, 64);
#else
    ud_set_mode(&disassembler, 32);
#endif
    ud_set_pc(&disassembler, bitwise_cast<uintptr_t>(codePtr.executableAddress()));
    ud_set_syntax(&disassembler, UD_SYN_ATT);
    
    uint64_t currentPC = disassembler.pc;
    while (ud_disassemble(&disassembler)) {
        char pcString[20];
        print(pcString, sizeof(pcString), currentPC);
        out.printf("%s%16s: %s\n", prefix, pcString, ud_insn_asm(&disassembler));
        currentPC = disassembler.pc;
    }
    
    return true;
}
void
lp_disassemble(const void* func)
{
#ifdef HAVE_UDIS86
   ud_t ud_obj;
   uint64_t max_jmp_pc;
   uint inst_no;
   boolean emit_addrs = TRUE, emit_line_nos = FALSE;

   ud_init(&ud_obj);

   ud_set_input_buffer(&ud_obj, (void*)func, 0xffff);

   max_jmp_pc = (uint64_t) (uintptr_t) func;
   ud_set_pc(&ud_obj, max_jmp_pc);

#ifdef PIPE_ARCH_X86
   ud_set_mode(&ud_obj, 32);
#endif
#ifdef PIPE_ARCH_X86_64
   ud_set_mode(&ud_obj, 64);
#endif

   ud_set_syntax(&ud_obj, UD_SYN_ATT);

   while (ud_disassemble(&ud_obj)) {

      if (emit_addrs) {
#ifdef PIPE_ARCH_X86
         debug_printf("0x%08lx:\t", (unsigned long)ud_insn_off(&ud_obj));
#endif
#ifdef PIPE_ARCH_X86_64
         debug_printf("0x%016llx:\t", (unsigned long long)ud_insn_off(&ud_obj));
#endif
      }
      else if (emit_line_nos) {
         debug_printf("%6d:\t", inst_no);
         inst_no++;
      }
#if 0
      debug_printf("%-16s ", ud_insn_hex(&ud_obj));
#endif

      debug_printf("%s\n", ud_insn_asm(&ud_obj));

      if(ud_obj.mnemonic != UD_Icall) {
         unsigned i;
         for(i = 0; i < 3; ++i) {
            const struct ud_operand *op = &ud_obj.operand[i];
            if (op->type == UD_OP_JIMM){
               uint64_t pc = ud_obj.pc;

               switch (op->size) {
               case 8:
                  pc += op->lval.sbyte;
                  break;
               case 16:
                  pc += op->lval.sword;
                  break;
               case 32:
                  pc += op->lval.sdword;
                  break;
               default:
                  break;
               }
               if(pc > max_jmp_pc)
                  max_jmp_pc = pc;
            }
         }
      }

      if (ud_obj.mnemonic == UD_Iinvalid ||
          (ud_insn_off(&ud_obj) >= max_jmp_pc &&
           (ud_obj.mnemonic == UD_Iret ||
            ud_obj.mnemonic == UD_Ijmp)))
         break;
   }

#if 0
   /* Print GDB command, useful to verify udis86 output */
   debug_printf("disassemble %p %p\n", func, (void*)(uintptr_t)ud_obj.pc);
#endif

   debug_printf("\n");
#else
   (void)func;
#endif
}
Beispiel #19
0
  virtual void Apply() override
  {
    if (applied_)
    {
      return;
    }

    if (detached_)
    {
      HADESMEM_DETAIL_ASSERT(false);
      return;
    }

    // Reset the trampolines here because we don't do it in remove, otherwise
    // there's a potential race condition where we want to unhook and unload
    // safely, so we unhook the function, then try waiting on our ref count to
    // become zero, but we haven't actually called the trampoline yet, so we end
    // up jumping to the memory we just free'd!
    trampoline_ = nullptr;
    trampolines_.clear();
    stub_gate_ = nullptr;

    SuspendedProcess const suspended_process{process_->GetId()};

    std::uint32_t const kMaxInstructionLen = 15;
    std::uint32_t const kTrampSize = kMaxInstructionLen * 3;

    trampoline_ = std::make_unique<Allocator>(*process_, kTrampSize);
    auto tramp_cur = static_cast<std::uint8_t*>(trampoline_->GetBase());

    auto const detour_raw = detour_.target<DetourFuncRawT>();
    if (detour_raw || detour_)
    {
      HADESMEM_DETAIL_TRACE_FORMAT_A(
        "Target = %p, Detour = %p, Trampoline = %p.",
        target_,
        detour_raw,
        trampoline_->GetBase());
    }
    else
    {
      HADESMEM_DETAIL_TRACE_FORMAT_A(
        "Target = %p, Detour = INVALID, Trampoline = %p.",
        target_,
        trampoline_->GetBase());
    }

    auto const buffer =
      ReadVector<std::uint8_t>(*process_, target_, kTrampSize);

    ud_t ud_obj;
    ud_init(&ud_obj);
    ud_set_input_buffer(&ud_obj, buffer.data(), buffer.size());
    ud_set_syntax(&ud_obj, UD_SYN_INTEL);
    ud_set_pc(&ud_obj, reinterpret_cast<std::uint64_t>(target_));
#if defined(HADESMEM_DETAIL_ARCH_X64)
    ud_set_mode(&ud_obj, 64);
#elif defined(HADESMEM_DETAIL_ARCH_X86)
    ud_set_mode(&ud_obj, 32);
#else
#error "[HadesMem] Unsupported architecture."
#endif

    stub_gate_ = detail::AllocatePageNear(*process_, target_);

    std::size_t const patch_size = GetPatchSize();

    std::uint32_t instr_size = 0;
    do
    {
      std::uint32_t const len = ud_disassemble(&ud_obj);
      if (len == 0)
      {
        HADESMEM_DETAIL_THROW_EXCEPTION(Error{}
                                        << ErrorString{"Disassembly failed."});
      }

#if !defined(HADESMEM_NO_TRACE)
      char const* const asm_str = ud_insn_asm(&ud_obj);
      char const* const asm_bytes_str = ud_insn_hex(&ud_obj);
      HADESMEM_DETAIL_TRACE_FORMAT_A(
        "%s. [%s].",
        (asm_str ? asm_str : "Invalid."),
        (asm_bytes_str ? asm_bytes_str : "Invalid."));
#endif

      ud_operand_t const* const op = ud_insn_opr(&ud_obj, 0);
      bool is_jimm = op && op->type == UD_OP_JIMM;
      // Handle JMP QWORD PTR [RIP+Rel32]. Necessary for hook chain support.
      bool is_jmem = op && op->type == UD_OP_MEM && op->base == UD_R_RIP &&
                     op->index == UD_NONE && op->scale == 0 && op->size == 0x40;
      if ((ud_obj.mnemonic == UD_Ijmp || ud_obj.mnemonic == UD_Icall) && op &&
          (is_jimm || is_jmem))
      {
        std::uint16_t const size = is_jimm ? op->size : op->offset;
        HADESMEM_DETAIL_TRACE_FORMAT_A("Operand/offset size is %hu.", size);
        std::int64_t const insn_target = [&]() -> std::int64_t
        {
          switch (size)
          {
          case sizeof(std::int8_t) * CHAR_BIT:
            return op->lval.sbyte;
          case sizeof(std::int16_t) * CHAR_BIT:
            return op->lval.sword;
          case sizeof(std::int32_t) * CHAR_BIT:
            return op->lval.sdword;
          case sizeof(std::int64_t) * CHAR_BIT:
            return op->lval.sqword;
          default:
            HADESMEM_DETAIL_ASSERT(false);
            HADESMEM_DETAIL_THROW_EXCEPTION(
              Error{} << ErrorString{"Unknown instruction size."});
          }
        }();

        auto const resolve_rel =
          [](std::uint64_t base, std::int64_t target, std::uint32_t insn_len)
        {
          return reinterpret_cast<std::uint8_t*>(
                   static_cast<std::uintptr_t>(base)) +
                 target + insn_len;
        };

        std::uint64_t const insn_base = ud_insn_off(&ud_obj);
        std::uint32_t const insn_len = ud_insn_len(&ud_obj);

        auto const resolved_target =
          resolve_rel(insn_base, insn_target, insn_len);
        void* const jump_target =
          is_jimm ? resolved_target : Read<void*>(*process_, resolved_target);
        HADESMEM_DETAIL_TRACE_FORMAT_A("Jump/call target = %p.", jump_target);
        if (ud_obj.mnemonic == UD_Ijmp)
        {
          HADESMEM_DETAIL_TRACE_A("Writing resolved jump.");
          tramp_cur += detail::WriteJump(
            *process_, tramp_cur, jump_target, true, &trampolines_);
        }
        else
        {
          HADESMEM_DETAIL_ASSERT(ud_obj.mnemonic == UD_Icall);
          HADESMEM_DETAIL_TRACE_A("Writing resolved call.");
          tramp_cur +=
            detail::WriteCall(*process_, tramp_cur, jump_target, trampolines_);
        }
      }
      else
      {
        std::uint8_t const* const raw = ud_insn_ptr(&ud_obj);
        Write(*process_, tramp_cur, raw, raw + len);
        tramp_cur += len;
      }

      instr_size += len;
    } while (instr_size < patch_size);

    HADESMEM_DETAIL_TRACE_A("Writing jump back to original code.");

    tramp_cur +=
      detail::WriteJump(*process_,
                        tramp_cur,
                        reinterpret_cast<std::uint8_t*>(target_) + instr_size,
                        true,
                        &trampolines_);

    FlushInstructionCache(
      *process_, trampoline_->GetBase(), trampoline_->GetSize());

    detail::WriteStubGate<TargetFuncT>(*process_,
                                       stub_gate_->GetBase(),
                                       &*stub_,
                                       &GetOriginalArbitraryUserPtrPtr);

    orig_ = ReadVector<std::uint8_t>(*process_, target_, patch_size);

    detail::VerifyPatchThreads(process_->GetId(), target_, orig_.size());

    WritePatch();

    FlushInstructionCache(*process_, target_, instr_size);

    applied_ = true;
  }
Beispiel #20
0
int x86_udis86_op(RAnal *anal, RAnalOp *op, ut64 addr, const ut8 *data, int len) {
	const char *pc = anal->bits==64? "rip": anal->bits==32? "eip": "ip";
	const char *sp = anal->bits==64? "rsp": anal->bits==32? "esp": "sp";
        const char *bp = anal->bits==64? "rbp": anal->bits==32? "ebp": "bp";
	int oplen, regsz = 4;
	char str[64], src[32], dst[32];
	struct ud u;
	switch (anal->bits) {
	case 64: regsz = 8; break;
	case 16: regsz = 2; break;
	default:
	case 32: regsz = 4; break;
	}

	UDis86Esil *handler;
	UDis86OPInfo info = {0, anal->bits, (1LL << anal->bits) - 1, regsz, 0, pc, sp, bp};
	memset (op, '\0', sizeof (RAnalOp));
	r_strbuf_init (&op->esil);
	op->addr = addr;
	op->jump = op->fail = -1;
	op->ptr = op->val = -1;

	ud_init (&u);
	ud_set_pc (&u, addr);
	ud_set_mode (&u, anal->bits);
	ud_set_syntax (&u, NULL);
	ud_set_input_buffer (&u, data, len);
	ud_disassemble (&u);

	oplen = op->size = ud_insn_len (&u);
	
	if (anal->decode && (handler = udis86_esil_get_handler (u.mnemonic))) {
		info.oplen = oplen;
		if (handler->argc > 0) {
			info.n = getval (u.operand);
			getarg (dst, &u, info.bitmask, 0);
			if (handler->argc > 1) {
				getarg (src, &u, info.bitmask, 1);
				if (handler->argc > 2)
					getarg (str, &u, info.bitmask, 2);
			}
		}
		handler->callback (&info, op, dst, src, str);
	}

	switch (u.mnemonic) {
	case UD_Iinvalid:
		oplen = op->size = -1;
		return -1;
		break;
	case UD_Itest:
	case UD_Icmp:
		op->type = R_ANAL_OP_TYPE_CMP;
		break;
	case UD_Isalc: // ??
		// al = cf
		break;
	case UD_Ixor:
		op->type = R_ANAL_OP_TYPE_XOR;
		break;
	case UD_Ior:
		op->type = R_ANAL_OP_TYPE_OR;
		break;
	case UD_Iand:
		op->type = R_ANAL_OP_TYPE_AND;
		break;
	case UD_Isar:
		op->type = R_ANAL_OP_TYPE_SAR;
		break;
	// XXX: sal ?!?
	case UD_Ishl:
		op->type = R_ANAL_OP_TYPE_SHL;
		break;
	case UD_Ishr:
		op->type = R_ANAL_OP_TYPE_SHR;
		break;
	case UD_Irol:
		op->type = R_ANAL_OP_TYPE_ROL;
		break;
	case UD_Iror:
		op->type = R_ANAL_OP_TYPE_ROR;
		break;
	case UD_Iint3:
		op->type = R_ANAL_OP_TYPE_TRAP;
		break;
	case UD_Iint:
		op->type = R_ANAL_OP_TYPE_SWI;
		op->val = u.operand[0].lval.uword;
		break;
	case UD_Ilea:
	case UD_Imov:
		op->type = R_ANAL_OP_TYPE_MOV;
		switch (u.operand[1].type) {
		case UD_OP_MEM:
			op->type = R_ANAL_OP_TYPE_MOV;
			if (u.operand[1].base == UD_R_RIP) {
				int delta = u.operand[1].lval.uword;
				op->ptr = addr + oplen + delta;
			}
			break;
		default:
			op->type = R_ANAL_OP_TYPE_MOV;
			op->ptr = getval (&u.operand[1]);
			// XX
			break;
		}
		op->stackop = R_ANAL_STACK_INC;
		op->stackptr = regsz;
		break;
	case UD_Ipush:
	case UD_Ipusha:
	case UD_Ipushad:
	case UD_Ipushfq:
	case UD_Ipushfd:
	case UD_Ipushfw:
		switch (u.operand[0].type) {
		case UD_OP_CONST:
		case UD_OP_JIMM:
		case UD_OP_IMM:
			op->type = R_ANAL_OP_TYPE_PUSH;
			op->ptr = getval (&u.operand[0]);
			break;
		case UD_OP_REG:
		case UD_OP_PTR:
		case UD_OP_MEM:
		default:
			op->type = R_ANAL_OP_TYPE_UPUSH;
			op->ptr = 0;
			break;
		}
		op->stackop = R_ANAL_STACK_INC;
		op->stackptr = regsz;
		break;
	case UD_Ipop:
	case UD_Ipopa:
	case UD_Ipopad:
	case UD_Ipopfw:
	case UD_Ipopfd:
	case UD_Ipopfq:
		op->type = R_ANAL_OP_TYPE_POP;
		op->stackop = R_ANAL_STACK_INC;
		op->stackptr = -regsz;
		break;
	case UD_Ileave:
		op->type = R_ANAL_OP_TYPE_MOV;
		op->stackop = R_ANAL_STACK_INC;
		op->stackptr = -regsz;
		break;
	case UD_Iadd:
	case UD_Isub:
		op->type = (u.mnemonic==UD_Iadd)? R_ANAL_OP_TYPE_ADD: R_ANAL_OP_TYPE_SUB;
		op->ptr = 0;
		op->stackptr = 0;
		if (u.operand[0].type == UD_OP_REG) {
			if (u.operand[0].base == UD_R_RSP) {
				int o = (int)getval (&u.operand[1]);
				op->stackop = R_ANAL_STACK_INC;
				if (u.mnemonic ==UD_Iadd) {
					op->stackptr = -o;
				} else {
					op->stackptr = o;
				}
			}
			if (u.operand[1].type != UD_OP_REG)
				op->val = getval (&u.operand[1]);
		}
		op->stackptr = 4;
		break;
	case UD_Iadc:
	case UD_Iinc:
		op->type = R_ANAL_OP_TYPE_ADD;
		break;
	case UD_Isbb:
	case UD_Idec:
		op->type = R_ANAL_OP_TYPE_SUB;
		break;
	case UD_Ijmp:
		switch (u.operand[0].type) {
		case UD_OP_MEM:
		case UD_OP_REG:
			op->type = R_ANAL_OP_TYPE_UJMP;
			break;
		default:
			op->type = R_ANAL_OP_TYPE_JMP;
#if 0
{
ut16 a = (op->lval.ptr.seg & 0xFFFF);
ut16 b = (op->lval.ptr.off);
switch (op->size) {
case 32:
	sprintf (src, "%04x:%04x", a, b & 0xFFFF);
	break;
case 48:
	sprintf (src, "%04x:%04x", a, b);
	break;
default:
	eprintf ("F**K YOU\n");
}
}
#endif
			if (u.operand[0].type==UD_OP_PTR) {
				op->jump = getval (&u.operand[0]);
			} else {
				if (anal->bits==16) {
					// honor segment
					op->jump = (addr&0xf0000) + oplen + \
						(((addr&0xffff)+getval (&u.operand[0])&0xffff));
				} else {
					op->jump = addr + oplen + (int)getval (&u.operand[0]);
				}
			}
		}
		break;
	case UD_Ije:
	case UD_Ijne:
	case UD_Ijb:
	case UD_Ijbe:
	case UD_Ija:
	case UD_Ijae:
	case UD_Ijs:
	case UD_Ijns:
	case UD_Ijo:
	case UD_Ijno:
	case UD_Ijp:
	case UD_Ijnp:
	case UD_Ijl:
	case UD_Ijge:
	case UD_Ijle:
	case UD_Ijg:
	case UD_Ijcxz:
	case UD_Iloop:
		op->type = R_ANAL_OP_TYPE_CJMP;
		op->jump = addr + oplen + (int)getval (&u.operand[0]);
		op->fail = addr+oplen;
		break;
	case UD_Icall:
		op->type = R_ANAL_OP_TYPE_CALL;
		switch (u.operand[0].type) {
		case UD_OP_REG:
			op->jump = 0; // EAX, EBX, ... use anal->reg
			break;
		case UD_OP_IMM:
		case UD_OP_MEM:
		case UD_OP_PTR:
		default:
			op->jump = addr + oplen + (int)getval (&u.operand[0]);
		}
		op->fail = addr + oplen;
		break;
	case UD_Ihlt:
		//op->type = R_ANAL_OP_TYPE_HALT;
		break;
	case UD_Iret:
	case UD_Iretf:
	case UD_Isysret:
		op->type = R_ANAL_OP_TYPE_RET;
		op->stackop = R_ANAL_STACK_INC;
		op->stackptr = -regsz;
		break;
	case UD_Isyscall:
		op->type = R_ANAL_OP_TYPE_SWI;
		break;
	case UD_Inop:
		op->type = R_ANAL_OP_TYPE_NOP;
		break;
	default:
		break;
	}
	return oplen;
}
Beispiel #21
0
void Analysis::disasm(pCodeBufferInfo pinfo,std::vector<CodePiece> & code)
{
    ud_t ud_obj;
    ud_init(&ud_obj);

#ifndef PROTECT_X64
    ud_set_mode(&ud_obj,32);
#else
    ud_set_mode(&ud_obj,64);
#endif
    ud_set_pc(&ud_obj,pinfo->addr);
    ud_set_input_buffer(&ud_obj, (uint8_t*)pinfo->buf, pinfo->size);
    ud_set_syntax(&ud_obj,UD_SYN_INTEL);

    base = pinfo->addr;
    size = pinfo->size;
    AddressArray a_array = analysis_code_piece_address(pinfo);

    int point = 0;
    const bool begin = true;
    const bool end = false;
    bool status = end;
    std::map<long,int> addr_id;

    set_label_address(pinfo,a_array,addr_id);
    CodePiece *piece = NULL;
    while (ud_disassemble(&ud_obj) != 0)
    {

        if (ud_obj.insn_offset == a_array[point] && status == end)
        {
            piece = new CodePiece;
            piece->set_label(point);
            point++;
            status = begin;
        }
        if (a_array.get_size() > point)
        {
            if (ud_obj.pc == a_array[point])
            {
                if (addr_id.find(ud_obj.pc) == addr_id.end()) //下条指令没有找到
                {
#ifdef DEBUG
                    printf("没有查找到数据,地址%08x\n",ud_obj.pc)  ;
#endif
                    //piece->set_jmplabel(PC_NONE);
                    if (ud_obj.mnemonic == UD_Iret)
                    {
                        //piece->set_jmplabel(PC_NONE);
                        piece->set_opcode_attribute(OPCODE_ATTRIBUTE_RET);
                    }
                    else if (ud_insn_mnemonic(&ud_obj) == UD_Ijmp)
                    {
                        long addr = ud_obj.operand[0].size == 8
                                            ? ((signed char)ud_obj.operand[0].lval.sbyte + ud_obj.pc) :
                                    (ud_obj.operand[0].lval.sdword + ud_obj.pc);
                        if (addr >= pinfo->addr && addr <= pinfo->addr + pinfo->size
                                && ud_obj.operand[0].type == UD_OP_JIMM)
                        {
                            piece->set_opcode_attribute(OPCODE_ATTRIBUTE_JMP);
                            piece->set_jmplabel(addr_id[addr]);
                        }
                        else
                        {
                           piece->set_opcode_attribute(OPCODE_ATTRIBUTE_EXTERNAL_JMP);
                           if (ud_obj.operand[0].type == UD_OP_JIMM)
                               piece->set_jmplabel(addr);
                           else
                               piece->set_jmplabel(PC_NONE);

                        }
                    }
                    else if (ud_insn_mnemonic(&ud_obj) == UD_Icall)
                    {
                        long addr = ud_obj.operand[0].size == 8
                                            ? ((signed char)ud_obj.operand[0].lval.sbyte + ud_obj.pc) :
                                    (ud_obj.operand[0].lval.sdword + ud_obj.pc);
                        //if (addr >= pinfo->addr && addr <= pinfo->addr + pinfo->size &&
                        if (addr >= pinfo->addr && addr < pinfo->addr + pinfo->size &&
                                ud_obj.operand[0].type == UD_OP_JIMM)
                        {
                            piece->set_opcode_attribute(OPCODE_ATTRIBUTE_CALL);
                            piece->set_jmplabel(addr_id[addr]);
                        }
                        else
                        {
                           piece->set_opcode_attribute(OPCODE_ATTRIBUTE_EXTERNAL_CALL);
                           if (ud_obj.operand[0].type == UD_OP_JIMM)
                               piece->set_jmplabel(addr);
                           else
                               piece->set_jmplabel(PC_NONE);
                        }
                    }
                    else
                    {
                        piece->set_opcode_attribute(OPCODE_ATTRIBUTE_EXIT);
                        piece->set_jmplabel(ud_obj.pc);
                    }
                }
                else
                {
                    if (ud_obj.operand[0].type == UD_OP_JIMM
                            || ud_obj.mnemonic == UD_Icall
                            || ud_obj.mnemonic == UD_Ijmp)//&& ud_obj.mnemonic != UD_Icall)
                    {
                        piece->set_is_jcc(ud_obj.mnemonic != UD_Icall &&
                                        ud_obj.mnemonic != UD_Iret &&
                                        ud_obj.mnemonic != UD_Ijmp);
                        if (ud_obj.operand[0].type == UD_OP_MEM
                                || ud_obj.operand[0].type == UD_OP_REG)
                        {
                            if (ud_insn_mnemonic(&ud_obj) == UD_Ijmp)
                            {
                                piece->set_opcode_attribute(OPCODE_ATTRIBUTE_EXTERNAL_JMP);
                            }
                            else if (ud_insn_mnemonic(&ud_obj) == UD_Icall)
                            {
                                piece->set_opcode_attribute(OPCODE_ATTRIBUTE_EXTERNAL_CALL);
                            }
                            else
                            {
                               //piece->set_opcode_attribute(OPCODE_ATTRIBUTE_JCC);
                            }
                            piece->set_jmplabel(PC_NONE);
                        }
                        else
                        {
                            long addr = ud_obj.operand[0].size == 8
                                            ? ((signed char)ud_obj.operand[0].lval.sbyte + ud_obj.pc) :
                                    (ud_obj.operand[0].lval.sdword + ud_obj.pc);
                            if (addr >= pinfo->addr && addr < pinfo->addr + pinfo->size) //<=pinfo->addr + pinfo->size将导致跳转到最后一条指令的下一条还是在范围之内
                            {
                                if (addr_id.find(addr) == addr_id.end())
                                {
                                    printf("没有找到跳转地址:%08x\n",addr );
                                }
                                if (ud_insn_mnemonic(&ud_obj) == UD_Ijmp)
                                {
                                   piece->set_opcode_attribute(OPCODE_ATTRIBUTE_JMP);
                                   piece->set_jmplabel(addr_id[addr]);
                                }
                                else if (ud_insn_mnemonic(&ud_obj) == UD_Icall)
                                {
                                   piece->set_opcode_attribute(OPCODE_ATTRIBUTE_CALL);
                                   piece->set_jmplabel(addr);
                                }
                                else
                                {
                                   piece->set_opcode_attribute(OPCODE_ATTRIBUTE_JCC);
                                   piece->set_jmplabel( addr_id[addr] );
                                }
                            }
                            else
                            {
                                if (ud_insn_mnemonic(&ud_obj) == UD_Ijmp)
                                {
                                   piece->set_opcode_attribute(OPCODE_ATTRIBUTE_EXTERNAL_JMP);
                                   //piece->set_jmplabel(addr_id[addr]);
                                }
                                else if (ud_insn_mnemonic(&ud_obj) == UD_Icall)
                                {
                                   piece->set_opcode_attribute(OPCODE_ATTRIBUTE_EXTERNAL_CALL);
                                   //piece->set_jmplabel(addr);
                                }
                                else
                                {
                                   //piece->set_opcode_attribute(OPCODE_ATTRIBUTE_JCC);
                                   printf("jcc不能跳转到虚拟机外部\n");
                                   //piece->set_jmplabel( addr_id[addr] );
                                }
                                piece->set_jmplabel(addr);
                            }
                        }
                    }
                    else
                    {
                        piece->set_jmplabel( addr_id[ud_obj.pc] );
                        piece->set_opcode_attribute(OPCODE_ATTRIBUTE_NORMAL);
                    }
                }
                if (ud_obj.mnemonic == UD_Iret)
                {
                    piece->set_jmplabel(PC_NONE);
                    piece->set_opcode_attribute(OPCODE_ATTRIBUTE_RET);
                    //piece->set_jmplabel(PC_RET);
                }
                piece->add_assemble(ud_obj);
                code.push_back(*piece);
                delete piece;
                piece = NULL;
                status = end;

            }
        }
        if (status == begin)
        {
            if (piece == NULL) {
                printf("没有为piece分配空间");
            }
            piece->add_assemble(ud_obj);
        }

    }
}
Beispiel #22
0
pAssemblerTree Analysis::disasm(pCodeBufferInfo pinfo)
{
  std::vector<CodePiece> piece_test;
  disasm(pinfo,piece_test) ;
  for (std::vector<CodePiece>::iterator iter = piece_test.begin();
      iter != piece_test.end();iter++)
  {
    printf("\033[31m标签:%08x,\033[34m跳转到:%08x\033[0m,条件跳转:%d\n",iter->get_label(),iter->get_jmplabel(),iter->get_is_jcc());   
    for (std::list<ud_t>::iterator xiter = iter->get_piece().begin();
        xiter != iter->get_piece().end();xiter++)
    {
        printf("%s\n",xiter->insn_buffer);
    }
  }

  //__asm("int3");
  ud_t ud_obj;
  ud_init(&ud_obj);

#ifndef PROTECT_X64
  ud_set_mode(&ud_obj,32);
#else
  ud_set_mode(&ud_obj,64);
#endif
  ud_set_pc(&ud_obj,pinfo->addr);
  ud_set_input_buffer(&ud_obj, (uint8_t*)pinfo->buf, pinfo->size);
  ud_set_syntax(&ud_obj,UD_SYN_INTEL);

  base = pinfo->addr;
  size = pinfo->size;
  
  std::vector <long> address_array;
  //pAssemblerTree root =  new AssemblerTree;
  //  pAssemblerTree nowtree = root;
  std::vector <ud_t> ud_obj_array;
  address_array.push_back(pinfo->addr);
  address_array.push_back(pinfo->addr + pinfo->size);
  while (ud_disassemble(&ud_obj) != 0)
  {
    ud_obj_array.push_back(ud_obj);
    //    nowtree.asmpiect.push_back(ud_obj);
    if (ud_obj.operand[0].type == UD_OP_JIMM || ud_obj.mnemonic == UD_Icall )//&& ud_obj.mnemonic != UD_Icall)
    {
          long addr = ud_obj.operand[0].size == 8
            ? ((signed char)ud_obj.operand[0].lval.sbyte + ud_obj.pc) :
            (ud_obj.operand[0].lval.sdword + ud_obj.pc);
      if (addr >= pinfo->addr && addr <= pinfo->addr + pinfo->size)
      {
         address_array.push_back(addr);
         address_array.push_back(ud_obj.pc);        
      }
    }
  }

  long count = 0;
  long *a_array;
  size_t address_size = address_array.size();
  a_array = new long[address_size];
  for (std::vector <long>::iterator iter = address_array.begin() ;
       iter != address_array.end() ; ++iter)
  {
    bool fk = true;
    for (int i = 0; i < count; ++i)
    {
      if (*iter == a_array[i])
      {
        fk = false;
      }
    }
    if (fk)
      a_array[count++] = *iter;
  }
  for (int i = 0; i < count; ++i)
  {
    for (int j = i; j < count ; ++j)
    {
      if (a_array[i] > a_array[j])
      {
        long t = a_array[i];
        a_array[i] = a_array[j];
        a_array[j] = t;
      }
    }
  }

  for (int i = 0; i < count; ++i)
  {
    printf("%08x\r\n",a_array[i]);
  }
  int point = 0;
  pAssemblerTree nowtree = NULL;
  pAssemblerTree parent = NULL;
      const bool begin = true;
    const bool end = false;
    bool status = end;
  for (std::vector <ud_t>::iterator iter = ud_obj_array.begin();
       iter != ud_obj_array.end(); ++iter)
  {
    //typedef  true begin;
    //typedef false end;
    // ud_t *p = iter;
    ud_t ud = *iter;
    if (ud.insn_offset == a_array[point] && status == end)
    {
      point++;
      status = begin;
      nowtree = new AssemblerTree;
      root ? NULL : root = nowtree;
      nowtree->LeftChild = NULL;
      nowtree->RightChild = NULL;

      nowtree->id = point - 1;


      //      nowtree.asmpiect.push_back(ud);
    }
    if (nowtree)
    {
      nowtree->asmpiece.push_back(ud);
    }
    if (ud.pc == a_array[point] && status == begin)
    {
      nowtree->base = a_array[point-1];
      
      //point++;
      nowtree->size = ud.pc - a_array[point-1]; //代码块大小
      status = end;
      parent = add_tree(parent,nowtree,L);
      
      //nowtree = new AssemblerTree;
      //nowtree->LeftChild = NULL;
      //nowtree->RightChild = NULL;
    }
    nowtree->reloc_address = -1;    
    nowtree->next_instruction = ud.pc;   
  }
  block_count = point;
  link_tree();
#ifdef DEBUG
  show_tree(root,"false:");
#endif
  delete [] a_array;
  // show_tree(root);
  
  /*for (std::vector <long>::iterator iter = address_array.begin() ;
       iter != address_array.end() ; ++iter)
  {
    int addr = *iter;
    printf("%08x\r\n",addr);
    }*/
  return NULL;
}
Beispiel #23
0
AddressArray Analysis::analysis_code_piece_address(pCodeBufferInfo pinfo)
{
  ud_t ud_obj;
  ud_init(&ud_obj);

#ifndef PROTECT_X64
  ud_set_mode(&ud_obj,32);
#else
  ud_set_mode(&ud_obj,64);
#endif
  ud_set_pc(&ud_obj,pinfo->addr);
  ud_set_input_buffer(&ud_obj, (uint8_t*)pinfo->buf, pinfo->size);
  ud_set_syntax(&ud_obj,UD_SYN_INTEL);

  base = pinfo->addr;
  size = pinfo->size;
  
  std::vector <long> address_array;
  //pAssemblerTree root =  new AssemblerTree;
  //  pAssemblerTree nowtree = root;
  
  address_array.push_back(pinfo->addr);
  address_array.push_back(pinfo->addr + pinfo->size);
  while (ud_disassemble(&ud_obj) != 0)
  {
    //if (ud_obj.operand[0].type == UD_OP_JIMM || ud_obj.mnemonic == UD_Icall )//&& ud_obj.mnemonic != UD_Icall)
    if (ud_obj.pfx_rep != 0 || ud_obj.pfx_repe != 0 || ud_obj.pfx_repne != 0)   //有前缀
    {
      address_array.push_back(ud_obj.pc);
      address_array.push_back(ud_obj.insn_offset);
    }
    if (ud_obj.operand[0].type == UD_OP_JIMM )
    {

          long addr = ud_obj.operand[0].size == 8
            ? ((signed char)ud_obj.operand[0].lval.sbyte + ud_obj.pc) :
            (ud_obj.operand[0].lval.sdword + ud_obj.pc);

      if (addr >= pinfo->addr && addr <= pinfo->addr + pinfo->size)
      {
         address_array.push_back(addr);
         address_array.push_back(ud_obj.pc);        
      }
      else
      {
        //address_array.push_back(ud_obj.pc);
        if (ud_obj.mnemonic != UD_Icall && ud_obj.mnemonic != UD_Ijmp)
        {
          printf("%x:跳转的地址无法找到:",ud_obj.insn_offset);
          printf("%x\n",addr);
         // __asm("int3");         //表示跳转地址是一个jcc指令
        }
        else
        {
          address_array.push_back(ud_obj.pc);
        }
      }
    }
    if (ud_obj.mnemonic == UD_Iret || ud_obj.mnemonic == UD_Icall || ud_obj.mnemonic == UD_Ijmp)
    {
      address_array.push_back(ud_obj.pc);
    }
    /*if (ud_obj.mnemonic == UD_Icall || ud_obj.mnemonic == UD_Iret)
    {
      address_array.push_back(ud_obj.pc);
    }*/
  }
  long count = 0;
  
  size_t address_size = address_array.size();
  AddressArray a_array(address_size);  
  for (std::vector <long>::iterator iter = address_array.begin() ;
       iter != address_array.end() ; ++iter)
  {
    bool fk = true;
    for (int i = 0; i < count; ++i)
    {
      if (*iter == a_array[i])
      {
        fk = false;
      }
    }
    if (fk)
      a_array[count++] = *iter;
  }
  for (int i = 0; i < count; ++i)
  {
    for (int j = i; j < count ; ++j)
    {
      if (a_array[i] > a_array[j])
      {
        long t = a_array[i];
        a_array[i] = a_array[j];
        a_array[j] = t;
      }
    }
  }
  a_array.set_size(count); 
#ifdef DEBUG
  //printf("a_array size:%08x",a_array.get_size()); 
  for (int i = 0; i < count - 1; ++i)
  {
    
    printf("标签%x,分支地址:%08x - %08x\n",i,a_array[i],a_array[i+1]-1);
  }
//__asm ("int3");
#endif
  
  return a_array;
}