Skip to content

GSOC 2026: Adding Cutter Diff; Basic Function diffing and HexDiffWidget#3625

Draft
NewtronReal wants to merge 11 commits into
rizinorg:devfrom
NewtronReal:diff-app
Draft

GSOC 2026: Adding Cutter Diff; Basic Function diffing and HexDiffWidget#3625
NewtronReal wants to merge 11 commits into
rizinorg:devfrom
NewtronReal:diff-app

Conversation

@NewtronReal

@NewtronReal NewtronReal commented Jun 20, 2026

Copy link
Copy Markdown
Contributor

Your checklist for this pull request

  • I've read the guidelines for contributing to this repository
  • I made sure to follow the project's coding style
  • I've updated the documentation with the relevant information (if needed)
  • I've used AI tools to generate fully or partially these code changes and I'm sure the changes are not copyrighted by somebody else.

Detailed description

Summary

This PR introduces a way to expose rz-diff features to Cutter as a new tool Cutter Diff. The Cutter Diff window can be opened by File->Cutter Diff. In the opened window user will be able to diff two new files(Can also diff with current open file at main cutter window). User can set analysis levels and compare logic then can run the bindiff for getting diff thread. It also introduces CutterDiff which will be used anlogouse to CutterCore in the CutterDiff window which exposes the rz-diff features as API. CutterDiff will be creating individual instances for each Cutter Diff window which allows user to diff multiple files to the same opened cutter main bin.

Pending work
Comparing to the main core file is also pending.
LineDiff..

The project was becoming so large that i was afraid reviewer might not be able to review it all at once so i opened this draft.

Added Widgets

CutterDiff // manages two cores initialization resource management and apis
BinDiff // runs as an external thread and provides basic binary diffing result
HexDiff // widget analogous to HexDump with diffing features implemented
DiffLoadWindow
DiffWaitWindow
CutterDiffWindow //The main window for cutter diff can be opened by File->Cutter Diff(should be moved to windows or tools?)
MemoryDiffData // manages the loading and storing of binary data from the core

class DiffFileContext
{
public:
    DiffFile file;
    uint64_t startAddress;
    std::unique_ptr<MemoryDiffData> data;
    QRectF addrArea;
    QRectF itemArea;
    QRectF asciiArea;
};

BasicDiffCursor //unnecessary and will be removed

HexDiffCursor
HexDiffSelection
LineDiffWidget

If added all the widget it will get too long so i listed only the important widgets to be noted.

Test plan (required)
Build Options:
CUTTER_ASAN=ON
CUTTER_USE_BUNDLED_RIZIN=OFF(use https://github.com/NewtronReal/rizin/tree/diffopstringify instead)
Compile and run. Open a file in cutter(an option for opening the Cutter Diff directly is also to be added). Select File A and File B. Select analysis level and compare logic. open the file change the tabs use the functions panel to navigate along the functions(HexDiff)

Screencast_20260620_224325.mp4

@NewtronReal NewtronReal marked this pull request as draft June 20, 2026 16:59
@notxvilka notxvilka requested review from PremadeS and wargio June 20, 2026 17:30
@wargio

wargio commented Jun 23, 2026

Copy link
Copy Markdown
Member

rebase on dev

@NewtronReal NewtronReal force-pushed the diff-app branch 3 times, most recently from fe979b0 to 28ea7c9 Compare June 23, 2026 13:48
@notxvilka

Copy link
Copy Markdown
Contributor

Please fix clang-tidy warnings

@NewtronReal NewtronReal force-pushed the diff-app branch 2 times, most recently from 63f2646 to a7eb734 Compare June 29, 2026 19:23
@NewtronReal

Copy link
Copy Markdown
Contributor Author

Think it's ready for review. Waiting for all checks to be green.

@wargio

wargio commented Jul 1, 2026

Copy link
Copy Markdown
Member

what happens when i open 2 big files? do i have a "waiting" dialog ?

@NewtronReal

Copy link
Copy Markdown
Contributor Author

what happens when i open 2 big files? do i have a "waiting" dialog ?

Yes you will have a waiting diolog until the function comparison is finished. This is actually not ideal for thos who just want to diff the hexdump so I was thinking of adding some options to choose what all diffing to be done in the initial options menu. Ex for those who just want to view the hexdump diff may be the unckeck the function comparison.

@PremadeS

PremadeS commented Jul 8, 2026

Copy link
Copy Markdown
Collaborator

Not going into the code details yet.
Here are the issues I found while testing, some of them could be because they aren't implemented yet, in that case this comment can serve as a checklist

1- "Diff files" option/action should be in "Tools" not in "File"

2- There should be an option to set current file as either "File 1" or "File 2"

3- Also, it would be better to allow user to manually type the filepath aswell - for "File 1" and "File 2" - (same as InitialFileDialog)

4- Not sure why "Match Results" have an odd greyish background
why-grey-1
why-grey-2

  • Also better to remove the initial padding that Qt automatically puts in treeview (the space on the left side of entries)

5- "Functions B" shows functions for "File 1" and "Functions A" shows functions for "File 2" for some reason

6- Why name them "File 1" and "File 2" in the initial dialog and then name them "Functions A" and "Functions B"? I think it would be better to name the binary itself instead of "Functions A" if the binary name is too long then you can put and max character limit on it and do string elision based on that (replace last X chars with ...), same with "INFO A" and "INFO B" and any other occurences

7- Function offsets should be in hex not decimal

  • Also copying function address through context menu should also copy in hex (just so it's consistent with disassembly)

8- It would be nice if when clicking on a any function entry in "Functions A/B" would switch to Hex Diff and seek to the function offset, same with entries in Match Results, Added and Removed tabs

9- IMO the "Select which files to compare" should be shown when opening "Diff files" through the "tools" menu, seeing and empty widget and clicking "File->Diff new Files" is a lot more work, however "File->Diff new Files" option should be there and it should pre-fill with currently opened binary paths when user does "File-> Diff new Files"

10- When diffing I used "diff -1" as "File -1" and "diff-2" as "File-2" - it correctly showed that "sym.mult" was removed in "diff-2" but if I diff them in opposite order (meaning diff-1 as File-2 and vice versa) it doesn't show that "sym.mult" was Added, both "Added" and "Removed" tabs become empty. I could be misinterpreting something or it could be a rizin issue (will double check this later)

  • For convenience "diff-1' and "diff-2" are attached at the end

11- When diffing a large file, the waiting dialog blocks the cutter main window as well, meaning user can't use the main cutter app when diffing is happening (if running it in a separate thread we have to make sure whether the diff functions change rizin's internal state or not, if they do then core has to be locked meaning the user can't use the main cutter app properly because no rizin function can be called till diffing is done - I will check more on this and provide an update)

12- Even though I like the appearance of waiting dialog, it doesn't seem consistent with cutter theme. You can leave it as it is for now - we can discuss the appearance of it later

Binaries:
diff-1.zip
diff-2.zip

@wargio

wargio commented Jul 9, 2026

Copy link
Copy Markdown
Member

10- When diffing I used "diff -1" as "File -1" and "diff-2" as "File-2" - it correctly showed that "sym.mult" was removed in "diff-2" but if I diff them in opposite order (meaning diff-1 as File-2 and vice versa) it doesn't show that "sym.mult" was Added, both "Added" and "Removed" tabs become empty. I could be misinterpreting something or it could be a rizin issue (will double check this later)

This sounds like a bug. let me also check rizin

Edit:

On rizin side, looks correct.

$ rz-diff -t command -e scr.color=0 -0 izzq diff-1 diff-2

--- diff-1
+++ diff-2
@@ -12,7 +12,7 @@
 0x51b 12 11 GLIBC_2.2.5
 0x1031 4 4 PTE1
 0x10cb 4 4 u3UH
-0x2040 4 4 \e\f\a\b
+0x2038 4 4 \e\f\a\b
 ---------- 27 26 GCC: (GNU) 16.1.1 20260430
 ---------- 8 7 Scrt1.o
 ---------- 10 9 __abi_tag
@@ -23,7 +23,7 @@
 ---------- 39 38 __do_global_dtors_aux_fini_array_entry
 ---------- 12 11 frame_dummy
 ---------- 31 30 __frame_dummy_init_array_entry
----------- 11 10 diff-1.cpp
+---------- 11 10 diff-2.cpp
 ---------- 10 9 crtendS.o
 ---------- 14 13 __FRAME_END__
 ---------- 19 18 __GNU_EH_FRAME_HDR
@@ -34,7 +34,6 @@
 ---------- 27 26 __cxa_finalize@GLIBC_2.2.5
 ---------- 5 4 main
 ---------- 13 12 __dso_handle
----------- 9 8 _Z4multv
 ---------- 6 5 _fini
 ---------- 29 28 __libc_start_main@GLIBC_2.34
 ---------- 6 5 _init

$ rz-diff -t command -e scr.color=0 -0 izzq diff-2 diff-1

--- diff-2
+++ diff-1
@@ -12,7 +12,7 @@
 0x51b 12 11 GLIBC_2.2.5
 0x1031 4 4 PTE1
 0x10cb 4 4 u3UH
-0x2038 4 4 \e\f\a\b
+0x2040 4 4 \e\f\a\b
 ---------- 27 26 GCC: (GNU) 16.1.1 20260430
 ---------- 8 7 Scrt1.o
 ---------- 10 9 __abi_tag
@@ -23,7 +23,7 @@
 ---------- 39 38 __do_global_dtors_aux_fini_array_entry
 ---------- 12 11 frame_dummy
 ---------- 31 30 __frame_dummy_init_array_entry
----------- 11 10 diff-2.cpp
+---------- 11 10 diff-1.cpp
 ---------- 10 9 crtendS.o
 ---------- 14 13 __FRAME_END__
 ---------- 19 18 __GNU_EH_FRAME_HDR
@@ -34,6 +34,7 @@
 ---------- 27 26 __cxa_finalize@GLIBC_2.2.5
 ---------- 5 4 main
 ---------- 13 12 __dso_handle
+---------- 9 8 _Z4multv
 ---------- 6 5 _fini
 ---------- 29 28 __libc_start_main@GLIBC_2.34
 ---------- 6 5 _init

@NewtronReal

NewtronReal commented Jul 9, 2026

Copy link
Copy Markdown
Contributor Author

10- When diffing I used "diff -1" as "File -1" and "diff-2" as "File-2" - it correctly showed that "sym.mult" was removed in "diff-2" but if I diff them in opposite order (meaning diff-1 as File-2 and vice versa) it doesn't show that "sym.mult" was Added, both "Added" and "Removed" tabs become empty. I could be misinterpreting something or it could be a rizin issue (will double check this later)

This sounds like a bug. let me also check rizin

Edit:

On rizin side, looks correct.

$ rz-diff -t command -e scr.color=0 -0 izzq diff-1 diff-2

--- diff-1
+++ diff-2
@@ -12,7 +12,7 @@
 0x51b 12 11 GLIBC_2.2.5
 0x1031 4 4 PTE1
 0x10cb 4 4 u3UH
-0x2040 4 4 \e\f\a\b
+0x2038 4 4 \e\f\a\b
 ---------- 27 26 GCC: (GNU) 16.1.1 20260430
 ---------- 8 7 Scrt1.o
 ---------- 10 9 __abi_tag
@@ -23,7 +23,7 @@
 ---------- 39 38 __do_global_dtors_aux_fini_array_entry
 ---------- 12 11 frame_dummy
 ---------- 31 30 __frame_dummy_init_array_entry
----------- 11 10 diff-1.cpp
+---------- 11 10 diff-2.cpp
 ---------- 10 9 crtendS.o
 ---------- 14 13 __FRAME_END__
 ---------- 19 18 __GNU_EH_FRAME_HDR
@@ -34,7 +34,6 @@
 ---------- 27 26 __cxa_finalize@GLIBC_2.2.5
 ---------- 5 4 main
 ---------- 13 12 __dso_handle
----------- 9 8 _Z4multv
 ---------- 6 5 _fini
 ---------- 29 28 __libc_start_main@GLIBC_2.34
 ---------- 6 5 _init

$ rz-diff -t command -e scr.color=0 -0 izzq diff-2 diff-1

--- diff-2
+++ diff-1
@@ -12,7 +12,7 @@
 0x51b 12 11 GLIBC_2.2.5
 0x1031 4 4 PTE1
 0x10cb 4 4 u3UH
-0x2038 4 4 \e\f\a\b
+0x2040 4 4 \e\f\a\b
 ---------- 27 26 GCC: (GNU) 16.1.1 20260430
 ---------- 8 7 Scrt1.o
 ---------- 10 9 __abi_tag
@@ -23,7 +23,7 @@
 ---------- 39 38 __do_global_dtors_aux_fini_array_entry
 ---------- 12 11 frame_dummy
 ---------- 31 30 __frame_dummy_init_array_entry
----------- 11 10 diff-2.cpp
+---------- 11 10 diff-1.cpp
 ---------- 10 9 crtendS.o
 ---------- 14 13 __FRAME_END__
 ---------- 19 18 __GNU_EH_FRAME_HDR
@@ -34,6 +34,7 @@
 ---------- 27 26 __cxa_finalize@GLIBC_2.2.5
 ---------- 5 4 main
 ---------- 13 12 __dso_handle
+---------- 9 8 _Z4multv
 ---------- 6 5 _fini
 ---------- 29 28 __libc_start_main@GLIBC_2.34
 ---------- 6 5 _init
    added = new DiffMismatchModel(&listDel, this);
    removed = new DiffMismatchModel(&listAdd, this);

Problem in the cutter part only will be fixing it.

clang formatted

new changes
clang format
turn off CUTTER_ASAN
new addition

unnecesssary

unnecessary
new Commit

Code notes.

clang-format

fixed clang-tidy errors

changes

clang-format
@NewtronReal

Copy link
Copy Markdown
Contributor Author

Not going into the code details yet. Here are the issues I found while testing, some of them could be because they aren't implemented yet, in that case this comment can serve as a checklist

1- "Diff files" option/action should be in "Tools" not in "File"
Done
2- There should be an option to set current file as either "File 1" or "File 2"
Done
3- Also, it would be better to allow user to manually type the filepath aswell - for "File 1" and "File 2" - (same as InitialFileDialog)
Done(Although not quite like InitialFileDialog)
4- Not sure why "Match Results" have an odd greyish background why-grey-1 why-grey-2

* Also better to remove the initial padding that Qt automatically puts in treeview (the space on the left side of entries)

Needed to add colors gui.match.partial and gui.match.perfect on rizin side the pr is still pending review.
rizin:#6614

5- "Functions B" shows functions for "File 1" and "Functions A" shows functions for "File 2" for some reason

Fixed.

6- Why name them "File 1" and "File 2" in the initial dialog and then name them "Functions A" and "Functions B"? I think it would be better to name the binary itself instead of "Functions A" if the binary name is too long then you can put and max character limit on it and do string elision based on that (replace last X chars with ...), same with "INFO A" and "INFO B" and any other occurences

Done

7- Function offsets should be in hex not decimal

* Also copying function address through context menu should also copy in hex (just so it's consistent with disassembly)

Done

8- It would be nice if when clicking on a any function entry in "Functions A/B" would switch to Hex Diff and seek to the function offset, same with entries in Match Results, Added and Removed tabs

Done(on double click it seeks to the function offset and shows hexdiff)

9- IMO the "Select which files to compare" should be shown when opening "Diff files" through the "tools" menu, seeing and empty widget and clicking "File->Diff new Files" is a lot more work, however "File->Diff new Files" option should be there and it should pre-fill with currently opened binary paths when user does "File-> Diff new Files"

Added(The CutterDiffWindows are now on independent(ie parent = nullptr) and deletes on close.)

10- When diffing I used "diff -1" as "File -1" and "diff-2" as "File-2" - it correctly showed that "sym.mult" was removed in "diff-2" but if I diff them in opposite order (meaning diff-1 as File-2 and vice versa) it doesn't show that "sym.mult" was Added, both "Added" and "Removed" tabs become empty. I could be misinterpreting something or it could be a rizin issue (will double check this later)

* For convenience "diff-1' and "diff-2" are attached at the end

This is a rizin side issue where they match every function of A to B means a function in matches multiple times in A(Atleast that's what i think it is am currently checking how analysis_match_functions work in rizin and soon will be fixing it from the qt side.)

11- When diffing a large file, the waiting dialog blocks the cutter main window as well, meaning user can't use the main cutter app when diffing is happening (if running it in a separate thread we have to make sure whether the diff functions change rizin's internal state or not, if they do then core has to be locked meaning the user can't use the main cutter app properly because no rizin function can be called till diffing is done - I will check more on this and provide an update)

Similar fix to that of CutterDiffWindow made it parentless and deleteonclose. Cores are locked in CutterDiff the cores are independent of the CutterCore rzCore. But still used a RAII for future purposes on assumption of other diffing operations may require multiple threads running at same time.

12- Even though I like the appearance of waiting dialog, it doesn't seem consistent with cutter theme. You can leave it as it is for now - we can discuss the appearance of it later

Left as it was for now.

Binaries: diff-1.zip diff-2.zip

@NewtronReal

Copy link
Copy Markdown
Contributor Author

Initial work on LineDiff had started which requires rizin#6614 as well.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants