Reverse Engineering RET Homepage RET Members Reverse Engineering Projects Reverse Engineering Papers Reversing Challenges Reverser Tools RET Re-Search Engine Reverse Engineering Forum Reverse Engineering Links

Go Back   Reverse Engineering Team Board > Reverse Engineering Board > .NET Reverse Engineering
FAQ Members List Calendar Search Today's Posts Mark Forums Read

Thread Tools Display Modes
Old 07-15-2010, 10:02 PM
TehAvatar TehAvatar is offline
Join Date: Jul 2010
Posts: 17
Default Unknown obfuscator, cant solve myself.

Hi folks,

Once again I turn to the reteam community for some help
I am unable to identify what obfuscator is used with this assembly, ive run NetID with no results. It seems the file is obfuscated - can someone remedy this?

Note that it is a very small file, probably only has one or two methods.

++The resource file seems encrypted
Reply With Quote
Old 07-16-2010, 12:45 AM
bball0002 bball0002 is offline
Senior Member
Join Date: Mar 2009
Posts: 72

Not sure, but it opens in Reflector Pro fine...
Reply With Quote
Old 07-16-2010, 05:54 AM
Kurapica Kurapica is offline
Senior Member
Join Date: May 2006
Location: Archives
Posts: 357

It looks like a custom Obfuscator, but they are using some

smartassembly methods like the

.method public hidebysig static pinvokeimpl("kernel32.dll" lasterr winapi) int32 SetProcessWorkingSetSize(native int , int32 , int32 )cilmanaged preservesig
which used to reduce the used RAM, also the renaming is like SmartAssembly style.

also the strings encryption is the same as in SamrtAssembly.
Life can only be understood backwards but It must be read forwards.

Last edited by Kurapica : 07-16-2010 at 05:57 AM.
Reply With Quote
Old 07-16-2010, 06:50 AM
kao kao is offline
Senior Member
Join Date: Sep 2007
Posts: 184

Haven't seen that protection before but it's boring as only user strings are protected. In total there are 43 strings, it takes 10-15 minutes of work and one ildasm-ilasm cycle to fix that.

Don't ask for somebody else to do your work, think and do it yourself! It's much more satisfying that way.

Just for your information, here are all the strings:
Connected client from 
Client dropped 
Process Exiting
Unloading scripts
Failed to start server
RunWoW server started
Unhandled Warning: 
Unhandled Error: 
Failed to load scripts
Failed to init scripts
Server stopping
HeapBuffes: Allocated {0}, Released {1}, Used {2}
Error at ServerMain: 
Packet not handled for RMSG.
Unhandled realm opcode
Reply With Quote
Old 07-16-2010, 04:35 PM
TehAvatar TehAvatar is offline
Join Date: Jul 2010
Posts: 17

Awesome kao.

I read somewhere on this forum someone said "kao simply knows."

Could you please elaborate on the method you used to get those strings? Im not so much interested in the strings them self as I am interested in the way used to decrypt them.

Take for example this snippet of obfuscated code within that assembly:

public override void SetDefaultValues()
    XmlElement newChild = base.m_document.CreateElement((0x496a994e));
    XmlElement element = base.m_document.CreateElement((0x496a9950));
    element.InnerText = (0x496a9962);
    element = base.m_document.CreateElement((0x496a9978));
    element.InnerText = (0x496a9977);
    element = base.m_document.CreateElement((0x496a9902));
    element.InnerText = (0x496a9911);
    element = base.m_document.CreateElement((0x496a9929));
    element.InnerText = (0x496a993b);
Obviously '0x496a993b' represents some string from the resource file (which is encrypted, and which you quickly decrypted above) but how would I link these references with resource file strings?

Thanks again
Reply With Quote
Old 07-16-2010, 04:48 PM
TehAvatar TehAvatar is offline
Join Date: Jul 2010
Posts: 17

++ Just for the lols:
I figured the strings would be stored in the resource file in the same order their 'references' are allocated. Hehe, seemed my quick-approach is correct:

0x496a9902	VerboseLevel
0x496a9911	3

0x496a9929	Scripts
0x496a993b	./RealmScripts

0x496a994e	RealmListConfig
0x496a9950	Address
0x496a9962	any
0x496a9977	3724
0x496a9978	Port
Reply With Quote
Old 07-16-2010, 04:56 PM
kao kao is offline
Senior Member
Join Date: Sep 2007
Posts: 184

My suggestion - get a better decompiler. I recommend Dis#, it has very nice "Deobfuscate" function.

The code you are looking at should look this:
        public override void SetDefaultValues()
            XmlElement xmlElement2 = m_document.CreateElement(Class7.Method7_1(1231722830));
            XmlElement xmlElement1 = m_document.CreateElement(Class7.Method7_1(1231722832));
            xmlElement1.InnerText = Class7.Method7_1(1231722850);
            xmlElement1 = m_document.CreateElement(Class7.Method7_1(1231722872));
            xmlElement1.InnerText = Class7.Method7_1(1231722871);
            xmlElement1 = m_document.CreateElement(Class7.Method7_1(1231722754));
            xmlElement1.InnerText = Class7.Method7_1(1231722769);
            xmlElement1 = m_document.CreateElement(Class7.Method7_1(1231722793));
            xmlElement1.InnerText = Class7.Method7_1(1231722811);
Notice Class7.Method7_1() that's missing in your code, making it hard to read and understand? That function returns string based on integer number that's passed as argument.

First, I decompiled entire application. Then I took entire Class7 and Class8, the corresponding encrypted resource and all calls and arguments to Class7.Method7_1(), put them in new file and compiled it. When you are reasonably skilled, it takes only few minutes.

What I got is a simple tool that prints all the decrypted strings. Something like this:
Console.WriteLine("{0} : {1}", "1231722830", Class7.Method7_1(1231722830));
Console.WriteLine("{0} : {1}", "1231722832", Class7.Method7_1(1231722832));
Simple, isn't it?

p.s. Strings I posted are intentionally sorted by number. It may or may not be the way they were stored in encrypted resource.
Reply With Quote
Old 07-16-2010, 09:40 PM
TehAvatar TehAvatar is offline
Join Date: Jul 2010
Posts: 17

Awesome! Thanks again for the great tips. The other executable in the project uses the same protection, so I'll try Dis# and your techniques soon.

However!...... I seem to have stumbled upon another problem.

The app I'm trying to decompile runs in a VM, (no problem, was able to dump *all* assemblies with WinDBG with the sos extention. Ive manually decompiled the exe to a state where it is able to compile. At runtime, I get an unable to load assembly message. Further investigation shows me this is what is happening:

        [DllImport("RunServer.IOCP.x86.dll", EntryPoint = "CreateSocket")]
        protected static extern IntPtr CreateSocket_x86(IntPtr completionPort, IntPtr socket, SendCallback sendCallback, ReceiveCallback receiveCallback, IntPtr param, bool useNagle);
        [DllImport("RunServer.IOCP.x86.dll", EntryPoint = "DeleteSocket")]
        protected static extern void DeleteSocket_x86(IntPtr handle);
        [DllImport("RunServer.IOCP.x86.dll", EntryPoint = "EndIOCPThread")]
        private static extern void EndIOCPThread_x86(IntPtr completionPort);
        [DllImport("RunServer.IOCP.x86.dll", EntryPoint = "StartSocket")]
        protected static extern void StartSocket_x86(IntPtr handle);
RunServer.IOCP.x86.dll is a native assembly for handling sockets, so it doesnt show up in !DumpDomain when looking at the assemblies loaded in WinDBG. You can see ModLoad RunServer.IOCP.x86.dll happening when the application starts using this lib but.... seems there is no way for me to get a hold of this dll?

Here comes the bummer: Ive dumped RunServer.IOCP.x86.dll using WinDBG from the ModLoad address..... checking out this library shows all of the exposed functions available (StartSocket,DeleteSocket...etc) but there is no way I can get this lib loaded with DllImport.

Im dumbstruct, why cant I import it?

Heres the dumped native dll:
Reply With Quote
Old 07-17-2010, 12:06 AM
TehAvatar TehAvatar is offline
Join Date: Jul 2010
Posts: 17

++ Here is dumped area from memory from ollydbg
Reply With Quote
Old 07-17-2010, 02:31 AM
kao kao is offline
Senior Member
Join Date: Sep 2007
Posts: 184

You cannot just dump native (x86) DLL from process memory and expect it to work. You need to dump it at an appropriate moment (before any code from this DLL is executed) so that information in the .data segment is intact. Also you need proper import table and relocations.

In your Windbg dump - .data segment is not good, import table is filled in (but probably still ok), relocations are ok.

As a quick hack, you might try to patch your windbg dumped dll like this:
0000D048: 96 40
0000D049: E1 30
0000D04A: 3D 00
0000D04B: E8 10
0000D588: 0F 00
0000D9B0: 48 88
0000D9B1: 16 D5
0000D9B2: 12 00
0000D9B3: 07 10
0000DAA8: DF 55
0000DAA9: E1 79
0000DAAA: 3D 00
0000DAAB: FD 10
0000DAAC: DF 55
0000DAAD: E1 79
0000DAAE: 3D 00
0000DAAF: FD 10
0000DAB0: DF 55
0000DAB1: E1 79
0000DAB2: 3D 00
0000DAB3: FD 10
0000DAB4: DF 55
0000DAB5: E1 79
0000DAB6: 3D 00
0000DAB7: FD 10
0000DAB8: DF 55
0000DAB9: E1 79
0000DABA: 3D 00
0000DABB: FD 10
0000DABC: DF 55
0000DABD: E1 79
0000DABE: 3D 00
0000DABF: FD 10
0000DAC0: DF 55
0000DAC1: E1 79
0000DAC2: 3D 00
0000DAC3: FD 10
0000DAC4: DF 55
0000DAC5: E1 79
0000DAC6: 3D 00
0000DAC7: FD 10
0000DAC8: DF 55
0000DAC9: E1 79
0000DACA: 3D 00
0000DACB: FD 10
0000DACC: DF 55
0000DACD: E1 79
0000DACE: 3D 00
0000DACF: FD 10
I cannot guarantee that all problems will be fixed by that. Properly unpacked dll would be much better solution.

There are plenty of tutorials about unpacking but I cannot recommend any particular one. Google around.
Reply With Quote

Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Forum Jump

Powered by vBulletin® Version 3.6.4
Copyright ©2000 - 2023, Jelsoft Enterprises Ltd.