Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > C/C++ программирование > Общие вопросы C/C++
Регистрация

Восстановить пароль

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 20.07.2011, 13:29   #1
coNsept
Форумчанин
 
Аватар для coNsept
 
Регистрация: 14.12.2009
Сообщений: 716
По умолчанию Подмена dll (OpenGL)

Доброго времени суток уважаемые эксперты.

1) Есть *.exe приложение (без исходного кода)
- Приложение во время запуска загружает библиотеку opengl из системной директории
2) Есть my *.dll в адресном пространстве этого процесса
- Внедрял следующим образом (OllyDbg)
Код:
 Push MyDllName
 Call LoadLibraryA
 Push FooExport
 Push Eax
 Call GetProcAddress
 Call Eax
А вот и экспортируемая функция моей *.dll

Код:
extern "C" _declspec(dllexport) void DllExport()
{
 DWORD OldProtect;
	
 if (VirtualProtect(LPVOID(0x401000), 0x00875FFF, PAGE_EXECUTE_READWRITE, &OldProtect)) {  
  //...          
 }
 else {
  //...
 }
}
3) Мне нужно подменить загрузку оригинальной opengl на мою opengl
4) Мне нужно экспортировать адреса всех функций из оригинальной opengl в мою opengl (Уже готов все экспортируемые функции писать в ручную ибо у меня не получилось с _IMAGE ... ThirstThunk и т.д. все время получаю ошибки)
5) Вообщем мне необходимо чтобы моя *.dll раздавала opengl функции этому приложению.

п.с. Писать за меня ничего не нужно, просто дайте какие либо подсказки да и все. Например чтобы подменить *.dll и импортировать все функции из нее необходимо то-то то-то, буду благодарен за интересные ссылки на статьи либо какой любой другой материал.

Thanks a lot!

Последний раз редактировалось coNsept; 20.07.2011 в 13:32.
coNsept вне форума Ответить с цитированием
Старый 20.07.2011, 13:43   #2
pproger
C++ hater
Старожил
 
Аватар для pproger
 
Регистрация: 19.07.2009
Сообщений: 3,333
По умолчанию

в линухе есть переменная окружения LD_PRELOAD, заставляет приложение вызывать функции из твоей библиотеки вместо стандартных. гемора минимум. для твоей задачи идеальная вещь. поищи, может и под твою ос что нить подобное есть
I invented the term Object-Oriented, and I can tell you I did not have C++ in mind. (c)Alan Kay

My other car is cdr.

Q: Whats the object-oriented way to become wealthy?
A: Inheritance
pproger вне форума Ответить с цитированием
Старый 20.07.2011, 13:52   #3
coNsept
Форумчанин
 
Аватар для coNsept
 
Регистрация: 14.12.2009
Сообщений: 716
По умолчанию

Цитата:
В windows есть аналог LD_PRELOAD? угу, замену оригинальной dll-ки нужно засунуть в ту же диру что и exe-шник.
Хех, работает
coNsept вне форума Ответить с цитированием
Старый 20.07.2011, 13:58   #4
pproger
C++ hater
Старожил
 
Аватар для pproger
 
Регистрация: 19.07.2009
Сообщений: 3,333
По умолчанию

2coNsept
ага, вот только придется сделать идентичную либу, с набором таких же функций, как и в основной. а с LD_PRELOAD ты можешь определить только нужный тебе набор функций, которые ты хочешь подменить. например, реализовываешь свою strcpy, пихаешь ее в сошник, указываешь сошник в LD_PRELOAD, и приложение будет юзать твою strcpy, игнорируя стандартную

http://fy.chalmers.se/~appro/nt/DLL_PRELOAD/
I invented the term Object-Oriented, and I can tell you I did not have C++ in mind. (c)Alan Kay

My other car is cdr.

Q: Whats the object-oriented way to become wealthy?
A: Inheritance

Последний раз редактировалось pproger; 20.07.2011 в 14:06.
pproger вне форума Ответить с цитированием
Старый 20.07.2011, 22:12   #5
coNsept
Форумчанин
 
Аватар для coNsept
 
Регистрация: 14.12.2009
Сообщений: 716
По умолчанию

Еще один вопросик, пока нахожусь не дома не могу проверить, поэтому спрашиваю правильно ли я думаю.
Вообщем подставил мою opengl32.dll в директорию с приложением и как видно в коде, я загружаю оригинальную opengl32.dll из системной директории, получаю адрес оригинальной функции и присваиваю моему указателю.
То есть теперь спокойно можно юзать мой указатель как оригинальную функцию? Например как-то так:

Код:
void Render() {
 ptr_glEnable(GL_FOG);
}
Код:
#define DLLExport extern "C" __declspec(dllexport)

const int MAXLEN = 255;

void (APIENTRY *ptr_glEnable)(GLenum cap);

extern "C" _declspec(dllexport) void DllExport()
{
 DWORD OldProtect;
	
 if (VirtualProtect(LPVOID(0x401000), 0x00875FFF, PAGE_EXECUTE_READWRITE, &OldProtect)) {  
   LPSTR lpBuffer = NULL;
   GetSystemDirectoryA(lpBuffer, MAXLEN); 
   lstrcatA(lpBuffer, "\\opengl32.dll");	
   HMODULE hSystemDLL = LoadLibraryA(lpBuffer);
   (FARPROC&)ptr_glEnable = GetProcAddress(hSystemDLL, "glEnable");      
 }
}
Это канеш прикольно но мне еще интересно можно ли как-то заюзать экспортируемую функцию как-то так.

Код:
DLLExport void APIENTRY glEnable(GLenum cap) {
 // ...
 // Здесь что-то свое натворить
 // ...
}
То есть идея я думаю понятна, выполнять еще что-то в внутри экспортируемой функции когда она уходит на съедение *.exe приложением.

Последний раз редактировалось coNsept; 20.07.2011 в 22:43.
coNsept вне форума Ответить с цитированием
Старый 21.07.2011, 04:33   #6
coNsept
Форумчанин
 
Аватар для coNsept
 
Регистрация: 14.12.2009
Сообщений: 716
По умолчанию

ммм, ребят чет у меня не получается скормить псевдо gl функции *.dll -> *.exe
как это можно сделать?

Последний раз редактировалось coNsept; 21.07.2011 в 04:38.
coNsept вне форума Ответить с цитированием
Старый 21.07.2011, 14:20   #7
coNsept
Форумчанин
 
Аватар для coNsept
 
Регистрация: 14.12.2009
Сообщений: 716
По умолчанию

Up. Никто никогда не делал такого?
coNsept вне форума Ответить с цитированием
Старый 21.07.2011, 14:34   #8
pproger
C++ hater
Старожил
 
Аватар для pproger
 
Регистрация: 19.07.2009
Сообщений: 3,333
По умолчанию

2coNsept
я же тебе дал ссылку. вкури
I invented the term Object-Oriented, and I can tell you I did not have C++ in mind. (c)Alan Kay

My other car is cdr.

Q: Whats the object-oriented way to become wealthy?
A: Inheritance
pproger вне форума Ответить с цитированием
Старый 21.07.2011, 20:00   #9
coNsept
Форумчанин
 
Аватар для coNsept
 
Регистрация: 14.12.2009
Сообщений: 716
По умолчанию

pproger выручай, все кипит. Уже второй день ну никак я не могу скормить эти функции. Как я только не пытался, не одним методом, все время выходит штукенция что ниже...
И то что ты мне скинул, почитал, сделал все по примерчику, тоже не катит.
Я увэ невнаю фто дэлаць.
Googl'ил по поводу, тоже ничего толком не нашел.



Код:
typedef void (APIENTRY *ptr_glClearColor) (GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha);

static ptr_glClearColor _glClearColor = NULL, *__glClearColor;
static void APIENTRY glClearColor_(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha) {
	return (*_glClearColor)(red, green, blue, alpha);
}
Код:
bool APIENTRY DllMain (HINSTANCE hInst, DWORD dwReason, LPVOID lpReserved)
{
 DWORD                    acc;
 HMODULE                  hmod;
 IMAGE_DOS_HEADER        *dos_header;
 IMAGE_NT_HEADERS        *nt_headers;
 IMAGE_DATA_DIRECTORY    *dir;
 IMAGE_IMPORT_DESCRIPTOR *idesc;
 IMAGE_THUNK_DATA        *thunk;
 static void             *page;
 static size_t            plen;

 switch (dwReason) 
 {	
 case DLL_PROCESS_ATTACH: 
  {
   hInstance = hInst;
   My3D.Hook();		
   DisableThreadLibraryCalls(hInst);

   const int MAXLEN = 255;
   char *pBuffer = new char [MAXLEN];
   GetSystemDirectoryA(pBuffer, MAXLEN); 
   lstrcatA(pBuffer, "\\opengl32.dll");
   MessageBoxA(NULL, pBuffer, "Msg", MB_OK);
   //hOpenGL = LoadLibraryA(pBuffer);
   
   if (!(hmod = GetModuleHandle(pBuffer))) {  
    OutputDebugString("opengl32.dll not found?");
    ::ExitProcess(0);
   }

   //delete pBuffer;

   _glClearColor = (ptr_glClearColor)GetProcAddress(hmod, "glClearColor");
   _glTranslatef = (ptr_glTranslatef)GetProcAddress(hmod, "glTranslatef");

   if (!(hmod = GetModuleHandle("kernel32.DLL"))) {   
    OutputDebugString("KERNEL32.DLL not found?");
    ::ExitProcess(0);
   }

   dos_header = (IMAGE_DOS_HEADER *)hmod;
   nt_headers = (IMAGE_NT_HEADERS *)((char *)hmod + dos_header->e_lfanew);
   dir = &nt_headers->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT];
   idesc = (IMAGE_IMPORT_DESCRIPTOR *)((char *)hmod + dir->VirtualAddress);

   while (idesc->Name)	{   
    if (!stricmp((char *)hmod+idesc->Name, "opengl32.DLL")) 
     break;
    idesc++;
   }
   
   if (!idesc->Name) {   
    OutputDebugString("Can't locate opengl32.dll import descriptor");
    ::ExitProcess(0);
   }

   for (thunk = (IMAGE_THUNK_DATA *)((char *)hmod + idesc->FirstThunk);  thunk->u1.Function && thunk->u1.Function != (ULONG_PTR)_glClearColor;	thunk++);
    __glClearColor = (ptr_glClearColor *)thunk;
		
   page = __glClearColor,
   plen = (size_t)__glClearColor - (size_t)page + sizeof(void(*)()); 

   if (!VirtualProtect (page, plen, PAGE_EXECUTE_READWRITE,&acc)) {  
    OutputDebugString("Unable to unlock Thunk Table");
    ::ExitProcess(0);
   }
    
   *__glClearColor = glClearColor_;
   *__glTranslatef = glTranslatef_;

   VirtualProtect (page, plen, acc, &acc);
  }
  break;
 }
 return TRUE;
}

Последний раз редактировалось coNsept; 21.07.2011 в 21:09.
coNsept вне форума Ответить с цитированием
Старый 21.07.2011, 23:29   #10
pproger
C++ hater
Старожил
 
Аватар для pproger
 
Регистрация: 19.07.2009
Сообщений: 3,333
По умолчанию

2coNsept
ты меня извини, но у меня нет желания ставить винду и ковыряться в этом. я тебе показал, как это можно сделать просто в линуксе, тебе нужно найти, как задействовать этот же механизм в винде (по моей ссылке или еще как нить).

набросал вот тебе пример с LD_PRELOAD.
Цитата:
приложение рисует белый квадратик. будем считать, что исходного кода у нас нет, но хотим изменить цвет квадратика на красный
Код:
#include <GL/gl.h>
#include <GL/glu.h>
#include <GL/glut.h>

void init(void)
{
    glClearColor(0.0, 0.0, 0.0, 0.0);
    glShadeModel(GL_FLAT);
}

void display(void)
{
    glClear(GL_COLOR_BUFFER_BIT);
    glPushMatrix();
    glColor3f(1.0, 1.0, 1.0);
    glRectf(-25.0, -25.0, 25.0, 25.0);
    glPopMatrix();
    glutSwapBuffers();
}

void reshape(int w, int h)
{
    glViewport(0, 0, (GLsizei) w, (GLsizei) h);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    glOrtho(-50.0, 50.0, -50.0, 50.0, -1.0, 1.0);
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
}

int main(int argc, char *argv[])
{
    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);
    glutInitWindowSize(250, 250);
    glutInitWindowPosition(100, 100);
    glutCreateWindow(argv[0]);
    init();
    glutDisplayFunc(display);
    glutReshapeFunc(reshape);
    glutMainLoop();

    return 0;
}
пишем библиотеку из одной функции
Код:
#include <dlfcn.h>
#include <GL/gl.h>

void glColor3f(GLfloat r, GLfloat g, GLfloat b)
{
    void (*real_glColor3f)(GLfloat, GLfloat, GLfloat);

    void *handle = dlopen("/usr/lib/libGL.so", RTLD_LAZY);
    *(void **) (&real_glColor3f) = dlsym(handle, "glColor3f");

    real_glColor3f(r, 0.0 , 0.0);

    dlclose(handle);
}
тут видно, что мы определили функцию установки цвета, аналогичной из OpenGL. для простоты внутри нее мы достаем указатель на реальную функцию (по нормальному это нужно вынести в какой нить init) и вызываем ее с измененными аргументами. в нашей же функции помимо вызова реальной можно делать что душе угодно.

компилируем либу как динамическую
Цитата:
gcc -FPIC -shared -o color.so color.c -lGL
и запускаем наше приложение так
Цитата:
LD_PRELOAD=./color.so ./a.out
glColor3f подменится нашей функцией.

я не знаю, как это сделать в винде, и реально ли. просто говорю, что знаю погугли на эту тему (или переходи на линуксы, если возможно)

в винде я бы попробовал поправить таблицу импорта у нашего приложения. но это все слова, особо инжектом в винде не занимался

пс. еще вариант - написать свою либу с полным набором opengl функций, внутри вызывать реальные. но это геморно
I invented the term Object-Oriented, and I can tell you I did not have C++ in mind. (c)Alan Kay

My other car is cdr.

Q: Whats the object-oriented way to become wealthy?
A: Inheritance

Последний раз редактировалось pproger; 22.07.2011 в 00:03.
pproger вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Подмена сессии Linel PHP 12 31.03.2010 22:03
подмена порта Bertrance Свободное общение 9 06.02.2010 08:30
Подмена IP ? KAKTYC PHP 2 28.10.2008 00:14
Подмена клавиш martinz Win Api 19 25.11.2007 09:02