简体   繁体   English

在C ++中将程序集转换为机器代码

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

I seek for any lib or function to convert a string of assembly code to machine code, like the following: 我寻找任何lib或函数将一串汇编代码转换为机器代码,如下所示:

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

The motivation is to inject machine code to call asm function in the program. 动机是注入机器代码来调用程序中的asm函数。 This injection mainly has 3 steps: VirtualAllocEx, WriteProcessMemory and CreateRemoteThread. 这个注入主要有3个步骤:VirtualAllocEx,WriteProcessMemory和CreateRemoteThread。 Here are the code: 这是代码:

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

You should define what you really want: 你应该定义你真正想要的东西:

Do you want to generate machine code at runtime? 您想在运行时生成机器代码吗? Then use some JIT compilation library like libgccjit , libjit , LLVM , GNU lightning , or asmjit . 然后使用一些JIT编译库,如libgccjitlibjitLLVMGNU lightningasmjit asmjit is a library emitting x86 machine code, probably what you need. asmjit是一个发出x86机器代码的库,可能就是你需要的。 There is no absolute need to use a string containing assembler code. 绝对不需要使用包含汇编代码的字符串

Or do you want to translate some assembler syntax (and there are several assembler syntaxes even for x86) to object code or machine code? 或者您是否想要将一些汇编语法(甚至对于x86有几种汇编语法)转换为对象代码或机器代码? Then you'll better run a real assembler as an external program. 那么你最好将一个真正的汇编程序作为外部程序运行。 The produced object code will contain relocation directives, and you'll need something to handle these (eg a linker ). 生成的目标代码将包含重定位指令,您需要处理这些指令(例如链接器 )。

Alternative, you should consider generating some (eg) C code at runtime, then forking a compilation, and dynamically loading and using the resulting function at runtime (eg with dlopen(3) and dlsym ). 或者,您应该考虑在运行时生成一些(例如)C代码,然后分支编译,并在运行时动态加载和使用结果函数(例如使用dlopen(3)dlsym )。 See this 看到这个

Details are obviously operating system, ABI , and processor specific. 详细信息显然是操作系统, ABI和处理器特定的。

I would recommend using both AsmJit and AsmTK . 我建议同时使用AsmJitAsmTK AsmTK is a new project that uses AsmJit as a toolkit and adds additional functionality on top of it. AsmTK是一个新项目,它使用AsmJit作为工具包,并在其上添加了额外的功能。 NOTE that at the moment AsmTK requies asmjit:next branch to work, as this is a new functionality. 注意,目前AsmTK需要asmjit:下一个分支工作,因为这是一个新功能。

This is a minimal example that uses AsmTK to parse some asm: 这是使用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 uses JitRuntime to allocate executable memory and to relocate the resulting machine code into it. AsmJit使用JitRuntime来分配可执行内存并将生成的机器代码重新定位到其中。 However, AsmJit's virtual memory allocator can be created with hProcess , which could be your remote process handle, so it can also allocate memory of that process. 但是,AsmJit的虚拟内存分配器可以使用hProcess创建,它可以是您的远程进程句柄,因此它也可以分配该进程的内存。 Here is a small example of how it could be done: 这是一个如何完成的小例子:

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

I would recommend wrapping such functionality into a new RemoteRuntime to make it a matter of a single function call, I can help with that if needed. 我建议将这些功能包装到一个新的RemoteRuntime中,以使其成为单个函数调用的问题,如果需要,我可以提供帮助。

Here is a project that can convert a string of assembly code (Intel or ARM) into its corresponding bytes. 这是一个可以将一串汇编代码(Intel或ARM)转换为相应字节的项目。

https://github.com/bsmt/Assembler https://github.com/bsmt/Assembler

It's written in Objective-C, but the source is there. 它是用Objective-C编写的,但源代码就在那里。 I hope this helps. 我希望这有帮助。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM