Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

Ошибка в dll заменяющей API функцию

32K
20 ноября 2007 года
fillVictor
4 / / 20.11.2007
Код изначально взят из статьи, но он не компилировался из-за ошибок.
Я исправил, но видимо ошибся. Помогите найти ошибку.
Вот dll
Код:
#include <windows.h>

#pragma argsused

DWORD adr_MessageBoxA;


BOOL WINAPI Intercept_MessageBoxA(HWND hwnd, char *text,
                                  char *hdr, UINT utype)
{
  //здесь вы выполняете любые свои действия
  char *str = "Hi From MessageBOX!!!!";
  // вызываем оригинальную функцию через указатель
  ((BOOL (__stdcall*)(HWND, char*, char*, UINT))adr_MessageBoxA)(hwnd,
            str, hdr, utype);
  return TRUE;
}

// Эта функция ищет в таблице импорта - .idata нужный адрес и меняет на
// адрес процедуры-двойника
void InterceptFunctions(void)
{
  // Начало отображения в памяти процесса
  BYTE *pimage = (BYTE*)GetModuleHandle(NULL);
  BYTE *pidata;
  // Стандартные структуры описания PE заголовка
  IMAGE_DOS_HEADER *idh;
  IMAGE_OPTIONAL_HEADER *ioh;
  IMAGE_SECTION_HEADER *ish;
  IMAGE_IMPORT_DESCRIPTOR *iid;
  DWORD *isd;  //image_thunk_data dword

  // Получаем указатели на стандартные структуры данных PE заголовка
  idh = (IMAGE_DOS_HEADER*)pimage;
  ioh = (IMAGE_OPTIONAL_HEADER*)(pimage + idh->e_lfanew
                                 + 4 + sizeof(IMAGE_FILE_HEADER));
  ish = (IMAGE_SECTION_HEADER*)((BYTE*)ioh + sizeof(IMAGE_OPTIONAL_HEADER));
  //если не обнаружен магический код, то у этой программы нет PE заголовка
  if (idh->e_magic != 0x5A4D)
  {
    MessageBox(NULL, "Not exe hdr", "Error!", 0);
    return;
  }

  //ищем секцию .idata
  for(int i=0; i<16; i++)
  {
    if(strcmp((char*)((ish+ i)->Name) , ".idata") == 0) break;
  if(i==16)
  {
    MessageBox(NULL, "Unable to find .idata section", "Error!", 0);
    return;
  }

  // Получаем адрес секции .idata(первого элемента IMAGE_IMPORT_DESCRIPTOR)
  iid = (IMAGE_IMPORT_DESCRIPTOR*)(pimage + (ish +i)->VirtualAddress );
 
  // Получаем абсолютный адрес функции для перехвата
  adr_MessageBoxA = (DWORD)GetProcAddress(
                        GetModuleHandle("user32.dll"), "MessageBoxA");
  if(adr_MessageBoxA == 0)
  {
    MessageBox(NULL, "Can`t get addr_MessageBoxA", "Error!", 0);
    return;
  }
  }
  // В таблице импорта ищем соответствующий элемент для
  // библиотеки user32.dll
  while(iid->Name)  //до тех пор пока поле структуры не содержит 0
  {
    if(strcmp((char*)(pimage + iid->Name), "user32.dll") ==0 ) break;
    iid++;
  }

  // Ищем в IMAGE_THUNK_DATA нужный адрес
  isd = (DWORD*)(pimage + iid->FirstThunk);
  while(*isd!=adr_MessageBoxA && *isd!=0)  isd++;
  if(*isd == 0)
  {
    MessageBox(NULL, "adr_MessageBoxA not found in .idata", "Error!", 0);
    return;
  }
 
  // Заменяем адрес на свою функцию
 
  DWORD buf =  (DWORD)&Intercept_MessageBoxA;
  DWORD op;
 
  // Обычно страницы в этой области недоступны для записи
  // поэтому принудительно разрешаем запись
  VirtualProtect((void*)(isd),4,PAGE_READWRITE, &op);

  DWORD written;

  // Пишем новый адрес
  WriteProcessMemory(GetCurrentProcess(), (void*)(isd),
                    (void*)&buf,4,&written);
  //восстанавливаем первоначальную защиту области по записи
  VirtualProtect((void*)(isd),4,op, &op);
  //если записать не удалось – увы, все пошло прахом…
  if(written!=4)
  {
    MessageBox(NULL, "Unable rewrite address", "Error!", 0);
    return;
  }
  MessageBox(NULL, "Вроде заменил.", "Инфо!", 0);
}
BOOL APIENTRY DllMain(HANDLE hModule, DWORD  ul_reason_for_call,
                      LPVOID lpReserved)
{
  if(ul_reason_for_call == DLL_PROCESS_ATTACH)
    InterceptFunctions();
  return TRUE;
}

Возникает ошибка :An exception (C0000005) occurred during DllEntryPoint or DllMain in module: ... \Project1.dll
Я предпологаю она возникает при выполнении кода
 
Код:
// В таблице импорта ищем соответствующий элемент для
  // библиотеки user32.dll
  while(iid->Name)  //до тех пор пока поле структуры не содержит 0
  {
    if(strcmp((char*)(pimage + iid->Name), "user32.dll") ==0 ) break;
    iid++;
  }
Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог