2015-11-25 2 views
3

У меня есть доступ к 32-битной dll из 64-разрядного приложения. Для этого я использую Shared Memory IPC, и я сделал что-то вроде этогоМожно ли загрузить dll в общую память?

TCHAR szName[]=TEXT(Path of DLL on local machine); 
TCHAR szMsg[]=TEXT("abc"); 

HANDLE file = CreateFile(szName,     
         GENERIC_READ,   
         0,      
         NULL,     
         CREATE_NEW,    
         FILE_ATTRIBUTE_NORMAL, 
         NULL); 

ли это правильный подход, чтобы разделить DLL злоумышленником IPC? Могу ли я получить доступ к функциям, определенным внутри DLL на интерфейсе считывателя?

+1

Извините, это не имеет смысла, если вы не уточните многое дальше. Забудьте о 32b против 64b на секунду. Как бы вы «делили DLL на IPC» и «обращались к функциям, определенным внутри DLL на интерфейсе считывателя», если оба конца были одинаковой битности, скажем, 32b? Возможно, вы имеете в виду http://stackoverflow.com/questions/128445/calling-32bit-code-from-64bit-process. – dxiv

ответ

5

Это по определению невозможно назвать 32-разрядной функцией из 64-битного кода. Процессор ведет себя по-разному в 32-битном и 64-битном режимах. ОС может делать разные вещи для 32-разрядных и 64-битных приложений, устанавливая селектор сегмента кода в 32- и 64-разрядный режим соответственно, но это большой переключатель для всего приложения.

  • 32-разрядные вызовы имеют 64-битный код для разных вызовов. (64-разрядный режим использует регистры для первых 5-6 аргументов для всех вызовов, 32-битный режим - только 3 аргумента, а не для всех функций). Общее использование регистров (для которых используются регистры), поэтому регистры, которые необходимо сохранить в 32-битном, не нужны в 64-битном бите и так далее.

  • 32-разрядные операции очищают верхнюю часть 64-разрядных регистров, хотят они этого или нет. Поэтому просто установка eax на 5 изменит верхние 64-разрядные значения eax, которые 32-разрядный код не знает даже.

  • Указатели в 64-разрядном режиме выделены в полном 64-битном диапазоне [ну, 47 бит, но это все еще 15 бит более 32], поэтому вы не сможете передавать какие-либо указатели на называемый кодом, даже если бы не существовала одна из других проблем.

  • push и pop инструкции с регистром операнда теперь 64-бит (независимо от того, хотите ли это или нет), так что 32-битный код будет сохранять регистры думать, что они занимают 4 байта стека, и они будут принимать up 8, то есть любое смещение от вычисления указателя стека будет неправильным внутри вызываемой функции - включая общую последовательность: push ebp и mov ebp, esp, значение esp в настоящее время не так.

  • Некоторые инструкции больше недоступны или доступны только в их альтернативной форме. В частности, байтовые значения 0x40-0x4f являются «префиксом» для 64-битных инструкций, а не инструкциями, которые они использовали.

  • Любые вызовы из вашего «импортированного кода» будут рассматриваться как 64-разрядные, поэтому вызовы OS, вызовы библиотеки C и т. Д. Будут работать некорректно.

Конечно, вы можете прочитать файл, транскрибировать его в 64-битном режиме, но это потребует огромное количество работы в придумывают с переводчиком, который понимает код и может перевести его это (так вам нужно знать, что такое фактический код, и что, например, скачкообразные таблицы для операторов switch или текстовых строк, встроенных в сегмент кода, которые не должны быть переведены, по крайней мере, не таким же образом).

Скорее всего, в 10 раз проще перекомпилировать код как 64-битный. Или перекомпилируйте свое 64-битное приложение как 32-битное (это почти наверняка вариант EASIEST).

3

Если вы не можете перекомпилировать эту DLL как 64-битную, то вы, ваш единственный выбор, действительно IPC, но не так, как вы ее описываете. Вам нужно будет написать дополнительное приложение, давайте назовите его dllwrapper32.exe, который будет загружать вашу 32-битную DLL и выставлять ее интерфейс с помощью некоторого метода IPC.Ваше 64-битное приложение будет использовать этот метод IPC для связи с 32-разрядной dll над процессом dllwrapper32.exe.

Вы также можете написать 64-разрядную оболочку dll, которая будет взаимодействовать между 64-битным процессом и dllwrapper32.exe. Таким образом, чтобы визуализировать основную идею:

     ^-- loads ----> [32 bit dll] 
        /
      [dllwrapper32.exe] <---- IPC -----> [64 bit process] 

теперь с 64 битным обертку DLL:

     ^-- loads ----> [32 bit dll] 
        /
      [dllwrapper32.exe] <---- IPC -----> [64 bit wrapper dll] 
                  /\ 
          [64 bit process] - loads ----' 

IPC может быть aything вы хотите:

  • Clipboard
  • COM
  • данных Копия
  • DDE
  • File Mapping
  • почтовые слоты
  • Трубы
  • RPC для Windows
  • Sockets

Я полагаю, COM будет порекомендован.

Так что в конце концов - много работы.

+0

Может ли труба использоваться здесь, например, для связи между двумя отдельными процессами, без какой-либо общей предки? –

+0

Я полагаю, что да, выбор метода IPC должен зависеть от того, как выглядит ваш DLL-api, если вы хотите получить доступ к одной функции api, тогда вы можете использовать более низкий уровень IPC-aproach, если у вас есть много функций для выставления, тогда COM может быть лучше. – marcinj

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