. A brief analysis of the basic principle and method of net program Packers

Source: Internet
Author: User
Tags reflector

. A brief analysis of the basic principle and method of net program Packers

Packers are a common method of protecting applications, and they are exactly an encryption method. Named Shell, meaning that the protection of the program is like a plant seed shell, we use a program to wrap our main program in the meantime, can not easily be seen by other people.
The shell of the program to operate in the first operation of an additional instruction, this additional instruction is completed after the operation will be launched the main program.
The Shell method can be broadly divided into compression and encryption.
Traditional non-custodial procedures, the goal of Packers is to assemble instructions; NET program's shell target is the metadata and IL code. The shell of the. NET program has not been innovated in theory and method, and is now directly inheriting and adding shell theory and method of Windows program. Most. NET Shell tool is also the traditional shell tool in its own function to provide expansion. Pure. NET completion of the Shell tool is still very small. There are many ways to shell, so let's take a look at the usual case of the storage compression shell for illustration.
In order to explore its compression principle, we first create a piece of code for experimentation.
For Shell program source code:
Class Program
{
static void Main (string[] args)
{
Dosth ();
}
public static void Dosth ()
{
}
}
The code eventually generates the ForCompress.exe file. Use reflector to check its IL code.
The IL Code of the Main method
. method private Hidebysig static void Main (string[] args) cil managed
{
. entrypoint
. maxstack 8
L_0000:nop
L_0001:call void Forcompress.program::D osth ()
L_0006:nop
L_0007:ret
}
At the moment, ForCompress.exe is shown in the results of the reflector in 1.
  
The structure of ForCompress.exe
  
Let's start with a model. NET compression tool, Netz to Shell ForCompress.exe. After the Packers, let's start reflector again to check the Packers ' files. As shown in 2.
  
ForCompress.exe file after Packers
As shown in Figure 1 and Figure 2, we find that the title space forcompress becomes Netz, and the class progress becomes the Netzstartter. The Assembly has a lot of capital file app.resources. Let's open the Netzstartter class and check out the method below. As shown in 3.
  
Figure 3 Methods of the Netzstartter class
From Figure 3 We can see that Netzstartter class defines a series of our "Do not know" approach, but there is no code dosth method. Let's analyze the launch process of the EXE file after the shell is added.
First, navigate to the main method and check its source code, as shown in Listing 9-16.
Code Listing 9-16 The main method of the Netzstartter class
[STAThread]
public static int Main (string[] args)
{
Try
{
INITXR ();
AppDomain.CurrentDomain.AssemblyResolve + = new Resolveeventhandler (Netzstarter.netzresolveeventhandler);
Return StartApp (args);
}
catch (Exception Exception)
{
String str = ". NET Runtime:";
Log (String. Concat (new object[] {"#Error:", exception. GetType (). ToString (), Environment.NewLine, exception. Message, Environment.NewLine, exception. StackTrace, Environment.NewLine, exception. InnerException, Environment.NewLine, "Using", str, Environment.Version.ToString (), Environment.NewLine, "Created with ", str," 2.0.50727.4927 "}));
return-1;
}
}
In code listing 9-16, the main method, the first call to the INITXR method, and then add a disposition for AppDomain.CurrentDomain.AssemblyResolve things, and finally call the Startapp method. Let's take a look at the initxr ways to do something. The Initxr method source code is shown in Listing 9-17.
Code Listing 9-17 Initxr method source
private static void Initxr ()
{
Try
{
String str = @ "file:\";
String str2 = "-netz.resources";
String directoryname = Path.getdirectoryname (assembly.getentryassembly (). Location);
if (Directoryname.startswith (str))
{
directoryname = directoryname.substring (str. Length, Directoryname.length-str. Length);
}
string[] files = Directory.GetFiles (directoryname, "*" + str2);
if ((Files! = null) && (files. Length > 0))
{
XRRM = new ArrayList ();
for (int i = 0; i < files. Length; i++)
{
String fileName = Path.getfilename (Files[i]);
ResourceManager manager = ResourceManager.CreateFileBasedResourceManager (filename.substring (0, Filename.length- Str2. Length) + "-netz", directoryname, NULL);
if (manager! = null)
{
Xrrm.add (manager);
}
}
}
}
Catch
{
}
}
The code in Listing 9-17 is very clear, search for the capital file in a particular file path, and then add it to the global variable XRRM.
AppDomain.CurrentDomain.AssemblyResolve + = new Resolveeventhandler (Netzstarter.netzresolveeventhandler) in the Main method There is no need to say a single line of code, just specify what to do when the assembly fails to parse.
Now let's look at the source code for the Startapp approach, as shown in Listing 9-18.
Code Listing 9-18 Startapp method source
public static int StartApp (string[] args)
{
byte[] resource = GetResource ("a6c24bf5-3690-4982-887e-11e1b159b249");
if (resource = = null)
{
throw new Exception ("Application data cannot be found");
}
int num = Invokeapp (getassembly (Resource), args);
resource = null;
return num;
}
The Startapp method, from the name, should be to invoke the encrypted source program. In the method body, the first call to the GetResource method, comes back to the specified capital, and then calls the Invokeapp method into the main program. In order to find out the ins and outs, let's first look at the GetResource method eventually did what? Listing 9-19 is the source code for the getresource approach.
Code Listing 9-19 GetResource method source
private static byte[] GetResource (string id)
{
byte[] buffer = NULL;
if (rm = = NULL)
{
RM = new ResourceManager ("app", assembly.getexecutingassembly ());
}
Try
{
Inresourceresolveflag = true;
String name = Mangledllname (ID);
if ((buffer = = null) && (XRRM! = null))
{
for (int i = 0; i < Xrrm.count; i++)
{
Try
{
ResourceManager manager = (ResourceManager) xrrm[i];
if (manager! = null)
{
Buffer = (byte[]) Manager. GetObject (name);
}
}
Catch
{
}
if (buffer! = NULL)
{
Break
}
}
}
if (buffer = = NULL)
{
Buffer = (byte[]) rm. GetObject (name);
}
}
Finally
{
Inresourceresolveflag = false;
}
return buffer;
}
Now let's make a brief analysis of the code listing 9-19.
if (rm = = NULL)
{
RM = new ResourceManager ("app", assembly.getexecutingassembly ());
}
The above code from the time the program gathered to get the title of the app's capital file, back to Figure 9-20, we can see the app. The resources file is embedded in the program to gather and be able to be acquired. The next code gets the specified title of the capital and then returns it in a byte array. What is the usefulness of returning capital? We continue to analyze.
Invokeapp (getassembly (Resource), args);
Above is the final call of the Startapp method, the GetAssembly method, from the name of which is to get the assembly, whose parameter is the GetResource method returned by the byte array. Let's go into its source code and explore it eventually. The source code for the GetAssembly method is shown in Listing 9-20.
Code Listing 9-20 GetAssembly method source
private static Assembly getassembly (byte[] data)
{
MemoryStream stream = null;
Assembly Assembly = null;
Try
{
stream = UNZIP (data);
Stream. Seek (0L, Seekorigin.begin);
Assembly = Assembly.Load (stream. ToArray ());
}
Finally
{
if (stream! = null)
{
Stream. Close ();
}
stream = null;
}
return assembly;
}
The code in Listing 9-20 is also simple to convert from a byte array to an assembly. The only thing we need to keep an eye on here is the following code:
stream = UNZIP (data);
Unzip method to decompress a byte array. This approach is the most critical way to run the entire program, but we do not pay attention to the detailed completion of the decompression. If you are interested, you can discuss it yourself.
After getting the assembly, only the real beginning fulfills the INVOKEAPP approach, let's look at code listing 9-21.
Code Listing 9-21 Invokeapp Source
private static int Invokeapp (Assembly Assembly, string[] args)
{
MethodInfo entrypoint = assembly. entrypoint;
parameterinfo[] Parameters = Entrypoint.getparameters ();
object[] Objarray = null;
if (Parameters! = null) && (parameters. Length > 0))
{
Objarray = new object[] {args};
}
Object obj2 = Entrypoint.invoke (null, objarray);
if ((obj2! = null) && (obj2 is int))
{
return (int) obj2;
}
return 0;
}
From code listing 9-21 we see that this code first gets the assembly's entry function, which is the main method, and then fulfills it. Here, the program is actually going from the shell to the real main program.
Combined with the above analysis, we summarize a pure. NET compression shell program operation Flow:
1) The main operating shell program when the program is running.
2) The shell reads the original data of the main program from its capital.
3) Unzip the original data and convert it into an assembly.
4) running the main program.
The two key points of this packers approach, one is the existence of the main program as a capital file for shell programs, and the second is to decrypt the capital file first and then reflect the performance.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.