Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "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.57 MB
Время: 0.007 c
3-95664
vovanx
2002-08-08 10:14
2002.08.29
TQuery


14-95942
Александр
2002-08-02 12:48
2002.08.29
Совместимость ПО с Windows XP


3-95640
Kyt
2002-08-07 16:41
2002.08.29
Insert в откатываемой транзакции


3-95637
DeniM
2002-08-07 16:51
2002.08.29
Как же все-таки правильно написать SQL запрос в дельфи? (+)


1-95850
Viacheslav
2002-08-17 22:17
2002.08.29
.rc-файлы (файлы ресурсов)





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский