eteran / edb-debugger

edb is a cross-platform AArch32/x86/x86-64 debugger.
GNU General Public License v2.0
2.68k stars 323 forks source link

Add Patch Manager #484

Open AaronOpfer opened 7 years ago

AaronOpfer commented 7 years ago

In Ollydbg, when the user has made a change to memory at a particular address, the user's patch bytes and instructions are highlighted red to indicate they are not the original bytes. In addition, there is a patch manager which lists all of the patches the user has made during the session which also shows the original content at the address and allows for the patch to be reversed.

I think this is an important feature for edb to have as it would make it easier to manage edits made using the "assembly" feature. When reverse-engineering I frequently make temporary patches that stub some calculations to reduce false positive breakpoint hits. I also will occasionally NOP calls in order to determine what a function might be responsible for (like NOPing a draw call resulting in items disappearing from the screen in a game). Once these patches are no longer necessary it should be possible to quickly and easily put the original assembly back without having to restart the debuggee.

--- Want to back this issue? **[Post a bounty on it!](https://www.bountysource.com/issues/39701702-add-patch-manager?utm_campaign=plugin&utm_content=tracker%2F14326212&utm_medium=issues&utm_source=github)** We accept bounties via [Bountysource](https://www.bountysource.com/?utm_campaign=plugin&utm_content=tracker%2F14326212&utm_medium=issues&utm_source=github).
eteran commented 7 years ago

Yup, I like this. It is also related to issue #220 as well

AaronOpfer commented 7 years ago

It looks like if we were to implement this we would need to implement a sibling to IProcess::write_bytes called IProcess::patch which would do basically the same thing except logs into the patching system (and also informs the breakpoint system about the new original bytes, somehow).

eteran commented 7 years ago

An interesting approach. I'd like the Patch manager to be a plugin which registers for this information somehow. We'll have to think about the API a but, but I like where this idea is going,

AaronOpfer commented 7 years ago

So I think we agree that every write to the process' memory needs to be classified as a user-requested patch or an automated write so that we don't do silly things like list breakpoints or plugin-injected shellcode in the patch list. So we definitely need another API for doing 'patches'.

What behavior specifically would you want the edb base to perform and what would you leave to the plugin? It seems unlikely to me that someone would want to replace the shipped patcher's behavior outright so I'm not sure what our goal is. I don't think we would need any kind of architecture-specific patcher since the API abstractions for reading/writing bytes seems good enough. Would this work something like the IAnalyzer interfaces where code writers have to obtain the global instance and interact with it?

IMO it would be best to split the work into two parts: doing #220 first, and then #484 (this issue) focused on the patch manager dialog afterward. This way the code gets reviewed sooner and can ship the useful feature.

eteran commented 7 years ago

Yea, I like the "patch oriented" write API idea, it is a fairly clean solution to the "what do we want to care about" problem.

So as far as the plugin, here's my mentality (always open for discussion BTW). edb's main design philosophy has been "if it can be a plugin, it generally is a plugin".

I've seen so many tools where users go to great lengths to hack in a "better" way to do something, and I want to make that process as painless as possible. Though you may be right that a "patch manager" may be fundamental enough to just have it built in. So you may be right.

Frankly, i don't expect this stuff to be a huge amount of code, so we can always pivot one way or the other going forward. So I'm not too worried at the moment :-).

AaronOpfer commented 7 years ago

Where would we store the patch information? Is this what the "Session" directory was meant to be used for? I don't see any uses for the Session directory as it is now.

eteran commented 7 years ago

The in tree session directory has been replaced with $HOME/.cache/codef00.com/edb/sessions by default. We already store some trivial information those session files and reload them on opening the same binary again.

Right now, a quick non-eventful debugging session of /bin/ls produces a file that looks like this:

{
    "id": "edb-session",
    "plugin-data": {
        "Bookmarks::Bookmarks": {
            "bookmarks": [
            ]
        }
    },
    "timestamp": "2016-12-10T07:41:50Z",
    "version": 1
}

Take a look at the bookmarks plugin for how it stores data in this file by working with the session management system :-)