Click here to Skip to main content
Licence CPOL
First Posted 26 Dec 2011
Views 8,278
Downloads 318
Bookmarked 38 times

ASM.Net - x86 Emulation

By | 26 Dec 2011 | Article
ASM.Net a assembly x86 emulator which emulates the language the managed way

Asm.Net is a assembly emulator which is developed in the language C#
Which will also help you develop your programs using the assembler language in the .Net Framework
You will also be able to run programs using Asm.Net for emulating programs

Introduction 

ASM.Net is a assembly x86 emulator which can emulate of course the instructions of assembly

Not all of them yet though, Yet there are a lot of instructions/opcodes which are already working

And may be enough for you to work in it

ASM.Net is also able to convert all the code you wrote to a byte array which ASM.Net can read again to get all his instructions/variables/APIs

So the code you write in ASM.Net is all portable and can be ran at another computer or process or where ever you want  without any problem

But this is not all, the byte array ASM.Net is able to generate is encrypted at every section and compressed to keep away to thiefs for your code 

Using the code

Using the code in ASM.Net is easy but you really need to have some knowledge about assembly to understand any of it, e.g. JMP, JNZ, CALL, XOR and so on... 

With the OpcodeWriter we can write our code, create variables and more 

At the end when we wrote everything what the program needs to do we can also debug it using the ASM.Net debugger and see if everything is working like expected

This is example code how to write our MessageBox

OpcodeWriter writer = new OpcodeWriter();

//Call MessageBox
writer.codeSection.PUSH_VALUE(0); //push a value to stack
writer.codeSection.PUSH_STRING("Title here"); //ASM.Net creates a new variable and pushes the address of it to stack
writer.codeSection.PUSH_STRING("Hello CodeProject!");
writer.codeSection.PUSH_VALUE(0); //push a value to stack
writer.codeSection.CALL(Functions.User32_MessageBoxA); //call our MessageBox
AsmNet asmNet = new AsmNet(writer.Generate(true)); //initialize ASM.Net
Processor Cpu = asmNet.InitializeCPU(); //initialize the CPU to be able to execute our code
Cpu.RunLoop(); //execute the code we wrote

As you can see it's not that much code to show a MessageBox 

And as may have noticed ASM.Net only needs 1 argument which is the byte array I told you about

The OpcodeWriter is able to convert to a byte array using the Generate function

The "True" you see as argument for the Generate function is to check every JUMP address for errors at runtime, This could prevent errors at runtime before you would share it with others

 

But showing a simple MessageBox is not all ASM.Net can do, It can do a lot and a lot more

This is a simple TCP Server 

             OpcodeWriter writer = new OpcodeWriter();

            WSAData wsaData = new WSAData();
            sockaddr_in sockaddr = new sockaddr_in();
            sockaddr_in Clientsockaddr = new sockaddr_in();
            VirtualAddress wsaDataAddr = writer.dataSection.CreateVariable(wsaData);
            VirtualAddress SockinAddress = writer.dataSection.CreateVariable(sockaddr);
            VirtualAddress ClientSockinAddress = writer.dataSection.CreateVariable(Clientsockaddr);
            VirtualAddress ArrayAddress = writer.dataSection.CreateVariable(ASCIIEncoding.ASCII.GetBytes(":)")); //the data we want to send when a client connects

            //socket initialization
            //set the WSADATA settings
            writer.codeSection.MOV_VARIABLE_VALUE(wsaDataAddr, "HighVersion", (ushort)2);
            writer.codeSection.MOV_VARIABLE_VALUE(wsaDataAddr, "Version", (ushort)2);

            //set the sockaddr_in settings, setting the family IPv4
            writer.codeSection.MOV_VARIABLE_VALUE(SockinAddress, "sin_family", (short)ValueCodes.InterNetworkv4);
            //setting port, we need to encode it first...
            writer.codeSection.PUSH_VALUE(1337); //1337=listen port
            writer.codeSection.CALL(Functions.ws2_32_htons);
            writer.codeSection.MOV_VARIABLE_REGISTER(SockinAddress, "sin_port", Register.EAX);

            writer.codeSection.PUSH_VARIABLE(wsaDataAddr);
            writer.codeSection.PUSH_VALUE(36);
            writer.codeSection.CALL(Functions.ws2_32_WSAStartup);

            //started successfully ?
            writer.codeSection.MOV_ECX(0);
            writer.codeSection.CMP(CmpRegisterOpcodes.CMP_ECX_EAX);
            writer.codeSection.JNE("failed");

        //create a socket
            writer.codeSection.PUSH_VALUE(ValueCodes.Tcp, (int)0);
            writer.codeSection.PUSH_VALUE(ValueCodes.Stream, (int)0);
            writer.codeSection.PUSH_VALUE(ValueCodes.InterNetworkv4, (int)0);
            writer.codeSection.CALL(Functions.ws2_32_socket);
                
        //is socket > 0 ?
            writer.codeSection.MOV_ECX((int)ValueCodes.INVALID_SOCKET);
            writer.codeSection.CMP(CmpRegisterOpcodes.CMP_ECX_EAX);
            writer.codeSection.JE("failed");

        //lets move our socket handle to EBX
            writer.codeSection.MOV(MovRegisterOpcodes.MOV_EBX_EAX);

        //lets bind our socket
            writer.codeSection.PUSH_VALUE(Marshal.SizeOf(sockaddr));
            writer.codeSection.PUSH_VARIABLE(SockinAddress); //our sockaddr_in
            writer.codeSection.PUSH_EBX(); //socket handle
            writer.codeSection.CALL(Functions.ws2_32_bind);

            //ok lets listen at a port
            writer.codeSection.PUSH_VALUE((int)100);
            writer.codeSection.PUSH_EBX(); //socket
            writer.codeSection.CALL(Functions.ws2_32_listen);


            //now a infinite loop for accept our connections but lets setup our console
            writer.codeSection.PUSH_VALUE(-11); //STD_OUTPUT_HANDLE
            writer.codeSection.CALL(Functions.Kernel32_GetStdHandle);
            writer.codeSection.MOV(MovRegisterOpcodes.MOV_EDX_EAX);

            writer.codeSection.CreateLabel("loop");
                //lets accept connections
                writer.codeSection.PUSH_VALUE(Marshal.SizeOf(Clientsockaddr));
                writer.codeSection.PUSH_VARIABLE(ClientSockinAddress);
                writer.codeSection.PUSH_EBX(); //server socket
                writer.codeSection.CALL(Functions.ws2_32_accept);
                writer.codeSection.MOV(MovRegisterOpcodes.MOV_EDI_EAX); //set client socket to EDI


                writer.codeSection.PUSH_VALUE(0);
                writer.codeSection.PUSH_VALUE(0);
                writer.codeSection.PUSH_VALUE(20);//char length
                writer.codeSection.PUSH_STRING("new client accepted\r\n");
                writer.codeSection.PUSH_EDX();
                writer.codeSection.CALL(Functions.Kernel32_WriteConsoleA);

                //lets send a packet
                writer.codeSection.PUSH_VALUE(0);
                writer.codeSection.PUSH_VALUE(2);
                writer.codeSection.PUSH_VARIABLE(ArrayAddress);
                writer.codeSection.PUSH_EDI(); //client socket
                writer.codeSection.CALL(Functions.ws2_32_send);

                //close our connection with the client...
                writer.codeSection.PUSH_EDI();
                writer.codeSection.CALL(Functions.ws2_32_closesocket);

            writer.codeSection.JMP("loop");

            writer.codeSection.PUSH_EBX();
            writer.codeSection.CALL(Functions.ws2_32_closesocket);

            writer.codeSection.CreateLabel("failed");
            writer.codeSection.XOR(XorRegisterOpcodes.XOR_ECX_ECX); 

When your reading through the code you will find some JUMPs, Calls etc

But this example is for starting a simple TCP Server which accepts connections and sends a simple smily face ":)" to the one who connects

As you can see here in this image it's waiting for a new connection

Btw don't think it's linux it's just windows 7 with a ubuntu theme

Ok so lets do for example in our command line of windows "telnet 127.0.0.1 1337"

As you can see when I pressed enter in the command line it came up with a smiley face

As you could see the ":)" came up and it worked just fine and something to another console was written that a new connection was accepted (look above for the code in the tcp server)

 

 And to make debugging a little more easier lets see where our JUMPs are going

As you can see the red line shows us instantly where the JUMP is going to

If there are any question I'd love to aswer those

But you also should need to dig in the code a little

There are also events etc you can use

Points of Interest 

While making ASM.Net I needed to laugh a little because I can now write portable code instead of using CodeDom which can give errors because a .dll's is missing what so ever and dumps his code to a temp directory that people can access and steal the code

And ASM.Net can run anywhere but it still needs the ASM.Net library and don't even needs to be dumped to the harddrive if not needed

History

You can checkout our SVN 

CodePlex: http://asmdotnet.codeplex.com/

SVN: https://asmdotnet.svn.codeplex.com/svn 

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

About the Author

Drag0nHunter



Netherlands Netherlands

Member



Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
You must Sign In to use this message board. (secure sign-in)
 
Search this forum  
 FAQ
    Noise  Layout  Per page   
  Refresh
Generalmeta meta Pinmemberdave.dolan4:32 10 Apr '12  
QuestionMessage Automatically Removed Pingroupsghjyuk1:17 7 Jan '12  
GeneralMy vote of 5 PinmemberSteppenwolfe17:09 5 Jan '12  
QuestionNice, but... PinmemberKenBeckett11:09 2 Jan '12  
SuggestionRe: Nice, but... PinmemberPhilip Liebscher15:12 3 Jan '12  
GeneralRe: Nice, but... PinmemberDragonHunt3r2:28 4 Jan '12  
QuestionCool stuff PinmemberHaBiX23:27 26 Dec '11  
QuestionVery cool idea. How's the performance? Pinmemberbuddy.james18:02 26 Dec '11  
AnswerRe: Very cool idea. How's the performance? PinmemberDragonHunt3r12:34 27 Dec '11  
GeneralRe: Very cool idea. How's the performance? PinprotectorMarc Clifton16:39 27 Dec '11  
QuestionAwesome! PinmemberYonghwi Kwon12:37 26 Dec '11  
AnswerRe: Awesome! PinmemberDragonHunt3r12:40 27 Dec '11  
AnswerRe: Awesome! PinmemberDerek Viljoen2:42 1 Feb '12  

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

Permalink | Advertise | Privacy | Mobile
Web01 | 2.5.120517.1 | Last Updated 26 Dec 2011
Article Copyright 2011 by Drag0nHunter
Everything else Copyright © CodeProject, 1999-2012
Terms of Use
Layout: fixed | fluid