-
Notifications
You must be signed in to change notification settings - Fork 4.8k
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
How to implement gcc __attribute__((constructor)) when compiling dynamic libraries under Linux #110102
Comments
Tagging subscribers to this area: @agocke, @MichalStrehovsky, @jkotas |
You can use module initializer for this purpose. Publish a project with module initializer: $ dotnet new classlib -n ModInitLib
$ cd ModInitLib
$ cat > Class1.cs <<EOF
using System;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
public static class LibraryInitializer
{
[ModuleInitializer]
public static void Initialize()
{
Console.WriteLine("Library has been initialized (ModuleInitializer)!");
}
[UnmanagedCallersOnly(EntryPoint = "say_hello")]
public static void SayHello()
{
Console.WriteLine("Hello from ModInitLib!");
}
}
EOF
$ dotnet publish -p:PublishAot=true -p:TargetName=libModInitLib -o dist --ucr Link with some executable code: $ cat > glue.c <<EOF
#include <stdio.h>
void say_hello();
int main(void)
{
say_hello();
return 0;
}
EOF
$ cc -o glue glue.c -L$(pwd)/dist -lModInitLib
$ LD_LIBRARY_PATH=$(pwd)/dist ./glue
Library has been initialized (ModuleInitializer)!
Hello from ModInitLib! |
1.First of all thank you for your answer |
The example I showed is the shared library.
ModuleInitializer will run before any other code from shared lib (libModInitLib.so in the example) is executed. |
It seems to have no effect under android dotnet publish -r linux-bionic-arm64 -p:DisableUnsupportedError=true -p:PublishAotUsingRuntimePack=true --ucr |
@am11 Sorry, after testing I found that it works,But it seems that he will only execute when a certain function is called, if we just dlopen the function, he won't do anything |
How do we execute in gcc's .init_array |
This was discussed and answered in #104529 |
Running managed code as part of gcc's .init_array is unsupported. We cannot guarantee that the runtime will be properly initialized to execute managed code. This class of issues is called "static initialization order fiasco". Even if this may appear to work, servicing updates to the .NET SDK can cause this to stop working. It would not be considered a .NET bug if that happens and we will not fix such bugs. |
There is no clear answer in this question, he seems to be crashing the runtime library when we link using gcc .o |
We often need this kind of problem when working in reverse, maybe there is another way we can do it? For example: actively call runtime init? , what should I do
When the program runs to so_main, it will crash. It seems that the runtime library has not been initialized. |
After my testing, it cannot work. Calling the export amplification of c# in c does not seem to initialize the runtime library when statically linking and compiling to .o. And I manually called the following functions, which means that none of them work. InitializeRuntime what should i do? |
If you need to run some unrelated code at startup, you can do so by manually adding the attribute constructor code as an object file like this: <ItemGroup>
<NativeLibrary Include="initializer.o" />
</ItemGroup> The object file ( cc -c initializer.c -o initializer.o However, invoking a managed function from the attribute constructor is problematic because managed methods require the runtime to be initialized. Manually running the full initialization routine (e.g., It would be more efficient if the runtime could provide a hook for such cases, perhaps through an attribute like |
How should I initialize manually, |
We are not interested in building unreliable features in .NET (#104529 (reply in thread)). |
ld invokes
Perhaps reconsider the requirement and try not to rely on the attribute constructor behavior. |
Maybe we can provide an intermediate method for dotnet, i.e. manually initialize the run timer,Provide a function that can manually initialize the runtimer in c, and then provide a property [ModuleInitializer(LibraryConstructor = false)] init_array is the basis for reverse engineering. I think .net will definitely shine in the field of reverse engineering. Otherwise, I think a large number of reverse engineers will work on dotnet. |
No, it is the basis of reverse engineering. Without init_array, we cannot work. This is what most reverse engineers hope for. |
I now use a C so program to guide it, then it can work normally, but I think this is very unnecessary. We can directly manually connect .o and .lib at some point to manually initialize the runtime library. Can anyone give me some advice? I have some guidance |
init_array is the main battlefield for anti-debugging, I think we should deal with it |
Description
How to implement gcc attribute((constructor)) when compiling dynamic libraries under Linux
Reproduction Steps
1.create classlib
2.dotnet publish -r linux-bionic-arm64 -p:DisableUnsupportedError=true -p:PublishAotUsingRuntimePack=true -p:RemoveSections=true
Expected behavior
gcc attribute((constructor))
Actual behavior
no init
Regression?
No response
Known Workarounds
No response
Configuration
No response
Other information
No response
The text was updated successfully, but these errors were encountered: