Building Finalizable and Disposable Types

If the caller forgets to call Dispose(), the unmanaged resources may be held in memory indefinitely.

class MyResourceWrapper : IDisposable
 {
     // The gc will call this method if the object user forgets to call Dispose()
     ~MyResourceWrapper()
     {
         // Clean up any internal unmanaged resources
         // Do **not** call Dispose() on any managed objects
     }
    // The object user will call this method to clean up resoucres ASAP.
     public void Dispose()
     {
         // Cleanup unmanaged resources here.
         // Call Dispose() on other contained disposable objects.
         // No need to finalize if user called Dispose(), so suppress finalization.
         GC.SuppressFinalize(this);
     }
 }

Understanding Lazy Object Instantiation

Don't create the object until you need it.

Lazy<MyClass> obj = new Lazy<MyClass>();
 
Value -> returns the object (creates on first call)
IsValueCreated -> True if already created, false if not.
Lazy<HttpClient> obj = new Lazy<HttpClient>(() =>
 {
     return new HttpClient();
 });

Offensive C# style:

  1. Implant starts with small memory footprint.
  2. Modules load only WHEN operator requests them.
  3. AV/EDT memory scan sees less suspicious code.

Normal : Agent starts -> All Modules in memory -> Heavy -> Detected

Lazy : Agent starts -> ZERO Modules loaded -> Light -> Stealthy

Operator says "hashdump" -> mimikatz loads -> executes -> done.

Lazy<T> is thread-safe by default.