反汇编引擎有很多,这个引擎没有Dll,是纯静态链接库,适合r3-r0环境,你可以将其编译为DLL文件,驱动强制注入到游戏进程中,让其快速反汇编,读取出反汇编代码并保存为txt文本,本地分析。
地址:https://github.com/BeaEngine/beaengine
BeaEngine 反汇编特定字符串
#include <stdio.h> #include <Windows.h> #define BEA_ENGINE_STATIC #define BEA_USE_STDCALL
extern "C" { #include "G:/beaengine/x64/BeaEngine.h" #pragma comment(lib, "G:/BeaEngine/x64/lib_static/BeaEngine.lib") }
void DisassembleCode(char *start_offset, int size) { DISASM Disasm_Info; int len; char *end_offset = (char*)start_offset + size; (void)memset(&Disasm_Info, 0, sizeof(DISASM)); Disasm_Info.EIP = (UInt64)start_offset; Disasm_Info.Archi = 1; Disasm_Info.Options = MasmSyntax; while (!Disasm_Info.Error) { Disasm_Info.SecurityBlock = (UInt64)end_offset - Disasm_Info.EIP; if (Disasm_Info.SecurityBlock <= 0) break; len = Disasm(&Disasm_Info); switch (Disasm_Info.Error) { case OUT_OF_BLOCK: break; case UNKNOWN_OPCODE: printf("%s \n", &Disasm_Info.CompleteInstr); Disasm_Info.EIP += 1; Disasm_Info.Error = 0; break; default: printf("%s \n", &Disasm_Info.CompleteInstr); Disasm_Info.EIP += len; } } }
int main(int argc,char *argv) { char *buffer = "\x55\x8b\xec\x81\xec\x24\x03\x00\x00\x6a\x17"; DisassembleCode(buffer, 11); BYTE bTest[] = { 0x68, 0x37, 0x31, 0x40, 0x00, 0xFF, 0x15, 0x0C, 0x20, 0x40 }; DisassembleCode(buffer, 14);
system("pause"); return 0; }
|

反汇编字节数组
void DisassembleCodeByte(BYTE *ptr,int len) { DISASM Disasm_Info; char *end_offset = (char*)ptr + 10; (void)memset(&Disasm_Info, 0, sizeof(DISASM)); Disasm_Info.EIP = (UInt64)ptr; Disasm_Info.Archi = 1; Disasm_Info.Options = MasmSyntax;
while (!Disasm_Info.Error) { Disasm_Info.SecurityBlock = (UInt64)end_offset - Disasm_Info.EIP; if (Disasm_Info.SecurityBlock <= 0) break; len = Disasm(&Disasm_Info); switch (Disasm_Info.Error) { case OUT_OF_BLOCK: break; case UNKNOWN_OPCODE: Disasm_Info.EIP += 1; Disasm_Info.Error = 0; break; default: printf("%s \n", &Disasm_Info.CompleteInstr); Disasm_Info.EIP += len; } } }
int main(int argc, char *argv) { BYTE bTest[] = { 0x55, 0x8b, 0xec, 0x81, 0xec, 0x24, 0x03, 0x00, 0x00, 0x6a, 0x17 }; DisassembleCodeByte(bTest,10); system("pause"); return 0; }
|
反汇编时,显示虚拟地址
void DisassembleCodeInstr(char *start_offset, char *end_offset, int virtual_address) { DISASM Disasm_Info; int len; (void)memset(&Disasm_Info, 0, sizeof(DISASM)); Disasm_Info.EIP = (UINT64)start_offset; Disasm_Info.VirtualAddr = (UINT64)virtual_address; Disasm_Info.Archi = 0; Disasm_Info.Options = MasmSyntax;
while (!Disasm_Info.Error) { Disasm_Info.SecurityBlock = (UInt64)end_offset - Disasm_Info.EIP; if (Disasm_Info.SecurityBlock <= 0) break; len = Disasm(&Disasm_Info); switch (Disasm_Info.Error) { case OUT_OF_BLOCK: break; case UNKNOWN_OPCODE: Disasm_Info.EIP += 1; Disasm_Info.VirtualAddr += 1; break; default: printf("%.16llx > %s\n", Disasm_Info.VirtualAddr,&Disasm_Info.CompleteInstr); Disasm_Info.EIP += len; Disasm_Info.VirtualAddr += len; } } }
int main(int argc,char *argv) {
void *pBuffer = malloc(200); memcpy(pBuffer, main, 200); DisassembleCodeInstr((char *)pBuffer, (char *)pBuffer + 200, 0x401000); system("pause"); return 0; }
|

检查EAX寄存器状态: 如何只检索修改寄存器eax的指令,也就是说,当我们的寄存器REG0零号,发生写入请求时,将自动获取到此处的汇编代码位置。
void DisassembleCodeInstr(char *start_offset, char *end_offset, int virtual_address) { DISASM Disasm_Info; int len; (void)memset(&Disasm_Info, 0, sizeof(DISASM)); Disasm_Info.EIP = (UINT64)start_offset; Disasm_Info.VirtualAddr = (UINT64)virtual_address; Disasm_Info.Archi = 0; Disasm_Info.Options = MasmSyntax;
while (!Disasm_Info.Error) { Disasm_Info.SecurityBlock = (UInt64)end_offset - Disasm_Info.EIP; if (Disasm_Info.SecurityBlock <= 0) break; len = Disasm(&Disasm_Info); switch (Disasm_Info.Error) { case OUT_OF_BLOCK: break; case UNKNOWN_OPCODE: Disasm_Info.EIP += 1; Disasm_Info.VirtualAddr += 1; break; default: if ( ((Disasm_Info.Operand1.AccessMode == WRITE) && (Disasm_Info.Operand1.Registers.gpr & REG0)) || ((Disasm_Info.Operand2.AccessMode == WRITE) && (Disasm_Info.Operand2.Registers.gpr & REG0)) || (Disasm_Info.Instruction.ImplicitModifiedRegs.gpr & REG0) ) { printf("%.16llx > %s \n", Disasm_Info.VirtualAddr, &Disasm_Info.CompleteInstr); } Disasm_Info.EIP += len; Disasm_Info.VirtualAddr += len; } } }
|

解码第三方可执行文件:
void DisassembleCodeRange(unsigned char *StartCodeSection, unsigned char *EndCodeSection, int(Virtual_Address)) { DISASM Disasm_Info; int len; memset(&Disasm_Info, 0, sizeof(DISASM)); Disasm_Info.EIP = (UInt64)StartCodeSection; Disasm_Info.VirtualAddr = (UInt64)Virtual_Address; Disasm_Info.Archi = 0; Disasm_Info.Options = MasmSyntax;
while (!Disasm_Info.Error) { Disasm_Info.SecurityBlock = (int)EndCodeSection - Disasm_Info.EIP; len = Disasm(&Disasm_Info); if (Disasm_Info.Error >= 0) { printf("%.16llx > %s \n", Disasm_Info.VirtualAddr, &Disasm_Info.CompleteInstr); Disasm_Info.EIP += len; Disasm_Info.VirtualAddr += len; } } }
int main(int argc, char *argv) { void *uBuffer; FILE *fp = fopen("c://main.exe", "rb+"); fseek(fp, 0, SEEK_END);
DWORD FileSize = ftell(fp); rewind(fp);
uBuffer = malloc(FileSize); memset(uBuffer, 0, sizeof(uBuffer)); fread(uBuffer, 1, FileSize, fp); fclose(fp);
DisassembleCodeRange((unsigned char*)uBuffer + 1025, (unsigned char*)uBuffer + 1099, 0x401000); system("pause"); return 0; }
|

XEDPARSE 汇编引擎: 将汇编代码汇编为机器码,keystone 汇编引擎也可,https://www.keystone-engine.org/download
#include <stdio.h> #include <Windows.h> #define BEA_ENGINE_STATIC #define BEA_USE_STDCALL
extern "C" { #include "G:/XEDParse/XEDParse.h" #pragma comment(lib, "G:/XEDParse/XEDParse_x86.lib") } void printOpcode(const unsigned char* pOpcode, int nSize) { for (int i = 0; i < nSize; ++i) { printf("%02X ", pOpcode[i]); } }
int main(int argc, char *argv) { XEDPARSE xed = { 0 };
xed.x64 = TRUE; scanf_s("%llx", &xed.cip);
gets_s(xed.instr, XEDPARSE_MAXBUFSIZE); if (XEDPARSE_OK != XEDParseAssemble(&xed)) { printf("指令错误: %s\n", xed.error); }
printf("%s : ", xed.instr); printOpcode(xed.dest, xed.dest_size); system("pause"); return 0; }
|

一次汇编多条指令
#include <stdio.h> #include <Windows.h> #define BEA_ENGINE_STATIC #define BEA_USE_STDCALL
extern "C" { #include "G:/XEDParse/XEDParse.h" #pragma comment(lib, "G:/XEDParse/XEDParse_x86.lib") } void printOpcode(const unsigned char* pOpcode, int nSize) { for (int i = 0; i < nSize; ++i) { printf("%02X ", pOpcode[i]); } printf("\n"); }
int main(int argc, char *argv) { XEDPARSE xed = { 0 };
xed.x64 = FALSE; char *abc[] = { "xor eax,eax", "xor ebx,ebx", "push eax", "push ebx", "mov ecx,3" };
for (int x = 0; x < 5; x++) { strcpy(xed.instr, abc[x]); if (XEDPARSE_OK != XEDParseAssemble(&xed)) { printf("指令错误: %s\n", xed.error); }
printf("%s : ", xed.instr); printOpcode(xed.dest, xed.dest_size); }
system("pause"); return 0; }
|

汇编引擎实现转ShellCode:
#include <stdio.h> #include <Windows.h>
extern "C" { #include "G:/XEDParse/XEDParse.h" #pragma comment(lib, "G:/XEDParse/XEDParse_x86.lib") }
int main(int argc, char *argv) {
XEDPARSE xed = { 0 }; xed.x64 = FALSE;
unsigned char *p; p = (unsigned char *)malloc(256);
char *OpCode[15] = { "push ebp", "push ebp", "xor eax,eax", "mov eax,1", "endp" };
for (int x = 0; x < sizeof(OpCode) / sizeof(OpCode[0]); x++) { if (strcmp(OpCode[x], "endp") == 0) break;
strcpy(xed.instr, OpCode[x]); if (XEDPARSE_OK != XEDParseAssemble(&xed)) break;
for (int y = 0; y < xed.dest_size; y++) { p[y] = xed.dest[y]; } }
system("pause"); return 0; }
|