Программирование на Visual C++. Архив рассылки
Шрифт:
if (IS_INTRESOURCE(szEntry)) {
// By ordinal
while(pNamesTable->u1.AddressOfData) {
if (IMAGE_SNAP_BY_ORDINAL(pNamesTable->u1.Ordinal) && WORD(szEntry) == IMAGE_ORDINAL(pNamesTable->u1.Ordinal)) {
hr = S_OK;
break;
}
pNamesTable++;
}
} else {
// By name
while(pNamesTable->u1.AddressOfData) {
if (!IMAGE_SNAP_BY_ORDINAL(pNamesTable->u1.Ordinal)) {
PIMAGE_IMPORT_BY_NAME pName = MakePtr(PIMAGE_IMPORT_BY_NAME, hModule, pNamesTable->u1.AddressOfData);
if (0 == ::lstrcmpiA(LPSTR(pName->Name), szEntry)) {
hr = S_OK;
break;
}
}
pNamesTable++;
}
}
if (SUCCEEDED(hr)) {
// Get address
LPVOID *pProc = MakePtr(LPVOID *, pNamesTable, pImpDesc->FirstThunk - pImpDesc->OriginalFirstThunk);
// Save original handler
if (ppOrig) *ppOrig = *pProc;
// write to write-protected memory
return WriteProtectedMemory(pProc, &pHijacker, sizeof(LPVOID));
}
break;
}
pImpDesc++;
}
return hr;
}
HRESULT WriteProtectedMemory(LPVOID pDest, LPCVOID pSrc, DWORD dwSize) {
// Make it writable
DWORD dwOldProtect = 0;
if (::VirtualProtect(pDest, dwSize, PAGE_READWRITE, &dwOldProtect)) {
::MoveMemory(pDest, pSrc, dwSize);
// Restore protection
::VirtualProtect(pDest, dwSize, dwOldProtect, &dwOldProtect);
return S_OK;
}
return HRESULT_FROM_WIN32(GetLastError);
}
Впрочем,
HRESULT ApiHijackExports(HMODULE hModule, LPSTR szEntry, LPVOID pHijacker, LPVOID *ppOrig) {
// Check args
if ((!IS_INTRESOURCE(szEntry) && ::IsBadStringPtrA(szEntry, -1)) || ::IsBadCodePtr(FARPROC(pHijacker))) {
return E_INVALIDARG;
}
PIMAGE_DOS_HEADER pDosHeader = PIMAGE_DOS_HEADER(hModule);
if (::IsBadReadPtr(pDosHeader, sizeof(IMAGE_DOS_HEADER)) || IMAGE_DOS_SIGNATURE != pDosHeader->e_magic) {
return E_INVALIDARG;
}
PIMAGE_NT_HEADERS pNTHeaders =
MakePtr(PIMAGE_NT_HEADERS, hModule, pDosHeader->e_lfanew);
if (::IsBadReadPtr(pNTHeaders, sizeof(IMAGE_NT_HEADERS)) || IMAGE_NT_SIGNATURE != pNTHeaders->Signature) {
return E_INVALIDARG;
}
HRESULT hr = E_UNEXPECTED;
IMAGE_DATA_DIRECTORY& expDir =
pNTHeaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT];
PIMAGE_EXPORT_DIRECTORY pExpDir =
MakePtr(PIMAGE_EXPORT_DIRECTORY, hModule, expDir.VirtualAddress);
LPDWORD pdwAddrs = MakePtr(LPDWORD, hModule, pExpDir->AddressOfFunctions);
LPWORD pdwOrd = MakePtr(LPWORD, hModule, pExpDir->AddressOfNameOrdinals);
DWORD dwAddrIndex = -1;
if (IS_INTRESOURCE(szEntry)) {
// By ordinal
dwAddrIndex = WORD(szEntry) - pExpDir->Base;
hr = S_OK;
} else {
// By name
LPDWORD pdwNames = MakePtr(LPDWORD, hModule, pExpDir->AddressOfNames);
for (DWORD iName = 0; iName < pExpDir->NumberOfNames; iName++) {
if (0 == ::lstrcmpiA(MakePtr(LPSTR, hModule, pdwNames[iName]), szEntry)) {
dwAddrIndex = pdwOrd[iName];
hr = S_OK;
break;
}
}
}
if (SUCCEEDED(hr)) {
if (pdwAddrs[dwAddrIndex] >= expDir.VirtualAddress && pdwAddrs[dwAddrIndex] < expDir.VirtualAddress + expDir.Size) {
// We have a redirection
LPSTR azRedir = MakePtr(LPSTR, hModule, pdwAddrs[dwAddrIndex]);
ATLASSERT(!IsBadStringPtrA(azRedir, -1));
LPSTR azDot = strchr(azRedir, '.');
int nLen = azDot - azRedir;
LPSTR azModule = (LPSTR)alloca(nLen);
memcpy(azModule, azRedir, nLen);
azModule[nLen] = '\x0';
// Try to patch redirected function
return ApiHijackExports(
::GetModuleHandle(azModule), azDot + 1, pHijacker, ppOrig);
}
if (ppOrig)
Поделиться с друзьями: