00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027 #define WIN32_LEAN_AND_MEAN
00028 #include <windows.h>
00029 #include <stdio.h>
00030 #include "HookDLL.h"
00031
00032 #include <sstream>
00033 std::stringstream _hookDllLogStream;
00034 #define LOG(s) \
00035 _hookDllLogStream.str(""); \
00036 _hookDllLogStream << "Synergy HookDLL: " << s << std::endl; \
00037 OutputDebugString( _hookDllLogStream.str().c_str() );
00038
00039
00040
00041
00042 void __cdecl DefaultHook( PVOID dummy )
00043 {
00044
00045 #ifdef _M_IX86
00046 __asm pushad
00047
00048
00049
00050
00051
00052 PDWORD pRetAddr = (PDWORD)(&dummy - 1);
00053
00054 DLPD_IAT_STUB * pDLPDStub = (DLPD_IAT_STUB *)(*pRetAddr - 5);
00055
00056 pDLPDStub->count++;
00057
00058 #if 0
00059
00060
00061 if ( !IMAGE_SNAP_BY_ORDINAL( pDLPDStub->pszNameOrOrdinal) )
00062 {
00063 LOG( "Called hooked function: " );
00064 LOG( (PSTR)pDLPDStub->pszNameOrOrdinal );
00065 }
00066 #endif
00067
00068 __asm popad
00069 #endif
00070 }
00071
00072
00073 void __cdecl DelayLoadProfileDLL_UpdateCount( PVOID dummy );
00074
00075 PIMAGE_IMPORT_DESCRIPTOR g_pFirstImportDesc;
00076
00077
00078
00079
00080 PIMAGE_NT_HEADERS PEHeaderFromHModule(HMODULE hModule)
00081 {
00082 PIMAGE_NT_HEADERS pNTHeader = 0;
00083
00084 __try
00085 {
00086 if ( PIMAGE_DOS_HEADER(hModule)->e_magic != IMAGE_DOS_SIGNATURE )
00087 __leave;
00088
00089 pNTHeader = PIMAGE_NT_HEADERS(PBYTE(hModule)
00090 + PIMAGE_DOS_HEADER(hModule)->e_lfanew);
00091
00092 if ( pNTHeader->Signature != IMAGE_NT_SIGNATURE )
00093 pNTHeader = 0;
00094 }
00095 __except( EXCEPTION_EXECUTE_HANDLER )
00096 {
00097 }
00098
00099 return pNTHeader;
00100 }
00101
00102
00103
00104
00105 bool RedirectIAT( SDLLHook* DLLHook, PIMAGE_IMPORT_DESCRIPTOR pImportDesc, PVOID pBaseLoadAddr )
00106 {
00107 PIMAGE_THUNK_DATA pIAT;
00108 PIMAGE_THUNK_DATA pINT;
00109 PIMAGE_THUNK_DATA pIteratingIAT;
00110
00111
00112 OSVERSIONINFO osvi;
00113 osvi.dwOSVersionInfoSize = sizeof(osvi);
00114 GetVersionEx( &osvi );
00115
00116
00117 if ( pImportDesc->OriginalFirstThunk == 0 )
00118 {
00119 LOG( "no IAT available." );
00120 return false;
00121 }
00122
00123 pIAT = MakePtr( PIMAGE_THUNK_DATA, pBaseLoadAddr, pImportDesc->FirstThunk );
00124 pINT = MakePtr( PIMAGE_THUNK_DATA, pBaseLoadAddr, pImportDesc->OriginalFirstThunk );
00125
00126
00127 pIteratingIAT = pIAT;
00128 unsigned cFuncs = 0;
00129 while ( pIteratingIAT->u1.Function )
00130 {
00131 cFuncs++;
00132 pIteratingIAT++;
00133 }
00134
00135 if ( cFuncs == 0 )
00136 {
00137 LOG( "no imported functions" );
00138 return false;
00139 }
00140
00141
00142
00143 DWORD flOldProtect, flNewProtect, flDontCare;
00144 MEMORY_BASIC_INFORMATION mbi;
00145
00146
00147 VirtualQuery( pIAT, &mbi, sizeof(mbi) );
00148
00149
00150 flNewProtect = mbi.Protect;
00151 flNewProtect &= ~(PAGE_READONLY | PAGE_EXECUTE_READ);
00152 flNewProtect |= (PAGE_READWRITE);
00153
00154 if ( !VirtualProtect( pIAT, sizeof(PVOID) * cFuncs,
00155 flNewProtect, &flOldProtect) )
00156 {
00157 LOG( "could not remove ReadOnly and ExecuteRead attributes, or add ReadWrite flag" );
00158 return false;
00159 }
00160
00161
00162 DLPD_IAT_STUB * pStubs = 0;
00163 if ( DLLHook->UseDefault )
00164 {
00165
00166
00167 pStubs = new DLPD_IAT_STUB[ cFuncs + 1];
00168 if ( !pStubs )
00169 {
00170 LOG( "could not allocate memory for redirection stubs" );
00171 return false;
00172 }
00173 }
00174
00175
00176
00177 pIteratingIAT = pIAT;
00178
00179 while ( pIteratingIAT->u1.Function )
00180 {
00181 void* HookFn = 0;
00182
00183 if ( !IMAGE_SNAP_BY_ORDINAL( pINT->u1.Ordinal ) )
00184 {
00185 PIMAGE_IMPORT_BY_NAME pImportName = MakePtr( PIMAGE_IMPORT_BY_NAME, pBaseLoadAddr, pINT->u1.AddressOfData );
00186
00187 LOG( "checking function with name: " << pImportName->Name );
00188
00189
00190 SFunctionHook* FHook = DLLHook->Functions;
00191 while ( FHook->Name )
00192 {
00193 if ( lstrcmpi( FHook->Name, (char*)pImportName->Name ) == 0 )
00194 {
00195
00196 FHook->OrigFn = (void*)pIteratingIAT->u1.Function;
00197 HookFn = FHook->HookFn;
00198
00199 LOG( "hooked function: " << pImportName->Name );
00200
00201 break;
00202 }
00203
00204 FHook++;
00205 }
00206
00207
00208 if ( DLLHook->UseDefault )
00209 pStubs->pszNameOrOrdinal = (DWORD)&pImportName->Name;
00210 }
00211 else
00212 {
00213 LOG( "checking function at ordinal: " << pINT->u1.Ordinal );
00214
00215 SFunctionHook* FHook = DLLHook->Functions;
00216 while ( FHook->Name )
00217 {
00218 if ( (DWORD)FHook->Name == pINT->u1.Ordinal )
00219 {
00220
00221 FHook->OrigFn = (void*)pIteratingIAT->u1.Function;
00222 HookFn = FHook->HookFn;
00223
00224 LOG( "hooked ordinal: " << pINT->u1.Ordinal );
00225
00226 break;
00227 }
00228 FHook++;
00229 }
00230
00231 if ( DLLHook->UseDefault )
00232 pStubs->pszNameOrOrdinal = (DWORD)pINT->u1.Ordinal;
00233 }
00234
00235
00236 if ( DLLHook->UseDefault )
00237 {
00238 pStubs->data_call = (DWORD)(PDWORD)DLLHook->DefaultFn
00239 - (DWORD)(PDWORD)&pStubs->instr_JMP;
00240 pStubs->data_JMP = *(PDWORD)pIteratingIAT - (DWORD)(PDWORD)&pStubs->count;
00241
00242
00243 if ( !HookFn )
00244 HookFn = (void*)pStubs;
00245 }
00246
00247
00248 if ( HookFn )
00249 {
00250
00251
00252 if ( IsBadWritePtr( (PVOID)pIteratingIAT->u1.Function, 1 ) )
00253 {
00254 pIteratingIAT->u1.Function = (DWORD)(PDWORD)HookFn;
00255 }
00256 else if ( osvi.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS )
00257 {
00258
00259
00260
00261 if ( pIteratingIAT->u1.Function > (DWORD)(PDWORD)0x80000000 )
00262 pIteratingIAT->u1.Function = (DWORD)(PDWORD)HookFn;
00263 }
00264 }
00265
00266 if ( DLLHook->UseDefault )
00267 pStubs++;
00268
00269 pIteratingIAT++;
00270 pINT++;
00271 }
00272
00273 if ( DLLHook->UseDefault )
00274 pStubs->pszNameOrOrdinal = 0;
00275
00276
00277 VirtualProtect( pIAT, sizeof(PVOID) * cFuncs, flOldProtect, &flDontCare);
00278
00279 return true;
00280 }
00281
00282
00283
00284 bool HookAPICalls( SDLLHook* hook )
00285 {
00286 if ( !hook )
00287 {
00288 LOG("no hook");
00289 return false;
00290 }
00291
00292 HMODULE hModEXE = GetModuleHandle( 0 );
00293
00294 PIMAGE_NT_HEADERS pExeNTHdr = PEHeaderFromHModule( hModEXE );
00295
00296 if ( !pExeNTHdr )
00297 {
00298 LOG("no PE header");
00299 return false;
00300 }
00301
00302 DWORD importRVA = pExeNTHdr->OptionalHeader.DataDirectory
00303 [IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress;
00304 if ( !importRVA )
00305 {
00306 LOG("no virtual address for image directory entry import");
00307 return false;
00308 }
00309
00310
00311 PIMAGE_IMPORT_DESCRIPTOR pImportDesc = MakePtr( PIMAGE_IMPORT_DESCRIPTOR,
00312 hModEXE, importRVA );
00313
00314
00315 g_pFirstImportDesc = pImportDesc;
00316
00317
00318 while ( pImportDesc->FirstThunk )
00319 {
00320 PSTR pszImportModuleName = MakePtr( PSTR, hModEXE, pImportDesc->Name);
00321
00322 if ( lstrcmpi( pszImportModuleName, hook->Name ) == 0 )
00323 {
00324 LOG( "found " << hook->Name << " in process" );
00325
00326 if ( RedirectIAT( hook, pImportDesc, (PVOID)hModEXE ) )
00327 {
00328 LOG( "redirected IAT ok" );
00329 return true;
00330 }
00331 else
00332 {
00333 LOG( "failed to redirect IAT" );
00334 }
00335 }
00336
00337 pImportDesc++;
00338 }
00339
00340 return false;
00341 }
00342