void test_labels(void) { init_hash_table(); Instruction* i = new_instruction_label("test", 1); TEST_ASSERT_EQUAL_STRING("test", i->opcode); TEST_ASSERT(i->type = I_TYPE_LABEL); set_label_address("test", 34); Address* a = addr_from_label(strdup("test")); resolve_address(a); TEST_ASSERT_EQUAL_INT_MESSAGE(34, a->immediate, "Incorrect label address"); free(a); free(i); }
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); } } }