Skip to content
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

[Feature] Unload ApplicationDomain when .NET execution completes #49

Open
TheWover opened this issue Mar 26, 2020 · 10 comments
Open

[Feature] Unload ApplicationDomain when .NET execution completes #49

TheWover opened this issue Mar 26, 2020 · 10 comments
Assignees
Labels
enhancement New feature or request
Milestone

Comments

@TheWover
Copy link
Owner

Received a request to add a feature for unloading newly created Application Domains after the execution of the payload is complete. We have looked into this before but did not end up adding it. Let's see if we can prototype a reliable unloader after the Assembly finishes. We may be able to just AppDomain.Unload() in FreeAssembly or LoadAssembly before the loader calls RtlExitUserThread/RtlExitUserProcess.

If we find that that prematurely exits, then we may need to leverage the .NET Debugging API to wait for execution of managed code in the process to finish.

@TheWover TheWover added the enhancement New feature or request label Mar 26, 2020
@TheWover TheWover added this to the v0.9.3 milestone Mar 26, 2020
@TheWover TheWover self-assigned this Mar 26, 2020
@odzhan
Copy link
Collaborator

odzhan commented Mar 27, 2020

Once ICorRuntimeHost::Stop is invoked, the .NET app exits prematurely. Are there any ETW events triggered when a .NET app terminates?

@TheWover
Copy link
Owner Author

TheWover commented Apr 1, 2020

I wonder if we could listen for ThreadCreated events for the new ApplicationDomain, then wait until all created threads generate a ThreadTerminated event? https://docs.microsoft.com/en-us/dotnet/framework/performance/application-domain-resource-monitoring-arm-etw-events

@TheWover
Copy link
Owner Author

TheWover commented Apr 1, 2020

Hmm... may also be able to use the Unmanaged Profiler API. Can set callbacks for different events.

A promising one is the Shutdown callback which is called when a managed application shuts down. But... the description indicates that it may not work if we have been injected into an originally unmanaged application. https://docs.microsoft.com/en-us/dotnet/framework/unmanaged-api/profiling/icorprofilercallback-shutdown-method

Could also monitor for thread creation and destruction events like with ETW: https://docs.microsoft.com/en-us/dotnet/framework/unmanaged-api/profiling/icorprofilercallback-threadcreated-method

As a last resort, could continuously enumerate threads until we find that all of the correct ones have terminated: https://docs.microsoft.com/en-us/dotnet/framework/unmanaged-api/profiling/icorprofilerinfo4-enumthreads-method

@TheWover
Copy link
Owner Author

TheWover commented Apr 1, 2020

Could also use try the Unmanaged CLR Debugging API. ICorDebugProcess lets you get the threads as ICorDebugThread. The thread class lets you check the AppDomain of the thread. So... you could poll the process for threads that are in the AppDomain that we created until none exist. https://docs.microsoft.com/en-us/dotnet/framework/unmanaged-api/debugging/icordebugthread-getappdomain-method

@TheWover
Copy link
Owner Author

TheWover commented Apr 1, 2020

Anyway, just researching for now. Looks like it is probably possible, just might be a little painful due to having to poll a process. Unless we can get ETW to work. That would probably be the simplest.

@odzhan
Copy link
Collaborator

odzhan commented Apr 2, 2020

The profiling interfaces look very promising. Haven't tested anything using these yet. Plenty of options available, which is good.

@TheWover
Copy link
Owner Author

TheWover commented Apr 17, 2020

I just had an idea. What if we queue APC on our current thread (within the loader) that will unload the application domain when it executes? I think the APC should fire either when ExitThread or ExitProcess is called during the loader's termination. Does that sound like it would work?

@TheWover
Copy link
Owner Author

Or we could just stop the CLR and clear the App Domain before calling ExitThread/ExitProcess?

@TheWover
Copy link
Owner Author

Possibly we could RESTART the CLR if need be. The AppDomains should still exist.

@odzhan
Copy link
Collaborator

odzhan commented Apr 18, 2020

I forgot to mention doing a test some days ago with the dotnet loader which was able to unload the disposable domain, but not the default domain.

@TheWover TheWover modified the milestones: v0.9.3, v1.1 Feb 28, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

2 participants