相比于直接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. vue项目总结

    1.项目的结构

  2. Python filter() 函数

    Python filter() 函数 描述 filter() 函数用于过滤序列,过滤掉不符合条件的元素,返回由符合条件元素组成的新列表. 该接收两个参数,第一个为函数,第二个为序列,序列的每个元素作为 ...

  3. dom编程艺术笔记2--第三章

    DOM 1.dom:简单理解为文档对象模型<==>节点树 2.宿主对象:浏览器提供的对象—>document对象 3. html标签为树顶点元素 head body为html子元素以 ...

  4. 自动化运维之Saltstack

    第三十八课 自动化运维之Saltstack 目录 一.自动化运维介绍 二. saltstack安装 三. 启动saltstack服务 四. saltstack配置认证 五. saltstack远程执行 ...

  5. Can peel peel solve pesticide problem

    Can peel peel solve pesticide problem? Middle peasants medicinal modern agriculture more and more, t ...

  6. Sql Server 2012 集群配置

    基于Windows Server 2008 R2的WSFC实现SQL Server 2012高可用性组(AlwaysOn Group) 2012年5月 微软新一代数据库产品SQL Server 201 ...

  7. pdf.js使用总结#如何在网页读取并显示PDF格式文档

    pdf.js可以实现在html下直接浏览pdf文档,是一款开源的pdf文档读取解析插件 pdf.js主要包含两个库文件,一个pdf.js和一个pdf.worker.js,一个负责API解析,一个负责核 ...

  8. eclipse安装反编译插件(附jad下载)

    eclipse安装反编译插件(附jad下载) 博客分类: eclipse   一.eclipse反编译插件Jadclipse jadclips插件网站:    http://jadclipse.sou ...

  9. jmeter的学习路线

  10. python 函数返回值(总结)

    关键字:return 没有返回值的叫过程 def test1(): msg="我是一个过程" print(msg) 有return的叫函数 def test02(): msg=&q ...