反汇编引擎

// 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;
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容