在C++中将汇编转换为机器代码
Convert assembly to machine code in 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;
}
我建议同时使用AsmJit和AsmTK。AsmTK是一个新项目,它使用AsmJit作为工具包,并在其上添加其他功能。请注意,目前AsmTK需要asmjit:next分支才能工作,因为这是一个新功能。
这是一个使用 AsmTK 解析某些 asm 的最小示例:
#include <stdio.h>
#include <stdlib.h>
#include <asmtk/asmtk.h>
using namespace asmjit;
using namespace asmtk;
static const char someAsm[] =
"test eax, eaxn"
"jz L1n"
"mov eax, ebxn"
"mov eax, 0xFFFFFFFFn"
"pand mm0, mm1n"
"paddw xmm0, xmm1n"
"vpaddw ymm0, ymm1, ymm7n"
"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 中,使其成为单个函数调用的问题,如果需要,我可以提供帮助。
你应该定义你真正想要的东西:
是否要在运行时生成机器代码?然后使用一些JIT编译库,如libgccjit,libjit,LLVM,GNU Lightning或asmjit。 asmjit
是一个发出x86机器码的库,可能是你需要的。没有绝对需要使用包含汇编程序代码的字符串。
或者您想将一些汇编语法(甚至对于 x86 也有几种汇编语法(转换为目标代码或机器代码?然后,您最好将真正的汇编程序作为外部程序运行。生成的目标代码将包含重定位指令,您需要一些东西来处理这些指令(例如链接器(。
或者,你应该考虑在运行时生成一些 (例如( C 代码, 然后分叉编译, 并在运行时动态加载和使用生成的函数 (例如, 使用 dlopen(3( 和 dlsym
(。看到这里
细节显然是特定于操作系统、ABI 和处理器的。
这是一个可以将一串汇编代码(英特尔或 ARM(转换为其相应字节的项目。
https://github.com/bsmt/Assembler
它是用Objective-C编写的,但源代码就在那里。 我希望这有所帮助。
- 处理小于cpu数据总线的数据类型.(c++转换为机器代码)
- 使用不同的链接器会产生不同的机器代码吗
- objdump 不显示机器代码,但显示 ASM
- 从.o目标文件中提取函数的原始机器代码?
- 我在区分源代码、目标代码、汇编代码和机器代码时感到困惑
- 如果C++编译为机器代码,为什么我们需要安装"运行时"?
- 是否可以执行存储在变量中的机器代码
- "Double or Nothing"赌博机器代码无法超过15组合
- 如何在 c++ 中将机器代码作为函数运行
- 可以从文件执行机器代码吗?
- 如何将x64机器代码写入虚拟内存并在C++中为Windows执行
- 如何将高级/低级编程代码直接转换为机器代码
- (如何)我可以使用LLVM机器代码分析器预测代码片段的运行时间
- 如何使用llvm生成机器代码
- 使用LLVM生成纯机器代码
- 注释会被翻译成机器代码吗?C++
- 如何使用c++执行附加在可执行文件末尾的机器代码
- 如何从机器代码中恢复C++尝试/抛出/捕获块长度和地址
- 是否有编译器可以编译为机器代码的 C C++ C# 编译器
- C++ - 极其奇怪的机器代码行为