2014-10-04 54 views
2

我尋求任何lib或起作用以彙編代碼的字符串轉換成機器代碼, 如下所示:轉換組件在C機器碼++

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

的動機是爲了注入機代碼來調用ASM功能在程序中。該注入主要有3個步驟: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#disassembly這是我用來將我的OP代碼轉換爲二進制表示(字節)的站點。否則,我沒有想法。附: 'asm'是一個保留關鍵字。另外,你的asm('mov eax,0x13')代碼相當於'{0xB8,0x13,0x00,0x00,0x00};' – Brandon 2014-10-04 07:00:09

+3

請記住'asm'可能是一個關鍵字。 – 2014-10-04 07:04:22

+0

布蘭登:我知道這個網站,但我想要一些C++ lib在運行時轉換它們。對丹尼爾:是的,你是對的!我改變了它。 – James 2014-10-04 07:10:00

回答

4

你應該定義你真正想要的:

你想在運行時生成機器碼?然後使用一些JIT compilation庫,如libgccjit,libjit,LLVM,GNU lightningasmjitasmjit是一個發佈x86機器碼的庫,可能是您需要的。並非絕對需要使用包含彙編代碼的字符串

或者您是否想要將某些彙編語法(即使是x86的幾種彙編語法)轉換爲目標代碼或機器代碼?那麼你會更好地運行一個真正的彙編程序作爲外部程序。生產的object code將包含relocation指令,您需要一些操作來處理這些指令(例如linker)。另外,您應該考慮在運行時生成一些(例如)C代碼,然後派生一個編譯,並在運行時動態加載並使用生成的函數(例如使用dlopen(3)dlsym)。請參閱this

詳細信息顯然是操作系統,ABI和處理器特定的。

2

這是一個項目,可以將彙編代碼(英特爾或ARM)的字符串轉換爲相應的字節。

https://github.com/bsmt/Assembler

這是寫在Objective-C,但來源是存在的。我希望這有幫助。

+1

鏈接的項目需要執行一個shell腳本,這需要安裝第三方彙編程序才能工作。此外,它似乎有一些與標籤有關的問題。 – Petr 2016-08-13 20:04:30

2

我會推薦使用AsmJitAsmTK。 AsmTK是一個新的項目,它使用AsmJit作爲工具包,並在其上增加額外的功能。請注意,目前AsmTK需要asmjit:下一個分支才能工作,因爲這是一項新功能。

這是一個使用AsmTK解析一些ASM最小例如:

#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,使之成爲一個函數調用的問題,我可以在需要時提供幫助的。