Показать сообщение отдельно

  #38  
Старый 22.03.2009, 15:57
criz
Постоянный
Регистрация: 04.11.2007
Сообщений: 303
С нами: 9746420

Репутация: 119
Question

Доброго времени суток! На rsdn есть статья, сделал все как там написано. Скомпилил dll-ку "перехватчик", затем написал прогу:
Код:
#include <windows.h>

int main(int argc, char* argv[])
{
  LoadLibrary("C:\\test.dll");
  MessageBox(NULL, "Test", "test", MB_OK);

  return 0;
}
Вылетает экзепшн. Подскажите плиз где ошибка?
P.S. вот исходник дллки:
Код:
// dll.cpp : Defines the entry point for the DLL application.
//

#include "stdafx.h"
#include <windows.h>
#include "dll.h"

void IntFunc(void);
BOOL WINAPI NewMessage(HWND hwnd, char *text, char *hdr, UINT utype);

#pragma pack(push, 1)
struct jmp_far
{
	BYTE instr_push;
	DWORD arg;
	BYTE instr_ret;
};
#pragma pack(pop)

BYTE old[6];
DWORD adr_MessageBoxA;
DWORD written;
jmp_far jump;

BOOL WINAPI Intercept_MessageBoxA(HWND hwnd, char *text, char *hdr, UINT utype)
{
  //Сначала восстанавливаем 6 первых байт функции. Это не обязательное 
  // действие, просто мы решили подшутить над пользователем, и все 
  // сообщения функции MessageBoxA переделать на свои, поэтому нам придется
  // вызвать оригинальную функцию, а для этого следует восстановить ее адрес:
  WriteProcessMemory(GetCurrentProcess(), (void*)adr_MessageBoxA, 
                     (void*)&old, 6, &written);

  //Здесь вы можете порезвиться от души и выполнить любые, пришедшие вам 
  // в голову действия. Мы просто заменили сообщение функции на свое:
  char *str = "Hi From MessageBOX!!!!";

  //Вызываем оригинальную функцию через указатель
  ((BOOL (__stdcall*)(HWND, char*, char*, UINT))adr_MessageBoxA)(hwnd, 
             str, hdr, utype);

  //Снова заменяем  6 байт функции на команду перехода на нашу функцию
  WriteProcessMemory(GetCurrentProcess(), (void*)adr_MessageBoxA, 
                     (void*)&jump, 6,&written);
  return TRUE;
}

void InterceptFunctions(void)
{
  DWORD op;
  //сначала получим абсолютный адрес функции для перехвата
  adr_MessageBoxA = (DWORD)GetProcAddress(GetModuleHandle("user32.dll"),
                    "MessageBoxA");
  if(adr_MessageBoxA == 0)
  {
    MessageBox(NULL, "Can`t get adr_MessageBoxA", "Error!", 0);
    return;
  }

  // Зададим машинный код инструкции перехода, который затем впишем 
  // в начало полученного адреса:
  jump.instr_push = 0x68;
  jump.arg = (DWORD)&Intercept_MessageBoxA;
  jump.instr_ret = 0xC3;

  //Прочитаем и сохраним первые оригинальные 6 байт стандартной API функции
  ReadProcessMemory(GetCurrentProcess(),(void*) adr_MessageBoxA, 
                    (void*)&old, 6, &written);

//Запишем команду перехода на нашу функцию поверх этих 6-ти байт
WriteProcessMemory(GetCurrentProcess(), (void*)adr_MessageBoxA, 
     (void*)&jump, sizeof(jmp_far), &written);
}

BOOL APIENTRY DllMain( HANDLE hModule, 
                       DWORD  ul_reason_for_call, 
                       LPVOID lpReserved
					 )
{
  if(ul_reason_for_call == DLL_PROCESS_ATTACH )
  {
    InterceptFunctions();
  }
  return TRUE;
}
 
Ответить с цитированием