BOOL isValidPreOpCode(BYTE *buffer, UINT nsize) { ud_t ud_obj; ud_init(&ud_obj); ud_set_input_buffer(&ud_obj, buffer, nsize); ud_set_mode(&ud_obj, 64); ud_set_syntax(&ud_obj, UD_SYN_INTEL); ud_t temp_ud_obj; while (ud_disassemble(&ud_obj)) { temp_ud_obj = ud_obj; } char *str = ud_insn_asm(&temp_ud_obj); if(!_stricmp(str, "ret ")) return true; if(!_stricmp(str, "nop ")) return true; if(!_stricmp(str, "int3 ")) return true; return false; }
void WDbgArkUdis::Init(const unsigned __int8 mode) { std::memset(&m_udis_obj, 0, sizeof(m_udis_obj)); ud_init(&m_udis_obj); ud_set_mode(&m_udis_obj, mode); ud_set_syntax(&m_udis_obj, UD_SYN_INTEL); DEBUG_PROCESSOR_IDENTIFICATION_ALL processor_info; HRESULT result = g_Ext->m_Data->ReadProcessorSystemData(0, DEBUG_DATA_PROCESSOR_IDENTIFICATION, &processor_info, static_cast<unsigned __int32>(sizeof(processor_info)), nullptr); unsigned __int32 vendor = UD_VENDOR_ANY; if (SUCCEEDED(result) && (g_Ext->m_ActualMachine == IMAGE_FILE_MACHINE_I386 || g_Ext->m_ActualMachine == IMAGE_FILE_MACHINE_AMD64) ) { std::string vendor_string; if ( g_Ext->m_ActualMachine == IMAGE_FILE_MACHINE_I386 ) vendor_string = processor_info.X86.VendorString; else vendor_string = processor_info.Amd64.VendorString; if ( vendor_string == "GenuineIntel" ) vendor = UD_VENDOR_INTEL; else vendor = UD_VENDOR_AMD; } ud_set_vendor(&m_udis_obj, vendor); }
void Translator::Translate(uchar* native, int nativeSize, std::vector<NhoInstr>* nhos) { int c = 0; ud_t dis; ud_init(&dis); ud_set_mode(&dis, 32); ud_set_syntax(&dis, UD_SYN_INTEL); NhoInstr nho; while (c < nativeSize) { ud_set_input_buffer(&dis, &native[c], nativeSize - c >= MAX_INSN_LENGTH ? MAX_INSN_LENGTH : nativeSize - c); c += ud_disassemble(&dis); nho.mnemonic = dis.mnemonic ^ MNE_XOR; memcpy(&nho.operands, &dis.operand, sizeof(nho.operands)); nho.pfx_adr = dis.pfx_adr; nho.pfx_lock = dis.pfx_lock; nho.pfx_opr = dis.pfx_opr; nho.pfx_rep = dis.pfx_rep; nho.pfx_repe = dis.pfx_repe; nho.pfx_repne = dis.pfx_repne; nho.pfx_rex = dis.pfx_rex; nho.pfx_seg = dis.pfx_seg; nho.pfx_str = dis.pfx_str; } }
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; }
/* * 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] = '_'; } } }
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++; } } }
int main(void) { ud_t ud_obj; char x[4]; unsigned char buff[256]; int i, j; printf("Content-Type: text/html\r\n"); printf("\r\n"); char *qs = getenv("QUERY_STRING"); if(qs == NULL) return 1; for(i=0, j=0; qs[i] == '%'; i+=3, j++){ if(j >= sizeof(buff)) break; x[0] = *(qs+i+1); x[1] = *(qs+i+2); x[2] = '\0'; buff[j] = (unsigned char)strtoul(x, NULL, 16); } ud_init(&ud_obj); ud_set_input_buffer(&ud_obj, buff, j); ud_set_mode(&ud_obj, 32); ud_set_syntax(&ud_obj, UD_SYN_INTEL); while(ud_disassemble(&ud_obj)){ //printf("%d:%s", ud_insn_len(&ud_obj), ud_insn_asm(&ud_obj)); printf("%10s: %s\n", ud_insn_hex(&ud_obj), ud_insn_asm(&ud_obj)); } return 0; }
EASYHOOK_NT_INTERNAL LhDisassembleInstruction(void* InPtr, ULONG* length, PSTR buf, LONG buffSize, ULONG64 *nextInstr) { /* Description: Takes a pointer to machine code and returns the length and ASM code for the referenced instruction. Returns: STATUS_INVALID_PARAMETER The given pointer references invalid machine code. */ // some exotic instructions might not be supported see the project // at https://github.com/vmt/udis86. ud_t ud_obj; ud_init(&ud_obj); #ifdef _M_X64 ud_set_mode(&ud_obj, 64); #else ud_set_mode(&ud_obj, 32); #endif ud_set_syntax(&ud_obj, UD_SYN_INTEL); ud_set_asm_buffer(&ud_obj, buf, buffSize); ud_set_input_buffer(&ud_obj, (uint8_t *)InPtr, 32); *length = ud_disassemble(&ud_obj); *nextInstr = (ULONG64)InPtr + *length; if(length > 0) return STATUS_SUCCESS; else return STATUS_INVALID_PARAMETER; }
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; }
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; } } }
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; }
/* * 预读分析阶段,在分区处理是时进行,数据与代码区域 * 范围的界定,纯数据区域返回TRUE,反之为FALSE */ __INLINE__ __bool __INTERNAL_FUNC__ PredictBlockEnd(__memory pMem, __address ImageBase, __memory pCurr, __integer iSize, \ __integer *piOutSize, PANALYZE_CONFIGURE pAnalyzeConfigure) { __bool bBlock = FALSE; __offset ofOffset = 0; ud_t ud_obj; ud_init(&ud_obj); ud_set_mode(&ud_obj, 32); ud_set_syntax(&ud_obj, UD_SYN_INTEL); ud_set_input_buffer(&ud_obj, pCurr, iSize); while (ud_disassemble(&ud_obj)) { enum ud_mnemonic_code mnemonic = ud_obj.mnemonic; if ((mnemonic == UD_Inop) || \ (mnemonic == UD_Iint3) || \ ((mnemonic == UD_Iadd) && (ud_obj.inp_ctr == 2) && (*(__word *)&(ud_obj.inp_sess) == 0))) { /* * 到达结束条件 * 检查是否到达了用户定义代码的最小范围,如果没到直接视为数据 * 如果大于等于则进入深入鉴别 */ if (ofOffset < pAnalyzeConfigure->bCodeMixSize) bBlock = TRUE; else // 进入深度分析 bBlock = DeepAnalyzeBlock(pMem, ImageBase, pCurr, ofOffset, pAnalyzeConfigure); *piOutSize = (__integer)ofOffset; return bBlock; }/* end if */ ofOffset += (__integer)ud_insn_len(&ud_obj); } // 这里做深度鉴别 bBlock = DeepAnalyzeBlock(pMem, ImageBase, pCurr, iSize, pAnalyzeConfigure); *piOutSize = (__integer)ofOffset; return bBlock; }
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); } }
DWORD DasmOp(LPVOID addr) { ud_init(&ud_obj); ud_set_mode(&ud_obj, 32); ud_set_syntax(&ud_obj, UD_SYN_INTEL); ud_set_input_hook(&ud_obj, DasmInputHookEIP); dasmAddr = (LPBYTE) addr; return (DWORD) ud_disassemble(&ud_obj); }
void LLVMState::show_machine_code(void* buffer, size_t size) { ud_t ud; ud_init(&ud); #ifdef IS_X8664 ud_set_mode(&ud, 64); #else ud_set_mode(&ud, 32); #endif ud_set_syntax(&ud, UD_SYN_ATT); ud_set_input_buffer(&ud, reinterpret_cast<uint8_t*>(buffer), size); while(ud_disassemble(&ud)) { void* address = reinterpret_cast<void*>( reinterpret_cast<uintptr_t>(buffer) + ud_insn_off(&ud)); std::cout << std::setw(10) << std::right << address << " "; std::cout << std::setw(24) << std::left << ud_insn_asm(&ud); if(ud.operand[0].type == UD_OP_JIMM) { const void* addr = (const void*)((uintptr_t)buffer + ud.pc + (int)ud.operand[0].lval.udword); std::cout << " ; " << addr; if(ud.mnemonic == UD_Icall) { Dl_info info; if(dladdr(addr, &info)) { int status = 0; char* cpp_name = abi::__cxa_demangle(info.dli_sname, 0, 0, &status); if(status >= 0) { // Chop off the arg info from the signature output char *paren = strstr(cpp_name, "("); *paren = 0; std::cout << " " << cpp_name; free(cpp_name); } else { std::cout << " " << info.dli_sname; } } } } for(uint8_t i = 0; i < 2; i++) { if(ud.operand[i].type == UD_OP_IMM) { Dl_info info; if(dladdr((void*)ud.operand[i].lval.uqword, &info)) { std::cout << " ; " << info.dli_sname; break; // only do one } } } std::cout << "\n"; } }
int ludis86_ud_set_syntax (lua_State * L) { ud_t * ud_obj; const char * syntax; ud_obj = ludis86_check_ud_t(L, 1); syntax = luaL_checkstring(L, 2); lua_pop(L, 2); if (strcmp(syntax, "UD_SYN_INTEL") == 0) ud_set_syntax(ud_obj, UD_SYN_INTEL); else if (strcmp(syntax, "UD_SYN_ATT") == 0) ud_set_syntax(ud_obj, UD_SYN_ATT); else luaL_error(L, "invalid syntax for ludis86"); return 0; }
/* * 参数: * pMem:被保护程序的文件映射 * pProcFileAddress:函数的文件地址 * ofProcMemRVA:函数的RVA * iProcSize:函数的长度 * pProtectInstructions:要加密的指令 * iProtectInstCount:要保护指令的个数 * pPowerProtecterEncryptInstruction:加密指令结构的指针(写入点) * pPowerProtecterEncryptProcedure:加密函数的结构的指针(写入点) * * 介绍: * 加密指定的函数函数 */ __INLINE__ __integer __INTERNAL_FUNC__ PowerProtectProcedure(__memory pMem, __memory pProcFileAddress, __offset ofProcMemRVA, __integer iProcSize, \ PPOWER_PROTECTER_INSTRUCTION pProtectInstructions, __integer iProtectInstCount, PPOWER_PROTECTER_ENCRYPT_INSTRUCTION pPowerProtecterEncryptInstruction, \ PPOWER_PROTECTER_ENCRYPT_PROCEDURE pPowerProtecterEncryptProcedure) { __integer iFlowInstCount = 0; __integer iInstLength = 0; __offset ofOffset = 0; __memory pCurr = NULL; __offset ofCurrMemRVA = 0; PPOWER_PROTECTER_ENCRYPT_INSTRUCTION pEncryptInstruction = NULL; PPOWER_PROTECTER_INSTRUCTION pNowProtectInstruction = NULL; ud_t ud_obj = {0}; pCurr = pProcFileAddress; ofCurrMemRVA = ofProcMemRVA; pEncryptInstruction = pPowerProtecterEncryptInstruction; ud_init(&ud_obj); ud_set_input_buffer(&ud_obj, pProcFileAddress, iProcSize); ud_set_mode(&ud_obj, 32); ud_set_syntax(&ud_obj, UD_SYN_INTEL); while (ud_disassemble(&ud_obj)) { iInstLength = ud_obj.inp_ctr;//指令长度 // 如果是其他指令则判断是否在保护范围内区域 pNowProtectInstruction = ThisInstructionIsNeedProtect(ofCurrMemRVA, pProtectInstructions, iProtectInstCount); if (pNowProtectInstruction) { /* * 如果是用户指定的保护指令 */ PowerProtectThisInstruction(pMem, &ud_obj, ofCurrMemRVA, iProcSize, pNowProtectInstruction, pEncryptInstruction); pEncryptInstruction++;//移动到下一个加密指令结构 } else if (IsFlowInstructionByOffset(&ud_obj) != PPFT_NONE) { /* * 如果是流程指令则必进行保护 */ POWER_PROTECTER_INSTRUCTION PowerProtecterInstruction = {0}; PowerProtecterInstruction.bWatched = FALSE; PowerProtecterInstruction.Instruction.ofMemRVA = ofCurrMemRVA; PowerProtecterInstruction.Instruction.iSize = iInstLength; pNowProtectInstruction = &PowerProtecterInstruction; PowerProtectThisInstruction(pMem, &ud_obj, ofCurrMemRVA, iProcSize, pNowProtectInstruction, pEncryptInstruction); pEncryptInstruction++;//移动到下一个加密指令结构 iFlowInstCount++; } // 记录相关信息 ofOffset += iInstLength; pCurr += iInstLength; ofCurrMemRVA += iInstLength; } return iFlowInstCount; }
// Function to read and disassemble one instrution after ptrace stopped on singlestep // written by Xiao Lin static void handle_singelstep() { struct user_regs_struct regfile; ptrace(PTRACE_GETREGS, tr_pid, NULL, ®file); unsigned long addr = regfile.eip; fprintf(stdout, "Address = 0x%08lx\n", addr); unsigned long data = 0; data = ptrace(PTRACE_PEEKTEXT, tr_pid, addr, NULL); fprintf(stdout, "Data = 0x%08lx\n", data); ud_t ud_obj; unsigned char buff[15]; memcpy(buff, (char*)&data, sizeof(long)); // setup udis86 ud_init(&ud_obj); ud_set_mode(&ud_obj, 32); ud_set_syntax(&ud_obj, UD_SYN_INTEL); ud_set_input_buffer(&ud_obj, buff, 15); // disassemble and have udis86 guess instruction length ud_disassemble(&ud_obj); unsigned int instr_len = ud_insn_len(&ud_obj); fprintf(stdout, "Instruction length = %d Bytes\n", instr_len); // get more byte via ptrace if intruction length > 4bytes int i = 4; while (i < instr_len) { data = ptrace(PTRACE_PEEKTEXT, tr_pid, addr+i, NULL); memcpy(buff+i, (char*)&data, sizeof(long)); i = i + 4; } // disassemble second time and print ud_init(&ud_obj); ud_set_mode(&ud_obj, 32); ud_set_syntax(&ud_obj, UD_SYN_INTEL); ud_set_input_buffer(&ud_obj, buff, 15); if (ud_disassemble(&ud_obj) != 0) { printf("Disassemble: %s %s\n", ud_insn_hex(&ud_obj), ud_insn_asm(&ud_obj)); } return; }
int main() { uint8_t raw[] = { 0xf0, 0x66, 0x36, 0x67, 0x65, 0x66, 0xf3, 0x67, 0xda }; uint8_t len = 9; ud_t ud_obj; ud_init(&ud_obj); ud_set_mode(&ud_obj, 16); ud_set_input_buffer(&ud_obj, raw, len); ud_set_syntax(&ud_obj, UD_SYN_INTEL); if (ud_disassemble(&ud_obj) != 0) { return 0; } return 1; }
int test() { uint8_t raw[] = { 0xf0, 0x66, 0x36, 0x67, 0x65, 0x66, 0xf3, 0x67, 0xda }; uint8_t len = 9; ud_t ud_obj; ud_init(&ud_obj); ud_set_mode(&ud_obj, 16); ud_set_input_buffer(&ud_obj, raw, len); ud_set_syntax(&ud_obj, UD_SYN_INTEL); // if (ud_disassemble(&ud_obj) != 0) { // fprintf(stdout,"%s",ud_insn_asm(&ud_obj)); // } return 0; }
/* * Function do_trace assumes that itrace as been attached (successfully) * to a process. It then output to stdout all the x86 instructions being * executed by traced program */ static void do_trace() { struct user_regs_struct registers; /* A struct to hold all registers of process */ size_t read_size = 15; /* how many bytes the disassembler should read */ unsigned char *buff; long eip_data[4]; /* a holding place for all the 15 bytes of eip (max intruction size) */ buff = (unsigned char *) malloc(sizeof(unsigned char)*15); int stop_status = 0; /* Loops until no more instructinos are being read */ do { ptrace(PTRACE_GETREGS, tr_pid, NULL, ®isters); eip_data[0]= ptrace(PTRACE_PEEKDATA, tr_pid, registers.eip, NULL); eip_data[1]= ptrace(PTRACE_PEEKDATA, tr_pid, registers.eip+4, NULL); eip_data[2]= ptrace(PTRACE_PEEKDATA, tr_pid, registers.eip+8, NULL); eip_data[3]= ptrace(PTRACE_PEEKDATA, tr_pid, registers.eip+12, NULL); memcpy(buff, eip_data, 15); /* Initialization of 3rd part disassembler */ ud_t ud_obj; ud_init(&ud_obj); ud_set_mode(&ud_obj, 32); ud_set_syntax(&ud_obj, UD_SYN_INTEL); ud_set_input_buffer(&ud_obj, buff, read_size); ud_disassemble(&ud_obj); /* Prints the disassembled x86 code */ printf("\t%s\n", ud_insn_asm(&ud_obj)); /* Tells the tracee to go to the next instruction, then wait */ ptrace(PTRACE_SINGLESTEP,tr_pid, 0,NULL); /* Waits until the tracee program as gon to the next intSruction and STOPPED before itrace continues */ waitpid(tr_pid, &stop_status, WUNTRACED|WCONTINUED); if(!stop_status) { printf("Something has gone wrong"); } }while (eip_data[0] != -1); return; }
int main() { ud_t u; ud_init(&u); ud_set_mode(&u, 32); ud_set_syntax(&u, UD_SYN_INTEL); ud_set_input_buffer(&u, buf, 3); ud_disassemble(&u); printf("%s\n", ud_insn_asm(&u)); printf("op0.size = %d\n", u.operand[0].size); return 0; }
bool MDBCode::isCallInstruction(uintptr_t address) { char buffer[32]; if (debugger->read(buffer, address, sizeof(buffer)) != sizeof(buffer)) { log.traceLn("Cannot read instruction memory."); } ud_t insn; ud_init(&insn); ud_set_input_buffer(&insn, (uint8_t*)buffer, 32); ud_set_mode(&insn, 32); ud_set_syntax(&insn, UD_SYN_INTEL); size_t length = ud_disassemble(&insn); log.traceLn("Instruction at 0x%X is %d bytes long.", address, length); return insn.mnemonic == UD_Icall; }
/* * 使用JMP指令进行鉴别 * 如果是纯数据区返回TRUE,反之返回FALSE */ __INLINE__ __bool __INTERNAL_FUNC__ AbyssAnalyze(__memory pMem, __address ImageBase, __memory pCurr, __integer iSize) { __address addrStartAddress = ImageBase + AnalyzerRaw2Rva(pMem, (__integer)(pCurr - pMem)); __offset ofOffset = 0; PX86INSTRUCTION pInstruction = NULL, pPrevInstruction = NULL, *pCurrInstructionPoint = &pInstruction; ud_t ud_obj; ud_init(&ud_obj); ud_set_mode(&ud_obj, 32); ud_set_syntax(&ud_obj, UD_SYN_INTEL); ud_set_input_buffer(&ud_obj, pCurr, iSize); // 使用第一次指令派遣函数进行分析 while (ud_disassemble(&ud_obj)) { __address addrCurrentAddress = addrStartAddress + ofOffset; *pCurrInstructionPoint = __logic_new__(X86INSTRUCTION, 1); __logic_memset__((*pCurrInstructionPoint), 0, sizeof(X86INSTRUCTION)); (*pCurrInstructionPoint)->addrCurrMemoryAddress = addrCurrentAddress; (*pCurrInstructionPoint)->addrMemoryBlockStart = addrStartAddress; (*pCurrInstructionPoint)->iBlockSize = iSize; (*pCurrInstructionPoint)->pMem = pMem; __logic_memcpy__(&((*pCurrInstructionPoint)->ud_obj), &ud_obj, sizeof(ud_t)); (*pCurrInstructionPoint)->pPrev = pPrevInstruction;//设置上层指令 (*pCurrInstructionPoint)->pNext = NULL; // 执行分析 InstructionDispatcher(g_pAnalyzeDataDispatcher, *pCurrInstructionPoint); if ((*pCurrInstructionPoint)->bErrorLogicInstruction) {//如果遇到逻辑错误指令则直接退出 ReleaseInstructionList(&pInstruction); return TRUE; } // 链接链表 if (pPrevInstruction) pPrevInstruction->pNext = (*pCurrInstructionPoint); pPrevInstruction = (*pCurrInstructionPoint); pCurrInstructionPoint = &((*pCurrInstructionPoint)->pNext);//下一个节点 ofOffset += (__integer)ud_insn_len(&ud_obj); }/* end while */ /* * 如果没有错误指令,则进入更加深入的分析流程 */ // 释放指令链表 ReleaseInstructionList(&pInstruction); return FALSE; }
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) //{ //} } }
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); } }
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; }
/* * * 参数: * pMem:被保护程序映射的内存指针 * pRecord:记录了要保护的信息 * * 介绍: * 核算所有加密函数结构的长度 */ __integer __API__ PowerProtecterAthCountAllEncryptProceduresSize(__memory pMem, PPOWER_PROTECTER_PROCEDURE pRecord) { __integer iTotalSize = 0; __integer i = 0; __integer iCount = 0; __integer iEncryptInstSize = 0; __integer iSize = 0; __address addrImageBase = 0; __integer iFlowCount = 0; ud_t ud_obj = {0}; addrImageBase = GetNtHeader(pMem)->OptionalHeader.ImageBase; iCount = pRecord->iCount; for (i = 0; i < iCount; i++) { __memory pProcFileAddress = NULL; __integer iProcSize = 0; __address addrProcMemAddress = 0; addrProcMemAddress = pRecord->Procedure[i].addrMemAddress; pProcFileAddress = pMem + Rva2Raw(pMem, addrProcMemAddress - addrImageBase); iProcSize = pRecord->Procedure[i].iSize; // 这里分析这个函数的流程指令计数 ud_init(&ud_obj); ud_set_input_buffer(&ud_obj, pProcFileAddress, iProcSize); ud_set_mode(&ud_obj, 32); ud_set_syntax(&ud_obj, UD_SYN_INTEL); while (ud_disassemble(&ud_obj)) { POWER_PROTECTER_FLOW_TYPE Type = PPFT_NONE; Type = IsFlowInstructionByOffset(&ud_obj); if (Type != PPFT_NONE) iFlowCount++; } // 计算最终所需的数据 iEncryptInstSize = (iFlowCount + pRecord->iInstructionCount[i]) * sizeof(POWER_PROTECTER_ENCRYPT_INSTRUCTION);//计算加密指令总长度 // 加密后函数的长度 + 函数加密结构长度 + 解密指令结构总长度 iSize = pRecord->Procedure[i].iSize + sizeof(POWER_PROTECTER_ENCRYPT_PROCEDURE) + iEncryptInstSize; iSize = Alig(iSize, __POWER_PROTECT_ENCRYPT_PROCEDURE_ALIGN__, TRUE); iTotalSize += iSize; } return iTotalSize; }
UINT GetInstrSize(BYTE *buffer, UINT nsize) { ud_t ud_obj; ud_init(&ud_obj); ud_set_input_buffer(&ud_obj, buffer, nsize); ud_set_mode(&ud_obj, 64); ud_set_syntax(&ud_obj, UD_SYN_INTEL); ud_t temp_ud_obj; while (ud_disassemble(&ud_obj)) { temp_ud_obj = ud_obj; } return temp_ud_obj.pc - temp_ud_obj.insn_offset; }
// use libudis to give human readable output of ASM void DasosPreproc::printDisasm_viaLib (uint8_t* raw, unsigned len) { ud_t ud_obj; ud_init (&ud_obj); ud_set_mode (&ud_obj, 32); ud_set_syntax (&ud_obj, UD_SYN_INTEL); ud_set_input_buffer(&ud_obj, raw, len); unsigned insn_len = 0; if ((insn_len = ud_disassemble (&ud_obj) ) != len) { s2e()->getDebugStream() << "disasm didn't do all insn bytes: " << insn_len << "/" << len << "\n"; return; } char buf[64]; snprintf (buf, sizeof (buf), " %-24s", ud_insn_asm (&ud_obj) ); s2e()->getDebugStream() << buf; return; } // end fn printDisasm_viaLib