uxmal / reko

Reko is a binary decompiler.
https://uxmal.github.io/reko
GNU General Public License v2.0
2.09k stars 250 forks source link

Disassembly view now corrupts at the start of some procedures. MASTER: WindowsDecompiler #1334

Closed gbody closed 4 months ago

gbody commented 4 months ago

Steps are to load sample LinkIIgs, select scan binaries from the menu, select procedure check_error_level. See attachment for description and example of corruption.

It appears this started after the implementation of the IMemory interface and is still occurring using the most recent commit.

reko - disassembly display issue.docx

gbody commented 4 months ago

Additional information.

AbstractMixedCodeDataModel.SpanGenerator.cs Lines 254 - 260 public override (ModelPosition, LineSpan)? GenerateSpan() { Debug.Assert(line.Count == 0); var addr = this.position.Address; if (program.TryCreateImageReader(program.Architecture, addr, item.Size, out var rdr)) { mem.Formatter.RenderLine(rdr, program.TextEncoding, this);

Prior to IMemory Interface When creating the the Image reader for the item it used the end address, item.EndAddress var rdr = program.CreateImageReader(program.Architecture, addr, item.EndAddress);

With new IMemory Interface when creating a reader for the current line of hex data, it uses the current address for the hex data to be displayed from and the Item.size to set the reader data size. If less than one line this works. If more than one line needs to be displayed it will attempt to display the first line correctly, but when it creates a reader for the second line of hex data for an item, it will use the address for the start of hex data to be displayed and use the Item.size to calculate the end of the reader data which is fine for a full line of hex data. But if the last line is a partial line
eg. for an Item starting at 0x00100F58 and Item.size of 18 (decimal) x00100F58 01 02 03 04 05 06 07 08 x00100F60 09 0a 0b 0c 0d 0e 0f 10 11 12 Line 1 generation with addr passed as x00100F58, Item.size is 18, calculated end address for reader rdr is x00100F6A Line 2 generation with addr passed as x00100F60, Item.size is 18, calculated end address for reader rdr is 0x00100F72, which is outside of the original Item range. When generating the hex representation for the current line, it checks to see if it's less than the end address and reads the data, if it is at the end address it should flag it and return invalid data, so it can pad the remainder of the line before adding the ASCII data view at the end of the line.
What is happening during line 2 generation is a full line of hex data is generated as the end address address is now outside of the range of the item and more than a full line. When the next item to show is being processed the current addr is at 0x00100F70, so the data from 00100F6A - 0x001006F was displayed as hex data and not disassembled code as expected.

uxmal commented 4 months ago

Fixed in 74817ce. Thanks for all the hard work digging up the cause of this regression.