下载

0下载券

加入VIP
  • 专属下载特权
  • 现金文档折扣购买
  • VIP免费专区
  • 千万文档免费下载

上传资料

关闭

关闭

关闭

封号提示

内容

首页 实用电脑技术实例-0583

实用电脑技术实例-0583.PDF

实用电脑技术实例-0583

等你来聊
2012-06-20 0人阅读 举报 0 0 0 暂无简介

简介:本文档为《实用电脑技术实例-0583pdf》,可适用于高等教育领域

破解技术实例《去除“HTMLHelpWorkshop”反编译功能中的Bug》标题:《去除“HTMLHelpWorkshop”反编译功能中的Bug》作者:Vegeta详细信息:《去除“HTMLHelpWorkshop”反编译功能中的Bug》相关下载天津赵春生“HTMLHelpWorkshop”是MS出品的一款用来制作CHM文件的软件(简称HHW)手头儿的版本是自带反编译功能但在使用的过程中发现此功能无法正确处理文件名中含有Unicode宽字节字符串的文件并且“CHMInformation”功能也有同样的问题。一:Bug形成的原因:为了方便调试我制作了一个“testchm”其中包含三个文件:“indexhtm”“htm”“测试文件htm”。其中“indexhtm”对其余两个文件有超链接引用这样该CHM文件中就存在了文件名中含有Unicode宽字节字符串的文件“测试文件htm”。分别执行“Decompile”和“CHMInformation”发现文件“测试文件htm”都没有被正确处理但从“CHMInformation”的LOG中发现其文件大小已被正确获取。见下图():http:vegetablogenorthcomcnattachmentpicjpg一个大胆的推测:这两个功能的Bug源于同一个程序模块。用OLLYDBG加载“hhwexe”发现调用了API“CreateFileA”设上断点并开始执行“Decompile”功能OLLYDBG中断后可以看到程序即将创建反编译出来的文件并且紧接着就是API“WriteFile”的调用随后程序跳到上面的代码继续处理下一个文件……经过艰苦地跟踪发现FD调用了“hhadll”空间中的代码F进去后惊喜地发现了出现Bug的原因现以“测试文件htm”为例进行说明:FAFCALLDWORDPTRDS:<KERNELlstrlenW>返回值为没错FAMOVEBP,EAXFALEAEAX,DWORDPTRSS:EBPFAAPUSHEAXFABCALLHHADFAPOPECXFAMOVESI,EAXFAPUSHEBX参数FAPUSHEBX参数FAPUSHEBP参数传递了错误的参数!FAPUSHESI参数FAPUSHEBP参数FAMOVDWORDPTRDS:EDI,ESIFAAPUSHDWORDPTRSS:ESP参数FAEPUSHEBX参数FAFPUSHEBX参数FACALLDWORDPTRDS:<KERNELWideCharToMultiByte>将宽字符串转换成多字节字符串FAMOVBYTEPTRDS:EAXESI,BL添''最终形成多字节字符串先来看看API(lstrlenW):“测试文件htm”的Unicode码为:BDDBFEEDANSI码为:BECADCECBCFEED执行API(lstrlenW)的返回值为x因为该API返回Unicode码字符长度且不包括字符串结束符''完全正确。再看看API(WideCharToMultiByte):intWideCharToMultiByte(UINTCodePage,codepageDWORDdwFlags,performanceandmappingflagsLPCWSTRlpWideCharStr,addressofwidecharacterstringintcchWideChar,numberofcharactersinstringLPSTRlpMultiByteStr,addressofbufferfornewstringintcchMultiByte,sizeofbufferLPCSTRlpDefaultChar,addressofdefaultforunmappablecharactersLPBOOLlpUsedDefaultCharaddressofflagsetwhendefaultcharused)ReturnValues:Ifthefunctionsucceeds,andcchMultiByteisnonzero,thereturnvalueisthenumberofbyteswrittentothebufferpointedtobylpMultiByteStrIfthefunctionsucceeds,andcchMultiByteiszero,thereturnvalueistherequiredsize,inbytes,forabufferthatcanreceivethetranslatedstringIfthefunctionfails,thereturnvalueiszero当前程序执行到FA时堆栈显示如下:FECodePage=CPACPFEOptions=FECDWideCharStr="测试文件htm"FFWideCharCount=FFDMultiByteStr=DFFMultiByteCount=错误的参数!应为xDFFCpDefaultChar=FpDefaultCharUsed=注意看参数MultiByteCount=对应SDK里的说明:“intcchMultiByte,sizeofbuffer”在这里该值应为xD为什么呢?因为“测试文件htm”的ANSI码为:BECADCECBCFEED一共个字节。试着将堆栈中的参数修改程序正确执行“Decompile”和“CHMInformation”功能正常工作!程序员在这里犯了两个小小的错误:其一:错误地将cchWideChar的值传递给了cchMultiBytecchMultiByte的大小决定了转换成多字节字符串所需的缓冲区大小本来个字节的内容非要写进个字节空间中去如此一来API执行失败返回了''EAX其二:没有判断API的返回值紧接着就执行了MOVBYTEPTRDS:EAXESI,BL这样可好原本个字节空间中的内容已经面目全非了还要在头上砸一个鸭蛋''形成了一个彻底的空串从而出现图()那样的情况。二:SMC:正确获取cchMultiByte的值并将其传递给API(WideCharToMultiByte)函数是消除本程序Bug的关键翻看SDK手册得知:当cchMultiByte=时API(WideCharToMultiByte)将返回目标所需缓冲区的大小值……这样一来我们可以自己构造函数参数在得到正确的cchMultiByte后再执行字符串的转换工作。在“hhadll”空间下面找出一块儿空白区用来存放我们的代码:DPUSHADDPUSHlpUsedDefaultCharDPUSHlpDefaultCharDPUSHcchMultiByte=这样就能返回目标所需缓冲区的大小值了DPUSHlpMultiByteStr不需要在缓冲区中写东西地址设就行DPUSHEBPcchWideChar=EBPAPI(lstrlenW)的返回值DAPUSHDWORDPTRSS:ESPClpWideCharStrUnicode字符串地址DEPUSHdwFlagsDPUSHCodePageCPACP=DCALLDWORDPTRDS:<KERNELWideCharToMultiByte>返回所需缓冲区的大小DMOVDWORDPTRDS:DA,EAX将所需缓冲区的大小保存到DS:DADDPOPADDEADDESP,调整栈指针移动到原来cchMultiByte参数的位置上DPUSHDWORDPTRDS:DA将所需缓冲区的大小入栈形成新的cchMultiByte参数DSUBESP,调整栈指针移动到栈顶既第一个参数的位置DACALLDWORDPTRDS:<KERNELWideCharToMultiByte>开始转换DJMPHHAFA返回原程序DNOP然后修改下面的代码使之跳转到我们的代码中:FACALLDWORDPTRDS:<KERNELWideCharToMultiByte>改为:FAJMPHHADFANOP补位因为我们的SMC代码需要向DS:DA中写入内容所以需要把该代码段所处的text节改为可写用LordPE即可。见下图():http:vegetablogenorthcomcnattachmentpicjpg现在修改后的程序已经能正确处理文件名中含有Unicode宽字节字符串的文件了下图()为执行“CHMInformation”后的效果图:http:vegetablogenorthcomcnattachmentpicjpg《去除“HTMLHelpWorkshop”反编译功能中的Bug》修经过反复地测试又在“hhadll”中找到了一个Bug见以下代码:FAFCALLDWORDPTRDS:<KERNELlstrlenW>kernellstrlenWFAMOVEBP,EAXFALEAEAX,DWORDPTRSS:EBPFAAPUSHEAXFABCALLHHAD得到ANSI字符串存放地址问题出现!FAPOPECX执行后ECX为Unicode字符串个数FAMOVESI,EAX将用来存放转化后的ANSI字符串地址EAX传递给ESIFAPUSHEBXFAPUSHEBXFAPUSHEBPFAPUSHESIANSI字符串存放地址作为参数入栈问题在于FAB这段代码这段代码得到的地址可能会与我们指定的Destinationfolder在内存中的地址冲突(Destinationfolder:指定存放反编译出来的文件的存放地址如:“C:temp”)从而导致以下问题的产生:文件存放路径和文件名被转换后的ANSI字符串破坏掉从而使得创建文件时失败……实践证明这种几率很大!不知道这个Bug和上次的程序修改是否有关……解决的方法有两个::改变反编译出来的文件的存放地址在内存中的位置:改变转换后的ANSI字符串在内存中的存放地址。相比起来后者较为简单因为所有的SMC代码都可以放在“hhadll”中。修改FA这段代码使之跳转到一个空白区D该区域的代码用来实现将指定的ANSI字符串的存放地址交给ESI寄存器:FAJMPHHAD跳转到DDMOVESI,HHADA将指定的ANSI字符串的存放地址交给ESI寄存器DPUSHEBX恢复代码DPUSHEBX恢复代码DPUSHEBP恢复代码DJMPHHAFA返回原程序DDNOP修改后程序执行正常……不再出现“ERRORINVALIDNAME”和“ERRORPATHNOTFOUND”错误但OLLYDBG加载调试时“hhwexe”会出现异常不去管她了……三:相关提示:HHW可从MS站点下载好象该程序已不再更新了……修改后的“hhadll”文件可从我的Blog下载将“hhadll”与“hhwexe”程序放在在同一目录下即可。Blog:http:timwyeahnethttp:timwcom祝大家新春快乐万事如意!!!::修

用户评价(0)

关闭

新课改视野下建构高中语文教学实验成果报告(32KB)

抱歉,积分不足下载失败,请稍后再试!

提示

试读已结束,如需要继续阅读或者下载,敬请购买!

评分:

/7

VIP

在线
客服

免费
邮箱

爱问共享资料服务号

扫描关注领取更多福利