vmt / udis86

Disassembler Library for x86 and x86-64
http://udis86.sourceforge.net
BSD 2-Clause "Simplified" License
1.01k stars 295 forks source link

REX prefix maybe not quite right? #122

Open GitHubbillm opened 7 years ago

GitHubbillm commented 7 years ago

I have been doing some work and noticed that in decode.c in handle_prefix there's some code that confuses me. The comments say (correctly) that a REX prefix must be last. The rules say legacy prefixes, then REX if needed, the the opcode. But the code really does not enforce this. For example, I ran this with udcli (added some comments):

41 63 c2 The rex prefix is 41 - looks OK 000000000000000b 4163c2 movsxd rax, r10d
2e 41 63 c2 OK here is a CS segment legacy prefix which is ignored, then the REX prefix - looks OK 000000000000000e 2e4163c2 movsxd rax, r10d
41 2e 63 c2 Now let's have the REX and then the CS override. Should this not be illegal? 0000000000000012 412e63c2 movsxd rax, edx

The tail end of decode_prefix in decode.c has this:

done = (u->dis_mode == 64 && (curr & 0xF0) == 0x40) ? 0 : 1;

But what this says to me is "if you see a REX prefix in 64 bit mode, you are NOT done." Then later it assigns the variable "last" over to the prefix:

/* rex prefixes in 64bit mode, must be the last prefix */
if (u->dis_mode == 64 && (last & 0xF0) == 0x40) {
    u->pfx_rex = last;

So I think the comment is right but the behavior is not exactly correct.

Thoughts?