Skip to content

Symbolic rewrite corruption #40

Open
@ghost

Description

The following code is producing corrupt results:

void run_err_test_1()
{
	auto b = vtil::basic_block::begin(0);
	auto first = vtil::register_desc(vtil::register_flag::register_local, 0, 64);
	auto second_ptr = vtil::register_desc(vtil::register_flag::register_local, 5, 64);
	auto second = vtil::register_desc(vtil::register_flag::register_local, 4, 64);
	auto result = vtil::register_desc(vtil::register_flag::register_local, 6, 64);
	auto dest = vtil::register_desc(vtil::register_flag::register_local, 37, 64);

	// load first value
	b->ldd(first, X86_REG_R11, 0x0);

	// load second value
	b->mov(second_ptr, X86_REG_R11);
	b->add(second_ptr, 0x8);
	b->ldd(second, second_ptr, 0x0);

	// calculate the result
	b->mov(result, first);
	b->add(result, second);

	// store the result
	b->mov(dest, X86_REG_R11);
	b->add(dest, 0x8);
	b->str(dest, 0x0, result);

	apply_optimizations(b, 0, optimization_type::optimization_type_symbolic_rewrite_pass_forced, 0);
	vtil::debug::dump(b);
}
 | | 0000: [ PSEUDO ]     +0x0     movq     t0           r11
 | | 0001: [ PSEUDO ]     +0x0     lddq     t1           t0           0x0
 | | 0002: [ PSEUDO ]     +0x0     movq     t2           t0
 | | 0003: [ PSEUDO ]     +0x0     addq     t2           0x8
 | | 0004: [ PSEUDO ]     +0x0     lddq     t3           t0           0x8
 | | 0005: [ PSEUDO ]     +0x0     movq     t4           t1
 | | 0006: [ PSEUDO ]     +0x0     addq     t4           t3
 | | 0007: [ PSEUDO ]     +0x0     movq     t0           t1
 | | 0008: [ PSEUDO ]     +0x0     movq     t5           t2
 | | 0009: [ PSEUDO ]     +0x0     movq     t4           t3
 | | 0010: [ PSEUDO ]     +0x0     movq     t6           t4
 | | 0011: [ PSEUDO ]     +0x0     movq     t37          t2
 | | 0012: [ PSEUDO ]     +0x0     strq     t0           0x8          t4

After a bit of messing around, I've narrowed down the cause to the register naming. Rewriting all register names to a higher index produces the following instead:

 | | 0000: [ PSEUDO ]     +0x0     movq     t0           r11
 | | 0001: [ PSEUDO ]     +0x0     lddq     t1           t0           0x0
 | | 0002: [ PSEUDO ]     +0x0     movq     t2           t0
 | | 0003: [ PSEUDO ]     +0x0     addq     t2           0x8
 | | 0004: [ PSEUDO ]     +0x0     lddq     t3           t0           0x8
 | | 0005: [ PSEUDO ]     +0x0     movq     t4           t1
 | | 0006: [ PSEUDO ]     +0x0     addq     t4           t3
 | | 0007: [ PSEUDO ]     +0x0     movq     t1500        t1
 | | 0008: [ PSEUDO ]     +0x0     movq     t1501        t2
 | | 0009: [ PSEUDO ]     +0x0     movq     t1502        t3
 | | 0010: [ PSEUDO ]     +0x0     movq     t1503        t4
 | | 0011: [ PSEUDO ]     +0x0     movq     t1504        t2
 | | 0012: [ PSEUDO ]     +0x0     strq     t0           0x8          t4

The pass appears to be restoring to the original registers, and is clobbering them in the process.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions