2016-10-09 3 views
0

Мы пытаемся понять некоторые более тонкие детали определения символа во время выполнения. Я уже рассмотрелДжеффри Рихтера, главы 19 (Основы DLL) и 20 (DLL Advanced). Рихтер немного более всеобъемлющий и более сплоченный, чем MSDN.Связывание неявных библиотек и GetModuleHandle/GetProcAdress

Мы пытаемся объединить неявное соединение библиотек с динамическим расположением символов. Мы хотим избежать звонков на LoadLibrary из-за некоторых потенциальных угроз безопасности. Мы также пытаемся избежать проблем с блокировкой загрузчика , если пользователь делает слишком много работы в функции DllMain.

#include <windows.h> 
#pragma comment(lib, "kernel32") 

extern "C" { 
    typedef BOOL (WINAPI * PFN_GOR)(HANDLE, LPOVERLAPPED, LPDWORD, BOOL); 
    typedef BOOL (WINAPI * PFN_GORX)(HANDLE, LPOVERLAPPED, LPDWORD, DWORD, BOOL); 
} 
int main(int argc, char* argv[]) 
{ 
    HINSTANCE hInst = GetModuleHandle("kernel32"); 
    PFN_GOR pfn1 = hInst ? (PFN_GOR)GetProcAddress(hInst, "GetOverlappedResult") : NULL; 
    PFN_GORX pfn2 = hInst ? (PFN_GORX)GetProcAddress(hInst, "GetOverlappedResultEx") : NULL; 

    std::cout << "kernel32: " << std::hex << (void*)hInst << std::endl; 
    std::cout << "GetOverlappedResult: " << std::hex << (void*)pfn1 << std::endl; 
    std::cout << "GetOverlappedResultEx: " << std::hex << (void*)pfn2 << std::endl; 

    return 0; 
} 

Мы отчасти повезло с GetOverlappedResult и GetOverlappedResultEx, потому что kernel32.dll обеспечивает им обоим независимо от платформы. kernel32.dll имеет еще одно приятное свойство, потому что каждое приложение Windows ссылается на него, и нет способа его вывести из строя.

Случайные числа с платформы выглядят немного более хлопотными. В Windows 7 и ниже мы имеем CryptGenRandom от advapi32.dll; в то время как Windows 10 и выше использует BCryptGenRandom от bcrypt.dll. Windows 8 - это серая область, потому что некоторые версии, такие как Windows Phone 8, ничего не предлагают. Мы считаем, что мы можем защитить включение библиотеки на основе WINVER или _WINNT_VER.

Я чувствую, что образец неявной связи библиотек в сочетании с GetModuleHandle и GetProcAdress необычен, но он соответствует нашим требованиям. Его необычный, потому что он использует неявное связывание и GetModuleHandle, а не LoadLibrary. Я также не могу найти текст, который запрещает неявное связывание и GetModuleHandle.

Он отвечает нашим требованиям, потому что мы не несем ответственности за небезопасную загрузку библиотеки из-за бинарной посадки и других трюков перенаправления DLL. Мы также избежим DoS'ов от случайного неправильного использования, сделав слишком много в DLLmain.

Мой вопрос в том, является ли код юридической комбинацией или узором. Если это дефектный шаблон, то в чем дефект?


Мы поддерживаем Windows XP и Visual Studio .Net через Windows, 10/10 Телефон/Магазин 10 с помощью Visual Studio 2015

В Windows XP код дает следующий результат:

>cl.exe /TP /EHsc test.cxx /Fetest.exe 
... 
>.\test.exe 
kernel32: 7D4C0000 
GetOverlappedResult: 7D52E12C 
GetOverlappedResultEx: 00000000 

в Windows 7 код дает следующий результат:

>cl.exe /TP /EHsc test.cxx /Fetest.exe 
... 
>.\test.exe 
kernel32: 772A0000 
GetOverlappedResult: 772CCC69 
GetOverlappedResultEx: 00000000 

в Windows 8, код выдает следующий результат (Windows 10 аналогична):

>cl.exe /TP /EHsc test.cxx /Fetest.exe 
... 
>.\test.exe 
kernel32: 74FD0000 
GetOverlappedResult: 74FEF8C0 
GetOverlappedResultEx: 7675C4D0 

В Windows 8 и 10 мы можем проверить только кросс-компилировать и компоновать с подсказкой ARM Developer.Мы тестируем компиляции для рабочего стола, телефона и магазина с помощью следующих дополнительных CXXFLAGS:

  • Чтобы проверить приложение рабочего стола, добавьте следующие CXXFLAGS:
    • /DWINAPI_FAMILY=WINAPI_FAMILY_DESKTOP_APP
  • Для тестирования приложения Windows Store, добавить следующие CXXFLAGS:
    • /DWINAPI_FAMILY=WINAPI_FAMILY_APP
  • Чтобы проверить Windows Phone, добавьте следующие CXXFLAGS:
    • /DWINAPI_FAMILY=WINAPI_FAMILY_PHONE_APP
  • Чтобы проверить Surface RT (ARM таблетки), добавьте следующие CXXFLAGS:
    • /D_ARM_WINAPI_PARTITION_DESKTOP_SDK_AVAILABLE=1 /DWINAPI_FAMILY=WINAPI_FAMILY_DESKTOP_APP

Я нахожу много хитов, как Implicit vs. Explicit linking to a DLL, но я не смог найти тот, который рассматривает некоторые из вопросов безопасности, которые LoadLibrary может наложить, и как избежать LoadLibrary вообще.

+0

Для тех, кому это интересно, вот комментарий к вопросу, который мы оцениваем и пытаемся: [комментарий 233405697] (http://github.com/weidai11/cryptopp/issues/178#issuecomment-233405697). – jww

+0

После прочтения ссылки github, похоже, вы пытаетесь получить свой минимум. и целевые платформы должным образом реализованы. Я бы предложил другое решение этой проблемы в целом: используйте [Поддержка компоновщика для DLL с задержкой] (https://msdn.microsoft.com/en-us/library/151kt790.aspx), укажите целевую версию через символы препроцессора , и изящно обрабатывать недоступные функции, предоставляя пользовательские функции задержки загрузки [вспомогательные функции] (https://msdn.microsoft.com/en-us/library/09t6x5ds.aspx). – IInspectable

+1

Я полагаю, вы уже знаете об этом, но для того, чтобы рассказать об этом для будущих читателей, этот подход не будет работать для Windows Phone, и я не думаю, что он будет работать и для UWP. Если вы их поддерживаете, вам придется использовать условную компиляцию, но это не будет означать '_WIN32_WINNT', который, похоже, вас раздражает. –

ответ

3

Здесь нечего сказать. Совершенно законно использовать GetProcAddress с ручкой модуля, полученной по телефону GetModuleHandle.

Обновление: Я написал это на основе оригинальной формы вопроса, которая не давала понять, что вопрос предназначен для покрытия мобильных платформ, а также рабочего стола.

+0

Спасибо, Дэвид. Это то, что я подумал, но я хотел убедиться, что я ничего не пропустил. Позвольте мне дать другим людям время для обратной связи. Я соглашусь, если нет дефектов. Еще раз спасибо. – jww

+0

Дэвид, возможно, вам стоит взвесить обсуждение в комментариях, особенно если я ошибаюсь, думая, что это не будет работать в сборке Store/Phone/UWP. (GetModuleHandle документируется как только для настольных компьютеров, но из того, что OP говорит, что этот код действительно строит без жалобы. Возможно, это приведет к отказу проверки?) –

Смежные вопросы