#include "StdAfx.h"
#include "hook_my.h"
#include<atlconv.h>
//全局变量
HINTERNET ForFileContent=NULL;
int ForFileHandle =0; //当到了files那个页面时,
// 初始化静态成员
PFN_LdrLoadDll CWininetHook::s_pfnLdrLoadDll = NULL;
PFN_LdrGetProcedureAddress CWininetHook::s_pfnLdrGetProcedureAddress = NULL;
PFN_HttpSendRequestA CWininetHook::s_pfnHttpSendRequestA = HttpSendRequestA;
PFN_HttpSendRequestW CWininetHook::s_pfnHttpSendRequestW = HttpSendRequestW;
PFN_HttpOpenRequestA CWininetHook::s_pfnHttpOpenRequestA = HttpOpenRequestA;
PFN_HttpOpenRequestW CWininetHook::s_pfnHttpOpenRequestW = HttpOpenRequestW;
PFN_InternetReadFile CWininetHook::s_pfnInternetReadFile= InternetReadFile;
//构造函数
CWininetHook::CWininetHook(void)
{
s_pfnLdrLoadDll = (PFN_LdrLoadDll)::GetProcAddress( ::GetModuleHandle(("NTDLL.DLL")), "LdrLoadDll");
s_pfnLdrGetProcedureAddress = (PFN_LdrGetProcedureAddress)::GetProcAddress( ::GetModuleHandle(("NTDLL.DLL")), "LdrGetProcedureAddress");
if( !s_pfnLdrLoadDll || !s_pfnLdrGetProcedureAddress )
return;
ReplaceIATEntryForAll( "NTDLL.DLL", s_pfnLdrLoadDll, &CWininetHook::_LdrLoadDll);
ReplaceIATEntryForAll( "NTDLL.DLL", s_pfnLdrGetProcedureAddress, &CWininetHook::_LdrGetProcedureAddress);
ReplaceIATEntryForAll( "WININET.DLL", s_pfnHttpSendRequestA, &CWininetHook::_HttpSendRequestA);
ReplaceIATEntryForAll( "WININET.DLL", s_pfnHttpSendRequestW, &CWininetHook::_HttpSendRequestW);
ReplaceIATEntryForAll( "WININET.DLL", s_pfnHttpOpenRequestA, &CWininetHook::_HttpOpenRequestA);
ReplaceIATEntryForAll( "WININET.DLL", s_pfnHttpOpenRequestW, &CWininetHook::_HttpOpenRequestW);
ReplaceIATEntryForAll( "WININET.DLL", s_pfnInternetReadFile,&CWininetHook::_InternetReadFile);
}
CWininetHook::~CWininetHook(void)
{
}
static CWininetHook g_oHook;
//////////////////////////////////////////////////////////////////////////
// Enumerate all the loaded modules in the current process, and search for the IAT to be processed
void CWininetHook::ReplaceIATEntryForAll(LPCSTR lpszDllName, LPVOID pfnCurrent, LPVOID pfnNew)
{
HMODULE hMods[1024] = {0};
DWORD cbNeeded;
HANDLE hProcess = ::GetCurrentProcess();
if( ::EnumProcessModules( hProcess, hMods, sizeof(hMods), &cbNeeded))
{
for ( UINT i = 0; i < (cbNeeded / sizeof(HMODULE)); i++ )
{
ReplaceIATEntryInImageImportTable( hMods[i]
, lpszDllName
, pfnCurrent
, pfnNew
);
}
}
}
// 在特定的模块中寻找IMAGE_IMPORT_DESCRIPTOR
BOOL CWininetHook::ReplaceIATEntryInImageImportTable( HANDLE hBaseAddress
, LPCSTR lpszDllName
, LPVOID pfnCurrent
, LPVOID pfnNew
)
{
ASSERT(hBaseAddress && lpszDllName && pfnCurrent && pfnNew );
// retrieve IMAGE_IMPORT_DESCRIPTOR
DWORD dwSize = 0;
PIMAGE_SECTION_HEADER pFoundHeader = NULL;
PIMAGE_IMPORT_DESCRIPTOR pImgImportDescriptor
= (PIMAGE_IMPORT_DESCRIPTOR)ImageDirectoryEntryToDataEx( hBaseAddress
, TRUE
, IMAGE_DIRECTORY_ENTRY_IMPORT
, &dwSize
, &pFoundHeader
);
if( pImgImportDescriptor == NULL ){ return FALSE; }
while (pImgImportDescriptor->Name)
{
if ( _strcmpi((CHAR*)((PBYTE)hBaseAddress+pImgImportDescriptor->Name), lpszDllName) == 0 )
{
break; // found
}
++pImgImportDescriptor;
}
// NOTE:
// If the special module can not be found in IMAGE_DIRECTORY_ENTRY_IMPORT
// Then should try to search it in IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT
if( !pImgImportDescriptor->Name )
return ReplaceIATEntryInDelayImageImportTable( hBaseAddress, lpszDllName, pfnCurrent, pfnNew);
// retrieve IAT
PIMAGE_THUNK_DATA pThunk = (PIMAGE_THUNK_DATA)(((LPBYTE)hBaseAddress) + pImgImportDescriptor->FirstThunk);
// enumerate functions in the IAT
while(pThunk->u1.Function)
{
PDWORD lpAddr = (PDWORD)&(pThunk->u1.Function);
if(*lpAddr == (DWORD)pfnCurrent)
{
// modify the address
::WriteProcessMemory(::GetCurrentProcess()
, lpAddr
, &pfnNew
, sizeof(DWORD)
, NULL
);
return TRUE;
}
pThunk++;
}
return FALSE;
}
// search in IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT for the special module
BOOL CWininetHook::ReplaceIATEntryInDelayImageImportTable( HANDLE hBaseAddress
, LPCSTR lpszDllName
, LPVOID pfnCurrent
, LPVOID pfnNew
)
{
ASSERT(hBaseAddress && lpszDllName && pfnCurrent && pfnNew );
// retrieve IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT
DWORD dwSize = 0;
PIMAGE_SECTION_HEADER pFoundHeader = NULL;
PImgDelayDescr pImgDelayDescr
= (PImgDelayDescr)ImageDirectoryEntryToDataEx( hBaseAddress
, TRUE
, IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT
, &dwSize
, &pFoundHeader
);
if( pImgDelayDescr == NULL ){ return FALSE; }
while (pImgDelayDescr->rvaDLLName)
{
if ( _strcmpi((CHAR*)((PBYTE)hBaseAddress+pImgDelayDescr->rvaDLLName), lpszDllName) == 0 )
{
break;
}
++pImgDelayDescr;
}
// Not found in IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT
if( !pImgDelayDescr->rvaDLLName )
return FALSE;
// retrieve IAT
PIMAGE_THUNK_DATA pThunk = NULL;
if( (pImgDelayDescr->grAttrs & dlattrRva) == 0 )
return FALSE;
pThunk = (PIMAGE_THUNK_DATA)(((LPBYTE)hBaseAddress) + pImgDelayDescr->rvaIAT);
// enumerate functions in the IAT
while(pThunk->u1.Function)
{
PDWORD lpAddr = (PDWORD)&(pThunk->u1.Function);
if(*lpAddr == (DWORD)pfnCurrent)
{
// modify the address
::WriteProcessMemory(::GetCurrentProcess()
, lpAddr
, &pfnNew
, sizeof(DWORD)
, NULL
);
return TRUE;
}
pThunk++;
}
return FALSE;
}
// 所有动态加载的DLL,都需要对IAT处理一次
NTSTATUS WINAPI CWininetHook::_LdrLoadDll(IN PWCHAR PathToFile OPTIONAL, IN ULONG Flags OPTIONAL, IN PUNICODE_STRING ModuleFileName, OUT PHANDLE ModuleHandle)
{
//这里有个非法访问的错误
NTSTATUS ntStatus = s_pfnLdrLoadDll( PathToFile, Flags, ModuleFileName, ModuleHandle);
if( ntStatus == STATUS_SUCCESS && (Flags & LOAD_LIBRARY_AS_DATAFILE) == 0 )
{
#ifdef _DEBUG
if( ModuleFileName->Length > 0 )
{
WCHAR wszPath[MAX_PATH] = {0};
//why error?
wcscat_s(wszPath,ModuleFileName->Buffer);
//memcpy( wszPath, ModuleFileName->Buffer, MAX_PATH*sizeof(WCHAR));
USES_CONVERSION;
TRACE( "调试:LdrLoadDll %s\n",W2A(wszPath ));
}
#endif
HANDLE hDll = *ModuleHandle;
ReplaceIATEntryInImageImportTable( hDll, "NTDLL.DLL", s_pfnLdrLoadDll, &CWininetHook::_LdrLoadDll);
ReplaceIATEntryInImageImportTable( hDll, "NTDLL.DLL", s_pfnLdrGetProcedureAddress, &CWininetHook::_LdrGetProcedureAddress);
ReplaceIATEntryInImageImportTable( hDll, "WININET.DLL", s_pfnHttpSendRequestA, &CWininetHook::_HttpSendRequestA);
ReplaceIATEntryInImageImportTable( hDll, "WININET.DLL", s_pfnHttpSendRequestW, &CWininetHook::_HttpSendRequestW);
ReplaceIATEntryInImageImportTable( hDll, "WININET.DLL", s_pfnHttpOpenRequestA, &CWininetHook::_HttpOpenRequestA);
ReplaceIATEntryInImageImportTable( hDll, "WININET.DLL", s_pfnHttpOpenRequestW, &CWininetHook::_HttpOpenRequestW);
ReplaceIATEntryInImageImportTable( hDll, "WININET.DLL", s_pfnInternetReadFile, &CWininetHook::_InternetReadFile);
}
return ntStatus;
}
#define TRY_GET_ADDRESS(name, fun1, fun2, type) \
if( strcmp( szFunName, name) == 0 ) { if( !fun1 ) { fun1 = (type)(*FunctionAddress); } *FunctionAddress = fun2; return ntStatus; }
// 如果是动态获取地址,则返回转接函数地址
NTSTATUS WINAPI CWininetHook::_LdrGetProcedureAddress(IN HMODULE ModuleHandle, IN PANSI_STRING FunctionName OPTIONAL, IN WORD Oridinal OPTIONAL, OUT PVOID *FunctionAddress )
{
NTSTATUS ntStatus = s_pfnLdrGetProcedureAddress( ModuleHandle, FunctionName, Oridinal, FunctionAddress);
if( ntSt