Create a gist now

Instantly share code, notes, and snippets.

Embed
What would you like to do?
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

This comment has been minimized.

Show comment
Hide comment
@liyonghelpme

liyonghelpme Mar 10, 2017

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

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