2 assembler & 2 disassembler

35 篇文章 0 订阅
8 篇文章 0 订阅

反汇编引擎:

BeaEngine

把headers和库文件win32两个文件夹拷贝到项目目录下。

预定义宏、包含头文件和库文件

#include "stdafx.h"
#include <windows.h>
#define BEA_ENGINE_STATIC
#define BEA_USE_STDCALL
#include "headers/BeaEngine.h"
#pragma comment(lib, "Win32/Lib/BeaEngine.lib")
#pragma comment(linker, "/NODEFAULTLIB:\"crt.lib\"")

使用头文件中的结构体:

#pragma pack(1)
typedef struct _Disasm {
   UIntPtr EIP;     // 你要反汇编的机器码的起始地址(数组)
   UInt64 VirtualAddr;  // 输出汇编语句时候指定的地址
   UInt32 SecurityBlock;
   char CompleteInstr[INSTRUCT_LENGTH]; //反汇编结果字符串
   UInt32 Archi;    // 平台,0表示X86_32,1表示X86_64
   UInt64 Options;  //  语法
   INSTRTYPE Instruction;   // 结果  操作码
   ARGTYPE Argument1;   // 结果  操作数1
   ARGTYPE Argument2;   // 结果  操作数2
   ARGTYPE Argument3;   // 结果  操作数3
   PREFIXINFO Prefix;   // 结果  前缀
   UInt32 Reserved_[40];
} DISASM, *PDISASM, *LPDISASM;
#pragma pack()
// 反汇编引擎_beaengine.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include <windows.h>
#define BEA_ENGINE_STATIC
#define BEA_USE_STDCALL
#include "headers/BeaEngine.h"
#pragma comment(lib, "Win32/Lib/BeaEngine.lib")
#pragma comment(linker, "/NODEFAULTLIB:\"crt.lib\"")

int main()
{

	BYTE bTest[] = { 0x68,0x37,0x31,0x40,0x00,0xFF,0x15,0x0C,0x20,0x40,0x00,0x83,0xC4,0x04,0xE8,0x0E,0x00,0x00,0x00,0xE8,0x3E,0x00,0x00,0x00,0xEB,0xE6,0x6A,0x00,0xE8,0x63,0x00,0x00 };
	// 1. 初始化反汇编引擎
	DISASM objDiasm;
	objDiasm.EIP = (UIntPtr)bTest; // 起始地址
	objDiasm.VirtualAddr = (UINT64)0x400000; // 虚拟内存地址(反汇编引擎用于计算地址)
	objDiasm.Archi = 0;                      // AI-X86
	objDiasm.Options = MasmSyntax;           // MASM
	UINT uLen = Disasm(&objDiasm);
	CHAR szOpcode[32] = {};
	PCHAR pOpcode = szOpcode;
	for (UINT i = 0; i < uLen; i++) {
		sprintf_s(&szOpcode[2 * i], 20, "%02x", bTest[i]);
	}
	printf("%s:%s\n", szOpcode, objDiasm.CompleteInstr);
	return 0;
}

Capstone

拷贝include文件夹和库文件capstone_x86.lib到项目文件夹下。

#include "include/capstone.h"

#ifdef _64
#pragma comment(lib,"capstone_x64.lib")
#else
#pragma comment(lib,"capstone_x86.lib")
#endif

定义cs_opt_mem结构体变量,然后依次使用4个函数:

  1. cs_option(),注册堆空间管理组函数
  2. cs_open(),初始化反汇编器句柄,(x86_64架构,32位模式,句柄)
  3. cs_disasm(),反汇编
  4. cs_free(pInsn, count);,释放内存
// 反汇编引擎_capstone.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include "include/capstone.h"

#ifdef _64
#pragma comment(lib,"capstone_x64.lib")
#else
#pragma comment(lib,"capstone_x86.lib")
#endif // _64



int _tmain(int argc, _TCHAR* argv[])
{
	csh handle;
	cs_err err;
	cs_insn* pInsn;
	unsigned int count = 0;
	// 在编译capstone库的时候, 如果选择了用户自定义堆空间管理组(没有定义`CAPSTONE_USE_SYS_DYN_MEM`宏)
	// 则需要调用cs_option函数来设定堆空间管理组函数
	// 然后用结构体来配置回调函数.

	// 定义结构体, 配置堆空间的回调函数
	cs_opt_mem memop;
	memop.calloc = calloc;
	memop.free = free;
	memop.malloc = malloc;
	memop.realloc = realloc;
	memop.vsnprintf = (cs_vsnprintf_t)vsprintf_s;
	// 注册堆空间管理组函数
	cs_option(0, CS_OPT_MEM, (size_t)&memop);


	//初始化反汇编器句柄,(x86_64架构,32位模式,句柄)
	err = cs_open(CS_ARCH_X86, CS_MODE_32, &handle);
	if (err != CS_ERR_OK) {
		printf("初始化反汇编器句柄失败\n");
		return 0;
	}

	unsigned char szOpcode[] = { "\x53\x83\xEC\x18\x83\x3D\x20\x20\x48\x00\x02\x8B\x44\x24\x24" };
	// 开始反汇编.
	count = cs_disasm(handle,/*反汇编器句柄,从cs_open函数得到*/
		szOpcode,/*需要反汇编的opcode的缓冲区首地址*/
		sizeof(szOpcode), /*opcode的字节数*/
		0x401000, /*opcode的所在的内存地址*/
		0, /*需要反汇编的指令条数,如果是0,则反汇编出全部*/
		&pInsn/*反汇编输出*/
	);

	size_t j;
	for (j = 0; j < count; j++) {
		printf("0x%llx:%s %s\n",
			pInsn[j].address, /*指令地址*/
			pInsn[j].mnemonic,/*指令操作码*/
			pInsn[j].op_str/*指令操作数*/
		);
	}

	cs_free(pInsn, count);
	return 0;
}

汇编引擎:

汇编引擎包下基本都有x86和x64两个版本。

XEDParse

拷贝XEDParse文件夹到项目目录中。

//1. 包含头文件和静态库
#include "XEDParse/XEDParse.h"

#ifdef _WIN64
#pragma comment (lib,"XEDParse/x64/XEDParse_x64.lib")
#else
#pragma comment (lib,"XEDParse/x86/XEDParse_x86.lib")
#endif

汇编结构体和api:

XEDPARSE xed = { 0 };
XEDParseAssemble(&xed);
//XEDParse structs
#pragma pack(push,8)
struct XEDPARSE
{
    bool x64; // use 64-bit instructions
    ULONGLONG cip; //instruction pointer (for relative addressing)
    unsigned int dest_size; //destination size (returned by XEDParse)
    CBXEDPARSE_UNKNOWN cbUnknown; //unknown operand callback
    unsigned char dest[XEDPARSE_MAXASMSIZE]; //destination buffer
    char instr[XEDPARSE_MAXBUFSIZE]; //instruction text
    char error[XEDPARSE_MAXBUFSIZE]; //error text (in case of an error)
};
#pragma pack(pop)
  • bool x64; // 是否使用X64指令集
  • ULONGLONG cip; //汇编的起始地址值,你给的
  • unsigned int dest_size; //汇编结果指令字节数
  • unsigned char dest[XEDPARSE_MAXASMSIZE]; //opcode存放地址
  • char instr[XEDPARSE_MAXBUFSIZE]; //汇编语句
#include "stdafx.h"

#include "XEDParse/XEDParse.h"

#ifdef _WIN64
#pragma comment (lib,"XEDParse/x64/XEDParse_x64.lib")
#else
#pragma comment (lib,"XEDParse/x86/XEDParse_x86.lib")
#endif // _WIN64

void printOpcode(const unsigned char* pOpcode, int nSize)
{
	for (int i = 0; i < nSize; ++i) {
		printf("%02X ", pOpcode[i]);
	}
}

int _tmain(int argc, _TCHAR* argv[])
{
	XEDPARSE xed = { 0 };
	
	do {
		printf("地址 指令:");
		
		// 接受指令的地址和汇编指令
		scanf_s("%llx", &xed.cip);
		gets_s(xed.instr, XEDPARSE_MAXBUFSIZE);

		if (XEDPARSE_OK != XEDParseAssemble(&xed)) {
			printf("指令错误:%s\n", xed.error);
			continue;
		}
		printf("%08X : ", (UINT)xed.cip);
		printOpcode(xed.dest, xed.dest_size);
		printf("\n");
	} while (*xed.instr);
	return 0;
}


地址 指令:00401000 push ebp
00401000 : 55

keystone

拷贝keystone文件夹到项目目录中。

包含头文件和静态库:

#include "keystone/keystone.h"
#pragma comment (lib,"keystone/x86/keystone_x86.lib")

使用的结构体是空的,我们需要定义一个指针。

struct ks_struct;
typedef struct ks_struct ks_engine;

四个步骤:

  1. ks_open()
  2. ks_asm()
  3. ks_free()
  4. ks_close()
// 汇编引擎_keystone.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"

//1. 包含头文件
#include "keystone/keystone.h"

//2. 包含静态库
#ifdef _WIN64
#pragma comment (lib,"keystone/x64/keystone_x86.lib")
#else
#pragma comment (lib,"keystone/x86/keystone_x86.lib")
#endif // _WIN64



// 打印opcode
void printOpcode(const unsigned char* pOpcode, int nSize)
{
	for (int i = 0; i < nSize; ++i) {
		printf("%02X ", pOpcode[i]);
	}
}


int _tmain(int argc, _TCHAR* argv[])
{
	ks_engine *pengine = NULL;
	if (KS_ERR_OK != ks_open(KS_ARCH_X86, KS_MODE_32, &pengine)) {
		printf("反汇编引擎初始化失败\n");
		return 0;
	}

	unsigned char* opcode = NULL; // 汇编得到的opcode的缓冲区首地址
	unsigned int nOpcodeSize = 0; // 汇编出来的opcode的字节数

								  // 汇编指令
								  // 可以使用分号,或者换行符将指令分隔开
	char asmCode[] =
	{
		"mov eax,edx;mov eax,1;mov dword ptr ds:[eax],20"
	};

	int nRet = 0; // 保存函数的返回值,用于判断函数是否执行成功
	size_t stat_count = 0; // 保存成功汇编的指令的条数

	nRet = ks_asm(pengine, /* 汇编引擎句柄,通过ks_open函数得到*/
		asmCode, /*要转换的汇编指令*/
		0x401000, /*汇编指令所在的地址*/
		&opcode,/*输出的opcode*/
		&nOpcodeSize,/*输出的opcode的字节数*/
		&stat_count /*输出成功汇编的指令的条数*/
	);

	// 返回值等于-1时反汇编错误
	if (nRet == -1) {
		// 输出错误信息
		// ks_errno 获得错误码
		// ks_strerror 将错误码转换成字符串,并返回这个字符串
		printf("错误信息:%s\n", ks_strerror(ks_errno(pengine)));
		return 0;
	}

	printf("一共转换了%d条指令\n", stat_count);

	// 打印汇编出来的opcode
	printOpcode(opcode, nOpcodeSize);

	// 释放空间
	ks_free(opcode);
	// 关闭句柄
	ks_close(pengine);


	return 0;
}


  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值