Skip to content

Instantly share code, notes, and snippets.

@Overv
Created April 21, 2012 20:31
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Overv/2439475 to your computer and use it in GitHub Desktop.
Save Overv/2439475 to your computer and use it in GitHub Desktop.
A simple runtime assembler written in C++
#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] );
}
#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 );
};
#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;
}
@liyonghelpme
Copy link

clear and simple show how to assembler in windows platform, thanks

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment