Wake of Gods Forum | Форум Во Имя Богов

Full Version: ERA II
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
Да, конечно же.

Code:
HINSTANCE hAngel                = LoadLibrary(TEXT("angel.dll"));
  EventParams           = (int*) GetProcAddress(hAngel, "EventParams");

  SaveEventParams       = (TSaveEventParams) GetProcAddress(hAngel, "SaveEventParams");
  RestoreEventParams    = (TRestoreEventParams)GetProcAddress(hAngel, "RestoreEventParams");
  /***/
  HINSTANCE hEra                  = (HINSTANCE) ErmV[1];

  WriteAtCode           = (TWriteAtCode) GetProcAddress(hEra, "WriteAtCode");
  Hook                  = (THook) GetProcAddress(hEra, "Hook");
...

Грр!
XEPOMAHT, пара заметок:
1) OllyDebugger 2.0 прекрасно работает с Эрой. На нём всё и отлаживаю.
2) Папка Debug\Era, файл exception context.txt с EIP и иже с ними.
3) Виртуальная файловая система перехватывает самые низкоуровневые функции, поэтому любой текстовик найдётся по виртуальному пути, если его открывать без права на запись.

feanor, пост выше не ясен, уточни, пожалуйста.
(04.06.2019 05:00)Berserker Wrote: [ -> ]1) OllyDebugger 2.0 прекрасно работает с Эрой. На нём всё и отлаживаю.

Да, всё таки удалось запустить ЭРА с OllyDebugger (получилось остановить процесс прямо перед зависанием отладчика), оказалось что феаноровский плагин на артефакты содержит кучку битых функций, из-за которых, скорее всего, и проблемы с совместимостью с ERA 2.8.2 (каким-то неведомым чудом старые версии ЭРЫ проглатывали весь этот мусор и плагин даже работал).

(03.06.2019 23:51)feanor Wrote: [ -> ]
Code:
HINSTANCE hAngel                = LoadLibrary(TEXT("angel.dll"));
  EventParams           = (int*) GetProcAddress(hAngel, "EventParams");

  SaveEventParams       = (TSaveEventParams) GetProcAddress(hAngel, "SaveEventParams");
  RestoreEventParams    = (TRestoreEventParams)GetProcAddress(hAngel, "RestoreEventParams");
  /***/
  HINSTANCE hEra                  = (HINSTANCE) ErmV[1];

  WriteAtCode           = (TWriteAtCode) GetProcAddress(hEra, "WriteAtCode");
  Hook                  = (THook) GetProcAddress(hEra, "Hook");
...

Да оно кажись как раз и не грузится там, попробую это наследие ЭРА 1.8 вырезать хексом:

Code:
Dump - emerald_v202a_era:.text
Address   Hex dump          Command                                             Comments
03C118B0   $  56            PUSH ESI
03C118B1   .  57            PUSH EDI
03C118B2   .  68 F842C103   PUSH OFFSET 03C142F8                                ; /FileName = "angel.dll"
03C118B7   .  FF15 0C40C103 CALL DWORD PTR DS:[<&KERNEL32.LoadLibraryW>]        ; \KERNEL32.LoadLibraryW
03C118BD   .  8B35 1040C103 MOV ESI,DWORD PTR DS:[<&KERNEL32.GetProcAddress>]
03C118C3   .  8BF8          MOV EDI,EAX
03C118C5   .  68 0C43C103   PUSH OFFSET 03C1430C                                ; ASCII "EventParams"
03C118CA   .  57            PUSH EDI
03C118CB   .  FFD6          CALL ESI
03C118CD   .  68 1843C103   PUSH OFFSET 03C14318                                ; ASCII "SaveEventParams"
03C118D2   .  57            PUSH EDI
03C118D3   .  A3 F040C803   MOV DWORD PTR DS:[3C840F0],EAX
03C118D8   .  FFD6          CALL ESI
03C118DA   .  68 2843C103   PUSH OFFSET 03C14328                                ; ASCII "RestoreEventParams"
03C118DF   .  57            PUSH EDI
03C118E0   .  A3 3C41C803   MOV DWORD PTR DS:[3C8413C],EAX
03C118E5   .  FFD6          CALL ESI
03C118E7      8B            DB 8B
03C118E8   .  3D 68768800   CMP EAX,887668
03C118ED   .  68 3C43C103   PUSH OFFSET 03C1433C                                ; ASCII "WriteAtCode"
03C118F2   .  57            PUSH EDI
03C118F3   .  A3 4041C803   MOV DWORD PTR DS:[3C84140],EAX
03C118F8   .  FFD6          CALL ESI
03C118FA   .  68 4843C103   PUSH OFFSET 03C14348                                ; ASCII "Hook"
03C118FF   .  57            PUSH EDI
03C11900   .  A3 F440C803   MOV DWORD PTR DS:[3C840F4],EAX
03C11905   .  FFD6          CALL ESI
(04.06.2019 05:00)Berserker Wrote: [ -> ]feanor, пост выше не ясен, уточни, пожалуйста.

Старый era.h с кучей сомнительных даже на первый взгляд решений.
Теперь все перекомпилировать, блин.
Berserker, объясни для чего вообще регестрировать события? Почему нельзя просто вызвать необходимую функцию по указателю GetEraVersion(); ?
Code:
typedef const char* (__stdcall *TGetEraVersion) ();
GetEraVersion         = (TGetEraVersion)        GetProcAddress(hEra, "GetVersion");
Ребят, там же код проще паренной репы. Из-за того геморроя, что творится в плюсах с импортом/экспортом (в delphi статический импорт функции без *.lib — одна строка) используется, как и в большинстве решений, динамический импорт через GetProcAddress. Единственное, что должно смущать — описатель hEra брался из v1 (решение плохое, глобальная переменная вместо вызова LoadLibrary), что объявлено устаревшим, но для пущей совместимости я теперь всегда v1 инициализирую в hEra даже для библиотек с расширением *.dll. *.dll плагины были для Эры 1.х, они вызывались после события OnAfterWoG и не использовали более новых функций. *.era плагины вызываются до события OnBeforeWoG.

Стоит, конечно, решить этот вопрос и вообще перестать грузить *.dll плагины, а также перестать наглухо зависеть от v1. Это не делалось из-за обратной совместимости. В старых dll-плагинах не было событий, никто не знал, когда их загрузят, патчи применялись прямо из DllMain. Реально они грузились после кода Вога и применения патчей Вога. Если их переименовать в *.era, они загрузятся ещё ДО кода вога и могут сильно засбоить.

// Теперь все перекомпилировать, блин.
Перекомпиляция занимает пару секунд, если есть исходники и студия, нет? Я по десятку раз проекты пересобираю к релизу ) Но лучше просто на github папку с исходниками кинуть.

igrik, два вопроса не связаны.

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

2) Адреса функций сохраняются в переменные, чтобы не дёргать медленный поиск по загруженным библиотекам (LoadLibraryA => LoadLibraryExW => LdrLoadLibrary | что-то там для поиска) для каждого вызова с последующим насилием на секцией экспорта библиотеки (GetProcAddress).
Один вызов ConnectEra из DllMain все указатели на функции заполняет.

3) GetEraVersion можно вызвать прямо в том месте, где это нужно, эм, через уже ранее инициализированный указатель Ab.

XEPOMAHT, если куча битых функций (адрес 0), значит библиотека имела неверное расширение, *.dll вместо *.era.

Загрузи, пожалуйста, пример одной dll, которая в 2.7.7 работает корректное, а в 2.8.2 нет. Причина, скорее всего банально, над комплексным решением подумаю.
Quote:Да, всё таки удалось запустить ЭРА с OllyDebugger (получилось остановить процесс прямо перед зависанием отладчика)
И у меня! Без зависаний на Win XP, Win 7, в Lubuntu. И даже у majaczek. Может нужна сразу настроенная сборка или какое-то ПО виновато?

Плагины Феанора запускаются, файлы по вирт. путям находят. У majaczek дикая смесь всего в сборке, такое не отладишь толком быстро.
Неверную обработку двойного расширения исправлю.

Обработку двойного расширения исправлю в ближайшем обновлении.
(05.06.2019 13:58)Berserker Wrote: [ -> ]Плагины Феанора запускаются, файлы по вирт. путям находят.

Добавьте в ERA проверку на папку EraPlugins, при её отсутствии её необходимо создавать, иначе плагигины Феанора не запускаются на ERA 2.8.2. И да, ERA 2.8.2 НЕ МОЖЕТ найти их в папке mods и настойчиво пытается отыскать в несуществующей папке, от того и происходит ошибка.
XEPOMAHT, плагины грузятся с папки EraPlugins. Как с Game\EraPlugins, так и с любой мод\EraPlugins. Зачем проверка?
(05.06.2019 16:44)Berserker Wrote: [ -> ]плагины грузятся с папки EraPlugins.

Этой папки может не быть (а у меня её нет, зачем мне лишняя пустая папка), а ERA 2.8.2 упорно не грузит феаноровские плагины при её отсутствии, с остальными плагинами такого нет - спокойно грузятся без EraPlugins.
XEPOMAHT, этой папки нет ни у кого. Плагины грузятся. Так работает виртуальная файловая система. Включи Debug.LogVirtualFileSystem=1 и Debug.DumpVirtualFileSystem=1, запусти игру и после вылета проверь файл Debug\Era\log.txt на предмет имени плагина.

Или загрузи хотя бы один плагин на dropmefiles.com, который не грузится. Проверю.
(05.06.2019 17:15)Berserker Wrote: [ -> ]проверь файл Debug\Era\log.txt на предмет имени плагина.

(05.06.2019 17:15)Berserker Wrote: [ -> ]Или загрузи хотя бы один плагин на dropmefiles.com, который не грузится. Проверю.

http://heroes3wog.net/bad-luck-download/
1) Плагин подхвачен: $\EraPlugins\badluck.era <= $\Mods\Bad Luck\EraPlugins\badluck.era
2) Плагин выведен в листинге виртуальной папки:
VFS: [INNER] NtQueryDirectoryFile
    Written entry: badluck.era
3) Плагин успешно проверен на существование файла:
>> VFS: [ENTER] NtQueryAttributesFile
    Dir: 0.
    Path: "\??\D:\Heroes 3 Testing\EraPlugins\badluck.era"

>> VFS: [LEAVE] NtQueryAttributesFile
    Result: 0. Attrs: 0x20.
4) Плагин успешно загружен:
>> VFS: NtOpenFile
    \??\D:\Heroes 3 Testing\EraPlugins\badluck.era

>> VFS: [ENTER] NtCreateFile
    Access: 0x100001. CreateDisposition: 0x1
    Path: "\??\D:\Heroes 3 Testing\EraPlugins\badluck.era"

>> VFS: [LEAVE] NtCreateFile
    Handle: 168. Status: 0.
    Expanded: "D:\Heroes 3 Testing\EraPlugins\badluck.era"
    Redirected: "D:\Heroes 3 Testing\Mods\Bad Luck\EraPlugins\badluck.era"

Если у тебя не так, удали установщик 2.8.2, выкачай и поставь поверх чистой папки. Мы уже успешно решили все вопросы даже с Win 10 поздних версий.

Да, при этом папки EraPlugins в каталоге игры нет, сам плагин в Mods\Bad Luck
(05.06.2019 20:02)Berserker Wrote: [ -> ]1) Плагин подхвачен: $\EraPlugins\badluck.era <= $\Mods\Bad Luck\EraPlugins\badluck.era
2) Плагин выведен в листинге виртуальной папки:
VFS: [INNER] NtQueryDirectoryFile
    Written entry: badluck.era
3) Плагин успешно проверен на существование файла:
>> VFS: [ENTER] NtQueryAttributesFile
    Dir: 0.
    Path: "\??\D:\Heroes 3 Testing\EraPlugins\badluck.era"

>> VFS: [LEAVE] NtQueryAttributesFile
    Result: 0. Attrs: 0x20.
4) Плагин успешно загружен:
>> VFS: NtOpenFile
    \??\D:\Heroes 3 Testing\EraPlugins\badluck.era

>> VFS: [ENTER] NtCreateFile
    Access: 0x100001. CreateDisposition: 0x1
    Path: "\??\D:\Heroes 3 Testing\EraPlugins\badluck.era"

>> VFS: [LEAVE] NtCreateFile
    Handle: 168. Status: 0.
    Expanded: "D:\Heroes 3 Testing\EraPlugins\badluck.era"
    Redirected: "D:\Heroes 3 Testing\Mods\Bad Luck\EraPlugins\badluck.era"

Всё точно так же, но... после этого согласно логу ЭРА зачем-то пытается загрузить badluck.era второй раз по этому же адресу, потом начинается обращение к каким-то badluck.era.2.Manifest и badluck.era.2.Config, которых никогда не было, потом, собственно, выводится ошибка... Мне надоело бороться с премудростями новой версии ERA, пускай будет валяться пустая папка EraPlugins, если эта ошибка не воспроизводится у других пользователей, то можно её больше не искать/не исправлять.
(05.06.2019 20:02)Berserker Wrote: [ -> ]Мы уже успешно решили все вопросы даже с Win 10 поздних версий.
Berserker, у XEPOMAHT'a винда особая!! Win 2003 если не ошибаюсь. Может в этом кроется проблема.
Reference URL's