ANI鼠标指针漏洞非官方免疫补丁源代码
复制内容到剪贴板
代码:
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <stdio.h>
//----------------
typedef HANDLE (WINAPI *API_LOADIMAGEA)(HINSTANCE, LPCSTR, UINT, int, int, UINT);
typedef HANDLE (WINAPI *API_LOADIMAGEW)(HINSTANCE, LPCWSTR, UINT, int, int, UINT);
PDWORD g_pdwRVALoadImageA;
DWORD g_dwOldRVALoadImageA;
API_LOADIMAGEA g_pfnLoadImageA;
CHAR g_szWindowsDir[MAX_PATH+4];
PDWORD g_pdwRVALoadImageW;
DWORD g_dwOldRVALoadImageW;
API_LOADIMAGEW g_pfnLoadImageW;
WCHAR g_wszWindowsDir[MAX_PATH+4];
////////////////////////////////
// MyLoadImageA
////////////////////////////////
HANDLE WINAPI MyLoadImageA(
HINSTANCE hinst,
LPCSTR lpszName,
UINT uType,
int cxDesired,
int cyDesired,
UINT fuLoad)
{
//----------------
if ( hinst == NULL && ((UINT_PTR)lpszName > 0xFFFF) && uType == IMAGE_CURSOR && (fuLoad & LR_LOADFROMFILE) != 0 &&
!IsBadStringPtrA(lpszName, (UINT)-1) )
{
if ( strnicmp(lpszName, g_szWindowsDir, strlen(g_szWindowsDir)) != 0 ||
strstr(lpszName, "\\..\\") != NULL )
{
SetLastError(ERROR_ACCESS_DENIED);
return NULL;
}
}
return g_pfnLoadImageA(hinst, lpszName, uType, cxDesired, cyDesired, fuLoad);
} //MyLoadImageA()
////////////////////////////////
// MyLoadImageW
////////////////////////////////
HANDLE WINAPI MyLoadImageW(
HINSTANCE hinst,
LPCWSTR lpwszName,
UINT uType,
int cxDesired,
int cyDesired,
UINT fuLoad)
{
//----------------
if ( hinst == NULL && ((UINT_PTR)lpwszName > 0xFFFF) && uType == IMAGE_CURSOR && (fuLoad & LR_LOADFROMFILE) != 0 &&
!IsBadStringPtrW(lpwszName, (UINT)-1) )
{
if ( wcsnicmp(lpwszName, g_wszWindowsDir, wcslen(g_wszWindowsDir)) != 0 ||
wcsstr(lpwszName, L"\\..\\") != NULL )
{
SetLastError(ERROR_ACCESS_DENIED);
return NULL;
}
}
return g_pfnLoadImageW(hinst, lpwszName, uType, cxDesired, cyDesired, fuLoad);
} //MyLoadImageW()
////////////////////////////////
// HookExports
////////////////////////////////
BOOL HookExports()
{
HMODULE hm;
PIMAGE_DOS_HEADER pmz;
PIMAGE_NT_HEADERS pnt;
PIMAGE_EXPORT_DIRECTORY ped;
PDWORD pdw;
PWORD pw;
DWORD i;
DWORD dwprotect;
//---------------- locate USER32.DLL export directory
hm = GetModuleHandle("user32.dll");
if (hm == NULL)
return FALSE;
pmz = (PIMAGE_DOS_HEADER)((UINT_PTR)hm & ~0x0FFF);
if ( pmz->e_magic != IMAGE_DOS_SIGNATURE ||
pmz->e_lfanew < sizeof(*pmz) || pmz->e_lfanew > 0x0FFF )
{
return FALSE;
}
pnt = (PIMAGE_NT_HEADERS)((PBYTE)pmz + pmz->e_lfanew);
if ( pnt->Signature != IMAGE_NT_SIGNATURE ||
pnt->FileHeader.SizeOfOptionalHeader < sizeof(pnt->OptionalHeader) ||
pnt->OptionalHeader.Magic != IMAGE_NT_OPTIONAL_HDR32_MAGIC ||
pnt->OptionalHeader.NumberOfRvaAndSizes < IMAGE_DIRECTORY_ENTRY_EXPORT ||
pnt->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress == 0 ||
pnt->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].Size < sizeof(*ped) )
{
return FALSE;
}
ped = (PIMAGE_EXPORT_DIRECTORY)((PBYTE)pmz + pnt->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress);
//---------------- look up LoadImageA and LoadImageW exports
pdw = (PDWORD)((PBYTE)pmz + ped->AddressOfNames);
pw = (PWORD) ((PBYTE)pmz + ped->AddressOfNameOrdinals);
for (i = 0; i < ped->NumberOfNames; i++)
{
if (pdw[i] == 0) continue;
if (strcmp((char*)pmz + pdw[i], "LoadImageA") == 0)
{
g_pdwRVALoadImageA = (PDWORD)((PBYTE)pmz + ped->AddressOfFunctions) + (DWORD)(pw[i]);
}
else if (strcmp((char*)pmz + pdw[i], "LoadImageW") == 0)
{
g_pdwRVALoadImageW = (PDWORD)((PBYTE)pmz + ped->AddressOfFunctions) + (DWORD)(pw[i]);
}
} //for(i)
//---------------- hook USER32.DLL exports by modifying RVAs
if (g_pdwRVALoadImageA != NULL)
{
g_dwOldRVALoadImageA = *g_pdwRVALoadImageA;
g_pfnLoadImageA = (API_LOADIMAGEA)((PBYTE)pmz + g_dwOldRVALoadImageA);
if (VirtualProtect(g_pdwRVALoadImageA, sizeof(*g_pdwRVALoadImageA), PAGE_EXECUTE_READWRITE, &dwprotect))
{
*g_pdwRVALoadImageA = ((DWORD)MyLoadImageA - (DWORD)pmz);
VirtualProtect(g_pdwRVALoadImageA, sizeof(*g_pdwRVALoadImageA), dwprotect, &dwprotect);
}
else g_pdwRVALoadImageA = NULL;
} //if(g_pdwRVALoadImageA)
if (g_pdwRVALoadImageW != NULL)
{
g_dwOldRVALoadImageW = *g_pdwRVALoadImageW;
g_pfnLoadImageW = (API_LOADIMAGEW)((PBYTE)pmz + g_dwOldRVALoadImageW);
if (VirtualProtect(g_pdwRVALoadImageW, sizeof(*g_pdwRVALoadImageW), PAGE_EXECUTE_READWRITE, &dwprotect))
{
*g_pdwRVALoadImageW = ((DWORD)MyLoadImageW - (DWORD)pmz);
VirtualProtect(g_pdwRVALoadImageW, sizeof(*g_pdwRVALoadImageW), dwprotect, &dwprotect);
}
else g_pdwRVALoadImageW = NULL;
} //if(g_pdwRVALoadImageW)
return TRUE;
} //HookExports()
////////////////////////////////
// HookModuleImports
////////////////////////////////
BOOL HookModuleImports(
LPBYTE lpbImageBase)
{
PIMAGE_DOS_HEADER pmz;
PIMAGE_NT_HEADERS pnt;
PIMAGE_IMPORT_DESCRIPTOR pimp;
PDWORD pdw, pdwia;
DWORD dwprotect;
//---------------- locate import directory
pmz = (PIMAGE_DOS_HEADER)lpbImageBase;
if ( pmz->e_magic != IMAGE_DOS_SIGNATURE ||
pmz->e_lfanew < sizeof(*pmz) || pmz->e_lfanew > 0x0FFF )
{
return FALSE;
}
pnt = (PIMAGE_NT_HEADERS)((PBYTE)pmz + pmz->e_lfanew);
if ( pnt->Signature != IMAGE_NT_SIGNATURE ||
pnt->FileHeader.SizeOfOptionalHeader < sizeof(pnt->OptionalHeader) ||
pnt->OptionalHeader.Magic != IMAGE_NT_OPTIONAL_HDR32_MAGIC ||
pnt->OptionalHeader.NumberOfRvaAndSizes < IMAGE_DIRECTORY_ENTRY_IMPORT ||
pnt->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress == 0 ||
pnt->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].Size < sizeof(*pimp) )
{
return FALSE;
}
//---------------- hook USER32.DLL imports of interest
for ( pimp = (PIMAGE_IMPORT_DESCRIPTOR)((PBYTE)pmz + pnt->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress);
(LONG)(pimp->OriginalFirstThunk) > 0;
pimp++ )
{
if (pimp->TimeDateStamp != 0 && pimp->TimeDateStamp != (DWORD)-1)
continue;
if ( pimp->Name == 0 || stricmp((char*)pmz + pimp->Name, "user32.dll") != 0 || pimp->FirstThunk == 0 )
{
continue;
}
pdw = (PDWORD)((PBYTE)pmz + pimp->OriginalFirstThunk);
pdwia = (PDWORD)((PBYTE)pmz + pimp->FirstThunk);
for ( ; *pdw != 0; pdw++, pdwia++)
{
if ( strcmp(((char*)pmz + *pdw + 2), "LoadImageA") == 0 )
{
if (VirtualProtect(pdwia, sizeof(*pdwia), PAGE_EXECUTE_READWRITE, &dwprotect))
{
*pdwia = (DWORD)MyLoadImageA;
VirtualProtect(pdwia, sizeof(*pdwia), dwprotect, &dwprotect);
}
}
else if ( strcmp(((char*)pmz + *pdw + 2), "LoadImageW") == 0 )
{
if (VirtualProtect(pdwia, sizeof(*pdwia), PAGE_EXECUTE_READWRITE, &dwprotect))
{
*pdwia = (DWORD)MyLoadImageW;
VirtualProtect(pdwia, sizeof(*pdwia), dwprotect, &dwprotect);
}
}
} //for(*pdw)
} //for(pimp->OriginalFirstThunk>0)
return TRUE;
} //HookModuleImports()
////////////////////////////////
// HookImports
////////////////////////////////
BOOL HookImports()
{
LPVOID lpv;
MEMORY_BASIC_INFORMATION mbi;
char szmodule[MAX_PATH+4];
//---------------- scan virtual memory for loaded images
for ( lpv = NULL;
(VirtualQuery(lpv, &mbi, sizeof(mbi)) == sizeof(mbi)) && (mbi.RegionSize > 0);
lpv = (LPBYTE)lpv + mbi.RegionSize )
{
if (mbi.BaseAddress != mbi.AllocationBase || mbi.State != MEM_COMMIT || mbi.Type != MEM_IMAGE)
continue;
if (GetModuleFileName((HMODULE)mbi.AllocationBase, szmodule, sizeof(szmodule)) == 0)
continue;
__try
{
HookModuleImports((LPBYTE)mbi.AllocationBase);
}
__except(1)
{
;
}
} //for(lpv)
return FALSE;
} //HookImports()
////////////////////////////////
// DllMain
////////////////////////////////
BOOL WINAPI DllMain(
HINSTANCE hinstDLL,
DWORD fdwReason,
LPVOID lpvReserved)
{
UINT c;
//----------------
switch (fdwReason)
{
case DLL_PROCESS_ATTACH:
g_pdwRVALoadImageA = NULL;
g_pdwRVALoadImageW = NULL;
c = GetWindowsDirectoryA(g_szWindowsDir, sizeof(g_szWindowsDir));
if (c == 0 || c >= sizeof(g_szWindowsDir))
break;
g_szWindowsDir[c] = 0;
c = GetWindowsDirectoryW( g_wszWindowsDir, (sizeof(g_wszWindowsDir) / sizeof(g_wszWindowsDir[0])) );
if ( c == 0 || c >= (sizeof(g_szWindowsDir) / sizeof(g_wszWindowsDir[0])) )
break;
g_szWindowsDir[c] = 0;
if (HookExports())
{
HookImports();
}
break;
} //switch(fdwReason)
return TRUE;
} //DllMain()