hasherezade / exe_to_dll

Converts a EXE into DLL
1.26k stars 191 forks source link

WinMain #7

Open jeky-- opened 1 year ago

jeky-- commented 1 year ago

Is it possible to make this tool compatible with windows applications? I've made som tries myself without any luck. The exe is correcly converted, but giving the entry point to the loader nothing happens.

I guess that may people would enjoy a "testload" applications, compiled as a DLL file, with a given export name, so i may be called with rundll32. This would enable to calle rundll32 testload.dll,Load

I should be able to write this for console applications, but (sady) not for Windows applications. Anyone would help? Thanks in advance! \Jeky--

hasherezade commented 1 year ago

Hi @jeky-- I made a modification that allows to skip using the "testload". Now, during the conversion, the Export Table is generated, and the original Entry Point of the application is available via export named "Start".

exports_table

I hope this improves overall usability. We can convert the application, and then directly use its former start function like a normal export from a DLL, i.e. by calling it via rundll32.

It tested it with some sample Windows applications, containing WinMain (attached here: Project1_demos.zip) - and everything worked as expected:

popup

Please let me know if it helps. You can get the fresh build from the AppVeyor build server: https://ci.appveyor.com/project/hasherezade/exe-to-dll/build/job/oomls77k7kgifyhn/artifacts

jeky-- commented 1 year ago

Thank you very much! My first enemy at this point are the command line arguments (as the applications receive dll_name.dll,Start), but with some binary patching I hope to manage. I confirm that the Windows applications also work. I'm getting some errors/instability on centrain exe, but I think there's a lot of things that can go wrong launching exe as dll, so I'll just try a different similar program.

hasherezade commented 1 year ago

@jeky-- : Indeed if the main function expects some commandline arguments, it may not work simply via rundll32. But yet, now it is easy to load this DLL via LoadLibrary, and you then fetch that function via GetProcAddress, and pass the proper arguments by your own loader. Regarding the errors and instability that you got with certain EXEs - can you share with me this application? I will look into this and check what's really causing it. You can pack it and paste here, or sent to my email: hasherezade-at-pm.me

jeky-- commented 1 year ago

The application I'm trying to convert are famous and public, so I can share them here: 1- procexp64.exe https://learn.microsoft.com/en-us/sysinternals/downloads/process-explorer After conversion gives "Initialization error" - "Failed to set property with error 0x00000578"

2- process hacker https://processhacker.sourceforge.io/downloads.php After conversion it starts without the file bar and sub-dialogs "crashes" (when you double click some process) This is an open source, so I guess that a better option is to re-compile it directly as DLL. Probably not worth investing time in, unless you are doing it for study reasons.

I had not thought of using a loader in the form of a dll, indeed it is a solution as simple as it is effective! I have already tried it and of course it works perfectly. (also the binary patching worked for process explorer, but took much more time)

hasherezade commented 1 year ago

I just checked Process Hacker, I didn't manage to reproduce the crash, but indeed the menu bar is missing. I guess this is because during the initialization it's trying to set the menu for the main module, which normally is it's own application - but when it's running as a DLL, now the main module is rundll32, or whatever the loader was. I guess there will be many of such cases, where the main executable will try to reference its own binary assuming that it the main module. And indeed it can cause a crash, or some things not working as they were supposed to. Well, this method has its limitation, not everything is easily convertible. The possible workaround that comes to my mind is to: 1) Create your own loader using the library via LoadLibrary-GetProcAddress. 2) Hook the relevant functions (from the loader's code) and redirect them to the proper module (i.e. with MS Detours)

But this is out of scope of the converter, and has to be done per each case separately, because the needs of what should be hooked may vary.

yume-chan commented 1 year ago

I can use LoadLibrary and GetProcAddress to call the Start function in converted DLL, but I can't pass custom arguments to it.

Since ucrt uses GetCommandLineA/W to initialize argc and argv, it always gets my exe's arguments. The Start function itself doesn't take any parameters.

image

hasherezade commented 1 year ago

@yume-chan - what about hooking GetCommandLineA/W within the loader, and replacing their output?

jeky-- commented 1 year ago

Effectively the wrapper I had tried to make was an exe, so it does not suffer from the rundll32 problem, doing the same thing from another dll the problem occurs again. In the specific case of procexp64 I had patched the binary to alter the behaviour according to the presence of arguments... unfortunately it still won't start.

qax-analyzer commented 1 year ago

I have never seen this tool, can you tell me what it is called? image

damywise commented 1 year ago

It's https://github.com/hasherezade/pe-bear

jeky-- commented 9 months ago

Hello again, while running AccessEnum (converted to exe) via rundll32, I receive a 0xC00000FD (STATUS_STACK_OVERFLOW) after few usage. Is there anything I can do to avoid this?