| 3 | Function::Function(DWORD startRva, DWORD endRva, std::vector<BYTE> bytes) : startRva(startRva), endRva(endRva), bytes(bytes) {}; |
| 4 | |
| 5 | bool Function::disassemble() |
| 6 | { |
| 7 | // initialise zydis decoder |
| 8 | ZydisDecoder decoder; |
| 9 | if (ZYAN_FAILED(ZydisDecoderInit(&decoder, ZYDIS_MACHINE_MODE_LONG_64, ZYDIS_STACK_WIDTH_64))) |
| 10 | { |
| 11 | std::cerr << "error initializing ZydisDecoder" << std::endl; |
| 12 | return 0; |
| 13 | } |
| 14 | |
| 15 | ZydisDecodedInstruction instructionInfo; |
| 16 | ZydisDecodedOperand operandInfo[ZYDIS_MAX_OPERAND_COUNT]; |
| 17 | |
| 18 | // first pass: disassemble each instruction |
| 19 | DWORD offset = 0; |
| 20 | while (offset < bytes.size()) |
| 21 | { |
| 22 | if (ZYAN_FAILED(ZydisDecoderDecodeFull(&decoder, bytes.data() + offset, bytes.size(), &instructionInfo, operandInfo))) |
| 23 | { |
| 24 | std::cerr << "error decoding instruction" << std::endl; |
| 25 | return 0; |
| 26 | } |
| 27 | |
| 28 | instructions.push_back(Instruction(instructionInfo, operandInfo, offset + startRva)); |
| 29 | |
| 30 | offset += instructionInfo.length; |
| 31 | } |
| 32 | |
| 33 | // second pass: find branch destinations |
| 34 | for (int i = 0; i < instructions.size(); i++) |
| 35 | { |
| 36 | if (instructions[i].isBranchInstruction()) |
| 37 | { |
| 38 | for (int j = 0; j < instructions.size(); j++) |
| 39 | { |
| 40 | // check if instruction is destination of our branch |
| 41 | if (instructions[i].getRva() + |
| 42 | instructions[i].getOperandInfo()[0].imm.value.s + |
| 43 | instructions[i].getInstructionInfo().length == instructions[j].getRva()) |
| 44 | { |
| 45 | instructions[i].setDestInstructionIndex(j); |
| 46 | } |
| 47 | } |
| 48 | } |
| 49 | } |
| 50 | |
| 51 | return 1; |
| 52 | } |
| 53 | |
| 54 | bool Function::compileInstructionsToVirtualInstructions() |
| 55 | { |
no test coverage detected