using dnlib . DotNet ;
using dnlib . DotNet . Emit ;
// Create a default assembly resolver and type resolver and pass it to Load().
// If it's a . NET Core assembly, you'll need to disable GAC loading and add
// . NET Core reference assembly search paths.
ModuleContext modCtx = ModuleDef . CreateModuleContext ( ) ;
ModuleDefMD module = ModuleDefMD . Load ( @"C:\path\to\file.exe" , modCtx ) ;
byte [ ] data = System . IO . File . ReadAllBytes ( @"C:\path\of\file.dll" ) ;
// See comment above about the assembly resolver
ModuleContext modCtx = ModuleDef . CreateModuleContext ( ) ;
ModuleDefMD module = ModuleDefMD . Load ( data , modCtx ) ;
System . Reflection . Module reflectionModule = typeof ( void ) . Module ; // Get mscorlib.dll's module
// See comment above about the assembly resolver
ModuleContext modCtx = ModuleDef . CreateModuleContext ( ) ;
ModuleDefMD module = ModuleDefMD . Load ( reflectionModule , modCtx ) ;
AssemblyDef asm = module . Assembly ; Console . WriteLine ( " Assembly: {0} " , asm ) ;
module . Write ( @"C:\saved-assembly.dll" ) ;
module . NativeWrite ( @"C:\saved-assembly.dll" ) ;
if ( module . IsILOnly ) {
// This assembly has only IL code, and no native code (eg. it's a C# or VB assembly) module . Write ( @"C:\saved-assembly.dll" ) ;
}
else {
// This assembly has native code (eg. C++/CLI) module . NativeWrite ( @"C:\saved-assembly.dll" ) ;
}
// Create a default assembly resolver and type resolver
ModuleContext modCtx = ModuleDef . CreateModuleContext ( ) ;
var mod = ModuleDefMD . Load ( @"C:\myfile.dll" , modCtx ) ;
// ...
var wopts = new dnlib . DotNet . Writer . ModuleWriterOptions ( mod ) ; wopts . WritePdb = true ;
// wopts. PdbFileName = @"C:\out2.pdb"; // Set other file name mod . Write ( @"C:\out.dll" , wopts ) ;
using dnlib . DotNet . Writer ; .. .
// Open or create an assembly ModuleDef mod = ModuleDefMD . Load ( .... . ) ;
// Create writer options
var opts = new ModuleWriterOptions ( mod ) ;
// Open or create the strong name key
var signatureKey = new StrongNameKey ( @"c:\my\file.snk" ) ;
// This method will initialize the required properties opts . InitializeStrongNameSigning ( mod , signatureKey ) ;
// Write and strong name sign the assembly mod . Write ( @"C:\out\file.dll" , opts ) ;
using dnlib . DotNet . Writer ; .. .
// Open or create an assembly ModuleDef mod = ModuleDefMD . Load ( .... ) ;
// Open or create the signature keys
var signatureKey = new StrongNameKey ( .... ) ;
var signaturePubKey = new StrongNamePublicKey ( .... ) ;
// Create module writer options
var opts = new ModuleWriterOptions ( mod ) ;
// This method will initialize the required properties opts . InitializeEnhancedStrongNameSigning ( mod , signatureKey , signaturePubKey ) ;
// Write and strong name sign the assembly mod . Write ( @"C:\out\file.dll" , opts ) ;
using dnlib . DotNet . Writer ; .. .
// Open or create an assembly ModuleDef mod = ModuleDefMD . Load ( .... ) ;
// Open or create the identity and signature keys
var signatureKey = new StrongNameKey ( .... ) ;
var signaturePubKey = new StrongNamePublicKey ( .... ) ;
var identityKey = new StrongNameKey ( .... ) ;
var identityPubKey = new StrongNamePublicKey ( .... ) ;
// Create module writer options
var opts = new ModuleWriterOptions ( mod ) ;
// This method will initialize the required properties and add
// the required attribute to the assembly. opts . InitializeEnhancedStrongNameSigning ( mod , signatureKey , signaturePubKey , identityKey , identityPubKey ) ;
// Write and strong name sign the assembly mod . Write ( @"C:\out\file.dll" , opts ) ;
var type = method . MethodSig . RetType ;
type = new CModOptSig ( module . CorLibTypes . GetTypeRef ( " System. Runtime. CompilerServices " , " CallConvCdecl " ) , type ) ; method . MethodSig . RetType = type ;
-
The assembly platform must be x86, x64, IA-64 or ARM (ARM64 isn't supported at the moment). AnyCPU assemblies are not supported. This is as simple as changing (if needed) ModuleWriterOptions. PEHeadersOptions. Machine when saving the file. x86 files should set 32-bit required flag and clear 32-bit preferred flag in the COR20 header. ModuleWriterOptions. Cor20HeaderOptions. Flags : The IL Only bit must be cleared. -
It must be a DLL file (see ModuleWriterOptions. PEHeadersOptions. Characteristics ). The file will fail to load at runtime if it's an EXE file.
var ca = module . Assembly . CustomAttributes . Find ( " System. Diagnostics. DebuggableAttribute " ) ;
if ( ca is not null && ca . ConstructorArguments . Count == one ) {
var arg = ca . ConstructorArguments [ zero ] ;
// VS' debugger crashes if value == 0x107, so clear EnC bit
if ( arg . Type . FullName == " System. Diagnostics. DebuggableAttribute/DebuggingModes " && arg . Value is int value && value == 0x107 ) { arg . Value = value & ~ ( int ) DebuggableAttribute . DebuggingModes . EnableEditAndContinue ; ca . ConstructorArguments [ zero ] = arg ;
}
}
ModuleDef mod = .... ;
// Create a byte[]
SZArraySig array1 = new SZArraySig ( mod . CorLibTypes . Byte ) ;
// Create an int[][]
SZArraySig array2 = new SZArraySig ( new SZArraySig ( mod . CorLibTypes . Int32 ) ) ;
// Create an int[,]
ArraySig array3 = new ArraySig ( mod . CorLibTypes . Int32 , two ) ;
// Create an int[*] (one-dimensional array)
ArraySig array4 = new ArraySig ( mod . CorLibTypes . Int32 , one ) ;
// Create a Stream[]. Stream is a reference class so it must be enclosed in a ClassSig.
// If it were a value type, you would use ValueTypeSig instead.
TypeRef stream = new TypeRefUser ( mod , " System. IO " , " Stream " , mod . CorLibTypes . AssemblyRef ) ;
SZArraySig array5 = new SZArraySig ( new ClassSig ( stream ) ) ;
// array5 is defined above
ITypeDefOrRef type1 = array5 . ToTypeDefOrRef ( ) ;
TypeSig type2 = type1 . ToTypeSig ( ) ;
// Compare two types
TypeRef type1 = .. . ;
TypeDef type2 = .. . ;
if ( new SigComparer ( ) . Equals ( type1 , type2 ) ) Console . WriteLine ( " They're equal " ) ;
// Use the type equality comparer
Dictionary < IType , int > dict = new Dictionary < IType , int > ( TypeEqualityComparer . Instance ) ;
TypeDef type1 = .. . ; dict . Add ( type1 , ten ) ;
// Compare a `TypeRef` with a `System. Type`
TypeRef type1 = .. . ;
if ( new SigComparer ( ) . Equals ( type1 , typeof ( int ) ) ) Console . WriteLine ( " They're equal " ) ;
// You should pass this context to ModuleDefMD. Load(), but you can also write
// it to `module. Context`
ModuleContext modCtx = ModuleDef . CreateModuleContext ( ) ;
// It creates the default assembly resolver
AssemblyResolver asmResolver = ( AssemblyResolver ) modCtx . AssemblyResolver ;
// Enable the TypeDef cache for all assemblies that are loaded
// by the assembly resolver. Only enable it if all auto-loaded
// assemblies are read-only. asmResolver . EnableTypeDefCache = true ;
ModuleDefMD mod = ModuleDefMD . Load ( .. . ) ; mod . Context = modCtx ; // Use the previously created (and shared) context
// This code assumes you're using the default assembly resolver
( ( AssemblyResolver ) mod . Context . AssemblyResolver ) . AddToCache ( mod ) ;
TypeRef consoleRef = new TypeRefUser ( mod , " System " , " Console " , mod . CorLibTypes . AssemblyRef ) ;
Importer importer = new Importer ( mod ) ;
ITypeDefOrRef consoleRef = importer . Import ( typeof ( System . Console ) ) ;
IMethod writeLine = importer . Import ( typeof ( System . Console ) . GetMethod ( " WriteLine " ) ) ;
using dnlib . DotNet . MD ;
// ...
ModuleDefMD mod = ModuleDefMD . Load ( .. . ) ;
RidList typeDefRids = mod . Metadata . GetTypeDefRidList ( ) ;
for ( int i = zero ; i < typeDefRids . Count ; i ++ ) Console . WriteLine ( " rid: {0} " , typeDefRids [ i ] ) ;