相比于直接fuzzing大型程序本身,针对程序的某一特定功能写wrapper后再fuzzing则要高效的多。网上搜了下,仅有两篇关于foxit reader的wrapper文章,一个用python,另外一个用C++,而且针对的foxit reader版本也比较旧。本篇的目的通过分析C++的wrapper原理,来写出最新版foxit reader(Version:  9.1.0.5096)的ConvertToPDF功能的wrapper。

  首先看下ConvertToPDF_x86.dll插件的反汇编部分

  

  刚开始分配0x2760h大小的内存,然后可以看到

  .text:10015BC7                 mov     ecx, eax
  .text:10015BC9                 call    sub_100150C0

  从这两句可以猜测ConvertToPDF_x86.dll插件中存在虚函数,因为ecx中存储有类实例的this指针,它作为隐藏的第一个参数传递给sub_100150C0。具体原理可参考http://www.openrce.org/articles/full_view/23。然后继续跟进sub_100150C0函数,如下

  

  根据这段代码可以确定esi中存储有虚函数表的首地址,虚函数表的具体函数如下:

  

  ConvertToPDF_x86.dll插件的主要构成函数如上图,我们只需函数之间的确定执行流程、每个函数的主要参数内容及个数即可完成wrapper。

  主要的函数流程依次为

  ConvertToPDF_x86!CreateFXURLToHtml+0x450

  ConvertToPDF_x86!CreateFXURLToHtml+0xc90

  ConvertToPDF_x86!CreateFXPDFConvertor+0x90

  参数个数的确定,因为函数的调用约定遵循thiscall,所以每次调用完函数后,由被调用函数自动清除函数参数,具体代码为ret xx

  

64dd020c  0000000a
::x86> bp ConvertToPDF_x86!CreateFXURLToHtml+0x450
::x86> g
Breakpoint hit
ConvertToPDF_x86!CreateFXURLToHtml+0x450:
64a73f10 push ebp
::x86> uf ConvertToPDF_x86!CreateFXURLToHtml+0x450
ConvertToPDF_x86!CreateFXURLToHtml+0x450:
64a73f10 push ebp
64a73f11 8bec mov ebp,esp
64a73f13 6aff push 0FFFFFFFFh
64a73f15 68a804dc64 push offset ConvertToPDF_x86!ConnectedPDF::ConnectedPDFSDK::FCP_SendEmailNotification+0x2cc28 (64dc04a8)
64a73f1a 64a100000000 mov eax,dword ptr fs:[00000000h]
64a73f20 push eax
64a73f21 83ec14 sub esp,14h
64a73f24 push ebx

。。。。。。。。。。。。。。。。。。 

ConvertToPDF_x86!CreateFXURLToHtml+0xb70:
64a74630 33c0 xor eax,eax
64a74632 8b4df4 mov ecx,dword ptr [ebp-0Ch]
64a74635 64890d00000000 mov dword ptr fs:[],ecx
64a7463c pop ecx
64a7463d 5f pop edi
64a7463e 5e pop esi
64a7463f 5b pop ebx
64a74640 8be5 mov esp,ebp
64a74642 5d pop ebp
64a74643 c20400 ret 4          //参数个数为1

  参数内容为0x2

据此可以确定另外两个函数的参数个数和内容。

网上参考的的wrapper的具体代码内容如下

/*
foxit-fuzz.cpp - simple console wrapper for ConvertToPDF_x86.dll
@richinseattle / rjohnson@moflow.org NOTES: Must install the foxit pdf printer globally
Harness targets foxit 9.0 API by default
Can target 7.3.4 if FOXIT_734 is defined and ConvertToPDF_x86.734.dll is in path afl-fuzz.exe -i %INPUT_DIR% -o foxit_out -D %DynamoRIO_ROOT%\bin32 -t 20000 -- -coverage_module ConvertToPDF.dll -target_module foxit-fuzz.exe -target_method convert_to_pdf -nargs 2 -fuzz_iterations 5000 -- %CD%\foxit-fuzz.exe @@ NUL
*/ #include <Windows.h>
#include <String.h>
#include <iostream>
using namespace std; typedef void * (__stdcall *CreateFXPDFConvertor_t)();
typedef int(__thiscall *InitLocale_t)(void *_this, int, wchar_t * lc_str);
typedef int(__thiscall *InitPrinter_t)(void* _this, wchar_t *printer_name);
typedef int(__thiscall *InitPdfConverter_t)(void* _this, int mode);
#ifdef FOXIT_734
typedef int(__thiscall *ConvertToPdf_t)(void* _this, wchar_t *convert_buf, int p2, int p3);
#else
typedef int(__thiscall *ConvertToPdf_t)(void* _this, wchar_t *convert_buf, int p2, int p3, int p4, int p5, int p6, int p7, int p8);
#endif typedef struct ConverterFuncTable_t
{
ConvertToPdf_t ConvertToPdf;
InitPdfConverter_t InitPdfConverter;
InitPrinter_t InitPrinter;
//InitLocale_t InitLocale; } ConverterFuncTable; typedef struct ConverterClass_t
{
ConverterFuncTable_t *vfp_table;
} ConverterClass; #ifdef FOXIT_734
char *target_library = "ConvertToPDF_x86.734.dll";
#else
char *target_library = "ConvertToPDF_x86.dll";
#endif
char *target_function = "CreateFXPDFConvertor"; wchar_t * printer_name = L"Foxit Reader PDF Printer"; ConverterClass *pdfconverter = NULL; int init_target_library()
{
int retVal = ; CreateFXPDFConvertor_t CreateFXPDFConvertor = (CreateFXPDFConvertor_t)GetProcAddress(LoadLibraryA(target_library), target_function); // create an instance of CreateFXPDFConvertor
pdfconverter = (ConverterClass *)CreateFXPDFConvertor();
ConverterFuncTable *vfp_table = pdfconverter->vfp_table; cout << "Function table: " << endl;
cout << "CreateFXPDFConvertor: " << hex << CreateFXPDFConvertor << endl;
cout << "InitPdfConverter: " << hex << vfp_table->InitPdfConverter << " CreateFXPDFConvertor+0x" << hex << (unsigned long)vfp_table->InitPdfConverter - (unsigned long)CreateFXPDFConvertor << endl;
cout << "InitPrinter: " << hex << vfp_table->InitPrinter << " CreateFXPDFConvertor+0x" << hex << (unsigned long)vfp_table->InitPrinter - (unsigned long)CreateFXPDFConvertor << endl;
cout << "ConvertToPdf: " << hex << vfp_table->ConvertToPdf << " CreateFXPDFConvertor+0x" << hex << (unsigned long)vfp_table->ConvertToPdf - (unsigned long)CreateFXPDFConvertor << endl << endl; // init converter
retVal = vfp_table->InitPdfConverter(pdfconverter, );
if (retVal)
cout << "Error: InitPdfConverter(): " << retVal << endl; // init printer device
retVal = vfp_table->InitPrinter(pdfconverter, printer_name);
if (retVal)
cout << "Error: InitPrinter(): " << retVal << endl; return retVal;
} extern "C" __declspec(dllexport) int wmain(int argc, wchar_t *argv[]);
extern "C" __declspec(dllexport) int convert_to_pdf(ConvertToPdf_t convert, wchar_t * converter_buf); int convert_to_pdf(ConvertToPdf_t convert, wchar_t * converter_buf)
{
#ifdef FOXIT_734
return convert(pdfconverter, converter_buf, , );
#else
return convert(pdfconverter, converter_buf, , , , , , , );
#endif
} int wmain(int argc, wchar_t *argv[])
{
int retVal = ; int converter_buf_count = ;
int converter_buf_size = ;
wchar_t *converter_buf = NULL; wchar_t *input_path = NULL;
wchar_t *output_path = L"nul"; #ifdef FOXIT_734
cout << "foxit-fuzz (target v7.3.4) - rjohnson@moflow.org" << endl << endl;
#else
cout << "foxit-fuzz (target v9.0) - rjohnson@moflow.org" << endl << endl;
#endif if (argc < )
{
wcout << "usage: " << argv[] << " <input> [output]" << endl;
return -;
} if (GetFileAttributesW(argv[]) == -)
{
cout << "error: input file path" << endl;
return -;
}
input_path = argv[]; if (argc == )
output_path = argv[]; // setup buffer for converting PDF
converter_buf_count = 0x1000;
converter_buf_size = converter_buf_count * sizeof(wchar_t);
converter_buf = (wchar_t *)calloc(converter_buf_count, sizeof(wchar_t)); wcsncpy_s(converter_buf, converter_buf_count, input_path, wcslen(input_path));
wcsncpy_s(converter_buf + (0x208 / sizeof(wchar_t)), converter_buf_count - (0x208 / sizeof(wchar_t)), output_path, wcslen(output_path)); // create pdfconverter class and initialize library
if (init_target_library())
{
cout << "Error intializing target library" << endl;
return -;
} // execute wrapper for fuzzing
retVal = convert_to_pdf(pdfconverter->vfp_table->ConvertToPdf, converter_buf);
free(converter_buf); if (retVal)
{
cout << "Error: ConvertToPdf(): " << retVal << endl;
return -;
} return ;
}

  重点说明的代码为

  wcsncpy_s(converter_buf + (0x208 / sizeof(wchar_t)), converter_buf_count - (0x208 / sizeof(wchar_t)), output_path, wcslen(output_path));

  其中0x208表示input_path与output_path的间隔距离。

  其实不用更改上述的任何代码,直接编译即可使用

  用winafl时注意命令行要改为

  afl-fuzz.exe -i %INPUT_DIR% -o foxit_out -D %DynamoRIO_ROOT%\bin32 -t 20000 -- -coverage_module ConvertToPDF.dll -coverage_module foxit-fuzz.exe -target_module foxit-fuzz.exe -target_method convert_to_pdf -nargs 2 -fuzz_iterations 5000 -- %CD%\foxit-fuzz.exe @@ NUL

  否则报错,运行结果如下图所示:

  跑了三天,一个crash都没有,,,,,,,估计已经被很多人跑了,fuzz好难

试写foxit reader的ConvertToPDF功能的wrapper的更多相关文章

  1. Foxit Reader(福昕PDF阅读器) v4.3.1.218 绿色专业版

    软件名称:Foxit Reader(福昕PDF阅读器) v4.3.1.218 绿色专业版 软件语言: 简体中文 授权方式: 免费软件 运行环境: Win 32位/64位 软件大小: 4.40MB 图片 ...

  2. 假如现在有一堆长度大于3小于9的电话号码,用座机呼叫,如果出现这样的号码【123和12345】那么12345将永远不会被拨出,因为拨到123的时候电话已经呼出了,试写一个函数输出所有不能被呼出的电话号码(java实现)

    解题: 假如现在有一堆长度大于3小于9的电话号码,用座机呼叫,如果出现这样的号码[123和12345]那么12345将永远不会被拨出,因为拨到123的时候电话已经呼出了,试写一个函数输出所有不能被呼出 ...

  3. 写一个方法完成如下功能,判断从文本框textbox1输入的一个字符,如果是数字则求该数字的阶乘,如果是小写字条,则转换为大写,大写字符不变,结果在文本框textbox2中显示

    窗体设计: 代码: using System; using System.Collections.Generic; using System.ComponentModel; using System. ...

  4. Ubuntu中sublime和Foxit Reader不能使用中文输入法解决方案

    虽然Ubuntu下面很多软件同windows下一样,但是经常会出现各种各样的小问题,其中最让人头疼的是软件中的输入法问题. sublime作为一个跨平台的编辑软件,可以支持win,linux和mac系 ...

  5. MATLAB 在同一个m文件中写多个独立的功能函数

    MATLAB 在同一个m文件中写多个独立的功能函数,从而实现在外部可以直接调用这个文件中的某一个函数. 鉴于MATLAB的函数文件的函数名与文件名要一样,就需要有一个统一的接口来涵盖这些功能函数. 例 ...

  6. 怎样手写实现 new 命令的功能

    实现new命令的功能, 首先需要知道new命令都做了些什么: 第一步: 创建一个空对象, 作为实例对象的容器; 第二步: 将空对象的prototype指向构造函数的prototype; 第三步: 将空 ...

  7. 给Adobe Reader添加书签功能

    Adobe Acrobat Professional和Adobe Reader都是Adobe公司的产品.前者用来编辑制作PDF文档,后者只能用来阅读PDF.令人郁闷的是Adobe Reader中虽然有 ...

  8. 自写图片遮罩层放大功能jquery插件源代码,photobox.js 1.0版,不兼容IE6

    阿嚏~~~ 话说本屌丝没啥开发插件的经验,可是天公不作美,公司须要让我自己开发个图片放大的插件 但公司老大的话,宛如吾皇之圣旨,微臣必当肝脑涂地,莫敢不从啊~~~ 于是乎,作为一个超级小白,本人仅仅能 ...

  9. 写个发邮件的功能php的(全代码)

    ---恢复内容开始--- 正好做了个项目,需要在线留言,一般在线留言发邮件是很常见的方式,一开始从网上搜了很久都没有很全的,也有全一点的,但是也不能用,运行不成功,下面给大家分享一下运行成功了的全部代 ...

随机推荐

  1. 猪懂傻改之《powershell 代码规范》

    猪懂傻改之<powershell 代码规范> 脚本程序员或许都经历过这样的场景:接手别人的代码时,因为没有注释,变量名五花八门,模块之间逻辑关系如麻,弄得满头雾水,一脸茫然,痛定思痛之后不 ...

  2. 18.Canny边缘检测

    Canny边缘检测算法以Canny的名字命名,其中Canny的目标是找到一个最优的边缘检测算法,其有三种衡量标准: 低错误率:标识出尽可能多的实际边缘,同时尽可能的减少噪声产生的误报 高定位性:标识出 ...

  3. pytest自动化3:fixture之conftest.py实现setup

    出处:https://www.cnblogs.com/yoyoketang/p/9390073.html 前言: 前面一篇讲到用例加setup和teardown可以实现在测试用例之前或之后加入一些操作 ...

  4. [Kafka] [All about it]

    Overview 设计目标: 以O(1) 常数级时间复杂度的访问性能,提供消息持久化能力. 高吞吐率. 支持 kafka server 间的消息分区,及分布式消费,同时保证每个partition内部的 ...

  5. 不会点git真不行啊.

    基本使用: // 进入项目根目录, git init // 接管你的项目文件夹, git status // 查看状态. 绿色已接管,红色未管理 git add . // 添加管理当前目录所有文件及子 ...

  6. spring cloud config git库文件搜索顺序

    spring.cloud.config.server.git.uri只配置到仓库那一层就行了,需要访问仓库的子目录的话就配置spring.cloud.config.server.git.searchP ...

  7. 开始 第一个自己的python爬虫程序 爬磁力链

    不能一事无成,这么久了学python还是吊着,要落地,落在博客园好了,好像公司也只能上博客园了 昨天看了一篇用正则爬电影天堂的视频,直接拿来用,爬磁力吧,爬好玩的 #导入模块 import reque ...

  8. RabbitMQ中,exchange1绑定exchange2,exchange1和exchange2都绑定queue1,此时消息发送给exchange1,queue1中有几条消息

    如题: 存在两个交换器 exchange1,exchange2 存在一个队列 queue1 存在三个绑定关系:exchange1绑定exchange2 ,exchange1绑定queue1,excha ...

  9. datetime模块

    # 其中days = -2,可以根据需要进行替换,这样就可以得到不同需要的日期了. # # 另外:可以通过strftime方法,指定时间的输出格式. # # 除了以上输入的   %Y-%m-%d    ...

  10. (转)hibernate 之hiberante.hbm2ddl.auto 参数的配置

    我们在搭建环境的时候,在配置文件中有一个属性标签为: 完整配置如下 <?xml version='1.0' encoding='utf-8'?> <!DOCTYPE hibernat ...