TheWover / donut

Generates x86, x64, or AMD64+x86 position-independent shellcode that loads .NET Assemblies, PE files, and other Windows payloads from memory and runs them with parameters
BSD 3-Clause "New" or "Revised" License
3.57k stars 633 forks source link

OEP argument must be a Virtual Address, donut currently expects an Absolute Address #83

Closed awgh closed 1 year ago

awgh commented 3 years ago

The -y argument takes the original entry point address "oep" as an argument. Donut expects this as a uint64 absolute address.

However, the use case for the -y oep argument is for when you are injecting a donut shellcode into a file using a tool such as binjection or backdoorfactory. When you are injecting a shellcode into a file, you only know virtual addresses in the file, you do not know the actual base address that the program will be loaded to.

Current Behavior: The oep argument is being passed directly into a ThreadContext, which expects an absolute address, as you can see in the following code:

        _GetThreadContext(_GetCurrentThread(), &c);
        #ifdef _WIN64
          c.Rip = inst->oep;
          c.Rsp &= -16;
        #else
          c.Eip = inst->oep;
          c.Esp &= -4;
        #endif

from here:

This code does not actually work, so the desired use case of injecting a donut shellcode into another executable file (on-disk, not in-memory) does not work.

Expected Behavior: The address being passed in "oep" should be a 32bit relative address. Before being inserted into the ThreadContext, the base address of the executable (as loaded in memory, which donut can see) should be added to the oep RVA, thus making it into the correct absolute address.

Suggested Fix: Determine the base address of the current executable and add that base address to inst->oep before copy that value to c.Rip and c.Eip.

Thanks!

awgh commented 2 years ago

@TheWover The "host" variable already contains the base address at this point in the code, so...

Really just need to use host + inst->oep instead of just inst->oep for the values of c.Rip/c.Eip.

TheWover commented 1 year ago

Pushed changes to dev branch that attempt to address this. If you wouldn't mind testing on your end, that would be appreciated. If it works then I'll close out this PR.

TheWover commented 1 year ago

@awgh verified that the fix is sufficient.