-
-
[学习笔记]修改Wininet.dll实现FTP断点续传(原创文章)
-
发表于: 2005-1-16 13:33 6563
-
看《内幕》很有收获,实验了一下
修改Wininet.dll实现FTP断点续传(原创文章)
论Wininet不支持HTTP和FTP的Resume
1,不支持HTTP的resume
Wininet的setfilepointer只是在Cache的状态下有效而且是控制的cachefile
的pointer。
但是可以用AddRequest的方法来进行底层的控制发送 range的head来实
现seek.
2,不支持FTP的resume
根据rfc(2a9K9s2c8@1M7q4)9K6b7g2)9J5c8W2)9J5c8Y4N6%4N6#2)9J5k6i4M7K6i4K6u0W2L8%4u0Y4i4K6u0r3f1s2u0G2N6r3!0U0L8$3I4K6i4K6u0r3i4@1g2r3i4@1u0o6i4K6R3&6i4@1f1^5i4@1p5$3i4K6R3I4i4@1f1$3i4@1t1I4i4K6R3J5f1V1g2e0g2l9`.`.(restart)后面紧
跟RETR,
而FTPReadFile非要画蛇添足地 Type to I PASV 等一大堆 然后才RETR
,所以
使REST过期了。
对于FTP函数就只能进行底层修改了。
BOOL WINAPI FtpOpenFile(
HINTERNET hConnect,
LPCTSTR lpszFileName,
DWORD dwAccess,
DWORD dwFlags,
DWORD dwContext);
修改成:
BOOL WINAPI FtpOpenFile(
HINTERNET hConnect,
LPCTSTR lpszFileName,
DWORD dwAccess,
DWORD dwFlags,
LPCTSTR *plpszSeekPos );
其中
CString sSeekPos;
SSeekPos.Format("%ld",dwSeekPos);
lpSeekPose=sSeekPos.LockBuffer();
plpszSeekPos=&lpSeekPose;
debug 进入 psdk 的wininet.dll中的FTPOpenFile经过很多个小时的跟
踪以后发现
以下三个函数入口:
761BB256 and ebx,80000000h
761BB25C mov eax,761DE8F0h
………………………………………………………
761BB261 jne 761BB268
761BB263 mov eax,761DE8E8h
761BB276 call 761BC0A2
format("RETR %s");
761BC213 push edi
761BC214 mov edi,dword ptr [ebp+70h]
761BC217 push eax
761BC218 push 761DE9ECh
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
761BC21D push edi
761BC21E push 0
761BC225 call 761BC1C3
format("TYPE %s");
761BC7F9 test eax,eax //没有用
761BC7FB jne 761BC89D //没有用
761BC801 push dword ptr [ebp+78h]
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ lpstrFileAtServer
761BC804 push 761DE93Ch
761BC809 push dword ptr [ebp+58h]
761BC80C call 761BC003
format("SIZE %s",lpstrFileAtServer)
修改DLL成 SIZE %s->REST %s
然后就是修改参数调用:
761BC7F9 85 C0 0F 85 9C 00 00 ?.?..
761BC800 00 FF 75 78
761BC7F9 test eax,eax //没有用
761BC7FB jne 761BC89D //没有用
761BC801 push dword ptr [ebp+78h]
的11个字节想办法修改成:
761BC7F9 90 8B C5 05 50 01 00 ?..P..
761BC800 00 50 90 90
nop;
mov eax, ebp ;
add eax, 0x150 ;
push eax ;
nop;
nop;
使用方法:
char lpPos[64];//注意必须是在stack里的局部临时变量,不可以在heap中
memset(lpPos,0,64);
sprintf(lpPos,"%ld",dOffsetToSeek);
m_hOpenFile = ::FtpOpenFile(m_hOpenUrlHandle,sFileNameAtServer
, GENERIC_R
EAD
, FTP_TRANSFER_TYPE_BINARY, (DWORD)&lpPos);
--
修改Wininet.dll实现FTP断点续传(原创文章)
论Wininet不支持HTTP和FTP的Resume
1,不支持HTTP的resume
Wininet的setfilepointer只是在Cache的状态下有效而且是控制的cachefile
的pointer。
但是可以用AddRequest的方法来进行底层的控制发送 range的head来实
现seek.
2,不支持FTP的resume
根据rfc(2a9K9s2c8@1M7q4)9K6b7g2)9J5c8W2)9J5c8Y4N6%4N6#2)9J5k6i4M7K6i4K6u0W2L8%4u0Y4i4K6u0r3f1s2u0G2N6r3!0U0L8$3I4K6i4K6u0r3i4@1g2r3i4@1u0o6i4K6R3&6i4@1f1^5i4@1p5$3i4K6R3I4i4@1f1$3i4@1t1I4i4K6R3J5f1V1g2e0g2l9`.`.(restart)后面紧
跟RETR,
而FTPReadFile非要画蛇添足地 Type to I PASV 等一大堆 然后才RETR
,所以
使REST过期了。
对于FTP函数就只能进行底层修改了。
BOOL WINAPI FtpOpenFile(
HINTERNET hConnect,
LPCTSTR lpszFileName,
DWORD dwAccess,
DWORD dwFlags,
DWORD dwContext);
修改成:
BOOL WINAPI FtpOpenFile(
HINTERNET hConnect,
LPCTSTR lpszFileName,
DWORD dwAccess,
DWORD dwFlags,
LPCTSTR *plpszSeekPos );
其中
CString sSeekPos;
SSeekPos.Format("%ld",dwSeekPos);
lpSeekPose=sSeekPos.LockBuffer();
plpszSeekPos=&lpSeekPose;
debug 进入 psdk 的wininet.dll中的FTPOpenFile经过很多个小时的跟
踪以后发现
以下三个函数入口:
761BB256 and ebx,80000000h
761BB25C mov eax,761DE8F0h
………………………………………………………
761BB261 jne 761BB268
761BB263 mov eax,761DE8E8h
761BB276 call 761BC0A2
format("RETR %s");
761BC213 push edi
761BC214 mov edi,dword ptr [ebp+70h]
761BC217 push eax
761BC218 push 761DE9ECh
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
761BC21D push edi
761BC21E push 0
761BC225 call 761BC1C3
format("TYPE %s");
761BC7F9 test eax,eax //没有用
761BC7FB jne 761BC89D //没有用
761BC801 push dword ptr [ebp+78h]
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ lpstrFileAtServer
761BC804 push 761DE93Ch
761BC809 push dword ptr [ebp+58h]
761BC80C call 761BC003
format("SIZE %s",lpstrFileAtServer)
修改DLL成 SIZE %s->REST %s
然后就是修改参数调用:
761BC7F9 85 C0 0F 85 9C 00 00 ?.?..
761BC800 00 FF 75 78
761BC7F9 test eax,eax //没有用
761BC7FB jne 761BC89D //没有用
761BC801 push dword ptr [ebp+78h]
的11个字节想办法修改成:
761BC7F9 90 8B C5 05 50 01 00 ?..P..
761BC800 00 50 90 90
nop;
mov eax, ebp ;
add eax, 0x150 ;
push eax ;
nop;
nop;
使用方法:
char lpPos[64];//注意必须是在stack里的局部临时变量,不可以在heap中
memset(lpPos,0,64);
sprintf(lpPos,"%ld",dOffsetToSeek);
m_hOpenFile = ::FtpOpenFile(m_hOpenUrlHandle,sFileNameAtServer
, GENERIC_R
EAD
, FTP_TRANSFER_TYPE_BINARY, (DWORD)&lpPos);
--
赞赏
赞赏
雪币:
留言: