Skip to content

Commit c471e33

Browse files
committed
ARM: Autodereference pointers, refactoring
1 parent 80b8db7 commit c471e33

File tree

4 files changed

+36
-20
lines changed

4 files changed

+36
-20
lines changed

capstonebundle/plugin/arm/common.h

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,5 +8,8 @@
88
#define ARM32LE_ID "arm32le"
99
#define ARM32BE_ID "arm32be"
1010

11-
#define ARM_IS_THUMB(address) (address & 1)
12-
#define ARM_PC(address) (address & ~1)
11+
template<typename T>
12+
inline T arm_is_thumb(T address) { return address & 1; }
13+
14+
template<typename T>
15+
inline T arm_address(T address) { return address & ~1ull; }

capstonebundle/plugin/arm32/common.cpp

Lines changed: 28 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,9 @@
33

44
void ARM32Common::emulate(Capstone* capstone, RDEmulateResult* result, const cs_insn* insn)
55
{
6-
rd_address address = ARM_PC(RDEmulateResult_GetAddress(result));
6+
rd_address address = arm_address(RDEmulateResult_GetAddress(result));
77
const auto& arm = insn->detail->arm;
88

9-
if(address == 0x08000110)
10-
{
11-
int zzz = 0;
12-
zzz++;
13-
}
14-
159
switch(insn->id)
1610
{
1711
case ARM_INS_B: {
@@ -28,26 +22,26 @@ void ARM32Common::emulate(Capstone* capstone, RDEmulateResult* result, const cs_
2822
case ARM_INS_BLX: {
2923
if(arm.operands[0].type != ARM_OP_IMM) return;
3024

31-
if(ARM_IS_THUMB(arm.operands[0].imm))
32-
RDContext_SetAddressAssembler(capstone->context(), ARM_PC(arm.operands[0].imm), capstone->endianness() == Endianness_Big ? THUMBBE_ID : THUMBLE_ID);
25+
if(arm_is_thumb(arm.operands[0].imm))
26+
RDContext_SetAddressAssembler(capstone->context(), arm_address(arm.operands[0].imm), capstone->endianness() == Endianness_Big ? THUMBBE_ID : THUMBLE_ID);
3327
else
34-
RDContext_SetAddressAssembler(capstone->context(), ARM_PC(arm.operands[0].imm), capstone->endianness() == Endianness_Big ? ARM32BE_ID : ARM32LE_ID);
28+
RDContext_SetAddressAssembler(capstone->context(), arm_address(arm.operands[0].imm), capstone->endianness() == Endianness_Big ? ARM32BE_ID : ARM32LE_ID);
3529

3630
if(arm.cc != ARM_CC_AL) {
3731

3832
}
39-
else RDEmulateResult_AddCall(result, ARM_PC(arm.operands[0].imm));
33+
else RDEmulateResult_AddCall(result, arm_address(arm.operands[0].imm));
4034

4135
return;
4236
}
4337

4438
case ARM_INS_BL: {
4539
if(capstone->mode() & CS_MODE_THUMB)
46-
RDContext_SetAddressAssembler(capstone->context(), ARM_PC(arm.operands[0].imm), capstone->endianness() == Endianness_Big ? THUMBBE_ID : THUMBLE_ID);
40+
RDContext_SetAddressAssembler(capstone->context(), arm_address(arm.operands[0].imm), capstone->endianness() == Endianness_Big ? THUMBBE_ID : THUMBLE_ID);
4741
else
48-
RDContext_SetAddressAssembler(capstone->context(), ARM_PC(arm.operands[0].imm), capstone->endianness() == Endianness_Big ? ARM32BE_ID : ARM32LE_ID);
42+
RDContext_SetAddressAssembler(capstone->context(), arm_address(arm.operands[0].imm), capstone->endianness() == Endianness_Big ? ARM32BE_ID : ARM32LE_ID);
4943

50-
RDEmulateResult_AddCall(result, ARM_PC(arm.operands[0].imm)); return;
44+
RDEmulateResult_AddCall(result, arm_address(arm.operands[0].imm)); return;
5145
return;
5246
}
5347

@@ -154,20 +148,38 @@ void ARM32Common::processOperands(Capstone* capstone, const cs_insn* insn, RDEmu
154148

155149
bool ARM32Common::isMemPC(const arm_op_mem& mem) { return (mem.index == ARM_REG_INVALID) && (mem.base == ARM_REG_PC); }
156150

151+
void ARM32Common::renderDereference(rd_location location, const RDRendererParams* rp)
152+
{
153+
auto* doc = RDContext_GetDocument(rp->context);
154+
auto flags = RDDocument_GetFlags(doc, location);
155+
156+
if(flags & AddressFlags_Pointer) {
157+
auto loc = RDDocument_Dereference(doc, location);
158+
159+
if(loc.valid) {
160+
RDRenderer_Text(rp->renderer, "=");
161+
RDRenderer_Reference(rp->renderer, arm_address(loc.address));
162+
return;
163+
}
164+
}
165+
166+
RDRenderer_Reference(rp->renderer, location);
167+
}
168+
157169
void ARM32Common::renderOperand(Capstone* capstone, const cs_insn* insn, const cs_arm_op& op, const RDRendererParams* rp)
158170
{
159171
const auto& arm = insn->detail->arm;
160172

161173
switch(op.type)
162174
{
163175
case ARM_OP_MEM: {
164-
if(ARM32Common::isMemPC(op.mem)) RDRenderer_Reference(rp->renderer, ARM32Common::pc(capstone, insn) + op.mem.disp); // [pc]
176+
if(ARM32Common::isMemPC(op.mem)) ARM32Common::renderDereference(ARM32Common::pc(capstone, insn) + op.mem.disp, rp); // [pc]
165177
else ARM32Common::renderMemory(capstone, arm, op, rp);
166178
break;
167179
}
168180

181+
case ARM_OP_IMM: ARM32Common::renderDereference(op.imm, rp); break;
169182
case ARM_OP_REG: RDRenderer_Register(rp->renderer, capstone->regName(op.reg)); break;
170-
case ARM_OP_IMM: RDRenderer_Reference(rp->renderer, op.imm); break;
171183
case ARM_OP_FP: RDRenderer_Text(rp->renderer, "ARM_OP_FP"); break;
172184
case ARM_OP_CIMM: RDRenderer_Text(rp->renderer, "ARM_OP_CIMM"); break;
173185
case ARM_OP_PIMM: RDRenderer_Text(rp->renderer, "ARM_OP_PIMM"); break;

capstonebundle/plugin/arm32/common.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ class ARM32Common
1515
static bool isMemPC(const arm_op_mem& mem);
1616

1717
private:
18+
static void renderDereference(rd_location location, const RDRendererParams* rp);
1819
static void renderOperand(Capstone* capstone, const cs_insn* insn, const cs_arm_op& op, const RDRendererParams* rp);
1920
static void renderMemory(Capstone* capstone, const cs_arm& arm, const cs_arm_op& op, const RDRendererParams* rp);
2021
static void checkFlowFrom(const cs_insn* insn, RDEmulateResult* result, int startidx);

capstonebundle/plugin/arm32/thumb32.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ Thumb::Thumb(RDContext* ctx, cs_mode mode): Capstone(ctx, CS_ARCH_ARM, static_ca
77

88
void Thumb::emulate(RDEmulateResult* result)
99
{
10-
rd_address address = ARM_PC(RDEmulateResult_GetAddress(result));
10+
rd_address address = arm_address(RDEmulateResult_GetAddress(result));
1111
auto* insn = this->decode(address, RDEmulateResult_GetView(result));
1212
if(!insn) return;
1313

@@ -18,7 +18,7 @@ void Thumb::emulate(RDEmulateResult* result)
1818

1919
void Thumb::render(const RDRendererParams* rp)
2020
{
21-
auto* insn = this->decode(ARM_PC(rp->address), &rp->view);
21+
auto* insn = this->decode(arm_address(rp->address), &rp->view);
2222
if(insn) ARM32Common::render(this, insn, rp);
2323
}
2424

0 commit comments

Comments
 (0)