tkx Newbie cheater
Reputation: 0
Joined: 28 Jul 2010 Posts: 14
|
Posted: Fri May 03, 2013 7:08 am Post subject: Big Disassembly Display Bug (mov with reg offsets, 64 bit) |
|
|
TL;DR: In 64 bit, the disassembler shows the wrong register on "mov" instructions when using r8-r15 as a base with a multiplied offset.
I was calculating some values by following pointers by hand and couldn't figure out why my calculations kept coming out wrong. It turns out that certain instructions appeared with the wrong register in the disassembler.
Specifically, when using mov with a multiplied offset and a base register of r8-r15, it would instead show rax-rdi.
Example:
mov [r11+r8*4],eax (bytes 43 89 04 83)
appears as
mov [rbx+r8*4],eax (bytes 42 89 04 83).
The r11 part of the op code is incorrectly displayed as rbx, but the bytes themselves are correct (you see 43 when it's r11 displayed as rbx, and 42 when it's actually rbx).
Steps to Reproduce
- Open CE 6.2 (64 Bit Version, or 32 Bit with the disassembler showing 64-bit disassembly output) on a 64 bit machine.
- Attach to any process, open the disassembler and allocate memory (or find any editable memory you don't care about).
- Edit one of the lines to "mov [r8+r8*4],eax" and confirm.
- See that the newly edited line actually says "mov [rax+r8*4],eax"
- Note the bytes (43 89 04 80), and then edit and confirm it.
- See that the first byte changes to 42, showing the now-correct underlying "mov [rax+r8*4],eax" line.
Notes
I (quickly) tested several various formats of mov, each using [regs8to15 + reg*num], and found that most of them display incorrectly for r8-r15. This includes: mov [regs8to15 + reg*num],reg; as well as mov reg,[regs8to15 + reg*num]. (Where "regs8to15" = r8-r15, and "reg" = rax to r15). In other words, this bug affects at least 30-40 opcodes, which is why I put "big" in the title. And also because I spent like 3 hours trying to figure out if I was doing pointer calculations incorrectly.
With the format mov [reg + r8*4],eax, I went through a few of them to see which op codes corresponded to which incorrect disassembly labels:
r8 -> rax
r9 -> rcx
r10 -> rdx
r11 -> rbx
r12 -> rsp
r13 -> This one is correct for some reason. It has a different length opcode too, and appears as [r13+r8*4+00] instead of just [r13+r8*4].
r14 -> rsi
r15 -> rdi
Also note that without a multiplied offset, it appears that the disassembler shows the correct labels with the few that I took a look at.
Other Info
I found the bug while debugging MineSweeper.exe (Windows 7 64 bit patched for Windows 8 ). Specifically at the instruction located at MineSweeper.exe+325B9 (mov ecx,[r11+r8*4]). You can also test the bug by setting a breakpoint there and right clicking on the board, and then doing the pointer calculations by hand at that instruction and what is set to ecx to see that they don't match up. The "Find out what addresses this instruction accesses" function also glitches due to the bug (probably if it uses the same byte to op code translation as the display).
I'm hoping that this isn't some huge defect with my computer/processor, but here is my computer information just in case:
System: Windows 8 Home 64 bit
CPU: Intel Core i7-3630QM
RAM: 16GB Memory DDR3
CE Version: 6.2, 64 Bit (but I tried it with the 32 Bit version and it also has the bug, as long as the disassembler is set to show disassembly output in 64-bit).
|
|