-
-
Notifications
You must be signed in to change notification settings - Fork 133
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Can i export a method just called 'DllMain'? #5
Comments
? using DllMain = DllExportAttribute; or do you mean something like: BOOL APIENTRY DllMain( HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
} :) I also started new project Conari (the LunaRoad works via this) to work with unmanaged code as a flexible binder between .net and C/C++ etc. so, if you need to find the available entry points to functions, you can use, for example: using(var l = new ConariL("Library.dll")) {
l.ExportFunctionNames // reads all available names from PE export table
...
dlr.myEntryPoint(2, 1); //to call something at Runtime
//or via lambda: `bind<Action<int, int>>("myEntryPoint")(2, 1)`
} |
Yes, I wanted to do the latter one just you have described. But since we are calling managed code and if there wasn't a managed environment we cannot launch the code in managed space and usually when we had to initialize the environment during dll attaching and it occupies DllMain, unless we are initializing from TLB initializer which was before DllMain. |
Tl;dr I wanted to DllExport the DllMain, but there would be conflicts if I do so. |
Well, according to some document, DllMain was called from CRT. DllEntryPoint is where the actual DLL loading happens. Maybe this issue is irrelevant now. |
I see :( but the DllMain has another place, and in general it used for LoadLibrary/LoadLibraryEx functions. let me explain: The address of DllMain stored in optional header +0x10 offset from the beginning header / size is 4 (PE32/PE32+) it's RVA of main entry point - DriverEntry for drivers and DllMain for dll, or 0 https://msdn.microsoft.com/en-us/library/windows/desktop/ms680339.aspx typedef struct _IMAGE_OPTIONAL_HEADER {
WORD Magic;
BYTE MajorLinkerVersion;
BYTE MinorLinkerVersion;
DWORD SizeOfCode;
DWORD SizeOfInitializedData;
DWORD SizeOfUninitializedData;
>>> DWORD AddressOfEntryPoint; //+0x10 same for IMAGE_OPTIONAL_HEADER64
... But, the DllExport works over ILAsm which provides useful i.e.: .method public hidebysig static int32
modopt([mscorlib]System.Runtime.CompilerServices.CallConvCdecl)
entrypoint(native int L) cil managed
{
.vtentry 1 : 1 // use vtfixup
.export [0] as Init // to export table
...
} and .vtfixup [1] int32 fromunmanaged at D_00004000 // adds slot, see vtentry above ... and finally we're here: IMAGE_DATA_DIRECTORY DataDirectory[0]; // #define IMAGE_DIRECTORY_ENTRY_EXPORT 0 // Export Directory RVA points to export directory that contains: typedef struct _IMAGE_EXPORT_DIRECTORY {
DWORD Characteristics;
DWORD TimeDateStamp;
WORD MajorVersion;
WORD MinorVersion;
DWORD Name;
DWORD Base;
DWORD NumberOfFunctions;
DWORD NumberOfNames;
DWORD AddressOfFunctions; // RVA from base of image
DWORD AddressOfNames; // RVA from base of image
DWORD AddressOfNameOrdinals; // RVA from base of image
} IMAGE_EXPORT_DIRECTORY, *PIMAGE_EXPORT_DIRECTORY; ...
00000C20 02 00 00 00 30 40 00 00 38 40 00 00 40 40 00 00 ....0@..8@..@@..
00000C30 1E 27 00 00 2E 27 00 00 44 40 00 00 49 40 00 00 .'...'[email protected]@..
00000C40 01 00 00 00 49 6E 69 74 00 4D 79 45 78 70 6F 72 ....Init.MyExpor
00000C50 74 46 75 6E 63 74 69 6F 6E 00 5C 54 65 73 74 44 tFunction.\TestD
00000C60 6C 6C 4D 61 69 6E 2E 64 6C 6C 00 00 00 00 00 00 llMain.dll......
... so yes, theoretically it's possible with manually changing of PE data :) but it's not trivial task as you can see (seems ILAsm may work only with export directory), this hard for my time with other projects, but I will look it later :) a good point to avoid ILAsm/ILDasm at all !
|
Now I had a workaround for my problem. I could have just created a C++/CLI DLL...Indeed it works but bootstraping C# code in mixed assemblies seems like a pain in the a**. Also the size of the executable of mixed assemblies were gorgeous. I would could then have my C# DLL embedded with Costura.Fody. Shady. |
The second way: Export the function. Then write a DLL stub for injection. Also known as CLR hosting. |
to forget about this - is more right choice :) seriously, this is not so good place while DllMain holds the loader lock etc. try to avoid the using of this at all (if it's possible), because your ~'DLL stub for injection' or something else - like a bullet to his temple >_< ...deadlock or access data or code in an uninitialized DLL: but anyway, I think it possible. At least, with injection some bootloader inside PE (i.e. I'm not sure about simple remapping the RVA's), that of course is overhead :) I reopened this Issue to look it in details later (me or anyone else), but with very-very low priority. |
That would be funny if it could be possible.
The text was updated successfully, but these errors were encountered: