rizinorg / rizin

UNIX-like reverse engineering framework and command-line toolset.

Home Page:https://rizin.re

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

`tp` command prints wrong member offsets and does not output the last member

rockrid3r opened this issue · comments

Work environment

Questions Answers
OS/arch/bits (mandatory) Debian 12, x86-64
File format of the file you reverse (mandatory) ELF
Architecture/bits of the file (mandatory) x86-64
rizin -v full output, not truncated (mandatory) rizin 0.7.0 @ linux-x86-64 commit: f98ab29

Actual behavior

For the following struct

struct simple {
    union {
        int a;
        int b;
    };
//    void *val_4;
//    void *val_5;
};
int main() {
    struct simple simple;
}

The command tp simple does not output anything.
For this:

struct simple {
    union {
        int a;
        int b;
    };
    void *val_4;
};

The command tp simple outputs

(anonymous_union_0x2e)anonymous_member_0x5c : 0x00001040 = (qword)0x89485ed18949ed31

For this:

struct simple {
    union {
        int a;
        int b;
    };
    void *val_4;
    void *val_5;
};

The command tp simple outputs

(anonymous_union_0x2e)anonymous_member_0x5c : 0x00001040 = (qword)0x89485ed18949ed31
                 val_4 : 0x00001040 = (qword)0x89485ed18949ed31

For this:

struct simple {
    union {
        int a;
        int b;
    };
    void *val_4;
    void *val_5;
    void *val_6;
    void *val_7;
    void *val_8;
    void *val_9;
    void *val_10;
};

The command tp simple outputs

(anonymous_union_0x2e)anonymous_member_0x5c : 0x00001040 = (qword)0x89485ed18949ed31
                 val_4 : 0x00001040 = (qword)0x89485ed18949ed31
                 val_5 : 0x00001040 = (qword)0x89485ed18949ed31
                 val_6 : 0x00001040 = (qword)0x89485ed18949ed31
                 val_7 : 0x00001040 = (qword)0x89485ed18949ed31
                 val_8 : 0x00001040 = (qword)0x89485ed18949ed31
                 val_9 : 0x00001040 = (qword)0x89485ed18949ed31

But for this:

struct simple {
    void *val_4;
    void *val_5;
};

it output correctly:

 val_4 : 0x00001040 = (qword)0x89485ed18949ed31
 val_5 : 0x00001048 = (qword)0x455450f0e48348e2
  • As you can see the command tp simple does not output the last member if union is defined.
  • And also the offsets are wrong: if union is defined, offsets are constant! (0x1040)

Expected behavior

For example, for the test case

struct simple {
    union {
        int a;
        int b;
    };
    void *val_4;
    void *val_5;
};

it should output:

(anonymous_union_0x2e)anonymous_member_0x5c : 0x00001040 = (qword)0x89485ed18949ed31
                 val_4 : 0x00001040 = (qword)0x89485ed18949ed31
                 val_5 : 0x00001048  = .....

Steps to reproduce the behavior

Copy this:

struct simple {
    union {
        int a;
        int b;
    };
    void *val_4;
    void *val_5;
    void *val_6;
    void *val_7;
    void *val_8;
    void *val_9;
    void *val_10;
};


int main() {
    struct simple simple;
}

Compile & run with

gcc simple.c -o simple 
rizin simple

And then enter tp simple:

[0x00001040]> tp simple