// XEDParse.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
//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 // _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[])
{
XEDPARSE xed = { 0 };
printf("地址:");
// 接受生成opcode的的初始地址
scanf_s( "%x" , &xed.cip );
getchar( );
do
{
// 接收指令
printf( "指令:" );
gets_s(xed.instr , XEDPARSE_MAXBUFSIZE);
// xed.cip, 汇编带有跳转偏移的指令时,需要配置这个字段
if(XEDPARSE_OK != XEDParseAssemble(&xed))
{
printf("指令错误:%s\n" , xed.error);
continue;
}
// 打印汇编指令所生成的opcode
printf("%08X : " , xed.cip );
printOpcode(xed.dest , xed.dest_size);
printf("\n");
// 将地址增加到下一条指令的首地址
xed.cip += xed.dest_size;
} while(*xed.instr);
return 0;
}
====================
// BeaEngine反汇编引擎使用示例.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
// 添加以下宏
#define BEA_ENGINE_STATIC
#define BEA_USE_STDCALL
// 1. 包含BegEngine的头文件
// Win32 是32位平台的程序可以使用的头文件
// Win64 是64位平台的程序可以使用的头文件
#ifndef _WIN64
#include "BeaEngine_4.1/Win32/headers/BeaEngine.h"
//2. 包含对应版本的静态库
#pragma comment (lib , "BeaEngine_4.1/Win32/Win32/Lib/BeaEngine.lib")
#else
#include "BeaEngine_4.1/Win64/headers/BeaEngine.h"
//2. 包含对应版本的静态库
#pragma comment (lib , "BeaEngine_4.1/Win64/Win64/Lib/BeaEngine.lib")
#endif
// 防止编译错误。
#pragma comment(linker, "/NODEFAULTLIB:\"crt.lib\"")
// 打印opcode
// const unsigned char* pOpcode : opcode 的缓冲区首地址
// nSize : opcdoe的字节数
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[])
{
DISASM disAsm = { 0 };
/*
typedef struct _Disasm
{
UIntPtr EIP; // opcode所在的地址
UInt64 VirtualAddr; // 保存opcode的缓冲区的首地址
UInt32 SecurityBlock;
char CompleteInstr[ INSTRUCT_LENGTH ]; // 转换出来的汇编指令
UInt32 Archi; // 处理器的架构,可以是32位CPU,或是64位的CPU
UInt64 Options;
INSTRTYPE Instruction;
ARGTYPE Argument1;
ARGTYPE Argument2;
ARGTYPE Argument3;
PREFIXINFO Prefix;
UInt32 Reserved_[ 40 ];
} DISASM , *PDISASM , *LPDISASM;
*/
unsigned char opcode[] =
{
"\x68\xE5\x30\x40\x00\x68\xE2\x30\x40\x00\xFF\x15\x08\x20\x40\x00\x83\xC4\x08\x68\x1A\x30\x40\x00\x68\xE2\x30\x40\x00\xFF\x15\x00\x20\x40\x00\x83\xC4\x08"
};
// 3. 配置结构体,初始化反汇编的opcode
disAsm.EIP = (UIntPtr)opcode; // 保存opcode的缓冲区首地址
disAsm.VirtualAddr = 0x401080 ; // opcode 指令的地址
disAsm.Archi = 0; // 0 => 32 , 1 => 64
disAsm.Options = 0x000; // masm 汇编指令格式
int nOpcodeSize = sizeof(opcode); // opcode的字节数
int nCount = 0;// 用于记录在循环当中,反汇编了多少个字节
int nLen = 0 ; // 用于记录当前的汇编指令的字节数
// 调用Disasm()进行反汇编,
while(nCount < nOpcodeSize)
{
nLen = Disasm(&disAsm); // 每次只反汇编一条汇编指令, 并且返回当前得到的汇编指令的长度
unsigned int uAddr = disAsm.VirtualAddr;
printf("%08X | " , uAddr); // 打印地址
printOpcode((const unsigned char*)disAsm.EIP , nLen); // 打印opcode
printf(" | %s\n" , disAsm.CompleteInstr); // 打印反汇编指令
nCount += nLen; // 累加已经反汇编的字节数
disAsm.EIP += nLen; // 定位到下一条汇编指令
disAsm.VirtualAddr += nLen; // 设置到下一条汇编指令的地址
}
return 0;
}
==============================
// capstoneTest.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include "capstone/include/capstone.h"
//1. 包含头文件
#ifdef _WIN64 // 64位平台编译器会自动定义这个宏
#pragma
comment(lib,"capstone/lib/capstone_x64.lib")
#else
#pragma comment(lib,"capstone/lib/capstone_x86.lib")
#endif // _64
int _tmain(int argc , _TCHAR* argv[])
{
csh handle; // 反汇编引擎句柄
cs_err err; // 错误信息
cs_insn* pInsn; // 保存反汇编得到的指令的缓冲区首地址
unsigned int count = 0; // 保存得到的反汇编的指令条数
//初始化反汇编器句柄,(x86_64架构,32位模式,句柄)
err = cs_open(CS_ARCH_X86 , /*x86指令集*/
CS_MODE_32 , /*使用32位模式解析opcode*/
&handle /*输出的反汇编句柄*/
);
if(err != CS_ERR_OK)
{
printf("初始化反汇编器句柄失败:%s\n",cs_strerror(err));
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%08X | %s %s\n" ,
(int)pInsn[ j ].address , /*指令地址*/
pInsn[ j ].mnemonic ,/*指令操作码*/
pInsn[ j ].op_str/*指令操作数*/
);
}
// 释放保存指令的空间
cs_free(pInsn , count);
// 关闭句柄
cs_close(&handle);
return 0;
}
===========================
// Keystone汇编引擎的使用示例.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
//1. 包含头文件
#include "keystone/keystone.h"
//2. 包含静态库
#pragma comment (lib,"keystone/x86/keystone_x86.lib")
// 打印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,ebx;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;
}