Search code examples
c++cassemblyjit

jit assembler in C++, using C functions


I'm developing a simple JIT Assembly system in C++, but, I whant to call C functions in this jit system, so, what I have thinked... I need the pointer of the command... but, I don't know how I can get this...

That is my code

#include <cstdio>
#include <vector>
#include <windows.h>

int Execute(std::vector<unsigned char> code)
{
    int eaxRegister;

    unsigned char* func = (unsigned char*)VirtualAlloc( 0, code.size() + 1, 0x1000, 0x40 );

    memcpy( func, code.data(), code.size() );
    func[code.size()] = 0xC3; // add the ret to the final of code final

    CallWindowProc( (WNDPROC)func, 0, 0, 0, 0 );

    _asm mov eaxRegister, eax;

    VirtualFree( func, code.size() + 1, 0x4000 );

    return eaxRegister;
}

int main()
{
    std::vector<unsigned char> code;

    //mov eax, 10
    code.push_back( 0xc7 );
    code.push_back( 0xc0 );
    code.push_back( 0xa );
    code.push_back( 0x0 );
    code.push_back( 0x0 );
    code.push_back( 0x0 );

    //mov ecx, 10
    code.push_back( 0xc7 );
    code.push_back( 0xc1 );
    code.push_back( 0xa );
    code.push_back( 0x0 );
    code.push_back( 0x0 );
    code.push_back( 0x0 );

    //add eax, ecx
    code.push_back( 0x3 );
    code.push_back( 0xc1 );

    // push MESSAGE
    const char* ohi = "HI";
    code.push_back( 0x69 );
    code.push_back( *ohi );

    // call prinf ?????
    code.push_back( 0xe8 );
    code.push_back( 0xfff/* offset of printf */ ) ;

    // add esp, 4
    code.push_back( 0x83 );
    code.push_back( 0xc4 );
    code.push_back( 0x04 );
    code.push_back( 0x0 );
    code.push_back( 0x0 );
    code.push_back( 0x0 );

    int exec = Execute( code );
    printf("SUM = %d", exec);

    return 0;
}

So, my problem is, how I can get the offset of printf command to use in JIT, or, how I can use the C function using the JIT ???

Thanks Alexandre


Solution

  • I have solved the questio, I passed to use the reinterpret_cast

    here my solution:

    #include <cstdio>
    #include <vector>
    #include <windows.h>
    
    using namespace std;
    
    class Buffer: public vector<unsigned char>
    {
    public:
        void push_dword(DWORD dw)
        {
            push_back(dw);
            push_back(dw >> 8);
            push_back(dw >> 16);
            push_back(dw >> 24);
        }
    
        void push_ptr(const void *p)
        {
            push_dword(reinterpret_cast<DWORD>(p));
        }
    
        int Execute()
        {
            char *func = reinterpret_cast<char *>(VirtualAlloc(
                0, size() + 1, MEM_COMMIT, PAGE_EXECUTE_READWRITE ));
    
            memcpy( func, data(), size() );
            func[size()] = 0xC3; // add the ret to the final of code final
    
            int ret = (*reinterpret_cast<int(*)()>(func))();
    
            VirtualFree( func, 0, MEM_RELEASE );
    
            return ret;
        }
    };
    
    int main()
    {
        Buffer code;
    
        // push MESSAGE
        const char* ohi = "HI\n";
        code.push_back( 0x68 );
        code.push_ptr( ohi );
    
        // mov eax, printf
        code.push_back( 0xb8 );
        code.push_ptr( reinterpret_cast<void *>(&printf) );
    
        // call eax
        code.push_back( 0xff );
        code.push_back( 0xd0 );
    
        // add esp, 4
        code.push_back( 0x83 );
        code.push_back( 0xc4 );
        code.push_back( 0x04 );
    
        int exec = code.Execute();
        printf("SUM = %d\n", exec);
    
        return 0;
    }