Assemblies contain modules, and modules contain types, and types also contain members. Reflection provides an object that encapsulates assemblies, modules, and types. You can use reflection to dynamically create an instance of a type, bind the type to an existing object, or get a type from an existing object. You can then invoke a method of the type or access its fields and properties.
The use of reflection is very large, in the last section of the article "late binding" is to take advantage of the reflection of the nature of the plug-in writing more need to reflect. Our commonly used anti-compilation tool, Refiector, also uses the nature of reflection.
We're going to write a simple refiector-like thing today and get a lot of information about the assembly through reflection.
1, get all the namespace of the Assembly
public static ArrayList Getallnamespace (Assembly Assembly)
{
ArrayList Namepacearry = new ArrayList ();
foreach (Type type in assembly. GetTypes ())
{
if (!namepacearry.contains (type. Namespace) && type. Namespace = null)
{
Namepacearry.add (type. Namespace);
}
}
return namepacearry;
}
2. Get all classes of the Assembly
public static ArrayList Getclassnames (Assembly Assembly, String nameSpace)
{
Type[] Types = assembly. GetTypes ();
ArrayList Classarray = new ArrayList ();
foreach (type type in types)
{
if (type. FullName = = NameSpace + "." + type. Name && type. Basetype.name = "Enum")
{
Classarray.add (type. Name);
}
}
return classarray;
}
3. Get all the methods in a class of assemblies
public static MethodInfo [] GetMethod (Assembly Assembly, String fullName)
{
Type type = assembly. GetType (FullName);
return type. GetMethods ();
}
The FullName here is a combination of namespace and class names.
4. Get all the attributes in a class in the assembly
public static propertyinfo[] Getpropertys (Assembly Assembly, String fullName)
{
Type type = assembly. GetType (FullName);
return type. GetProperties ();
}
5. Get the enumeration type of the assembly
public static ArrayList Getenums (Assembly Assembly, String nameSpace)
{
Type[] Types = assembly. GetTypes ();
ArrayList Classarray = new ArrayList ();
foreach (type type in types)
{
if (type. FullName = = NameSpace + "." + type. Name && type. Basetype.name = = "Enum")
{
Classarray.add (type. Name);
}
}
return classarray;
}
6. Get the content enumerated in the assembly, and the value of each item
public static fieldinfo [] getsubenums ( Assembly assembly, string fullname)
{
return assembly. GetType (FullName). GetFields ();
}
public static string getsubenumsdata ( Assembly assembly, string fullname,string name)
{
fieldinfo info = assembly. GetType (FullName). GetField (name);
return info. Getrawconstantvalue (). ToString ();
}
7. Get all the properties of a class in the program set
public static propertyinfo[] Getpropertys (Assembly Assembly, String fullName)
{
Type type = assembly. GetType (FullName);
return type. GetProperties ();
}
8. Get the IL code for a specific method in the program set
public static string Getmethoddata (Assembly Assembly, string fullname,string name, Type [] types)
{
Type type = assembly. GetType (FullName);
MethodInfo info = type. GetMethod (name, types);
string data = String.Empty;
if (info. Getmethodbody ()! = null)
{
byte[] Il = info. Getmethodbody (). Getilasbytearray ();
if (il! = null)
{
int inslength;
for (int currentpos = 0;currentpos < IL. Length;currentpos + = inslength)
{
inslength = 0;
Data + = String.Format ("{0:x8}: {1}", Currentpos,disassembler.decode (IL, currentpos, out inslength)) + "\ r \ n";
}
}
return data;
}
Return "This function does not do anti-compilation processing";
}
1. Reflective Packers
I have published in the 06 "hacker defense" in a "C # implementation from their own resources to extract EXE files," The main point is how to save the exe file in the form of resources in the PE file, and then self-release (imitation Trojan self-release function), then used the reflection technology. After a lapse of 2 years, the time of the night struggle scene I still vaguely remember, through the article to guide, release will get a separate EXE file. The principle of the donet reflector shell is to simply release the managed program into memory in the reflection shell and find its entry point, then execute the entry function (not releasing the real file). What do you think. It seems very simple.
We'll take a crackme today to add a simple reflective shell.
Start by creating a new CMD project, copy the Crackme into the project file, and set the "Embedded Resource" in the solution to be the project.
Then we will convert this resource into a byte array in the code:
Stream sr = assembly.getexecutingassembly (). GetManifestResourceStream ("CiCiPackDemo.CrackMe1.exe");
byte[] filebytes = new BYTE[SR. Length];
Sr. Read (filebytes, 0, (int) Sr. LENGTH-1);
Assembly Assembly = Assembly.Load (filebytes);
MethodInfo mi = assembly. entrypoint;
Mi. Invoke (null, NULL);
Note: the "Cicipackdemo" here is the namespace for the project, and "CrackMe1.exe" is the embedded Resource name.
Then we can find the CrackME1.exe function entry point and run it.
Finally, we will set the project's compilation type to the Windows program, compiled once, the simplest reflection shell is finished. We can see that the process is: read its own resource, the transform resource is assembly-> find the entry point, and execute the entry function.
We use reflector to open the shell and shell of the program to view:
The non-Packers program is as follows:
The shell has been added as follows:
After comparison we found that the shell after the program to save CrackMe1.exe as a resource file, and our refletor can not view its code. It has a simple cryptographic protection function.
This is the reflective shell, very simple ^_^!
2. Reflective shelling
It is certainly a matter of course that the shell can be shelled. In the Win32 era ollydbg seems to be the darling of the platform, but for the reflector donet platform shell, the software will fly the program as soon as it loads. Have a skill but do not display ...
So how to deal with the reflection shell under the Donet platform. Looking back at the shell principle, let's take a closer look at this code: Assembly Assembly = Assembly.Load (filebytes); This means that the system will restore the shell's program in-memory to a assembly object anyway. Then we can get this object, we will be able to obtain information about this program, in conjunction with the previous article we can even get IL code. So how do you get this object? In the program domain there is such a method AppDomain.CurrentDomain.GetAssemblies (), unfortunately only in this Assembly can be called so, after some thinking, we found that the managed code can be injected into the program, and then use the method to obtain its object.
Through the tool I wrote in the previous article: "Universal Managed code syringe". You can inject a managed program into any process. According to the previous article injected cicireflection into the upper shell Cicipackdemo can get Crackme1.exe complete information.
So how do we get this Crackme1.exe assembly complete dump down? In the introduction of the principle before telling everyone a disappointment, this reflection shelling in the current donet decryption is not practical, more is based on the JIT layer of shelling, not based on the software itself, but as a way of shelling is still necessary to share with you.
One: Share the methods of Rick Daniel, which I understand after reading some of Rick Daniel's articles. (Because the Ox person writes the article often only has the code and donuts, I wait for rookie but to digest very long). Using a third-party dump software to dump this assembly first, and then according to the Assembly object to obtain some data to repair the dump file, it is equivalent to the WIN32 program after shelling to repair the input and output table is the same reason. And donet reflex shelling is to repair "method body, head file, metadata" and so on. In order not to mislead people or deliberately advertise their suspicions, I still ask you to look at Rick Daniel's code: http://bbs.pediy.com/showthread.php?t=47330
Second: The principle of the Rick Daniel, and then look at my direct injection into the reflection of the method of obtaining data. Of course we need to use my universal managed code syringe and write myself a plugin code as follows:
if (folderbrowserdialog1.showdialog () = = DialogResult.OK)
{
Try
{
Assembly [] assemblies = AppDomain.CurrentDomain.GetAssemblies ();
BOOL Isunpack = false;
foreach (Assembly Assembly in assemblies)
{
if (Path.getfilename (assembly. Location). ToLower () = = "Cicipackdemo.exe")
{
Using (Stream SR =assembly. GetManifestResourceStream ("CiCiPackDemo.CrackMe1.exe"))
{
&nb