7

Is it possible for a file to be both an executable (EXE) and a dynamic-link library (DLL) at the same time? (I.e. it can be executed as an EXE and loaded at run-time as a shared library.)

I can't see why it shouldn't be possible, but maybe someone can give an explanation?

Shuzheng
  • 11,288
  • 20
  • 88
  • 186
  • 1
    It cannot. See the following: http://stackoverflow.com/questions/1210873/difference-between-dll-and-exe – Artem Sokolov Aug 24 '16 at 19:07
  • Related: http://stackoverflow.com/questions/19110747/loadlibrary-an-exe – Sami Kuhmonen Aug 24 '16 at 19:11
  • Not an an expert, so I will just add 2 things to watch out: 1) two main entry points (exe vs dll have different ). 2) dll base address is not fixed, so your "dll" code must be "position-independent code". There's for sure lot more things to get right about the file content to have all the required sections, etc.. looks like Sami's comment has nice tutorial how to. I would avoid that mix due to maintenance reasons (MS will break it one day, I bet :) ). But it looks possible, if you insist. – Ped7g Aug 24 '16 at 19:34
  • No, it is not possible. There is a single bit in the PE header that the loader uses to differentiate between EXEs and DLLs. A single file cannot possibly be both, because a bit cannot be both set and unset. However, you can load resources and code from an EXE in a very similar way that you could from a DLL. Is there an actual problem that you're trying to solve? If you [edit] that into your question, we could provide you with much more helpful and detailed answers. – Cody Gray - on strike Aug 24 '16 at 19:36
  • @CodyGray - IMAGE_FILE_EXECUTABLE_IMAGE (0x002) and IMAGE_FILE_DLL (0x2000) are both flags of the Characteristics field of the PE-header. Your point is that these flags cannot both be set by their description? But their values could be OR'd - I guess by your explanation, that the loader would generate an error then? No, I'm just making the question, because I was wondering, not because I've an actual problem :-) – Shuzheng Aug 25 '16 at 08:27

2 Answers2

7

From LoadLibrary documentation:

The name of the module. This can be either a library module (a .dll file) or an executable module (an .exe file). The name specified is the file name of the module and is not related to the name stored in the library module itself, as specified by the LIBRARY keyword in the module-definition (.def) file.

EDIT: I expected downvotes when I wrote this answer. I know many people think it is not possible (SO questions and answers from comments confirm it). But for those who are interested I can provide POC (or simply look at well known "process explorer" sources)

Note that if you need to export symbols from module you need to use those EXPORT statements in .def file. Then you can use GetProcAddress

Actually, I see that this SO question, also mentioned in comments, has answer that points to article "Load EXE as DLL: Mission Possible", which I also was going to quote. That answer is not accepted, accepted answer says "no" and even is taken as community wiki. Well "SO doesn't claim to be (in part) a library reference"

Community
  • 1
  • 1
mvidelgauz
  • 2,176
  • 1
  • 16
  • 23
  • Um, the article basically shows how you can do the extra work that LoadLibrary *doesn't* do for DLLs. It doesn't show how something can be both an EXE and a DLL, it shows how you can jump through extra hoops to make a DLL work like an EXE. Of course that is possible, you just write the same code that Microsoft did in the loader. I don't know what you mean by "process explorer sources". Do you have the source code for Process Explorer? How is it relevant to this issue? – Cody Gray - on strike Aug 24 '16 at 19:38
  • Also, I suspect the real reason why the LoadLibrary function documentation says this is historical. In the 16-bit days, the DLL extension was not widely used (in Windows 1.0, of course, it didn't even exist). All code-containing binaries had the file extension EXE, including KRNL386.EXE, USER.EXE, GDI.EXE, etc. But these were just DLLs as we now know them. A single bit in the PE header determined how they were to be loaded. The documentation has probably never been updated, and backwards compatibility dicates that the code hasn't been either. Plus, resources can be loaded from an EXE this way. – Cody Gray - on strike Aug 24 '16 at 19:42
  • 1
    @CodyGray: I don't think that's right. DLLs come with all sorts of extensions (eg .ocx) and even a .exe doesn't have to end with .exe. – Martin Bonner supports Monica Aug 24 '16 at 19:44
  • @CodyGray I don't want to start a terminology discussion but the question was _"Is it possible for a file to be both an executable (EXE) and a dynamic-link library (DLL) at the same time?"_ My answer is that yes, exe **can** be **dynamic-link library**, i. e. a binary module that you can dynamically load at run-time and use it as library, dynamically linking to its exported symbols – mvidelgauz Aug 24 '16 at 19:45
  • Well, the point is that the file extension doesn't matter. It can be anything you want. The bits in the binary determine it, specifically the PE header when you're talking about Windows binaries. The loader does something different with what we know as executables (generally with the extension EXE but not necessarily), and what we know as dynamic libraries (generally with the extension DLL but not necessarily). You can write additional code to make them behave in similar ways, but it doesn't change the fact that they are two different things as far as the loader is concerned. And the spec. – Cody Gray - on strike Aug 24 '16 at 19:47
  • Thanks @MartinBonner for doing my work here, I was going to mention .ocx, .tli, etc... even .txt can be DLL in the sence of this question... – mvidelgauz Aug 24 '16 at 19:48
  • @CodyGray My last post in this page: I read this question just __practicaly__. It is not a theoretical situation and I was there by myself: I had a big executable with a lot of functions that could be used in another project. Re-factoring that exe (old and huge) into dll was not possible due to a lot unrelated reasons. I needed to use those functions in another exe and had very short time to get it working. Thanks to the fact that _"exe can be used as library"_ that goal was achived quite quickly. Thus my answer. – mvidelgauz Aug 24 '16 at 19:58
2

In the official PE documentation, IMAGE_FILE_EXECUTABLE_IMAGE (0x002) and IMAGE_FILE_DLL (0x2000) are both flags of the Characteristics field of the PE-header.

As seen in the IMAGE_FILE_DLL (0x2000):

The image file is a dynamic-link library (DLL). Such files are considered executable files for almost all purposes, although they cannot be directly run.

However, for IMAGE_FILE_EXECUTABLE_IMAGE (0x002):

Image only. This indicates that the image file is valid and can be run. If this flag is not set, it indicates a linker error.

Since, the DLL cannot be directly run, it may not have the IMAGE_FILE_EXECUTABLE_IMAGE (0x002) flag set.

I guess, that these flags OR'd toghether would result in an error at load time, but I'm not sure.

Nicolas Lykke Iversen
  • 3,660
  • 1
  • 11
  • 9