2014-10-04 2 views
2

я ищу для любой Lib или функции для того чтобы преобразовать строку ассемблера в машинный код, как следующий:Преобразовать сборки в машинный код в C++

char asmString[] = {"mov eax,13H"}; 
byte[] output; // array of byte 
output = asm2mach(asmString); // {0xB8, 0x13, 0x00, 0x00, 0x00} 

мотивация вводить машинный код для вызова ассемблера функции в программе. Эта инъекция в основном состоит из трех этапов: VirtualAllocEx, WriteProcessMemory и CreateRemoteThread. Вот код:

bool injectAsm(const char* exeName,const byte* code, int size) 
{ 
    LPVOID allocAddr = NULL; 
    HANDLE ThreadProcess = NULL; 
    HANDLE hProcess = OpenProcessEasy(exeName); 

    allocAddr = VirtualAllocEx(hProcess, NULL, size, MEM_COMMIT, PAGE_READWRITE); 
    if(allocAddr){ 
     if(WriteProcessMemory(hProcess, allocAddr, code, size, NULL)) { 
      ThreadProcess = CreateRemoteThread(hProcess, NULL, 0, (LPTHREAD_START_ROUTINE)allocAddr, NULL, 0, NULL); 
      WaitForSingleObject(ThreadProcess, INFINITE); 
      VirtualFreeEx(hProcess,allocAddr, 0, MEM_RELEASE); 
      CloseHandle(ThreadProcess); 
      return true; 
     } 
    } 
    if(allocAddr){ 
     VirtualFreeEx(hProcess, allocAddr, 0, MEM_RELEASE); 
    } 
    return false; 
} 

int main() 
{ 
    byte code[] = {0xB8, 0x10, 0xED, 0x4A, 0x00, 0xFF, 0xD0, 0xC3, 0x90}; 
    injectAsm("game.exe",code,sizeof(code)); 
    system("pause"); 
    return 0; 
} 
+1

У меня нет функции, но .. если вы отправляете запрос на этот сайт с помощью сокета, он может работать, я думаю: https://defuse.ca/online-x86-assembler.htm # дизассемблер. Это сайт, который я использую для преобразования моих OP-кодов в двоичное представление (байты). В противном случае у меня нет идей. Постскриптум 'asm' - зарезервированное ключевое слово. Кроме того, ваш код asm ('mov eax, 0x13') эквивалентен' {0xB8, 0x13, 0x00, 0x00, 0x00}; ' – Brandon

+3

Имейте в виду, что' asm' может быть ключевым словом. –

+0

Брэндон: Я знал этот сайт, но я хочу, чтобы C++ lib конвертировал их во время работы. Даниилу: Да, вы правы! Я изменил его. – James

ответ

4

Вы должны определить, что вы действительно хотите:

Вы хотите генерировать машинный код во время выполнения? Затем используйте библиотеку JIT compilation, такую ​​как libgccjit, libjit, LLVM, GNU lightning, или asmjit. asmjit - это библиотека, испускающая машинный код x86, возможно, что вам нужно. Нет абсолютной необходимости использовать строку , содержащую код ассемблера.

Или вы хотите перевести некоторый синтаксис ассемблера (а также несколько синтаксисов ассемблера даже для x86) на код объекта или машинный код? Тогда вам лучше запустить настоящий ассемблер в качестве внешней программы. Произведенный object code будет содержать директивы relocation, и вам понадобится что-то для их обработки (например, linker).

Альтернативный вариант, вы должны рассмотреть возможность создания некоторого (например,) кода C во время выполнения, а затем для форматирования компиляции и динамической загрузки и использования результирующей функции во время выполнения (например, с помощью dlopen(3) и dlsym). См. this

Данные, очевидно, являются операционной системой, ABI и конкретными процессорами.

2

Вот проект, который может преобразовать строку кода сборки (Intel или ARM) в соответствующие байты.

https://github.com/bsmt/Assembler

Он написан на Objective-C, но источник есть. Надеюсь, это поможет.

+1

Связанный проект должен выполнить сценарий оболочки, для которого необходимо установить сторонний ассемблер для работы. Кроме того, у него, похоже, есть проблемы с ярлыками. – Petr

2

Я бы рекомендовал использовать как AsmJit, так и AsmTK. AsmTK - это новый проект, который использует AsmJit в качестве инструментария и добавляет дополнительные функции поверх него. Обратите внимание, что на данный момент AsmTK требует asmjit: следующая ветвь для работы, так как это новая функциональность.

Это минимальный пример, который использует AsmTK разобрать некоторый ассемблер:

#include <stdio.h> 
#include <stdlib.h> 
#include <asmtk/asmtk.h> 

using namespace asmjit; 
using namespace asmtk; 

static const char someAsm[] = 
    "test eax, eax\n" 
    "jz L1\n" 
    "mov eax, ebx\n" 
    "mov eax, 0xFFFFFFFF\n" 
    "pand mm0, mm1\n" 
    "paddw xmm0, xmm1\n" 
    "vpaddw ymm0, ymm1, ymm7\n" 
    "vaddpd zmm0 {k1}{z}, zmm1, [rax] {1tox}\n" 
    "L1:\n"; 

int main(int argc, char* argv[]) { 
    CodeHolder code; 
    // Here select the target architecture - either X86 or X64. 
    code.init(CodeInfo(Arch::kTypeX64)); 

    X86Assembler a(&code); 
    AsmParser p(&a); 

    Error err = p.parse(someAsm); 
    if (err) { 
    printf("ERROR: %0.8x (%s)\n", err, DebugUtils::errorAsString(err)); 
    return 1; 
    } 

    // The machine-code is now stored in CodeHolder's first section: 
    code.sync(); 
    CodeBuffer& buffer = code.getSection(0)->buffer; 

    // You can do whatever you need with the buffer: 
    uint8_t* data = buffer.data; 
    size_t length = buffer.length; 

    return 0; 
} 

AsmJit использует JitRuntime выделить исполняемые памяти и перенести полученный машинный код в него. Однако диспетчер виртуальной памяти AsmJit может быть создан с помощью hProcess, который может быть вашим дескриптором удаленного процесса, поэтому он также может выделять память этого процесса. Вот небольшой пример того, как это можно сделать:

bool addToRemote(HPROCESS hRemoteProcess, CodeHolder& code) { 
    // VMemMgr is AsmJit's low-level VM manager. 
    VMemMgr vm(hRemoteProcess); 

    // This will tell `vm` to not destroy allocated blocks when it 
    // gets destroyed. 
    vm.setKeepVirtualMemory(true); 

    // Okay, suppose we have the CodeHolder from previous example. 
    size_t codeSize = code.getCodeSize(); 

    // Allocate a permanent memory of `hRemoteProcess`. 
    uint64_t remoteAddr = (uint64_t) 
    vm.alloc(codeSize, VMemMgr::kAllocPermanent); 

    // Temporary buffer for relocation. 
    uint8_t* tmp = ::malloc(code.getCodeSize()); 
    if (!tmp) return false; 

    // First argument is where to relocate the code (it must be 
    // current's process memory), second argument is the base 
    // address of the relocated code - it's the remote process's 
    // memory. We need `tmp` as it will temporarily hold code 
    // that we want to write to the remote process. 
    code.relocate(tmp, remoteAddr); 

    // Now write to the remote process. 
    SIZE_T bytesWritten; 
    BOOL ok = WriteProcessMemory(
    hRemoteProcess, (LPVOID)remoteMem, tmp, codeSize, &bytesWritten); 

    // Release temporary resources. 
    ::free(tmp); 

    // Now the only thing needed is the CreateRemoteThread thingy... 
    return ok; 
} 

Я бы рекомендовал оборачивать такую ​​функциональность в новую RemoteRuntime, чтобы сделать его вопрос о вызове одной функции, я могу помочь с этим, если это необходимо.

Смежные вопросы