Berserker
Posts: 16657
|
|
09.11.2017 03:46 |
|
Berserker
Posts: 16657
|
Написал на PHP инструмент для компиляции map-файлов (файлов с именами и адресами идентификаторов: переменных, функций, классов и их адресов в исполняемых модулях) в двоичные упорядоченные по возрастания адресов (для бинарного поиска) .dbgmap-файлы со следующей структурой:
Code:
/**
* [0] Labels section
* [4] Number of labels
* > Repeat "Number of labels" times
* [4] Label address
* [4] Label name length
* [...] Label name
* [0] Modules section (program modules = source code containers, used in line numbers tracking, example: "stdio.c")
* [4] Number of modules
* > Repeat "Number of modules" times
* [4] Module name length
* [...] Module name
* [0] Line numbers section
* [4] Number of line numbers
* > Repeat "Number of line numbers" times
* [4] Address of code/data
* [4] Module index (from modules table, starting from zero)
* [4] Line number
*
* All addresses are relative to PE image base. Ex. for 0x401000 absolute address and 0x400000 image
* base, relative address will be 0x001000.
*/
Следующий шаг — научить Эру загружать эти файлы по требованию и в отчётах об исключениях и обработчиках событий применять его при генерации человеко-читаемых адресов. Результат должен изрядно помогать в поиске источников вылетов как в оригинальном файле h3te, так и в Эре и любых пользовательских плагинах, для которых компилятор поддерживает генерацию map-файлов.
На текущий момент у меня есть актуальный map для era.dll (генерируется при компиляции) и h3hota.map от Сава (несколько лет назад попросил), который я почищу скриптом от бессмысленных идентификаторов и планирую таки использовать, хотя покрытие кода метками там и невелико.
Оригиналы map-файлов (почищенные), dbgmap-файлы и сами инструменты можно отыскать всё в том же хранилище Эры
|
|
11.11.2017 03:21 |
|
Berserker
Posts: 16657
|
Реализовал. Господа, зацените. Адреса для dll/exe с отладочными картами заиграли новыми красками:
Code:
> Event handlers
$OnBeforeResetErmFunc:
Era.3E86C (PoTweak.OnBeforeResetErmFunc in PoTweak.pas on line 117)
OnAfterBattleAction:
Yona.1A918
OnAfterLoadGame:
Yona.1C10C
OnAfterWoG:
Era.2CC90 (Stores.OnAfterWoG in Stores.pas on line 432)
Era.303D4 (AdvErm.OnAfterWoG in AdvErm.pas on line 1511)
Era.339F4 (Erm.OnAfterWoG in Erm.pas on line 1765)
Era.37604 (Lodman.OnAfterWoG in Lodman.pas on line 446)
Era.3A1F4 (Tweaks.OnAfterWoG in Tweaks.pas on line 734)
Era.3C9B0 (Rainbow.OnAfterWoG in Rainbow.pas on line 579)
Era.3E468 (Triggers.OnAfterWoG in Triggers.pas on line 510)
Era.3E878 (PoTweak.OnAfterWoG in PoTweak.pas on line 122)
Era.3F508 (SndVid.OnAfterWoG in SndVid.pas on line 426)
Era.3FCEC (EraButtons.OnAfterWoG in EraButtons.pas on line 191)
OnBattleMouseHint:
Yona.19C84
OnBattleRound:
Yona.18F38
OnBattleScreenMouseClick:
Yona.1A6DC
OnBeforeBattleAction:
Yona.1A8A0
OnBeforeBattleUniversal:
Yona.1AA2C
OnBeforeErm:
Era.33934 (Erm.OnBeforeErm in Erm.pas on line 1752)
OnBeforeErmInstructions:
Era.303EC (AdvErm.OnBeforeErmInstructions in AdvErm.pas on line 1520)
Era.373E0 (Lodman.OnBeforeErmInstructions in Lodman.pas on line 392)
Yona.1C10C
OnBeforeTrigger:
Era.3CB40 (Triggers.OnBeforeTrigger in Triggers.pas on line 94)
OnBeforeWoG:
Era.303B8 (AdvErm.OnBeforeWoG in AdvErm.pas on line 1504)
Era.339D4 (Erm.OnBeforeWoG in Erm.pas on line 1759)
Era.375BC (Lodman.OnBeforeWoG in Lodman.pas on line 435)
Wog_patcherizer.1330
OnEraStart:
Era.40BD4 (EraSettings.OnEraStart in EraSettings.pas on line 80)
OnGenerateDebugInfo:
Era.3037C (AdvErm.OnGenerateDebugInfo in AdvErm.pas on line 1499)
Era.33928 (Erm.OnGenerateDebugInfo in Erm.pas on line 1744)
Era.3A1D8 (Tweaks.OnGenerateDebugInfo in Tweaks.pas on line 718)
Era.2B850 (GameExt.OnGenerateDebugInfo in GameExt.pas on line 466)
OnKeyPressed:
Yona.1A530
OnMonsterPhysicalDamage:
Yona.1A924
OnSavegameRead:
Era.2EF1C (AdvErm.OnSavegameRead in AdvErm.pas on line 1067)
Era.3369C (Erm.OnSavegameRead in Erm.pas on line 1661)
Era.374C4 (Lodman.OnSavegameRead in Lodman.pas on line 417)
Era.3E828 (PoTweak.OnSavegameRead in PoTweak.pas on line 110)
OnSavegameWrite:
Era.2EA78 (AdvErm.OnSavegameWrite in AdvErm.pas on line 917)
Era.335B8 (Erm.OnSavegameWrite in Erm.pas on line 1639)
Era.373F4 (Lodman.OnSavegameWrite in Lodman.pas on line 397)
Era.3E7E8 (PoTweak.OnSavegameWrite in PoTweak.pas on line 104)
OnStackToStackDamage:
Yona.18F58
OnTrigger 89999:
Yona.1AA4C
|
|
11.11.2017 19:52 |
|
Berserker
Posts: 16657
|
Обновил GitHub-репозиторий и Яндекс-диск.
Бес, это как если на месте ошибочной ЕРМ команды тебе бы игра писала: ошибка по адресу 12345ADEBBA, а ты бы гадал, что это за место. А после, как в Эре 2.47+, писалось бы:
> ERA version: 2.47.2
> ERM context in era - quick savings.erm:95:15
Это сразу понятнее. Файл era - quick savings.erm, строка 95, позиция 15. Для скомпилированного кода такой магии не было (была, но ручная и в отладчике). Теперь есть
|
|
11.11.2017 21:33 |
|
Berserker
Posts: 16657
|
Сделал отладочную карту для angel.dll (Era 1.x) и добавил анализ данных (число, строка?) в файл с дампом контекста исключения. Пример вылета:
Failed to read data at E17994F6.
EIP: E17994F6. Code: C0000005
> Registers
EAX: H3era.009273E7 (wog_start + 2253799) (int: 9597927, pint: 0x00004000 = 16384)
ECX: 00000000 (int: 0)
EDC: 0028953C (int: 2659644, pint: 0x00000000)
EBX: 00000000 (int: 0)
ESP: 002894A4 (int: 2659492, pint: 0x009273F7 = 9597943)
EBP: 0C8C9000 (int: 210538496, pint: 0x97375E91)
ESI: 06741570 (int: 108270960, pint: 0x0063A678 = 6530680)
EDI: 00289E24 (int: 2661924, pint: 0x00000002)
> Callstack
038DE001
> Stack
00289490: 0CC9E3DD (int: 214557661, pint: 0x2F317945 = 791771461, str: "Ey1/0/y1;
** WoG Cheat Menu 0.7")
00289494: 00000008 (int: 8)
00289498: 0000000E (int: 14)
0028949C: 00000000 (int: 0)
002894A0: 00000000 (int: 0)
002894A4*: H3era.009273F7 (wog_start + 2253815) (int: 9597943, pint: 0xF8F0E5E2, str: "вершена!\x00")
002894A8: Angel.10BA (Main.CallProc + 102) (int: 96407738, pint: 0x01F87D83 = 33062275)
002894AC: H3era.009273E8 (wog_start + 2253800) (int: 9597928, pint: 0x20000040 = 536870976)
002894B0: 0CC9E3DD (int: 214557661, pint: 0x2F317945 = 791771461, str: "Ey1/0/y1;
** WoG Cheat Menu 0.7")
002894B4: 00000000 (int: 0)
002894B8: 002894B0 (int: 2659504, pint: 0x0CC9E3DD = 214557661)
002894BC: 002896B0 (int: 2660016, pint: 0x002896F4 = 2660084)
002894C0: Angel.143B (int: 96408635, pint: 0x00023BE9 = 146409)
002894C4: 00000001 (int: 1)
002894C8: 0028952C (int: 2659628, pint: 0x009273E8 = 9597928)
002894CC: 00000000 (int: 0)
002894D0: H3era.009273E8 (wog_start + 2253800) (int: 9597928, pint: 0x20000040 = 536870976)
002894D4: 0028FEA4 (int: 2686628, pint: 0x0028FF78 = 2686840)
002894D8: Angel.16AA (int: 96409258, pint: 0x003CADE9 = 3976681)
002894DC: 002896B0 (int: 2660016, pint: 0x002896F4 = 2660084)
002894E0: 0028A070 (int: 2662512, pint: 0x00000200 = 512)
002894E4: 06741570 (int: 108270960, pint: 0x0063A678 = 6530680)
002894E8: 00000001 (int: 1)
002894EC: 00000001 (int: 1)
002894F0: 00000001 (int: 1)
002894F4: 00000000 (int: 0)
002894F8: 00000000 (int: 0)
002894FC: 00000000 (int: 0)
00289500: 00000000 (int: 0)
00289504: 00000000 (int: 0)
00289508: 00000000 (int: 0)
0028950C: H3era.009273E8 (wog_start + 2253800) (int: 9597928, pint: 0x20000040 = 536870976)
00289510: 00000000 (int: 0)
00289514: 00000000 (int: 0)
00289518: 00000000 (int: 0)
0028951C: 00000000 (int: 0)
00289520: 00000000 (int: 0)
00289524: 00000000 (int: 0)
00289528: 00000000 (int: 0)
0028952C: H3era.009273E8 (wog_start + 2253800) (int: 9597928, pint: 0x20000040 = 536870976)
Angel.10BA (Main.CallProc + 102) - значит кто-то вызвал SN:E. Об этом же подозрительно напоминает и:
00289490: 0CC9E3DD (int: 214557661, pint: 0x2F317945 = 791771461, str: "Ey1/0/y1;
Нет стека вызовов — произошёл переход на левый адрес с данными, не принадлежащими ни одному модулю.
|
|
12.11.2017 00:10 |
|
Berserker
Posts: 16657
|
А вот другой вылет:
Failed to read data at 0.
EIP: 05AF2A54. Code: C0000005
> Registers
EAX: 00000000 (int: 0)
ECX: 00000001 (int: 1)
EDC: 002896D0 (int: 2660048, pint: 0x00000001)
EBX: 00000001 (int: 1)
ESP: 00289604 (int: 2659844, pint: 0x0028A070 = 2662512)
EBP: 002896F4 (int: 2660084, pint: 0x00289C5C = 2661468)
ESI: 067F1570 (int: 108991856, pint: 0x0063A678 = 6530680)
EDI: 0028A070 (int: 2662512, pint: 0x00000200 = 512)
> Callstack
H3era.00749416 (wog_start + 295958)
H3era.0074CD20 (wog_start + 310560)
H3era.0074EE4B (wog_start + 319051)
H3era.0074EEBC (wog_start + 319164)
H3era.0040895A (A0_AdvMgr_Main_sub_408710 + 586)
H3era.004B0C39
Era.2371C (PatchApi.CALL_THIS + 80 in PatchApi.pas on line 789)
Era.2380F (PatchApi.Call + 91 in PatchApi.pas on line 847 offset 15)
Era.3E76D (in Triggers.pas on line 501)
02950804
H3era.004F824F
H3era.0061A964 (_WinMainCRTStartup + 224)
Kernel32.1336A
Ntdll.398F2
Ntdll.398C5
> Stack
002895F0: 00000001 (int: 1)
002895F4: 002896D0 (int: 2660048, pint: 0x00000001)
002895F8: 00000001 (int: 1)
002895FC: 00000000 (int: 0)
00289600: H3era.0073208B (wog_start + 200843) (int: 7544971, pint: 0x6ABC4589 = 1790723465)
00289604*: 0028A070 (int: 2662512, pint: 0x00000200 = 512)
00289608: 067F1570 (int: 108991856, pint: 0x0063A678 = 6530680)
0028960C: 00000001 (int: 1)
00289610: 0028A070 (int: 2662512, pint: 0x00000200 = 512)
00289614: 067F1570 (int: 108991856, pint: 0x0063A678 = 6530680)
00289618: 00289640 (int: 2659904, pint: 0x00000006)
0028961C: 00289630 (int: 2659888, pint: 0x067F1570 = 108991856)
00289620: 00000001 (int: 1)
00289624: 00289B00 (int: 2661120, pint: 0x00289B28 = 2661160)
00289628: 00000000 (int: 0)
0028962C: 0028A070 (int: 2662512, pint: 0x00000200 = 512)
00289630: 067F1570 (int: 108991856, pint: 0x0063A678 = 6530680)
00289634: 0028965C (int: 2659932, pint: 0x002896C4 = 2660036)
00289638: 0028964C (int: 2659916, pint: 0x0028A070 = 2662512)
0028963C: 00000001 (int: 1)
00289640: 00000006 (int: 6)
00289644: 0028995C (int: 2660700, pint: 0x00000006)
00289648: 00289B78 (int: 2661240, pint: 0x00000007)
0028964C: 0028A070 (int: 2662512, pint: 0x00000200 = 512)
00289650: 00000002 (int: 2)
00289654: 00000001 (int: 1)
00289658: 00000004 (int: 4)
0028965C: 002896C4 (int: 2660036, pint: 0x067F1570 = 108991856)
00289660: H3era.0073F36B (wog_start + 254827) (int: 7598955, pint: 0x1EEBC033 = 518766643)
00289664: 0028A070 (int: 2662512, pint: 0x00000200 = 512)
00289668: 067F1570 (int: 108991856, pint: 0x0063A678 = 6530680)
0028966C: 00000001 (int: 1)
00289670: 00000000 (int: 0)
00289674: 0028A070 (int: 2662512, pint: 0x00000200 = 512)
00289678: 067F1570 (int: 108991856, pint: 0x0063A678 = 6530680)
0028967C: 00000001 (int: 1)
00289680: 00000004 (int: 4)
00289684: 002896C4 (int: 2660036, pint: 0x067F1570 = 108991856)
00289688: H3era.00741C20 (wog_start + 265248) (int: 7609376, pint: 0x000001B8 = 440)
0028968C: 0028A070 (int: 2662512, pint: 0x00000200 = 512)
Функция обработки сообщений окна, перехваченная Эрой, вызывает обычную геройскую функцию обработки сообщений, дело доходит до менеджера приключений, который обрабатывает правый щелчок мышью. Получает управления WoG (4 верхний адреса в стеке вызовов), где одна из вредных команд и производит вылет.
Какая? erm memory dump.txt
Code:
> ERA version: 2.47.2
> ERM context in 1 wog - cheat menu.erm:3:7
!!UN:C0/1/7;
|
|
12.11.2017 00:17 |
|
Berserker
Posts: 16657
|
Добавил отладочную карту для Yona. Теперь в обработчиках событий сплошная красота:
Code:
$OnBeforeResetErmFunc:
Era.3EB9C (PoTweak.OnBeforeResetErmFunc in PoTweak.pas on line 117)
OnAfterBattleAction:
Yona.1ABBC (Yo.OnAfterBattleAction in Yo.pas on line 994)
OnAfterLoadGame:
Yona.1C3D8 (YoDescs.OnGameStartOrLoad in YoDescs.pas on line 195)
OnAfterWoG:
Era.2CF88 (Stores.OnAfterWoG in Stores.pas on line 432)
Era.306CC (AdvErm.OnAfterWoG in AdvErm.pas on line 1511)
Era.33CFC (Erm.OnAfterWoG in Erm.pas on line 1765)
Era.3790C (Lodman.OnAfterWoG in Lodman.pas on line 446)
Era.3A524 (Tweaks.OnAfterWoG in Tweaks.pas on line 734)
Era.3CCE0 (Rainbow.OnAfterWoG in Rainbow.pas on line 579)
Era.3E798 (Triggers.OnAfterWoG in Triggers.pas on line 510)
Era.3EBA8 (PoTweak.OnAfterWoG in PoTweak.pas on line 122)
Era.3F838 (SndVid.OnAfterWoG in SndVid.pas on line 426)
Era.4001C (EraButtons.OnAfterWoG in EraButtons.pas on line 191)
OnBattleMouseHint:
Yona.19F24 (Yo.OnBattleMouseHint in Yo.pas on line 672)
OnBattleRegeneratePhase:
Yona.1ABC8 (Yo.OnBattleRegeneratePhase in Yo.pas on line 1016)
OnBattleRound:
Yona.191D8 (Yo.OnBattleRound in Yo.pas on line 377)
OnBattleScreenMouseClick:
Yona.1A97C (Yo.OnBattleScreenMouseClick in Yo.pas on line 933)
OnBeforeBattleAction:
Yona.1AB40 (Yo.OnBeforeBattleAction in Yo.pas on line 982)
OnBeforeBattleUniversal:
Yona.1ACF8 (Yo.OnBeforeBattleUniversal in Yo.pas on line 1065)
Yona.1ACF8 (Yo.OnBeforeBattleUniversal in Yo.pas on line 1065)
OnBeforeErm:
Era.33C3C (Erm.OnBeforeErm in Erm.pas on line 1752)
OnBeforeErmInstructions:
Era.306E4 (AdvErm.OnBeforeErmInstructions in AdvErm.pas on line 1520)
Era.376E8 (Lodman.OnBeforeErmInstructions in Lodman.pas on line 392)
Yona.1C3D8 (YoDescs.OnGameStartOrLoad in YoDescs.pas on line 195)
OnBeforeTrigger:
Era.3CE70 (Triggers.OnBeforeTrigger in Triggers.pas on line 94)
OnBeforeWoG:
Era.306B0 (AdvErm.OnBeforeWoG in AdvErm.pas on line 1504)
Era.33CDC (Erm.OnBeforeWoG in Erm.pas on line 1759)
Era.378C4 (Lodman.OnBeforeWoG in Lodman.pas on line 435)
Wog_patcherizer.1330
OnEraStart:
Era.40F04 (EraSettings.OnEraStart in EraSettings.pas on line 80)
OnGenerateDebugInfo:
Era.30674 (AdvErm.OnGenerateDebugInfo in AdvErm.pas on line 1499)
Era.33C30 (Erm.OnGenerateDebugInfo in Erm.pas on line 1744)
Era.3A508 (Tweaks.OnGenerateDebugInfo in Tweaks.pas on line 718)
Era.2BB44 (GameExt.OnGenerateDebugInfo in GameExt.pas on line 472)
OnKeyPressed:
Yona.1A7D0 (Yo.OnKeyPressed in Yo.pas on line 877)
OnMonsterPhysicalDamage:
Yona.1ABF0 (Yo.OnMonsterPhysicalDamage in Yo.pas on line 1032)
OnSavegameRead:
Era.2F214 (AdvErm.OnSavegameRead in AdvErm.pas on line 1067)
Era.339A4 (Erm.OnSavegameRead in Erm.pas on line 1661)
Era.377CC (Lodman.OnSavegameRead in Lodman.pas on line 417)
Era.3EB58 (PoTweak.OnSavegameRead in PoTweak.pas on line 110)
OnSavegameWrite:
Era.2ED70 (AdvErm.OnSavegameWrite in AdvErm.pas on line 917)
Era.338C0 (Erm.OnSavegameWrite in Erm.pas on line 1639)
Era.376FC (Lodman.OnSavegameWrite in Lodman.pas on line 397)
Era.3EB18 (PoTweak.OnSavegameWrite in PoTweak.pas on line 104)
OnStackToStackDamage:
Yona.191F8 (Yo.OnStackToStackDamage in Yo.pas on line 423)
OnTrigger 89999:
Yona.1AD18 (Yo.OnNet in Yo.pas on line 1072)
|
|
12.11.2017 02:31 |
|