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

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

Вернуться   Форум программистов > Низкоуровневое программирование > Win Api
Регистрация

Восстановить пароль
Повторная активизация e-mail

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

Ответ
 
Опции темы Поиск в этой теме
Старый 20.12.2013, 15:08   #1
Berlioz
Изучающий C и ASM
Пользователь
 
Регистрация: 25.05.2012
Сообщений: 89
Лампочка Отстутствующая функция в DLL

Всем привет! Встала проблема:
Использую Windows 2000 SP4(машина слабая). Не так давно захотел обновить браузер (Opera@USB). Обнаружил, что в kernel32.dll нет GetUserGeoID.

Вопрос: как можно перехватить вызов на эту функцию во время инициализации таблицы импорта?

Проблема в том, что у нас не может быть оригинального адреса функции, т.к. ее просто нет, соотвтетсвенно программа вылетит еще до установки перехватчика

P.S. Видел в инете патчи ядра 2000, но им не доверяю, да и самому охота разобраться
Berlioz вне форума Ответить с цитированием
Старый 20.12.2013, 15:23   #2
Stilet
Белик Виталий :)
Старожил
 
Аватар для Stilet
 
Регистрация: 23.07.2007
Сообщений: 57,097
По умолчанию

Без вариантов. Только патчить или менять винду.
Серверные сборки ограничены, и не расчитаны на такие пользовательские действия.
I'm learning to live...
Stilet вне форума Ответить с цитированием
Старый 20.12.2013, 21:52   #3
Son Of Pain
Участник клуба
 
Регистрация: 23.12.2010
Сообщений: 1,129
По умолчанию

Я решал точно такую проблему, когда хотел запустить компилятор из visual studio 2012 под xp. В итоге пришел к написанию proxy dll. Суть такова (инструкция для visual c++):

1) Получаешь каким-то образом (через dumpbin, например) список функций, которые экспортирует kernel32.dll на твоей системе.

2) Составляешь из них .def-файл (назовем k32proxy.def) по такому принципу:
Код:
LIBRARY k32proxy
EXPORTS
ActivateActCtx=kernel32.ActivateActCtx
AddAtomA=kernel32.AddAtomA
AddAtomW=kernel32.AddAtomW
И так для всего списка. т. е. твоя длл будет перенаправлять существующие функции в kernel32.
В конец файла дописываешь недостающие функции, которые нужны браузеру, замангленные в stdcall. Примерно так:
Код:
GetThreadPreferredUILanguages=_GetThreadPreferredUILanguages@16
SetThreadPreferredUILanguages=_SetThreadPreferredUILanguages@12
Цифра после @ - размер передаваемых параметров в байтах (считаешь из объявления нужной функции в msdn).

3) Дальше, собственно, пишешь сам код длл, реализующей эти недостающие функции. При этом они должны находиться внутри блока extern "C" {}. И, очевидно, иметь _stdcall calling convention.
Тут можно либо с нуля писать реализацию, если не лень, либо вытащить дизассемблером готовую из kernel32.dll от более старшей версии винды. Если выбираешь второй вариант - нужно внимательно следить, чтобы функция не делала ничего такого, что не будет работать на твоей системе (обращение к внутренним структурам данных, имеющим другой формат, например).
А еще можно написать просто заглушку, возвращающую дефолтное значение (или ошибку), если функция не особо важна для работы программы. Или какой-то один частный случай реализовать. В общем, зависит от ситуации.

4) Теперь нужно собрать полученную длл. Примерно так:
cl /wd4273 k32proxy.cpp /link /release /dll /def:k32proxy.def /OUT:k32proxy.dll
Если ты в своей реализации заинклудишь windows.h, компилятор будет на каждую дописанную функцию выдавать предупреждение "Two definitions in a file differ in their use of dllimport", потому его отключаем.

Но не все так просто. Когда ты попытаешься сделать это - получишь от линкера пачку unresolved externals, потому что внутри kernel32.lib, поставляемого вместе с msvs, перечислены не все экспортируемые функции. Тут у тебя есть два варианта - либо просто удалить их из своего k32proxy.def (если ты уверен, что истязаемая программа не будет обращаться к ним), либо сделать дополнительный .lib-файл kernel32_.lib.
Во втором случае создаешь файл kernel32_.def, перечисляешь в нем функции, которые не отрезолвил линкер (просто названия, без =kernel32.blahblah!), пишешь команду lib /DEF:wkernel32_.def /OUT:kernel32_.lib, и дописываешь полученный kernel32_.lib в параметры линкера в команде выше.

5) И, наконец, в секции импортов той софтины, которую пытаешься запустить, меняешь "kernel32" на "k32proxy". Кладешь новорожденную дллку рядом с экзешником, плюешь трижды через левое плечо и запускаешь его )

Вроде ничего не забыл. Спрашивай, если что-то не получится.
Son Of Pain вне форума Ответить с цитированием
Старый 21.12.2013, 07:52   #4
Berlioz
Изучающий C и ASM
Пользователь
 
Регистрация: 25.05.2012
Сообщений: 89
По умолчанию

Son Of Pain, спасибо большое! Буду разбираться
Berlioz вне форума Ответить с цитированием
Ответ


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



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Почему не работает DLL - функция, содержащая CDialog? Dmitry_B Visual C++ 0 20.01.2013 10:58
Функция чтения писем в dll vovken1997 Общие вопросы Delphi 7 08.01.2013 20:45
Delph. Функция из DLL возвращает 0. Oliveyra Помощь студентам 0 01.12.2011 10:43
Функция из DLL BARNEY Фриланс 2 11.10.2011 15:32
Invalid Pointer Operation, DLL + Строковая функция Alex Cones Общие вопросы Delphi 13 18.09.2009 21:47