This type of encryption protection method belongs to the wholeProgramSet encryption protection.
The primary problem solved by this method is how native code interacts with. Net code.
Three implementation methods are introduced here.
1. c ++/CLI implementation.
This is relatively simple, and C ++/CLI can be completed at once.
Loader is implemented by C ++/CLI. during runtime, it is loaded and then run through the decoding Assembly through reflection.
Void invokeassemblyresource ()
{
Try
{
Byte [] pbuf = getdecryptedresource ();
Assembly ^ ASM = Assembly: load (pbuf );
ASM-> entrypoint-> invoke (nullptr, nullptr );
}
Catch (exception ^ ex)
{
MessageBox: Show (ex-> message );
}
}
2. Use the C # export COM interface to interact with native code.
Loader consists of C # And native code.
C # SectionCode
Public interface iinvokeassembly
{
Void loadandexecute (byte [] pbuf );
};
Public class cinvokeassembly: iinvokeassembly
{
Public cinvokeassembly ()
{
}
Public void loadandexecute (byte [] pbuf)
{
Try
{
Assembly ASM = assembly. Load (pbuf );
ASM. entrypoint. Invoke (null, null );
}
Catch (exception ex)
{
MessageBox. Show (ex. Message );
}
}
}
The iinvokeassembly interface exported here will be used in native code.
Native code
Void invokeassemblyresource ()
{
Iinvokeassemblyptr pinvoker; // com pointer to the. NET Interface
If (failed (pinvoker. createinstance (clsid_cinvokeassembly )))
{
MessageBox (null, _ T ("unable to create invoke Assembly object !! "), _ T (" error "), mb_ OK | mb_iconerror );
Return;
}
Hrsrc HRC = findresource (null, makeintresource (idr_embedded_assembly), "rt_embedded_assembly ");
Hglobal hres = loadresource (null, HRC );
DWORD dwsize = sizeofresource (null, HRC );
Safearray * PSA = NULL;
If (null! = (PSA = safearraycreatevector (vt_ui1, 0, dwsize )))
{
Lpvoid pbuf = NULL;
If (failed (safearrayaccessdata (PSA, & pbuf )))
MessageBox (null, _ T ("unable to access safearray data"), _ T ("error"), mb_ OK | mb_iconerror );
Else
{
Lpvoid hasm = lockresource (hres );
Memcpy (pbuf, hasm, dwsize );
Unlockresource (hres );
Safearrayunaccessdata (PSA );
}
Pinvoker-> loadandexecute (PSA); // invoke the reflection to load and execute our byte []
}
Else
MessageBox (null, _ T ("unable to allocate memory"), _ T ("memory allocate error"), mb_ OK | mb_iconerror );
If (PSA) safearraydestroy (PSA );
}
There is another problem here. loader is two parts. The encrypted assembly can be checked into the native code loader as a resource. But how to deal with C?
A relatively concealed method is to install the program to GAC during installation.
3. Use the CLR-hosting interface. For details, refer to the local interface documentation in msdn.
Bool invokeassemblyresource ()
{
Ccomptr <icorruntimehost> spruntimehost;
Ccomptr <_ appdomain> spappdomain;
Ccomptr <iunknown> spunk;
Bool bsuccess = false;
If (failed (corbindtoruntimeex (null, // latest version by default
L "wks", // workstation build
Startup_loader_optimization_single_domain,
Clsid_corruntimehost,
Iid_icorruntimehost,
(Void **) & spruntimehost )))
{
Gerrmsg = _ T ("unable to bind CLR ");
Return false;
}
If (failed (spruntimehost-> Start ()))
{
Gerrmsg = _ T ("unable to start CLR ");
Return false;
}
Do
{
If (failed (spruntimehost-> getdefadomain domain (& spunk )))
{
Gerrmsg = _ T ("unable to getdefadomain domain ");
Break;
}
If (failed (spunk-> QueryInterface (& spappdomain. p )))
{
Gerrmsg = _ T ("unable to query appdomain interface ");
Break;
}
Safearray * PSA = getdecryptedresource ();
If (PSA)
{
Try
{// Invoke the entry point with no arguments
Spappdomain-> load_3 (PSA)-> entrypoint-> invoke_3 (_ variant_t (), null );
Bsuccess = true; // everything went fine !!
}
Catch (_ com_error ex)
{
Gerrmsg = ex. errormessage ();
}
Safearraydestroy (PSA );
PSA = NULL;
}
} While (false );
If (failed (spruntimehost-> stop ()))
{
Gerrmsg = _ T ("unable to stop CLR ");
Return false;
}
Return bsuccess;
}
Generally, this type of encryption tool selects the third implementation method, such as. Net reactor.
However, the installation of pure overall encryption protection is very low. You can use some other methods to increase the protection intensity, such as. Net reactor's necrobit.
Because it is easy to be dumped out of the Assembly during load, this method is to make the Assembly loaded during load not complete (except for the Il code part, necrobit ).
After load is complete, the Il code is restored before the Assembly is executed.