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();
writer.codeSection.PUSH_VALUE(0); writer.codeSection.PUSH_STRING("Title here"); writer.codeSection.PUSH_STRING("Hello CodeProject!");
writer.codeSection.PUSH_VALUE(0); writer.codeSection.CALL(Functions.User32_MessageBoxA); AsmNet asmNet = new AsmNet(writer.Generate(true)); Processor Cpu = asmNet.InitializeCPU(); Cpu.RunLoop();
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(":)"));
writer.codeSection.MOV_VARIABLE_VALUE(wsaDataAddr, "HighVersion", (ushort)2);
writer.codeSection.MOV_VARIABLE_VALUE(wsaDataAddr, "Version", (ushort)2);
writer.codeSection.MOV_VARIABLE_VALUE(SockinAddress, "sin_family", (short)ValueCodes.InterNetworkv4);
writer.codeSection.PUSH_VALUE(1337); 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);
writer.codeSection.MOV_ECX(0);
writer.codeSection.CMP(CmpRegisterOpcodes.CMP_ECX_EAX);
writer.codeSection.JNE("failed");
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);
writer.codeSection.MOV_ECX((int)ValueCodes.INVALID_SOCKET);
writer.codeSection.CMP(CmpRegisterOpcodes.CMP_ECX_EAX);
writer.codeSection.JE("failed");
writer.codeSection.MOV(MovRegisterOpcodes.MOV_EBX_EAX);
writer.codeSection.PUSH_VALUE(Marshal.SizeOf(sockaddr));
writer.codeSection.PUSH_VARIABLE(SockinAddress); writer.codeSection.PUSH_EBX(); writer.codeSection.CALL(Functions.ws2_32_bind);
writer.codeSection.PUSH_VALUE((int)100);
writer.codeSection.PUSH_EBX(); writer.codeSection.CALL(Functions.ws2_32_listen);
writer.codeSection.PUSH_VALUE(-11); writer.codeSection.CALL(Functions.Kernel32_GetStdHandle);
writer.codeSection.MOV(MovRegisterOpcodes.MOV_EDX_EAX);
writer.codeSection.CreateLabel("loop");
writer.codeSection.PUSH_VALUE(Marshal.SizeOf(Clientsockaddr));
writer.codeSection.PUSH_VARIABLE(ClientSockinAddress);
writer.codeSection.PUSH_EBX(); writer.codeSection.CALL(Functions.ws2_32_accept);
writer.codeSection.MOV(MovRegisterOpcodes.MOV_EDI_EAX);
writer.codeSection.PUSH_VALUE(0);
writer.codeSection.PUSH_VALUE(0);
writer.codeSection.PUSH_VALUE(20); writer.codeSection.PUSH_STRING("new client accepted\r\n");
writer.codeSection.PUSH_EDX();
writer.codeSection.CALL(Functions.Kernel32_WriteConsoleA);
writer.codeSection.PUSH_VALUE(0);
writer.codeSection.PUSH_VALUE(2);
writer.codeSection.PUSH_VARIABLE(ArrayAddress);
writer.codeSection.PUSH_EDI(); writer.codeSection.CALL(Functions.ws2_32_send);
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