Capstone反汇编引擎数据类型及API剖析及示例(二) | 申博官网
登录
  • 欢迎进入申博官网!
  • 如果您觉得申博官网对你有帮助,那么赶紧使用Ctrl+D 收藏申博官网并分享出去吧
  • 这里是申博官方网!
  • 申博官网是菲律宾sunbet官网品牌平台!
  • 申博开户专业品牌平台!

Capstone反汇编引擎数据类型及API剖析及示例(二)

申博_安全防护 申博 133次浏览 已收录 0个评论

Capstone反汇编引擎数据范例及API剖析及示例(二)

Capstone反汇编引擎数据范例及API剖析及示例(一)
上篇剖析了Capstone开放的数据范例,下面就来正式看看API吧
官方开放的API只要二十个摆布,但为了能写的更易懂,我将连系实例,分多篇写。
API中作者将capstone缩写为cs,下面我也用这类体式格局形貌

API剖析

cs_malloc_t

void* (CAPSTONE_API *cs_malloc_t)(size_t size);

cs的动态内存分派,用于

struct cs_opt_mem {
    cs_malloc_t malloc;
    cs_calloc_t calloc;
    cs_realloc_t realloc;
    cs_free_t free;
    cs_vsnprintf_t vsnprintf;
} cs_opt_mem;

cs_malloc_t定义于capstone.lib和capstone.dll的cs.c中,
Capstone反汇编引擎数据类型及API剖析及示例(二)

在用户形式下,cs_mem_malloc默许运用体系malloc

Windows driver形式下,cs_malloc_t cs_mem_malloc = cs_winkernel_malloc;
cs_winkernel_malloc定义于\capstone-4.0.1\windows\winkernel_mm.c,

完成代码

void * CAPSTONE_API cs_winkernel_malloc(size_t size)
{
    // 长度不能分派为0
    NT_ASSERT(size);

    // FP; NonPagedPool用于支撑 Windows 7 
#pragma prefast(suppress : 30030)       // 分派可执行的POOL_TYPE内存
    size_t number_of_bytes = 0;
    CS_WINKERNEL_MEMBLOCK *block = NULL;
    // 特定的值能形成溢出
    // 假如value中的和超越或低于范例容量,函数将返回NULL。
    if (!NT_SUCCESS(RtlSizeTAdd(size, sizeof(CS_WINKERNEL_MEMBLOCK), &number_of_bytes))) {
        return NULL;
    }
    block = (CS_WINKERNEL_MEMBLOCK *)ExAllocatePoolWithTag(
            NonPagedPool, number_of_bytes, CS_WINKERNEL_POOL_TAG);
    if (!block) {
        return NULL;
    }
    block->size = size;

    return block->data;
}

OSX kernel形式下,cs_malloc_t cs_mem_malloc = kern_os_malloc;,这里暂且不讨论。

cs_calloc_t

void* (CAPSTONE_API *cs_calloc_t)(size_t nmemb, size_t size);

cs请求内存并初始化
用于struct cs_opt_mem,定义于cs.c
用户形式: cs_calloc_t cs_mem_calloc = calloc;,运用体系calloc
Windows driver形式: cs_calloc_t cs_mem_calloc = cs_winkernel_calloc;
完成代码

void * CAPSTONE_API cs_winkernel_calloc(size_t n, size_t size)
{
    size_t total = n * size;

    void *new_ptr = cs_winkernel_malloc(total);
    if (!new_ptr) {
        return NULL;
    }

    return RtlFillMemory(new_ptr, total, 0);
}

OSX kernel形式: cs_calloc_t cs_mem_calloc = cs_kern_os_calloc;
Capstone反汇编引擎数据类型及API剖析及示例(二)
直接挪用kern_os_malloc了

cs_realloc_t

void* (CAPSTONE_API *cs_realloc_t)(void *ptr, size_t size);

cs从新分派内存
用于struct cs_opt_mem,定义于cs.c
用户形式: cs_realloc_t cs_mem_realloc = realloc;,挪用体系realloc
Windows driver形式: cs_realloc_t cs_mem_realloc = cs_winkernel_realloc;

完成代码,能够看出是应用cs_winkernel_malloc从新请求

void * CAPSTONE_API cs_winkernel_realloc(void *ptr, size_t size)
{
    void *new_ptr = NULL;
    size_t current_size = 0;
    size_t smaller_size = 0;

    if (!ptr) {
        return cs_winkernel_malloc(size);
    }

    new_ptr = cs_winkernel_malloc(size);
    if (!new_ptr) {
        return NULL;
    }

    current_size = CONTAINING_RECORD(ptr, CS_WINKERNEL_MEMBLOCK, data)->size;
    smaller_size = (current_size < size) ? current_size : size;
    RtlCopyMemory(new_ptr, ptr, smaller_size);
    cs_winkernel_free(ptr);

    return new_ptr;
}

OSX kernel形式: cs_realloc_t cs_mem_realloc = kern_os_realloc;

cs_free_t

typedef void (CAPSTONE_API *cs_free_t)(void *ptr);

cs开释内存
用于struct cs_opt_mem,定义于cs.c
用户形式: cs_free_t cs_mem_free = free;,挪用体系free
Windows driver形式: cs_free_t cs_mem_free = cs_winkernel_free;

完成代码

void CAPSTONE_API cs_winkernel_free(void *ptr)
{
    if (ptr) {
        ExFreePoolWithTag(CONTAINING_RECORD(ptr, CS_WINKERNEL_MEMBLOCK, data), CS_WINKERNEL_POOL_TAG);
    }
}

OSX kernel形式: cs_free_t cs_mem_free = kern_os_free;

cs_vsnprintf_t

int (CAPSTONE_API *cs_vsnprintf_t)(char *str, size_t size, const char *format, va_list ap);

按size大小输出到字符串str中

用户形式:
Capstone反汇编引擎数据类型及API剖析及示例(二)
值得注意的是,假如体系为wince,将运用_vsnprintf函数
vsnprintf ()和_vsnprintf()关于驱动程序都是可用的,然则它们有一些差别。
在须要返回值和设置空终止符时应运用vsnprintf()

vsnprintf定义在stdio.h
Capstone反汇编引擎数据类型及API剖析及示例(二)

Windows Kernel Exploit (六)

0x00:前言 这是 Windows kernel exploit 系列的第六部分,前一篇我们讲了空指针解引用,这一篇我们讲内核未初始化栈利用,这篇虽然是内核栈的利用,与前面不同的是,这里需要引入一个新利用手法 => 栈喷射,需要你对内核栈和用户栈理解的比较深入,看此文章之前你需要有以下准备: Windows 7 x86 sp1虚拟机 配置好windbg等调试工具,建议配合VirtualKD使用 HEVD+OSR

Windows driver形式: cs_vsnprintf_t cs_vsnprintf = cs_winkernel_vsnprintf;

代码完成

int CAPSTONE_API cs_winkernel_vsnprintf(char *buffer, size_t count, const char *format, va_list argptr)
{
    int result = _vsnprintf(buffer, count, format, argptr);

        // _vsnprintf()在字符串被截断时返回-1,在全部字符串被存储但“buffer”末端没有“\0”时返回“count”。在这两种情况下,都须要手动增加空终止符。
    if (result == -1 || (size_t)result == count) {
        buffer[count - 1] = '\0';
    }

    if (result == -1) {
        // 在返回-1时,函数必需猎取并返回一些原本要写入的字符。因而,经由过程重试运用temp buffer举行雷同的转换,这个缓冲区就可能足够大来完成格式化,而且取得许多本应写入的字符。
        char* tmp = cs_winkernel_malloc(0x1000);
        if (!tmp) {
            return result;
        }

        result = _vsnprintf(tmp, 0x1000, format, argptr);
        NT_ASSERT(result != -1);
        cs_winkernel_free(tmp);
    }

    return result;
}

OSX kernel形式: cs_vsnprintf_t cs_vsnprintf = vsnprintf;,运用默许vsnprintf

cs_skipdata_cb_t

size_t (CAPSTONE_API cs_skipdata_cb_t)(const uint8_t code, size_t code_size, size_t offset, void *user_data);

SKIPDATA选项的用户自定义回调函数。

code:包括要剖析的代码的输入缓冲区。和传递给cs_disasm()的缓冲区雷同。
code_size:上面的code缓冲区的大小(以字节为单元)。
offset:上面提到的输入缓冲区code中当前搜检字节的位置。
user_data:用户数据经由过程cs_opt_skipdata构造中的@user_data字段传递给cs_option()。
return:返回要跳过的字节数,或许0示意马上住手反汇编。

cs_skipdata_cb_t在struct cs_opt_skipdata中挪用,下面来看一个例子
剖析写在解释中

#include <stdio.h>
#include <stdlib.h>

#include "platform.h"
#include "capstone.h"

struct platform {
    cs_arch arch;
    cs_mode mode;
    unsigned char* code;
    size_t size;
    const char* comment;
    cs_opt_type opt_type;
    cs_opt_value opt_value;
    cs_opt_type opt_skipdata;
    size_t skipdata;
};

static void print_string_hex(unsigned char* str, size_t len)  //输出机器码
{
    unsigned char* c;

    printf("Code: ");
    for (c = str; c < str + len; c++) {
        printf("0x%02x ", *c & 0xff);
    }
    printf("\n");
}

static void test()
{

#define X86_CODE32 "\x8d\x4c\x32\x08\x01\xd8\x81\xc6\x34\x12\x00\x00\x00\x91\x92"  //测试用机器码

#define RANDOM_CODE "\xed\x00\x00\x00\x00\x1a\x5a\x0f\x1f\xff\xc2\x09\x80\x00\x00\x00\x07\xf7\xeb\x2a\xff\xff\x7f\x57\xe3\x01\xff\xff\x7f\x57\xeb\x00\xf0\x00\x00\x24\xb2\x4f\x00\x78"

    cs_opt_skipdata skipdata = {
        // 把默许 "data" 形貌符从 ".byte" 重命名为 "db"
        "db",
    };

    struct platform platforms[2] = {         //以默许形貌符和自定义形貌符两种体式格局竖立一个数组
        {
            CS_ARCH_X86,
            CS_MODE_32,
            (unsigned char*)X86_CODE32,
            sizeof(X86_CODE32) - 1,
            "X86 32 (Intel syntax) - Skip data",
        },
        {
            CS_ARCH_X86,
            CS_MODE_32,
            (unsigned char*)X86_CODE32,
            sizeof(X86_CODE32) - 1,
            "X86 32 (Intel syntax) - Skip data with custom mnemonic",
            CS_OPT_INVALID,
            CS_OPT_OFF,
            CS_OPT_SKIPDATA_SETUP,
            (size_t)& skipdata,
        },

    };

    csh handle;   //竖立capstone句柄
    uint64_t address = 0x1000;  //设置肇端地点
    cs_insn* insn;  //详细信息构造体
    cs_err err;  //毛病罗列
    int i;
    size_t count;  //胜利反汇编行数

    for (i = 0; i < sizeof(platforms) / sizeof(platforms[0]); i++) {
        printf("****************\n");
        printf("Platform: %s\n", platforms[i].comment);
        err = cs_open(platforms[i].arch, platforms[i].mode, &handle);  //毛病搜检
        if (err) {
            printf("Failed on cs_open() with error returned: %u\n", err);
            abort();
        }

        if (platforms[i].opt_type)
            cs_option(handle, platforms[i].opt_type, platforms[i].opt_value);

        // 翻开SKIPDATA 形式
        cs_option(handle, CS_OPT_SKIPDATA, CS_OPT_ON);
        cs_option(handle, platforms[i].opt_skipdata, platforms[i].skipdata);

        count = cs_disasm(handle, platforms[i].code, platforms[i].size, address, 0, &insn);
        if (count) {
            size_t j;

            print_string_hex(platforms[i].code, platforms[i].size);
            printf("Disasm:\n");

            for (j = 0; j < count; j++) {  //输出汇编
                printf("0x%" PRIx64 ":\t%s\t\t%s\n",
                    insn[j].address, insn[j].mnemonic, insn[j].op_str);
            }

            // 末了一行代码后打印偏移
            printf("0x%" PRIx64 ":\n", insn[j - 1].address + insn[j - 1].size);

            // 开释cs_disasm()请求的内存
            cs_free(insn, count);
        }
        else {
            printf("****************\n");
            printf("Platform: %s\n", platforms[i].comment);
            print_string_hex(platforms[i].code, platforms[i].size);
            printf("ERROR: Failed to disasm given code!\n");
            abort();
        }

        printf("\n");

        cs_close(&handle);
    }
}

int main()
{
    test();

    return 0;
}

运转效果以下,能够看出,默许的 .byte数据范例被改成db形貌符
Capstone反汇编引擎数据类型及API剖析及示例(二)

cs_version

unsigned int CAPSTONE_API cs_version(int *major, int *minor);

用来输出capstone版本号
参数
major: API主版本
minor: API次版本
return: 返回主次版本的16进制,如4.0版本返回 0x0400

经由过程剖析源码发明
Capstone反汇编引擎数据类型及API剖析及示例(二)

Capstone反汇编引擎数据类型及API剖析及示例(二)
该版本定义于cs.c中,编译后不可变动,不接受自定义版本

示例1:

#include <stdio.h>
#include <stdlib.h>

#include "platform.h"
#include "capstone.h"

static int test()
{
    return cs_version(NULL, NULL);  
}

int main()
{
    int version = test();
    printf("%X", version);
    return 0;
}

输出
Capstone反汇编引擎数据类型及API剖析及示例(二)

示例2,强行修正版本:

#include <stdio.h>
#include <stdlib.h>

#include "platform.h"
#include "capstone.h"

static int test()
{
    int ma[] = { 5 };
    int mi[] = { 6 };

    return cs_version(ma, mi);  
}

int main()
{
    int version = test();
    printf("%X", version);
    return 0;
}

输出:
Capstone反汇编引擎数据类型及API剖析及示例(二)
能够看到并不能转变

cs_support

bool CAPSTONE_API cs_support(int query);

用来搜检capstone库是不是支撑参数输入的架构或处于某编译选项
经由过程检察源码得知,共有四种查询参数

bool CAPSTONE_API cs_support(int query)
{
    if (query == CS_ARCH_ALL)
        return all_arch == ((1 << CS_ARCH_ARM) | (1 << CS_ARCH_ARM64) |
                (1 << CS_ARCH_MIPS) | (1 << CS_ARCH_X86) |
                (1 << CS_ARCH_PPC) | (1 << CS_ARCH_SPARC) |
                (1 << CS_ARCH_SYSZ) | (1 << CS_ARCH_XCORE) |
                (1 << CS_ARCH_M68K) | (1 << CS_ARCH_TMS320C64X) |
                (1 << CS_ARCH_M680X) | (1 << CS_ARCH_EVM));

    if ((unsigned int)query < CS_ARCH_MAX)
        return all_arch & (1 << query);

    if (query == CS_SUPPORT_DIET) {
#ifdef CAPSTONE_DIET
        return true;
#else
        return false;
#endif
    }

    if (query == CS_SUPPORT_X86_REDUCE) {
#if defined(CAPSTONE_HAS_X86) && defined(CAPSTONE_X86_REDUCE)
        return true;
#else
        return false;
#endif
    }

    // unsupported query
    return false;
}

示例1(CS_ARCH_ALL,搜检是不是支撑一切架构):
Capstone反汇编引擎数据类型及API剖析及示例(二)

示例2(CSARCH*,搜检是不是支撑指定架构)
Capstone反汇编引擎数据类型及API剖析及示例(二)

示例3(搜检是不是处于DIET编译形式):
Capstone反汇编引擎数据类型及API剖析及示例(二)

示例4(搜检是不是处于X86_REDUCE编译形式):
Capstone反汇编引擎数据类型及API剖析及示例(二)


申博|网络安全巴士站声明:该文看法仅代表作者自己,与本平台无关。版权所有丨如未注明 , 均为原创丨本网站采用BY-NC-SA协议进行授权
转载请注明Capstone反汇编引擎数据类型及API剖析及示例(二)
喜欢 (0)
[]
分享 (0)
发表我的评论
取消评论
表情 贴图 加粗 删除线 居中 斜体 签到

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址