From 06c2f877e65742f15b2cd58e35f61ad3c1a1ae3a Mon Sep 17 00:00:00 2001 From: Rene Gollent Date: Sat, 19 Mar 2016 16:12:07 -0400 Subject: [PATCH] Debugger: Fix udis86 usage for resolving target address. DisassemblerX86{64}: - Fix problematic usage of udis86 that was broken during an update. Rather than calling the appropriate udis86 function to retrieve the operand, we were accessing it directly on the ud struct, which was fully filled in implicitly in previous versions of the library. However, in the updated version of udis86, the operands are only lazily decoded on request, and as such this data was invalid, leading to us not resolving target addresses properly. This primarily affected determining the location of return values. --- .../arch/x86/disasm/DisassemblerX86.cpp | 22 ++++++----- .../arch/x86_64/disasm/DisassemblerX8664.cpp | 38 ++++++++++--------- 2 files changed, 32 insertions(+), 28 deletions(-) diff --git a/src/apps/debugger/arch/x86/disasm/DisassemblerX86.cpp b/src/apps/debugger/arch/x86/disasm/DisassemblerX86.cpp index 2d8d50d983..bcedc2c9f3 100644 --- a/src/apps/debugger/arch/x86/disasm/DisassemblerX86.cpp +++ b/src/apps/debugger/arch/x86/disasm/DisassemblerX86.cpp @@ -1,6 +1,7 @@ /* * Copyright 2009-2012, Ingo Weinhold, ingo_weinhold@gmx.de. * Copyright 2008, François Revol, revol@free.fr + * Copyright 2016, Rene Gollent, rene@gollent.com. * Distributed under the terms of the MIT License. */ @@ -185,36 +186,37 @@ DisassemblerX86::GetInstructionTargetAddress(CpuState* state) const return 0; target_addr_t targetAddress = 0; - switch (fUdisData->operand[0].type) { + const struct ud_operand* op = ud_insn_opr(fUdisData, 0); + switch (op->type) { case UD_OP_REG: { targetAddress = x86State->IntRegisterValue( - RegisterNumberFromUdisIndex(fUdisData->operand[0].base)); - targetAddress += fUdisData->operand[0].offset; + RegisterNumberFromUdisIndex(op->base)); + targetAddress += op->offset; } break; case UD_OP_MEM: { targetAddress = x86State->IntRegisterValue( - RegisterNumberFromUdisIndex(fUdisData->operand[0].base)); + RegisterNumberFromUdisIndex(op->base)); targetAddress += x86State->IntRegisterValue( - RegisterNumberFromUdisIndex(fUdisData->operand[0].index)) - * fUdisData->operand[0].scale; - if (fUdisData->operand[0].offset != 0) - targetAddress += fUdisData->operand[0].lval.sdword; + RegisterNumberFromUdisIndex(op->index)) + * op->scale; + if (op->offset != 0) + targetAddress += op->lval.sdword; } break; case UD_OP_JIMM: { targetAddress = ud_insn_off(fUdisData) - + fUdisData->operand[0].lval.sdword + ud_insn_len(fUdisData); + + op->lval.sdword + ud_insn_len(fUdisData); } break; case UD_OP_IMM: case UD_OP_CONST: { - targetAddress = fUdisData->operand[0].lval.udword; + targetAddress = op->lval.udword; } break; diff --git a/src/apps/debugger/arch/x86_64/disasm/DisassemblerX8664.cpp b/src/apps/debugger/arch/x86_64/disasm/DisassemblerX8664.cpp index 3c32a10f03..b3dcd88396 100644 --- a/src/apps/debugger/arch/x86_64/disasm/DisassemblerX8664.cpp +++ b/src/apps/debugger/arch/x86_64/disasm/DisassemblerX8664.cpp @@ -2,6 +2,7 @@ * Copyright 2012, Alex Smith, alex@alex-smith.me.uk. * Copyright 2009-2012, Ingo Weinhold, ingo_weinhold@gmx.de. * Copyright 2008, François Revol, revol@free.fr + * Copyright 2016, Rene Gollent, rene@gollent.com. * Distributed under the terms of the MIT License. */ @@ -196,34 +197,35 @@ DisassemblerX8664::GetInstructionTargetAddress(CpuState* state) const return 0; target_addr_t targetAddress = 0; - switch (fUdisData->operand[0].type) { + const struct ud_operand* op = ud_insn_opr(fUdisData, 0); + switch (op->type) { case UD_OP_REG: { targetAddress = x64State->IntRegisterValue( - RegisterNumberFromUdisIndex(fUdisData->operand[0].base)); - targetAddress += fUdisData->operand[0].offset; + RegisterNumberFromUdisIndex(op->base)); + targetAddress += op->offset; } break; case UD_OP_MEM: { targetAddress = x64State->IntRegisterValue( - RegisterNumberFromUdisIndex(fUdisData->operand[0].base)); + RegisterNumberFromUdisIndex(op->base)); targetAddress += x64State->IntRegisterValue( - RegisterNumberFromUdisIndex(fUdisData->operand[0].index)) - * fUdisData->operand[0].scale; + RegisterNumberFromUdisIndex(op->index)) + * op->scale; off_t offset = 0; - switch (fUdisData->operand[0].offset) { + switch (op->offset) { case 8: - offset = fUdisData->operand[0].lval.sbyte; + offset = op->lval.sbyte; break; case 16: - offset = fUdisData->operand[0].lval.sword; + offset = op->lval.sword; break; case 32: - offset = fUdisData->operand[0].lval.sdword; + offset = op->lval.sdword; break; case 64: - offset = fUdisData->operand[0].lval.sqword; + offset = op->lval.sqword; break; } targetAddress += offset; @@ -232,20 +234,20 @@ DisassemblerX8664::GetInstructionTargetAddress(CpuState* state) const case UD_OP_JIMM: { targetAddress = ud_insn_off(fUdisData) + ud_insn_len(fUdisData); - if (fUdisData->operand[0].size == 32) - targetAddress += fUdisData->operand[0].lval.sdword; + if (op->size == 32) + targetAddress += op->lval.sdword; else - targetAddress += fUdisData->operand[0].lval.sqword; + targetAddress += op->lval.sqword; } break; case UD_OP_IMM: case UD_OP_CONST: { - if (fUdisData->operand[0].size == 32) - targetAddress = fUdisData->operand[0].lval.udword; - else if (fUdisData->operand[0].size == 64) - targetAddress = fUdisData->operand[0].lval.uqword; + if (op->size == 32) + targetAddress = op->lval.udword; + else if (op->size == 64) + targetAddress = op->lval.uqword; } break;