Написал чуток кода по перехвату функций вызовов DLL. Его навалом в 1С++, только в том и дело, что он там выглядит убого, по-хакерски без комментариев и вообще жестоко, т.к. там сплошные указатели, в которых запутаться - 1 секунда. Копирование циклом 6-и байт for(i = 0; i<6;i++)... меня добило. Может, так будет кому полезней? (да, что это не лучший способ перехвата - мне известно, но так уж повелось что он применяется в 1С++ повсеместно)
_______________
//SFnOverrideStruct.hpp
// License: free, not Gnu!
#ifndef SFNOVERRIDESTRUCT_HPP
#define SFNOVERRIDESTRUCT_HPP
#if USE_PRAGMA_ONCE
#pragma once
#endif
struct SFnOverrideStruct
{
struct SSixBytes
{
BYTE m_aBytes[6];
};
BOOL ProcessOverride(TCHAR* p_acDllName,
char* p_acFunctionName,
FARPROC p_pFnNew);
void Restore();
void QuickOverride();
SSixBytes m_sixbytesOldBytes;
FARPROC m_pFunctionPointerOld;
FARPROC m_pFunctionPointerNew;
};
#endif //SFNOVERRIDESTRUCT_HPP
_________________
//SFnOverrideStruct.cpp
// License: free, not Gnu!
#include "stdafx.hpp"
#include "SFnOverrideStruct.hpp"
#define OPCODE_RELATIVE_JMP 0x25FF
///////////////////////////////////////////////////////////////////////////////
// Function : ProcessOverride
// Author : Suslo P.
// Date : 16.12.2006
//-----------------------------------------------------------------------------
// Parameters :
// [in] TCHAR* p_acDllName - dll name
// [in] char* p_acFunctionName - function name
// [in] FARPROC p_pFnNew - n_e_w function pointer
// Description : overrides function p_acFunctionName of DLL p_acDllName by
// p_pFnNew
// License: free, not Gnu!
// Output : nonzero on success, otherwise 0
///////////////////////////////////////////////////////////////////////////////
BOOL SFnOverrideStruct:
rocessOverride(TCHAR* p_acDllName,
char* p_acFunctionName,
FARPROC p_pFnNew)
{
//--- fill the struct
m_pFunctionPointerNew = (FARPROC)p_pFnNew;
HINSTANCE l_hMouleHandle=GetModuleHandle(p_acDllName);
DWORD oldProtect;
m_pFunctionPointerOld=GetProcAddress(l_hMouleHandle, p_acFunctionName);
m_sixbytesOldBytes = *(SSixBytes*)m_pFunctionPointerOld;
//--- override
VirtualProtect(m_pFunctionPointerOld,
6,
PAGE_EXECUTE_READWRITE,
&oldProtect);
QuickOverride();
//---
return !FALSE;
}
///////////////////////////////////////////////////////////////////////////////
// Function : QuickOverride
// Author : Suslo P.
// License: free, not Gnu!
// Date : 16.12.2006
//-----------------------------------------------------------------------------
// Description : Overrides function. ProcessOverride must be executed once before.
///////////////////////////////////////////////////////////////////////////////
void SFnOverrideStruct::QuickOverride()
{
BYTE* l_pAddr = (BYTE*)m_pFunctionPointerOld;
*(WORD*)l_pAddr= OPCODE_RELATIVE_JMP;
l_pAddr+=2;
*(DWORD*)l_pAddr=(DWORD)&m_pFunctionPointerNew;
}
///////////////////////////////////////////////////////////////////////////////
// Function : Restore
// Author : Suslo P.
// License: free, not Gnu!
// Date : 16.12.2006
//-----------------------------------------------------------------------------
// Description : Restores function out of the override
///////////////////////////////////////////////////////////////////////////////
void SFnOverrideStruct::Restore()
{
*(SSixBytes*)m_pFunctionPointerOld = m_sixbytesOldBytes;
}
-----------------------------
//test cpp
#include "stdafx.hpp"
#include "SFnOverrideStruct.hpp"
SFnOverrideStruct g_overrideStruct;
// test override of MessageBox
int WINAPI MessageBoxA_Override(HWND hWnd,
LPCSTR lpText,
LPCSTR lpCaption,
UINT uType)
{
//--- preprocess
Beep(300, 300);
//--- call base
g_overrideStruct.Restore();
int l_nRetVal = MessageBoxA(hWnd,
lpText,
lpCaption,
uType);
g_overrideStruct.QuickOverride();
//--- postprocess
Beep(400, 300);
return l_nRetVal;
}
void main()
{
//--- no beeps before override
MessageBoxA(NULL, "Test", "Test_", MB_OK);
//--- override
g_overrideStruct.ProcessOverride(_T("user32.dll"),
"MessageBoxA",
(FARPROC)MessageBoxA_Override);
//--- it is a call of an overrided function
MessageBoxA(NULL, "Test2", "Test2_", MB_OK);
}