Skip to content

Embed URL

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
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;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.