簡體   English   中英

在C ++中將程序集轉換為機器代碼

[英]Convert assembly to machine code in C++

我尋找任何lib或函數將一串匯編代碼轉換為機器代碼,如下所示:

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;
} 

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

您想在運行時生成機器代碼嗎? 然后使用一些JIT編譯庫,如libgccjitlibjitLLVMGNU lightningasmjit asmjit是一個發出x86機器代碼的庫,可能就是你需要的。 絕對不需要使用包含匯編代碼的字符串

或者您是否想要將一些匯編語法(甚至對於x86有幾種匯編語法)轉換為對象代碼或機器代碼? 那么你最好將一個真正的匯編程序作為外部程序運行。 生成的目標代碼將包含重定位指令,您需要處理這些指令(例如鏈接器 )。

或者,您應該考慮在運行時生成一些(例如)C代碼,然后分支編譯,並在運行時動態加載和使用結果函數(例如使用dlopen(3)dlsym )。 看到這個

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

我建議同時使用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中,以使其成為單個函數調用的問題,如果需要,我可以提供幫助。

這是一個可以將一串匯編代碼(Intel或ARM)轉換為相應字節的項目。

https://github.com/bsmt/Assembler

它是用Objective-C編寫的,但源代碼就在那里。 我希望這有幫助。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM