Saturday, May 3, 2014

.Net Reflector Anti-Decompiling Trick Explained

NET Reflector is well known decompiler for .NET executables. There are a lot of tutorials in the wild that mention a simple trick to protect your software from being decompiled by .NET Reflector.
 
However, all tutorials I have seen so far, don't explain why it works and they do it the wrong way.
What I mean with wrong, is that "their method" will only work in a few cases, but not with every .NET executable. You will see why.
 
This little paper shall fill the niche by explaining what is actually going on and how to perform the "hack" in a way that works.
 
Tools needed
 
For doing it manually you need at least a Hex editor. A PE viewer can help you too.
Alternatively you may just use the program I provide below to do it for you.
 
The PE format in short
 
An .exe file--no matter if .NET or not--has the Portable Executable format specified in http://msdn.microsoft.com/en-us/library/gg463119.aspx
Also DLL, SYS, FON and other files have this same format. The general structure looks like this:


 
What you need to know in order to understand the hack is this:
 
The PE file has several headers and sections in it. The information within the headers is used to map the necessary data into memory. 
Within the optional header at offset 92 for PE32 or offset 108 for PE32+ files there is a value called NumberOfRvaAndSizes. This value tells how many entries are in the data directory table. The data directory table entries denote where to find certain information in the sections, e.g. the import table that is used to load functions from DLLs. That means some of the data directory table entries are important for the executable to work properly. Therefore changing the NumberOfRvaAndSizes may corrupt the PE.
 
The trick
 
For some reason, .NET Reflector expects the NumberOfRvaAndSizes to be 16. If it is lower than that, .NET Reflector is unable to decompile the program. That means changing the value of NumberOfRvaAndSizes will give a slight protection against .NET Reflector decompilation (note: it probably only works against beginners in reverse engineering).
 
tbz7wu2y.png
 
 
Tutorials like this one: http://www.codingvision.net/security/c-prevent-reflector-from-decompiling
tell you to change the value at a certain offset. This is wrong, because the NumberOfRvaAndSizes is not always in the same file offset.
 
In order to get the correct file offset, you need to look at the file with a Hex editor or a PE viewing software. You need the following information: The offset of the Optional Header and the Magic Number.
 
The Magic Number is the first value in the Optional Header and tells you if the file is a PE32 or a PE32+ file. The value 0x10b is a PE32 (32-bit address space), the value 0x20b is a PE32+ (64-bit address space).
 
If your PE viewing software doesn't show the file offset of the Optional Header you can get it as follows (this is the most complicated part):
 
1. Get the offset of the signature 'PE\0\0'. You can look into the hex editor and search for the string or you can look into offset 0x3c where the next two bytes are the offset to the PE signature.
 
2. Now that you have the offset add (decimal) 24 to it. That is the beginning of the Optional Header. If you don't have a PE viewer read the Magic Number at this offset to determine whether it is a PE32 or PE32+. If you have a PE32 add 92, if you have a PE32+ add 108. The resulting value is the file offset to the NumberOfRvaAndSizes.
 
So in short:
 
PE\0\0 offset + 24 = offset for Magic Number
 
For PE32:
PE\0\0 offset + 24 + 92 = offset for NumberOfRvaAndSizes
 
For PE32+:
PE\0\0 offset + 24 + 108 = offset for NumberOfRvaAndSizes
 
This number is probably 0x10 or decimal 16.
Now use your hex editor, navigate there and change the number to e.g. 9. Save your file and run it to see if it still works.
Then try to open it in .NET Reflector. 
 
A program to spare your time
 
Of course this manual stuff is annoying if you have to do it more than one time. So here is also a small Python (2.7) script that does it for you:
 
Code: Python
  1. # copyright @ deque 2014
  2. # patches a .net PE file to protect against .net reflector
  3. # WARNING: this may corrupt your file, make a copy before execution
  4. import sys
  5. def unpack(byte):
  6. return sum([
  7. ord(b) << (8 * i) for i, b in enumerate(byte)
  8. ])
  9. if len(sys.argv) == 1:
  10. print >> sys.stderr, "No input file given!"
  11. else:
  12. myfile = sys.argv[1]
  13. with open(myfile, "r+") as f:
  14. f.seek(0x3c)
  15. peoffset = unpack(f.read(2))
  16. optoffset = peoffset + 24
  17. f.seek(optoffset)
  18. magic = f.read(2)
  19. offset = -1
  20. if magic == '\x0b\x01':
  21. offset = 92 + optoffset
  22. else:
  23. offset = 108 + optoffset
  24. f.seek(offset)
  25. f.write('\x09')
  26. print "Found patch location at:", hex(offset)
  27. print "Your file is now protected!"

0 Comments:

Post a Comment