Форум: "WinAPI";
Текущий архив: 2002.08.29;
Скачать: [xml.tar.bz2];
ВнизLastMsgBoxInfo. Переват API-вызовов Найти похожие ветки
← →
StAL (2002-05-29 19:33) [0]В книге Рихтера приводится утилита LastMsgBoxInfo, которая перехватывает функции MessageBoxA и MessageBoxW.
А мне бы такое на DELPHI! Пожалуйста, помогите перевести!
Вот исходники на с++ из 4-го издания:
/******************************************************************************
Module: APIHook.cpp
Notices: Copyright (c) 2000 Jeffrey Richter
******************************************************************************/
#include "..\CmnHdr.h"
#include <ImageHlp.h>
#pragma comment(lib, "ImageHlp")
#include "APIHook.h"
#include "..\04-ProcessInfo\Toolhelp.h"
///////////////////////////////////////////////////////////////////////////////
// When an application runs on Windows 98 under a debugger, the debugger
// makes the module"s import section point to a stub that calls the desired
// function. To account for this, the code in this module must do some crazy
// stuff. These variables are needed to help with the crazy stuff.
// The highest private memory address (used for Windows 98 only)
PVOID CAPIHook::sm_pvMaxAppAddr = NULL;
const BYTE cPushOpCode = 0x68; // The PUSH opcode on x86 platforms
///////////////////////////////////////////////////////////////////////////////
// The head of the linked-list of CAPIHook objects
CAPIHook* CAPIHook::sm_pHead = NULL;
///////////////////////////////////////////////////////////////////////////////
CAPIHook::CAPIHook(PSTR pszCalleeModName, PSTR pszFuncName, PROC pfnHook,
BOOL fExcludeAPIHookMod) {
if (sm_pvMaxAppAddr == NULL) {
// Functions with address above lpMaximumApplicationAddress require
// special processing (Windows 98 only)
SYSTEM_INFO si;
GetSystemInfo(&si);
sm_pvMaxAppAddr = si.lpMaximumApplicationAddress;
}
m_pNext = sm_pHead; // The next node was at the head
sm_pHead = this; // This node is now at the head
// Save information about this hooked function
m_pszCalleeModName = pszCalleeModName;
m_pszFuncName = pszFuncName;
m_pfnHook = pfnHook;
m_fExcludeAPIHookMod = fExcludeAPIHookMod;
m_pfnOrig = GetProcAddressRaw(
GetModuleHandleA(pszCalleeModName), m_pszFuncName);
chASSERT(m_pfnOrig != NULL); // Function doesn"t exist
if (m_pfnOrig > sm_pvMaxAppAddr) {
// The address is in a shared DLL; the address needs fixing up
PBYTE pb = (PBYTE) m_pfnOrig;
if (pb[0] == cPushOpCode) {
// Skip over the PUSH op code and grab the real address
PVOID pv = * (PVOID*) &pb[1];
m_pfnOrig = (PROC) pv;
}
}
// Hook this function in all currently loaded modules
ReplaceIATEntryInAllMods(m_pszCalleeModName, m_pfnOrig, m_pfnHook,
m_fExcludeAPIHookMod);
}
///////////////////////////////////////////////////////////////////////////////
CAPIHook::~CAPIHook() {
// Unhook this function from all modules
ReplaceIATEntryInAllMods(m_pszCalleeModName, m_pfnHook, m_pfnOrig,
m_fExcludeAPIHookMod);
// Remove this object from the linked list
CAPIHook* p = sm_pHead;
if (p == this) { // Removing the head node
sm_pHead = p->m_pNext;
} else {
BOOL fFound = FALSE;
// Walk list from head and fix pointers
for (; !fFound && (p->m_pNext != NULL); p = p->m_pNext) {
if (p->m_pNext == this) {
// Make the node that points to us point to the our next node
p->m_pNext = p->m_pNext->m_pNext;
break;
}
}
chASSERT(fFound);
}
}
///////////////////////////////////////////////////////////////////////////////
// NOTE: This function must NOT be inlined
FARPROC CAPIHook::GetProcAddressRaw(HMODULE hmod, PCSTR pszProcName) {
return(::GetProcAddress(hmod, pszProcName));
}
///////////////////////////////////////////////////////////////////////////////
// Returns the HMODULE that contains the specified memory address
static HMODULE ModuleFromAddress(PVOID pv) {
MEMORY_BASIC_INFORMATION mbi;
return((VirtualQuery(pv, &mbi, sizeof(mbi)) != 0)
? (HMODULE) mbi.AllocationBase : NULL);
}
section
}
См. следующее сообщение
← →
StAL (2002-05-29 19:39) [1]Какое-то section влезло. Его там нет. Дальше:
///////////////////////////////////////////////////////////////////////////////
void CAPIHook::ReplaceIATEntryInAllMods(PCSTR pszCalleeModName,
PROC pfnCurrent, PROC pfnNew, BOOL fExcludeAPIHookMod) {
HMODULE hmodThisMod = fExcludeAPIHookMod
? ModuleFromAddress(ReplaceIATEntryInAllMods) : NULL;
// Get the list of modules in this process
CToolhelp th(TH32CS_SNAPMODULE, GetCurrentProcessId());
MODULEENTRY32 me = { sizeof(me) };
for (BOOL fOk = th.ModuleFirst(&me); fOk; fOk = th.ModuleNext(&me)) {
// NOTE: We don"t hook functions in our own module
if (me.hModule != hmodThisMod) {
// Hook this function in this module
ReplaceIATEntryInOneMod(
pszCalleeModName, pfnCurrent, pfnNew, me.hModule);
}
}
}
///////////////////////////////////////////////////////////////////////////////
void CAPIHook::ReplaceIATEntryInOneMod(PCSTR pszCalleeModName,
PROC pfnCurrent, PROC pfnNew, HMODULE hmodCaller) {
// Get the address of the module"s import section
ULONG ulSize;
PIMAGE_IMPORT_DESCRIPTOR pImportDesc = (PIMAGE_IMPORT_DESCRIPTOR)
ImageDirectoryEntryToData(hmodCaller, TRUE,
IMAGE_DIRECTORY_ENTRY_IMPORT, &ulSize);
if (pImportDesc == NULL)
return; // This module has no import section
// Find the import descriptor containing references to callee"s functions
for (; pImportDesc->Name; pImportDesc++) {
PSTR pszModName = (PSTR) ((PBYTE) hmodCaller + pImportDesc->Name);
if (lstrcmpiA(pszModName, pszCalleeModName) == 0)
break; // Found
}
if (pImportDesc->Name == 0)
return; // This module doesn"t import any functions from this callee
// Get caller"s import address table (IAT) for the callee"s functions
PIMAGE_THUNK_DATA pThunk = (PIMAGE_THUNK_DATA)
((PBYTE) hmodCaller + pImportDesc->FirstThunk);
// Replace current function address with new function address
for (; pThunk->u1.Function; pThunk++) {
// Get the address of the function address
PROC* ppfn = (PROC*) &pThunk->u1.Function;
// Is this the function we"re looking for?
BOOL fFound = (*ppfn == pfnCurrent);
if (!fFound && (*ppfn > sm_pvMaxAppAddr)) {
// If this is not the function and the address is in a shared DLL,
// then maybe we"re running under a debugger on Windows 98. In this
// case, this address points to an instruction that may have the
// correct address.
PBYTE pbInFunc = (PBYTE) *ppfn;
if (pbInFunc[0] == cPushOpCode) {
// We see the PUSH instruction, the real function address follows
ppfn = (PROC*) &pbInFunc[1];
// Is this the function we"re looking for?
fFound = (*ppfn == pfnCurrent);
}
}
if (fFound) {
// The addresses match, change the import section address
WriteProcessMemory(GetCurrentProcess(), ppfn, &pfnNew,
sizeof(pfnNew), NULL);
return; // We did it, get out
}
}
// If we get to here, the function is not in the caller"s import section
}
///////////////////////////////////////////////////////////////////////////////
// Hook LoadLibrary functions and GetProcAddress so that hooked functions
// are handled correctly if these functions are called.
CAPIHook CAPIHook::sm_LoadLibraryA ("Kernel32.dll", "LoadLibraryA",
(PROC) CAPIHook::LoadLibraryA, TRUE);
CAPIHook CAPIHook::sm_LoadLibraryW ("Kernel32.dll", "LoadLibraryW",
(PROC) CAPIHook::LoadLibraryW, TRUE);
CAPIHook CAPIHook::sm_LoadLibraryExA("Kernel32.dll", "LoadLibraryExA",
(PROC) CAPIHook::LoadLibraryExA, TRUE);
CAPIHook CAPIHook::sm_LoadLibraryExW("Kernel32.dll", "LoadLibraryExW",
(PROC) CAPIHook::LoadLibraryExW, TRUE);
CAPIHook CAPIHook::sm_GetProcAddress("Kernel32.dll", "GetProcAddress",
(PROC) CAPIHook::GetProcAddress, TRUE);
← →
StAL (2002-05-29 19:46) [2]
///////////////////////////////////////////////////////////////////////////////
void CAPIHook::FixupNewlyLoadedModule(HMODULE hmod, DWORD dwFlags) {
// If a new module is loaded, hook the hooked functions
if ((hmod != NULL) && ((dwFlags & LOAD_LIBRARY_AS_DATAFILE) == 0)) {
for (CAPIHook* p = sm_pHead; p != NULL; p = p->m_pNext) {
ReplaceIATEntryInOneMod(p->m_pszCalleeModName,
p->m_pfnOrig, p->m_pfnHook, hmod);
}
}
}
///////////////////////////////////////////////////////////////////////////////
HMODULE WINAPI CAPIHook::LoadLibraryA(PCSTR pszModulePath) {
HMODULE hmod = ::LoadLibraryA(pszModulePath);
FixupNewlyLoadedModule(hmod, 0);
return(hmod);
}
///////////////////////////////////////////////////////////////////////////////
HMODULE WINAPI CAPIHook::LoadLibraryW(PCWSTR pszModulePath) {
HMODULE hmod = ::LoadLibraryW(pszModulePath);
FixupNewlyLoadedModule(hmod, 0);
return(hmod);
}
///////////////////////////////////////////////////////////////////////////////
HMODULE WINAPI CAPIHook::LoadLibraryExA(PCSTR pszModulePath,
HANDLE hFile, DWORD dwFlags) {
HMODULE hmod = ::LoadLibraryExA(pszModulePath, hFile, dwFlags);
FixupNewlyLoadedModule(hmod, dwFlags);
return(hmod);
}
///////////////////////////////////////////////////////////////////////////////
HMODULE WINAPI CAPIHook::LoadLibraryExW(PCWSTR pszModulePath,
HANDLE hFile, DWORD dwFlags) {
HMODULE hmod = ::LoadLibraryExW(pszModulePath, hFile, dwFlags);
FixupNewlyLoadedModule(hmod, dwFlags);
return(hmod);
}
///////////////////////////////////////////////////////////////////////////////
FARPROC WINAPI CAPIHook::GetProcAddress(HMODULE hmod, PCSTR pszProcName) {
// Get the true address of the function
FARPROC pfn = GetProcAddressRaw(hmod, pszProcName);
// Is it one of the functions that we want hooked?
CAPIHook* p = sm_pHead;
for (; (pfn != NULL) && (p != NULL); p = p->m_pNext) {
if (pfn == p->m_pfnOrig) {
// The address to return matches an address we want to hook
// Return the hook function address instead
pfn = p->m_pfnHook;
break;
}
}
return(pfn);
}
//////////////////////////////// End of File //////////////////////////////////
← →
StAL (2002-05-29 19:51) [3]DLL:
/******************************************************************************
Module: LastMsgBoxInfoLib.cpp
Notices: Copyright (c) 2000 Jeffrey Richter
******************************************************************************/
#define WINVER 0x0500
#include "..\CmnHdr.h"
#include <WindowsX.h>
#include <tchar.h>
#include <stdio.h>
#include "APIHook.h"
#define LASTMSGBOXINFOLIBAPI extern "C" __declspec(dllexport)
#include "LastMsgBoxInfoLib.h"
///////////////////////////////////////////////////////////////////////////////
// Prototypes for the hooked functions
typedef int (WINAPI *PFNMESSAGEBOXA)(HWND hWnd, PCSTR pszText,
PCSTR pszCaption, UINT uType);
typedef int (WINAPI *PFNMESSAGEBOXW)(HWND hWnd, PCWSTR pszText,
PCWSTR pszCaption, UINT uType);
// We need to reference these variables before we create them.
extern CAPIHook g_MessageBoxA;
extern CAPIHook g_MessageBoxW;
///////////////////////////////////////////////////////////////////////////////
// This function sends the MessageBox info to our main dialog box
void SendLastMsgBoxInfo(BOOL fUnicode,
PVOID pvCaption, PVOID pvText, int nResult) {
// Get the pathname of the process displaying the message box
char szProcessPathname[MAX_PATH];
GetModuleFileNameA(NULL, szProcessPathname, MAX_PATH);
// Convert the return value into a human-readable string
PCSTR pszResult = "(Unknown)";
switch (nResult) {
case IDOK: pszResult = "Ok"; break;
case IDCANCEL: pszResult = "Cancel"; break;
case IDABORT: pszResult = "Abort"; break;
case IDRETRY: pszResult = "Retry"; break;
case IDIGNORE: pszResult = "Ignore"; break;
case IDYES: pszResult = "Yes"; break;
case IDNO: pszResult = "No"; break;
case IDCLOSE: pszResult = "Close"; break;
case IDHELP: pszResult = "Help"; break;
case IDTRYAGAIN: pszResult = "Try Again"; break;
case IDCONTINUE: pszResult = "Continue"; break;
}
// Construct the string to send to the main dialog box
char sz[2048];
wsprintfA(sz, fUnicode
? "Process: (%d) %s\r\nCaption: %S\r\nMessage: %S\r\nResult: %s"
: "Process: (%d) %s\r\nCaption: %s\r\nMessage: %s\r\nResult: %s",
GetCurrentProcessId(), szProcessPathname,
pvCaption, pvText, pszResult);
// Send the string to the main dialog box
COPYDATASTRUCT cds = { 0, lstrlenA(sz) + 1, sz };
FORWARD_WM_COPYDATA(FindWindow(NULL, TEXT("Last MessageBox Info")),
NULL, &cds, SendMessage);
}
///////////////////////////////////////////////////////////////////////////////
// This is the MessageBoxW replacement function
int WINAPI Hook_MessageBoxW(HWND hWnd, PCWSTR pszText, LPCWSTR pszCaption,
UINT uType) {
// Call the original MessageBoxW function
int nResult = ((PFNMESSAGEBOXW)(PROC) g_MessageBoxW)
(hWnd, pszText, pszCaption, uType);
// Send the information to the main dialog box
SendLastMsgBoxInfo(TRUE, (PVOID) pszCaption, (PVOID) pszText, nResult);
// Return the result back to the caller
return(nResult);
}
///////////////////////////////////////////////////////////////////////////////
// This is the MessageBoxA replacement function
int WINAPI Hook_MessageBoxA(HWND hWnd, PCSTR pszText, PCSTR pszCaption,
UINT uType) {
// Call the original MessageBoxA function
int nResult = ((PFNMESSAGEBOXA)(PROC) g_MessageBoxA)
(hWnd, pszText, pszCaption, uType);
// Send the infomration to the main dialog box
SendLastMsgBoxInfo(FALSE, (PVOID) pszCaption, (PVOID) pszText, nResult);
// Return the result back to the caller
return(nResult);
}
///////////////////////////////////////////////////////////////////////////////
// Hook the MessageBoxA and MessageBoxW functions
CAPIHook g_MessageBoxA("User32.dll", "MessageBoxA",
(PROC) Hook_MessageBoxA, TRUE);
CAPIHook g_MessageBoxW("User32.dll", "MessageBoxW",
(PROC) Hook_MessageBoxW, TRUE);
// Since we do DLL injection with Windows" hooks, we need to save the hook
// handle in a shared memory block (Windows 2000 actually doesn"t need this)
#pragma data_seg("Shared")
HHOOK g_hhook = NULL;
#pragma data_seg()
#pragma comment(linker, "/Section:Shared,rws")
///////////////////////////////////////////////////////////////////////////////
← →
RV (2002-05-29 20:55) [4]Присоединяюсь к просьбе....
или даже как можно сделать:
есть dll1.dll, в крой есть функция function1
//
function1(x,y:integer):integer;
begin
result:=x+y;
end;
//
Задача: перехватить вызов
и в вызывающую прогу передать (result+1)
← →
VuDZ (2002-05-29 22:10) [5]а что именно вызывает сложность?
← →
Gluka (2002-05-30 02:37) [6]Уважаемый СТАЛ (или кто-нить) если есть ета глава с книги рихтера в електронном виде, то можно мне на мыло или Линк!!!!
С Ув. -=[Gluka]=-
← →
RV (2002-05-30 08:26) [7]to VuDZ
си я не знаю, даже синтаксис каже непонятным...
на делфях глобальные ловушки на сообщения ставить умею,
ну что-то типа клавиатурного шпиона писать умею, но там опять же сообщение надо перехватить, а тут функцию надо забить.
← →
StAL (2002-05-30 14:02) [8]Спасибо, что прочитали.
2RV Ловушки я тоже ставить умею, и клавиатурного шпиона. А мне именно перехват API нужен.
2Gluka
Книга у меня на компакте в электронном виде, только на аглицком. Могу прислать.
Спасибо за ответы.
StAL
← →
paul_shmakov (2002-05-30 15:41) [9]идя на поводу популярности темы я давно уже начал писать аналог: набор классов на Delphi для перехвата вызовов, на 50% уже готово, а вот на остальные 50 все времени не хватает.
но так как интерес снова возрос, обязуюсь докончить этот код в ближайшее время и выложить в кладовку.
← →
ZZ (2002-05-30 16:12) [10]Gluka
если есть ета глава с книги рихтера в електронном виде, то можно мне на мыло или Линк!!!!
Посмотри на сайте Anatoly Podgoretsky http://www.podgoretsky.com/
← →
RV (2002-05-31 08:31) [11]Мне в общем то тоже перехват API нужен (to StAL)
но говорю же, на худой конец хоть перехватить фцию, крую я чуть выше описал.
Знатоки, неужели так это сложно на Делфях сделать?!
Пожалуйста, хоть как нибудь, не надо наворотов по универсальности перехвата и т.п., просто один пример (на Делфи, стствено) - век благодарен буду.
to paul_shmakov
Буду ждать, если не трудно отпишите по окончанию в эту ветку
← →
StAL (2002-05-31 19:47) [12]Спасибо всем, кто ответил.
To paul_shmakov
Пожалуйста, докончите.
Очень надо.
Еще раз спаибо всем
← →
SHREK2002 (2002-06-02 02:52) [13]В своё время долго возился с такой же бодягой, и переделал кучу исходников с Cи и т.п.
Все есть - причем практически на все случаи жизни.
но тебе бы посоветовал не мучиться, скачать и посмотреть примеры из APIHOOKS
http://www.anticracking.sk/EliCZ/export/AH38.ZIP
посмотри - там есть много чего интересного
есть новая APIHOOKS 5.5 APIKernelHooks и т.п.
у меня есть исходники APIHooks 2.2 на ASM
Это DLL с интерфейсами к Delphi, C++, ASM
специально для перехвата API функций
C тебя ПИВО!!!
← →
SHREK2002 (2002-06-02 03:38) [14]В принципе весь смысл основного (классического) способа перехвата API функций:
1) Пишем DLL которая при своей инициализации корректирует IAT (Import Address Table) нашего PE-файла (программы) - меняет там адрес необходимой API функции на адрес своей функции - описанной в этой DLL.
2) Любым из возможных способов внедряем эту DLL в адресное пространство нашей программы.
3) Ну вот вроде и всё!
А в APIHOOKS вы пишите DLL c экспортируемой структурой в которой описываются все адреса и способы перехвата необходимых функций.
И программу, которая запускает процесс, внедряет в него DLL и перехватывает указанные функции.
Перечитал - сумбурно и криво объяснил, но для подробностей см. исходники примеров - там все понятно.
← →
SHREK2002 (2002-06-03 19:09) [15]С точки зрения банальной эрудиции не каждый индивидум способен противостоять тенденциям парадоксальных эмоций
← →
StAL (2002-06-05 10:43) [16]2SHREK2002
Спасибо. Это безусловно мне очень помогло, но я хотел сам научиться перехватывать API. Что-то вроде самому научиться писать такую ДЛЛ. И еще там отсутствует какой-то processworks. Наверное для получения PID"ов.
Спасибо всем.
2paul_shmakov
Не закончили еще.
ЗЫ
SHREK2002, насчет пива могу в JPG :)
← →
shrek2002 (2002-06-13 01:15) [17]не понимаю людей, которым дали адрес сайта и они на нем не могут найти 2 файла им необходимых
На сайте прямым текстом написаны названия всех библиотек - качай все что понадобиться
А если ты хочешь сам научиться писать такие DLL - то сначала почитай про PE формат. И неужели так сложно переделать исходник с C++ или хотя бы понять смысл.
Я тебе API HOOK могу тоже в jPG
← →
StAL (2002-06-14 16:54) [18]2SHREK2002
Спасибо. ДЛЛку я нашел, а с С++ на Дельфи ни как не могу переделать. А очень нужно.
На счет пива, я имел ввиду, что не могу тебе его прислать. По почте что-ли???
А так еще раз всем спасибо.
2paul_shmakov
Пожалуйста, закончите скорее и, если можно пришлите мне на эмэйл, когда закончите.
С уважением, StAL.
← →
Digitman (2002-06-14 18:41) [19]способ "в лоб".
непричесанный, но - вполне работоспособный
неленивый - причешет)
uses
windows;
type
PImageThunkData = ^TImageThunkData;
TImageThunkData = packed record
case Byte of
0: (ForwarderString: PByte);
1: (Func: PLongWord);
2: (Ordinal: LongWord);
3: (AddressOfData: PLongWord);
end;
PImageImportDescriptor = ^TImageImportDescriptor;
TImageImportDescriptor = packed record
RVAImportLookupTable: LongWord;
TimeDateStamp: LongWord;
FowarderChain: LongWord;
RVAImportModuleName: LongWord;
RVAImportAddressTable: LongWord;
end;
...
function GetBoundImportAddress(hImporter: THandle; pModuleName, pFuncName: PChar; pImportDirectoryInfo: PImageDataDirectory): PLongWord;
const
SIZE_OF_NT_SIGNATURE = SizeOf(DWord);
var
hExporter: THandle;
dwExpAddr: LongWord;
pIDD: PImageDataDirectory;
pIOH: PImageOptionalHeader;
pIID: PImageImportDescriptor;
pITD: PImageThunkData;
begin
Result := nil;
if hImporter = 0 then
hImporter := GetModuleHandle(nil)
else
if FindhInstance(Pointer(hImporter)) <> hImporter then
Exit;
hExporter := GetModuleHandle(pModuleName);
Win32Check(hExporter <> 0);
dwExpAddr := DWord(GetProcAddress(hExporter, pFuncName));
Win32Check(dwExpAddr <> 0);
pIOH := PImageOptionalHeader(hImporter + PImageDosHeader(hImporter)._lfanew + SIZE_OF_NT_SIGNATURE + IMAGE_SIZEOF_FILE_HEADER);
pIDD := PImageDataDirectory(@pIOH.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT]);
if Assigned(pImportDirectoryInfo) then
with pImportDirectoryInfo^ do
begin
VirtualAddress := hImporter + pIDD.VirtualAddress;
Size := pIDD.Size;
end;
if pIDD.Size = 0 then
Exit;
pIID := PImageImportDescriptor(hImporter + pIDD.VirtualAddress);
while Assigned(PChar(pIID.RVAImportModuleName)) do
begin
if lstrcmpi(PChar(hImporter + pIID.RVAImportModuleName), pModuleName) <> 0 then
Inc(pIID)
else
begin
pITD := PImageThunkData(hImporter + LongWord(pIID.RVAImportAddressTable));
while Assigned(pITD.Func) do
if pITD.Func = PLongWord(dwExpAddr) then
begin
Result := @pITD.Func;
Exit;
end
else
Inc(pITD);
end;
end;
end;
....
var
OldProtect, OldAddr: DWord;
pAddr: PLongWord = nil;
procedure SetHook;
var
hProcess: Thandle;
begin
pAddr := GetBoundImportAddress(0, "msvcrt.dll", "free", nil);
if Assigned(pAddr) then
begin
hProcess := OpenProcess(PROCESS_VM_OPERATION, False, ProcessId);
try
if VirtualProtectEx(GetCurrentProcess, pAddr, SizeOf(pAddr^), PAGE_EXECUTE_READWRITE, OldProtect) then
begin
OldAddr := pAddr^;
pAddr^ := LongWord(@hooked_free);
VirtualProtectEx(GetCurrentProcess, pAddr, SizeOf(pAddr^), OldProtect, OldProtect);
end;
finally
CloseHandle(hProcess);
end;
end;
end;
procedure ResetHook;
var
hProcess: Thandle;
begin
if Assigned(pAddr) then
begin
hProcess := OpenProcess(PROCESS_VM_OPERATION, False, ProcessId);
try
if VirtualProtectEx(GetCurrentProcess, pAddr, SizeOf(pAddr^), PAGE_EXECUTE_READWRITE, OldProtect) then
begin
OldAddr := pAddr^;
pAddr^ := OldAddr;
VirtualProtectEx(GetCurrentProcess, pAddr, SizeOf(pAddr^), OldProtect, OldProtect);
end;
finally
CloseHandle(hProcess);
end;
end;
end;
← →
SHREK2002 (2002-06-15 20:18) [20]Если есть желание узнать побольше сходите на www.codemanual.net и посмотрите исходники Hook Development Kit (Михаил Любушкин).
Все написано на C++, но в в архиве есть прекрасная документация по этому делу - советую почитать - много интересного http://www.codemanual.net/windows/samples/Hdk.zip
← →
StAL (2002-06-17 13:57) [21]Спасибо всем.
2Digitman.
GetBoundImportAddress почему-то зависает в бесконечном цикле.
Или это я тупой. Не могли бы Вы подсказать, в чем тут дело?
Еще раз спасибо, что откликнулись.
С уважением, StAL
← →
StAL (2002-06-20 11:05) [22]Ну пожалуйста, кто-нибудь. Скажите, что не так.
2SHREK2002 Скачал. Спасибо. Но ВСЕ РАВНО НИЧЕГО НЕ ПОЛУЧАЕТСЯ.
ПОМОГИТЕ!!!
← →
a_k_v (2002-06-24 06:55) [23]2StaL
Дигитмэн же писал: ...неленивый причешет
цикл бесконечный из-за while Assigned(pITD.Func) do
попробуй: while Assigned(pITD) do
там еще есть пара мест для причесывания но они очевидны
← →
Digitman (2002-06-24 08:31) [24]вот этот вар-т чуть более "причесан" :
type
PImageThunkData = ^TImageThunkData;
TImageThunkData = packed record
case Byte of
0: (ForwarderString: PByte);
1: (Func: PLongWord);
2: (Ordinal: LongWord);
3: (AddressOfData: PLongWord);
end;
PImageImportDescriptor = ^TImageImportDescriptor;
TImageImportDescriptor = packed record
RVAImportLookupTable: LongWord;
TimeDateStamp: LongWord;
FowarderChain: LongWord;
RVAImportModuleName: LongWord;
RVAImportAddressTable: LongWord;
end;
function GetBoundImportAddress(hImporter: THandle; pModuleName, pFuncName: PChar; pImportDirectoryInfo: PImageDataDirectory): PLongWord;
const
SIZE_OF_NT_SIGNATURE = SizeOf(DWord);
var
hExporter: THandle;
dwExpAddr: LongWord;
pIDD: PImageDataDirectory;
pIOH: PImageOptionalHeader;
pIID: PImageImportDescriptor;
pITD: PImageThunkData;
begin
Result := nil;
if hImporter = 0 then
hImporter := GetModuleHandle(nil)
else
if FindhInstance(Pointer(hImporter)) <> hImporter then
Exit;
hExporter := GetModuleHandle(pModuleName);
Win32Check(hExporter <> 0);
dwExpAddr := DWord(GetProcAddress(hExporter, pFuncName));
Win32Check(dwExpAddr <> 0);
pIOH := PImageOptionalHeader(hImporter + PImageDosHeader(hImporter)._lfanew + SIZE_OF_NT_SIGNATURE + IMAGE_SIZEOF_FILE_HEADER);
pIDD := PImageDataDirectory(@pIOH.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT]);
if Assigned(pImportDirectoryInfo) then
with pImportDirectoryInfo^ do
begin
VirtualAddress := hImporter + pIDD.VirtualAddress;
Size := pIDD.Size;
end;
if pIDD.Size = 0 then
Exit;
pIID := PImageImportDescriptor(hImporter + pIDD.VirtualAddress);
while Assigned(PChar(pIID.RVAImportModuleName)) do
begin
if lstrcmpi(PChar(hImporter + pIID.RVAImportModuleName), pModuleName) = 0 then
begin
pITD := PImageThunkData(hImporter + LongWord(pIID.RVAImportAddressTable));
while Assigned(pITD.Func) do
if pITD.Func = PLongWord(dwExpAddr) then
begin
Result := @pITD.Func;
Exit;
end
else
Inc(pITD);
end;
Inc(pIID)
end;
end;
//pModuleName - имя импортируемого модуля,
//pFuncName - имя ф-ции, имп. из модуля (чувствительно к регистру !!)
//lpProcAddr - новый адрес
//Result - старый адрес
function SetProcAddress(pModuleName, pFuncName: PChar; lpProcAddr: Pointer): Pointer;
var
hProcess: Thandle;
lpAddr: PLongWord;
dwProtect: DWord;
begin
Result := nil;
lpAddr := GetBoundImportAddress(0, pModuleName, pFuncName, nil);
if Assigned(lpAddr) then
begin
hProcess := OpenProcess(PROCESS_VM_OPERATION, False, GetCurrentProcessId);
try
if VirtualProtectEx(hProcess, lpAddr, SizeOf(lpAddr^), PAGE_EXECUTE_READWRITE, dwProtect) then
begin
Result := Pointer(lpAddr^);
lpAddr^ := LongWord(lpProcAddr);
VirtualProtectEx(hProcess, lpAddr, SizeOf(lpAddr^), dwProtect, dwProtect);
end;
finally
CloseHandle(hProcess);
end;
end;
end;
пример вызова :
type
TSetJmp = function(pJmpBuf: Pointer): Integer; cdecl;
var
pOriginal_SetJmp: TSetJmp;
...
function Hooked_SetJmp(pJmpBuf: PJumpBuffer): Integer; cdecl;
begin
...
asm
pop ebp
jmp [pOriginal_SetJmp]
end;
end;
//set hook
@pOriginal_SetJmp := SetProcAddress("msvcrt.dll", "_setjmp", @Hooked_SetJmp);
//reset hook
@pOriginal_SetJmp := SetProcAddress("msvcrt.dll", "_setjmp", @pOriginal_SetJmp);
← →
StAL (2002-06-26 11:38) [25]Спасибо всем за ответы, и, особенно, Digitman, НО
у меня все равно не получается. Я пытаюсь перехватить MessageBoxA и GetBoundImportAddress все время возвращает Nil. Может нюанс какой есть?
Функция точно импортируется. USER32.MessageBoxA
ПОЖАЛУЙСТА, ПОМОГИТЕ!!!
← →
Digitman (2002-06-26 13:33) [26]>>"точно импортируется"
Не уверен. Возможно, ты путаешь понятия "экспорт" и "импорт" в модульном контексте.
Приведи фрагмент своего кода вызова SetProcAddr().
Страницы: 1 вся ветка
Форум: "WinAPI";
Текущий архив: 2002.08.29;
Скачать: [xml.tar.bz2];
Память: 0.56 MB
Время: 0.008 c