Сейчас на форуме: jinoweb, bartolomeo (+5 невидимых)

 eXeL@B —› Программирование —› Windows PE-файл ручками: эфективаная загрузка dll
Посл.ответ Сообщение

Ранг: 3.0 (гость)
Активность: 0=0
Статус: Участник

Создано: 02 декабря 2016 12:02
· Личное сообщение · #1

Доброго времени суток и приятного прочтения,
Я тут решил по заниматься садо-программированием PE на Ассемблере, то есть
Code:
  1. PE_Signature db 'MZ'
и т.д. И вроде всё шло очень даже прилично(ещё не компилировал, но вроде как проблем в понимании написанного не возникало) и тут я добрался до import table и вообщем загрузки модулей, где как раз и началось недопонимание. Хочется сделать всё максимально эффективно(чтоб клик по иконке, а окошко уже 10 секунд как открыто), сначала думал обойтись вообще без таблиц импорта: вылавливать kernel32.dll и через него подгружать нужные библиотеки чуть ли не кусками в удобные места моего кода, позже начал рассматривать статическое связывание. И тут информации почти нет: вроде как есть таблица куда заносишь имя библиотеки и версию, он проверяет версию и если она совпадает, тогда он её грузит. Только там нет указания адреса, то есть (насколько я понял) он грузит её по imageBase, которая для 90% dll = 0x10000000, а это значит - все кроме первой dll будут загружены по другим адресам и при этом сам PE-загрузчик ни куда не возвращает новый адрес загрузки. А если самому грузить, то к чему вообще этот вид связывания и тогда надо через динамическую линковку грузить первую kernel32.dll как минимум.
В общем: как лучше(быстро) всё это грузить? если через статику, то как правильно, да вообще как? и kernel32 можно ли выловить по быстренькому?

Честно говоря я вообще не рассчитываю на скорость со стороны PE-загрузчика Windows.
Конкретные библиотеки: user32, vulkan-1(не то что бы я убийцу ГТА собрался писать, просто ведьмака3 хочу оптимально переписать) - тут у меня вопрос: vulkan поставляется производителем ГП вместе с дровами, а значит что размер dll может отличаться, а если это внешний общий api, который на всех компах одинаков, значит он переадресует на другие dll(которые уже от производителя) - будет ли статика здесь приемлема?

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



Ранг: 590.6 (!), 408thx
Активность: 0.360.18
Статус: Модератор

Создано: 02 декабря 2016 12:55
· Личное сообщение · #2

Ты задачу бы описал что ли. Начал за здравие, а кончил за упокой.
Динамическое связывание - это LoadLibrary + GetProcAddress. Получить базу загруженного модуля можно через GetModuleHandle с оговорками.
Статическое связывание у тебя отрабатывает система при CreateProcess.
Загрузка по разным базам корректируется через релоки. Системные dll предзагружены по "фиксированным" адресам.

-----
старый пень





Ранг: 338.5 (мудрец), 348thx
Активность: 2.112.42
Статус: Участник

Создано: 02 декабря 2016 13:12
· Личное сообщение · #3

Ruins007

> И тут информации почти нет: вроде как есть таблица куда заносишь имя библиотеки и версию, он проверяет версию и если она совпадает, тогда он её грузит.

Сформулируйте свои мысли более корректно и чётко, а так совсем не понятно. Вы хотите реализовать свой загрузчик или для каких то целей(каких?) использовать системный ?

-----
vx




Ранг: 3.0 (гость)
Активность: 0=0
Статус: Участник

Создано: 02 декабря 2016 14:27 · Поправил: Ruins007
· Личное сообщение · #4

Я специально вынес отдельно,
Ruins007 пишет:
В общем: как лучше(быстро) всё это грузить? если через статику, то как правильно, да вообще как? и kernel32 можно ли выловить по быстренькому?

Я рассматриваю разные способы загрузки dll. Мне интересно какой способ даёт максимум скорости при запуске Шник.exe? и как этот способ правильно использовать?

Добавлено спустя 6 минут
r_e пишет:
Динамическое связывание - это LoadLibrary + GetProcAddress. Получить базу загруженного модуля можно через GetModuleHandle с оговорками.
Статическое связывание у тебя отрабатывает система при CreateProcess.


Описание таблицы импорта cs.usu.edu.ru/



Ранг: 71.2 (постоянный), 33thx
Активность: 0.050.12
Статус: Участник

Создано: 02 декабря 2016 15:51 · Поправил: kunix
· Личное сообщение · #5

Максимальную скорость даст склеить все EXE и DLL в один модуль, при этом пофиксив импорты, релоки, ресурсы и т.д., проставить прямые адреса в системных библиотеках в таблицу импорта и вырезать ее, вырезать релоки.
И положить все это говно на RAMDISK.
Только нахера? Все равно создание процесса - операци достаточно быстрая, кроме совсем уже извращенных случаев.



Ранг: 3.0 (гость)
Активность: 0=0
Статус: Участник

Создано: 02 декабря 2016 16:10
· Личное сообщение · #6

Так каким образом мне "проставить прямые адреса в системных библиотеках"?
kunix пишет:
Только нахера? Все равно создание процесса - операци достаточно быстрая, кроме совсем уже извращенных случаев.

Это не для практичного решения, а скорей интерес в создания максимально быстрого импорта



Ранг: 71.2 (постоянный), 33thx
Активность: 0.050.12
Статус: Участник

Создано: 02 декабря 2016 16:13 · Поправил: kunix
· Личное сообщение · #7

Все просто.
Пройтись по таблице импорта каждого модуля и проставить туда нужные адреса в системных библиотеках.
Потому убрать таблицу импорта из модулей, чтобы загрузчик PE не обрабатывал ее еще раз.
И конечно же, отключить ASLR для данного процесса, чтобы системные DLL имели всегда нужные адреса.
А вообще вы маетесь херней.



Ранг: 431.7 (мудрец), 390thx
Активность: 0.730.32
Статус: Участник

Создано: 02 декабря 2016 17:02 · Поправил: dosprog
· Личное сообщение · #8

Не надо заниматься бесполезными вещами.
Загрузка DLL "более эффективная", чем системным загрузчиком, всё равно не получится.

Можно залепить PE-файл вообще без PE-таблицы импорта,
то есть весь импорт загружать динамически (LoadLibrary/GetProcAddress) из программы.
Но зачем такое нужно?

Что касается "моделирования PE" - тоже бесполезная затея.
Не надо напрягать транслятор самодельными эквивалентами функционала линковщика.

Кстати, посмотрите, как всё это организовано в FASM'е.




Ранг: 88.2 (постоянный), 111thx
Активность: 0.070.01
Статус: Участник

Создано: 02 декабря 2016 18:29
· Личное сообщение · #9

Просто ему заняться нечем, вот и мозги сношает. У баб тоже так, когда заняться нечем - мозг сношают, а так борщ отправляешь варить и все нормально




Ранг: 338.5 (мудрец), 348thx
Активность: 2.112.42
Статус: Участник

Создано: 03 декабря 2016 03:07 · Поправил: difexacaw
· Личное сообщение · #10

ТС так и не ответил, ну ладно. Обычно пытаются примитивными методами реализовать загрузку - разбор пе, вот недавно заспамила все форумы примитивная поделка --> Link <--

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

В любом случае это решение не системное, это костыль. Нэйтивный лодер слишком сложный, в нём реализовано столь много механизмов, что даже их зная, вспомнить и перечислить не представляется возможным.

За всё время было лишь одно приемлемое и эффективное решение, но это не просто примитивная реализация работы с пе - враппер над системным лодером(LWE). Оно было реализовано под ось младших версий, но подход оказался крайне годным - в каждой новой версии системы оно робит без ошибок или багов.

-----
vx




Ранг: 3.0 (гость)
Активность: 0=0
Статус: Участник

Создано: 05 декабря 2016 20:42
· Личное сообщение · #11

И на том спасибо, ладно буду всё таки import table использовать.


 eXeL@B —› Программирование —› Windows PE-файл ручками: эфективаная загрузка dll
:: Ваш ответ
Жирный  Курсив  Подчеркнутый  Перечеркнутый  {mpf5}  Код  Вставить ссылку 
:s1: :s2: :s3: :s4: :s5: :s6: :s7: :s8: :s9: :s10: :s11: :s12: :s13: :s14: :s15: :s16:


Максимальный размер аттача: 500KB.
Ваш логин: german1505 » Выход » ЛС
   Для печати Для печати