Git Product home page Git Product logo

Comments (6)

phiber0 avatar phiber0 commented on June 21, 2024 1

wow, you are amazing!

I will wait for your pe2shc update!.

this problem is also happening if you use ReflectiveDLLInjection so your solution could help a loot of people.

thank you

from pe_to_shellcode.

hasherezade avatar hasherezade commented on June 21, 2024

hi @phiber0 !
I tried to reproduce the problem you described, but for some reason everything worked fine for me.
This is what I used to build the project: https://gist.github.com/hasherezade/21d3938a3f846d988c1b030c3a713872 - your snippet + my CMakeLists.txt from which I generated a VisualStudio project, used VS2019.
I am attaching the binaries generated from my build, both converted and before conversion: test_case2_bin.zip

example_working

Please let me know if my binaries work for you. Also, please share the binaries from your builds, and I will check them.

P.S. Although the DllMain worked fine, and the DLL got loaded, I see a problem with the SayGoodbye function: this function throws and exception, which won't be handled if the binary is loaded manually by the stub. So it not gonna work from the shellcode, but crash instead. But I guess this was not your question.

from pe_to_shellcode.

phiber0 avatar phiber0 commented on June 21, 2024

Hi!,
Thank you for taking the time to check this one.

I have used your CMakeLists.txt to create my VS project and you are right, the dll is loaded if the compiled is set to 2019/2017, but crashed if we use 2015/2013. (tested on win10 and win7, same results).

I have attached 4 compilations, one for each version if you can take a look.
I didn't change anything on the code/options, just the toolset version and compiled release.

let me know if I can do anything else.

Ps, SayGoodbye was in the original code, I just use it to have a place to insert the std::mutex to trigger the error.

test_cases.zip

from pe_to_shellcode.

hasherezade avatar hasherezade commented on June 21, 2024

I see, you are right - the binaries created with the older Visual Studio indeed crash. I will check them in more details and let you know what I found.

from pe_to_shellcode.

hasherezade avatar hasherezade commented on June 21, 2024

@phiber0 - I investigated it, and now I understand what causes it.

The binaries compiled in older versions of Visual Studio have one more initialization function that they run in _initterm.
This is from VS2015:
init_vs2015

And from VS2017:
init_vs2017

And the problem with that function is, that it makes use of the API function RtlPcToFileHeader to fetch the base of the current module.

init_error

Due to the fact that the shellcodified PE is loaded manually, its base will not be retrieved. The function returns a NULL pointer, which will be further used as a base. And finally it causes exception:

access_violation

I tested it with a libPeConv-based manual loader, where I hooked the function RtlPcToFileHeader, and finally it works:

This PoC confirms that this is where the problem is located.

However, in the stub that I use in pe2shc, I don't want to use any function hooking, so I can't solve it the same way.
Looking at the implementation of this function from ReactOS:

 PVOID NTAPI
 RtlPcToFileHeader(IN PVOID PcValue,
                   PVOID* BaseOfImage)
 {
     PLIST_ENTRY ModuleListHead;
     PLIST_ENTRY Entry;
     PLDR_DATA_TABLE_ENTRY Module;
     PVOID ImageBase = NULL;
 
     RtlEnterCriticalSection (NtCurrentPeb()->LoaderLock);
     ModuleListHead = &NtCurrentPeb()->Ldr->InLoadOrderModuleList;
     Entry = ModuleListHead->Flink;
     while (Entry != ModuleListHead)
     {
         Module = CONTAINING_RECORD(Entry, LDR_DATA_TABLE_ENTRY, InLoadOrderLinks);
 
         if ((ULONG_PTR)PcValue >= (ULONG_PTR)Module->DllBase &&
                 (ULONG_PTR)PcValue < (ULONG_PTR)Module->DllBase + Module->SizeOfImage)
         {
             ImageBase = Module->DllBase;
             break;
         }
         Entry = Entry->Flink;
     }
     RtlLeaveCriticalSection (NtCurrentPeb()->LoaderLock);
 
     *BaseOfImage = ImageBase;
     return ImageBase;
 }

It seems the only way to solve this would be to add the shellcode to the list of loaded modules. But doing so will make the injected shellcode to be less stealthy. I will probably make it optional.

from pe_to_shellcode.

hasherezade avatar hasherezade commented on June 21, 2024

thank you! at least now we know the reason! but solving it seems not so easy as I thought earlier:

I tried to add the shellcode to the list of the loaded modules, and it seemed to work fine (the module got added) - yet RtlPcToFileHeader still didn't work as expected.

I was doing my experiments on Windows 10, and I ended up going down the function RtlPcToFileHeader to see what is wrong. It turns out that this function evolved quite a lot, and is no longer that simple as in the ReactOS version (the decompiled version of the new one is here).

So, adding the module to the InLoadOrderLinks list is no longer the solution. I need to analyze it in more details, and then will see what else I can do.

from pe_to_shellcode.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    πŸ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. πŸ“ŠπŸ“ˆπŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❀️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.