Created
April 21, 2012 20:31
-
-
Save Overv/2439475 to your computer and use it in GitHub Desktop.
A simple runtime assembler written in C++
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include "Assembler.hpp" | |
Assembler::Assembler() | |
{ | |
} | |
int Assembler::Run() | |
{ | |
if ( code.size() == 0 ) return -1; | |
int reg_eax; | |
unsigned char* func = (unsigned char*)VirtualAlloc( 0, code.size() + 1, 0x1000, 0x40 ); | |
memcpy( func, code.data(), code.size() ); | |
func[code.size()] = 0xC3; | |
CallWindowProc( (WNDPROC)func, 0, 0, 0, 0 ); | |
_asm mov reg_eax, eax; | |
VirtualFree( func, code.size() + 1, 0x4000 ); | |
return reg_eax; | |
} | |
void Assembler::Clear() | |
{ | |
code.clear(); | |
} | |
void Assembler::INop() | |
{ | |
code.push_back( 0x90 ); | |
} | |
void Assembler::IMov32( Register dst, int value ) | |
{ | |
code.push_back( 0xC7 ); | |
code.push_back( 0xC0 | dst ); | |
PushInt32( value ); | |
} | |
void Assembler::IMov32( Register dst, Register src ) | |
{ | |
code.push_back( 0x8B ); | |
code.push_back( 0xC0 | ( dst << 3 ) | src ); | |
} | |
void Assembler::IInc32( Register reg ) | |
{ | |
code.push_back( 0xFF ); | |
code.push_back( 0xC0 | reg ); | |
} | |
void Assembler::IAdd32( Register dst, Register src ) | |
{ | |
code.push_back( 0x03 ); | |
code.push_back( 0xC0 | ( dst << 3 ) | src ); | |
} | |
void Assembler::IPush32( int value ) | |
{ | |
code.push_back( 0x68 ); | |
PushInt32( value ); | |
} | |
void Assembler::IPop32( Register reg ) | |
{ | |
code.push_back( 0x8F ); | |
code.push_back( 0xC0 | reg ); | |
} | |
void Assembler::PushInt32( int i ) | |
{ | |
char b[4]; | |
memcpy( b, &i, 4 ); | |
code.push_back( b[0] ); | |
code.push_back( b[1] ); | |
code.push_back( b[2] ); | |
code.push_back( b[3] ); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <Windows.h> | |
#include <vector> | |
// TODO: | |
// Preserve registers besides EAX (with naked function call?) | |
// Allow addressing beyond just registers (e.g. addresses in registers) | |
// Available registers for addressing | |
enum Register { | |
REG_EAX = 0, | |
REG_ECX = 1 | |
}; | |
// Class that allows programs to conveniently construct machine code at runtime | |
class Assembler | |
{ | |
public: | |
Assembler(); | |
int Run(); | |
void Clear(); | |
// Instructions | |
void INop(); | |
void IMov32( Register dst, int value ); | |
void IMov32( Register dst, Register src ); | |
void IInc32( Register reg ); | |
void IAdd32( Register dst, Register src ); | |
void IPush32( int value ); | |
void IPop32( Register reg ); | |
private: | |
std::vector<unsigned char> code; | |
void PushInt32( const int i ); | |
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <cstdio> | |
#include "Assembler.hpp" | |
int main() | |
{ | |
Assembler as; | |
as.IMov32( REG_EAX, 2 ); | |
as.IMov32( REG_ECX, 4 ); | |
as.IAdd32( REG_EAX, REG_ECX ); | |
int eax = as.Run(); | |
printf( "EAX contains %d\n", eax ); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
clear and simple show how to assembler in windows platform, thanks