Skip to content

Commit

Permalink
analyzer: check if a pointer is dereferenced before analysing as code
Browse files Browse the repository at this point in the history
  • Loading branch information
plasma-disassembler committed May 13, 2017
1 parent 7f75740 commit a5d7a62
Show file tree
Hide file tree
Showing 4 changed files with 29 additions and 12 deletions.
10 changes: 8 additions & 2 deletions plasma/lib/analyzer.py
Original file line number Diff line number Diff line change
Expand Up @@ -278,7 +278,7 @@ def add_stack_variable(self, func_obj, inst, offset, op_size):
# Do an analysis if the immediate is an address
# If from_save_imm is true, op is the destination where we save imm
# -> inst op, computed_imm
def analyze_imm(self, i, op, imm, from_save_imm):
def analyze_imm(self, i, op, imm, from_save_imm, is_deref_pointer):
if imm <= 1024:
return False

Expand Down Expand Up @@ -327,7 +327,7 @@ def analyze_imm(self, i, op, imm, from_save_imm):
if ty == MEM_UNK:
# Do an analysis on this value, if this is not code
# nothing will be done.
if s.is_exec and self.first_inst_are_code(ad):
if not is_deref_pointer and s.is_exec and self.first_inst_are_code(ad):
self.analyze_flow(
ad,
entry_is_func=self.has_prolog(ad),
Expand Down Expand Up @@ -594,6 +594,12 @@ def __sub_analyze_flow(self, func_obj, entry, inner_code, add_if_code):

while stack:
(regsctx, ad) = stack.pop()

if ad in self.db.mem.mm:
ty = self.db.mem.mm[ad][1]
if not(ty == MEM_UNK or ty == MEM_CODE or ty == MEM_FUNC):
continue

inst = self.disasm(ad)

if inst is None:
Expand Down
10 changes: 6 additions & 4 deletions plasma/lib/arch/arm/analyzer.c
Original file line number Diff line number Diff line change
Expand Up @@ -456,6 +456,7 @@ static PyObject* analyze_operands(PyObject *self, PyObject *args)
int values[3] = {0, 0, 0};
bool is_stack[3] = {false, false, false};
bool err[3];
bool is_load_insn = len_ops == 2 && is_load(id);

// The first operand is always a register and always the destination (except st* ?)
int r1 = get_op_reg(ops[0]);
Expand Down Expand Up @@ -483,8 +484,8 @@ static PyObject* analyze_operands(PyObject *self, PyObject *args)
}
}

PyObject_CallMethod(analyzer, "analyze_imm", "OOiB",
insn, ops[i], values[i], false);
PyObject_CallMethod(analyzer, "analyze_imm", "OOiBB",
insn, ops[i], values[i], false, is_load_insn);
}

// err[0] = !is_reg_supported(r1)
Expand All @@ -506,7 +507,7 @@ static PyObject* analyze_operands(PyObject *self, PyObject *args)
}

// Undefine the register if it's a load
if (is_load(id)) {
if (is_load_insn) {
regs->is_def[r1] = false;
}

Expand Down Expand Up @@ -551,7 +552,8 @@ static PyObject* analyze_operands(PyObject *self, PyObject *args)
int v = get_reg_value(regs, r1);

PyObject *ret = PyObject_CallMethod(
analyzer, "analyze_imm", "OOiB", insn, ops[0], v, true);
analyzer, "analyze_imm", "OOiBB",
insn, ops[0], v, true, is_load_insn);

if (ret == Py_True) {
db = PyObject_GetAttrString(analyzer, "db");
Expand Down
8 changes: 5 additions & 3 deletions plasma/lib/arch/mips/analyzer.c
Original file line number Diff line number Diff line change
Expand Up @@ -549,6 +549,7 @@ static PyObject* analyze_operands(PyObject *self, PyObject *args)
long values[3] = {0, 0, 0};
bool is_stack[3] = {false, false, false};
bool err[3];
bool is_load_insn = len_ops == 2 && is_load(id);

// The first operand is always a register and always the destination (except st* ?)
int r1 = get_op_reg(ops[0]);
Expand Down Expand Up @@ -578,8 +579,8 @@ static PyObject* analyze_operands(PyObject *self, PyObject *args)
}
}

PyObject_CallMethod(analyzer, "analyze_imm", "OOiB",
insn, ops[i], values[i], false);
PyObject_CallMethod(analyzer, "analyze_imm", "OOiBB",
insn, ops[i], values[i], false, is_load_insn);
}

// err[0] = !is_reg_supported(r1)
Expand Down Expand Up @@ -670,7 +671,8 @@ static PyObject* analyze_operands(PyObject *self, PyObject *args)
if (use_real_gp) {
if (id != MIPS_INS_LUI) {
PyObject *ret = PyObject_CallMethod(
analyzer, "analyze_imm", "OOiB", insn, ops[0], v, true);
analyzer, "analyze_imm", "OOiBB",
insn, ops[0], v, true, is_load_insn);
save = ret == Py_True;
}
}
Expand Down
13 changes: 10 additions & 3 deletions plasma/lib/arch/x86/analyzer.c
Original file line number Diff line number Diff line change
Expand Up @@ -790,6 +790,7 @@ static PyObject* analyze_operands(PyObject *self, PyObject *args)
long values[2] = {0, 0};
bool is_stack[2] = {false, false};
bool err[2];
bool is_deref_pointer;

if (len_ops == 1) {
// Stack simualation not supported, just update the stack register
Expand Down Expand Up @@ -843,6 +844,7 @@ static PyObject* analyze_operands(PyObject *self, PyObject *args)
if (err[i] == true)
continue;


if (get_op_type(ops[i]) == X86_OP_MEM) {
// Pointers are not dereferenced actually.
// So it means that we will not simulate this instruction.
Expand All @@ -859,10 +861,15 @@ static PyObject* analyze_operands(PyObject *self, PyObject *args)
get_op_size(ops[i]));
continue;
}

is_deref_pointer = id != X86_INS_LEA;
}
else {
is_deref_pointer = false;
}

PyObject_CallMethod(analyzer, "analyze_imm", "OOiB",
insn, ops[i], values[i], false);
PyObject_CallMethod(analyzer, "analyze_imm", "OOiBB",
insn, ops[i], values[i], false, is_deref_pointer);
}

if (id == X86_INS_XADD && get_op_type(ops[1]) == X86_OP_REG) {
Expand Down Expand Up @@ -937,7 +944,7 @@ static PyObject* analyze_operands(PyObject *self, PyObject *args)

if (id != X86_INS_MOV && id != X86_INS_LEA) {
PyObject *ret = PyObject_CallMethod(
analyzer, "analyze_imm", "OOiB", insn, ops[0], v, true);
analyzer, "analyze_imm", "OOiBB", insn, ops[0], v, true, false);
save = ret == Py_True;
} else {
save = false;
Expand Down

0 comments on commit a5d7a62

Please sign in to comment.