修改http请求文件为本地文件的一种方法hook InternetReadFile 和 HttpOpenRequest.docx

上传人:b****8 文档编号:10124344 上传时间:2023-05-23 格式:DOCX 页数:7 大小:16.93KB
下载 相关 举报
修改http请求文件为本地文件的一种方法hook InternetReadFile 和 HttpOpenRequest.docx_第1页
第1页 / 共7页
修改http请求文件为本地文件的一种方法hook InternetReadFile 和 HttpOpenRequest.docx_第2页
第2页 / 共7页
修改http请求文件为本地文件的一种方法hook InternetReadFile 和 HttpOpenRequest.docx_第3页
第3页 / 共7页
修改http请求文件为本地文件的一种方法hook InternetReadFile 和 HttpOpenRequest.docx_第4页
第4页 / 共7页
修改http请求文件为本地文件的一种方法hook InternetReadFile 和 HttpOpenRequest.docx_第5页
第5页 / 共7页
修改http请求文件为本地文件的一种方法hook InternetReadFile 和 HttpOpenRequest.docx_第6页
第6页 / 共7页
修改http请求文件为本地文件的一种方法hook InternetReadFile 和 HttpOpenRequest.docx_第7页
第7页 / 共7页
亲,该文档总共7页,全部预览完了,如果喜欢就下载吧!
下载资源
资源描述

修改http请求文件为本地文件的一种方法hook InternetReadFile 和 HttpOpenRequest.docx

《修改http请求文件为本地文件的一种方法hook InternetReadFile 和 HttpOpenRequest.docx》由会员分享,可在线阅读,更多相关《修改http请求文件为本地文件的一种方法hook InternetReadFile 和 HttpOpenRequest.docx(7页珍藏版)》请在冰点文库上搜索。

修改http请求文件为本地文件的一种方法hook InternetReadFile 和 HttpOpenRequest.docx

修改http请求文件为本地文件的一种方法hookInternetReadFile和HttpOpenRequest

修改http请求文件为本地文件的一种方法:

hookInternetReadFile和HttpOpenRequest

  今天没事的时候学了一下easyhook来hook本进程API,确实很简单就能hook。

然后想到这个问题:

替换webbrowser请求的文件为本地文件。

有什么用就不说了,都懂。

因为没有用API写过http方面的东西,所以先hook了几个函数,其中InternetReadFile是webbrowser用来获取文件的,而文件句柄可以来源于internetopenurl和HttpOpenRequest等API,挨个下一下钩子就知道用的是HttpOpenRequest。

当然,获取方法是多种多样的,也可以用x64dbg等调试工具。

确定下来hook这两个可以达成目标就可以了:

1、从HttpOpenRequest知道要下载的是哪个文件,过滤需要替换的那个。

2、HttpOpenRequest的返回值就是打开文件句柄了,在InternetReadFile中识别这个句柄就可以。

3、在给InternetReadFile的自定义例程中,对需要替换的文件进行替换。

  接下来,让我们考虑一下替换的流程:

webbrowser调用InternetReadFile的时候,先到达我们的自定义例程,然后由我们调用API函数InternetReadFile,于是我们可以在自定义函数中把相应文件句柄的数据请求吃掉——把我们的数据写入缓冲区,而后直接返回不掉用API。

对于我们不关心的文件句柄调用API。

  查看InternetReadFile的API声明:

<DllImport("wininet.dll",SetLastError:

=True)>

PublicSharedFunctionInternetReadFile(ByValhFileAsIntPtr,ByVallpBufferAsIntPtr,ByValdwNumberOfBytesToReadAsInteger,ByReflpdwNumberOfBytesReadAsInteger)AsBoolean

EndFunction

可以知道,第一个参数是HttpOpenRequest返回的文件句柄,lpbuffer是接收数据的缓冲区,dwnumberofbytestoread是期望读取的字节数,即缓冲区大小,lpdwnumberofbytesread是实际写入缓冲区的字节数。

返回值表示函数调用是否成功。

所以,当lpdwnumberofbytesread为0且函数返回值为true时,达到文件结尾——函数调用成功却没有数据写入,说明数据写完了。

于是,在我们的自定义例程中也需要遵守该约定——当写入数据时返回实际写入的数据大小,写完数据后再次被调用时返回0并进行清理。

首先,来看一下比较简单的一个hook:

ImportsSystem.Runtime.InteropServices

ImportsSystem.Text

PublicClassHookHttpOpenRequest

<DllImport("wininet.dll")>

PublicSharedFunctionHttpOpenRequestW(hConnectAsIntPtr,szVerbAsIntPtr,szURIAsIntPtr,szHttpVersionAsIntPtr,szRefererAsIntPtr,accetpTypeAsIntPtr,dwflagsAsInteger,dwcontextAsIntPtr)AsIntPtr

EndFunction

PrivateDelegateFunctionHttpOpenRequestDelegate(hConnectAsIntPtr,szVerbAsIntPtr,szURIAsIntPtr,szHttpVersionAsIntPtr,szRefererAsIntPtr,accetpTypeAsIntPtr,dwflagsAsInteger,dwcontextAsIntPtr)AsIntPtr

PrivateSharedhookAsEasyHook.LocalHook=Nothing

FriendSharedSubInstall()

Usinghook

IfEasyHook.NativeAPI.GetModuleHandle("wininet.dll")=IntPtr.ZeroThen

EasyHook.NativeAPI.LoadLibrary("wininet.dll")

EndIf

hook=EasyHook.LocalHook.Create(EasyHook.LocalHook.GetProcAddress("wininet.dll","HttpOpenRequestW"),NewHttpOpenRequestDelegate(AddressOfsendProc),Nothing)

hook.ThreadACL.SetInclusiveACL(NewInteger(){0})

EndUsing

EndSub

FriendSharedSubUnInstall()

Usinghook

IfhookIsNotNothingThen

hook.ThreadACL.SetExclusiveACL(NewInteger(){0})

EndIf

EndUsing

EndSub

PrivateSharedFunctionsendProc(hConnectAsIntPtr,szVerbAsIntPtr,szURIAsIntPtr,szHttpVersionAsIntPtr,szRefererAsIntPtr,accetpTypeAsIntPtr,dwflagsAsInteger,dwcontextAsIntPtr)AsIntPtr

DimuriAsString=Marshal.PtrToStringUni(szURI)

DimresultAsIntPtr=HttpOpenRequestW(hConnect,szVerb,szURI,szHttpVersion,szReferer,accetpType,dwflags,dwcontext)

Ifuri.Contains("/56896-20170216102630488-270057596.jpg")Then'根据名称区分要替换的图片.

HookInternetReadFile.CheatFileHandle=resultEndIfReturnresultEndFunctionEndClass

easyhook用起来确实比较简单,首先是注入过程,因为webbrowser对wininte.dll的加载是请求第一个页面时,所以可能导致这个DLL不在进程空间,那么先加载它。

之后的hook非常易懂(函数名我没有修改,复制粘贴的之前写的sendhook),唯一需要注意的是实际hook的过程调用的是ThreadACL.SetInclusiveACL,unhook类似。

在自定义函数中,首先调用API,得到句柄,然后根据要替换的名称来确定是否启动给InternetReadFile的自定义例程。

而后,看一下对数据的处理过程:

ImportsSystem.IO

ImportsSystem.Runtime.InteropServices

PublicClassHookInternetReadFile

<DllImport("wininet.dll",SetLastError:

=True)>

PublicSharedFunctionInternetReadFile(ByValhFileAsIntPtr,ByVallpBufferAsIntPtr,ByValdwNumberOfBytesToReadAsInteger,ByReflpdwNumberOfBytesReadAsInteger)AsBoolean

EndFunction

PrivateDelegateFunctionInternetReadFileDelegate(ByValhFileAsIntPtr,ByVallpBufferAsIntPtr,ByValdwNumberOfBytesToReadAsInteger,ByReflpdwNumberOfBytesReadAsInteger)AsBoolean

PrivateSharedhookAsEasyHook.LocalHook=Nothing

FriendSharedCheatFileHandleAsIntPtr=IntPtr.Zero'要替换的文件的句柄,来源于HttpOpenRequest的返回值。

FriendSharedCheatFile()AsByte=File.ReadAllBytes(My.Application.Info.DirectoryPath&"\abc.jpg")'用于替换的文件

PrivateSharedcurcntAsInteger=0

FriendSharedSubInstall()

Usinghook

IfEasyHook.NativeAPI.GetModuleHandle("wininet.dll")=IntPtr.ZeroThen

EasyHook.NativeAPI.LoadLibrary("wininet.dll")

EndIf

hook=EasyHook.LocalHook.Create(EasyHook.LocalHook.GetProcAddress("wininet.dll","InternetReadFile"),NewInternetReadFileDelegate(AddressOfsendProc),Nothing)

hook.ThreadACL.SetInclusiveACL(NewInteger(){0})

EndUsing

EndSub

FriendSharedSubUnInstall()

Usinghook

IfhookIsNotNothingThen

hook.ThreadACL.SetExclusiveACL(NewInteger(){0})

EndIf

EndUsing

EndSub

PrivateSharedFunctionsendProc(ByValhFileAsIntPtr,ByVallpBufferAsIntPtr,ByValdwNumberOfBytesToReadAsInteger,ByReflpdwNumberOfBytesReadAsInteger)AsBoolean

IfhFile=CheatFileHandleThen

Ifcurcnt=CheatFile.LengthThen

CheatFileHandle=IntPtr.Zero

curcnt=0

lpdwNumberOfBytesRead=0

Else

Ifcurcnt+dwNumberOfBytesToRead<=CheatFile.LengthThen

lpdwNumberOfBytesRead=dwNumberOfBytesToRead

Marshal.Copy(CheatFile,curcnt,lpBuffer,lpdwNumberOfBytesRead)

curcnt+=dwNumberOfBytesToRead

Else

lpdwNumberOfBytesRead=CheatFile.Length-curcnt

Marshal.Copy(CheatFile,curcnt,lpBuffer,lpdwNumberOfBytesRead)

curcnt=CheatFile.Length

EndIf

EndIf

ReturnTrue

Else

ReturnInternetReadFile(hFile,lpBuffer,dwNumberOfBytesToRead,lpdwNumberOfBytesRead)

EndIf

EndFunction

EndClass

因为是一个基本结构范例,所以偷懒直接用了参数,这里应该有错误处理过程才行。

hook的过程和前面一致,只是在自定义函数中处理把自定义数据写入缓冲区然后返回了。

具体的API过程没有跟踪,所以不知道不调用InternetReadFile这个API会不会有内存泄漏之类的什么问题,如果需要调用也非常简单:

在恰当的时机循环读取一次就可以了。

最后是窗体代码:

PublicClassForm1

PrivateSubForm1_Load(senderAsObject,eAsEventArgs)HandlesMyBase.Load

wb.Navigate("

EndSub

PrivateSubbutGotoUrl_Click(senderAsObject,eAsEventArgs)HandlesbutGotoUrl.Click

wb.Refresh()

EndSub

PrivateSubchkCheat_CheckedChanged(senderAsObject,eAsEventArgs)HandleschkCheat.CheckedChanged

IfchkCheat.CheckedThen

HookHttpOpenRequest.Install()

HookInternetReadFile.Install()

Else

HookHttpOpenRequest.UnInstall()

HookInternetReadFile.UnInstall()

EndIf

EndSub

EndClass

窗体上一个webbrowser重命名为wb,一个checkbox重命名为chkcheat,一个button重命名为butgotourl,另外,在程序所在目录放一个abc.jpg。

对,这个范例就是这么简陋,好在现在就可以测试了。

如果图片换名字了,那需要修改url地址的同时修改

Ifuri.Contains("/56896-20170216102630488-270057596.jpg")Then'根据名称区分要替换的图片

才可以正确运行。

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 经管营销 > 经济市场

copyright@ 2008-2023 冰点文库 网站版权所有

经营许可证编号:鄂ICP备19020893号-2