|
|
|
Канал X-Tension/X-BTF: «Структура данных X-Tension» |
|
|
Blueboar
125 EGP
  Рейтинг канала: 2(12) Репутация: 20 Сообщения: 47 Откуда: Курган Зарегистрирован: 01.12.2004
 |
|
Итак, ассемблерные функции. Что про них удалось узнать? Про то, что их имена есть в STRG в зашифрованном виде и через него адресуются вы и без меня знаете. А вот как находится адрес для перехода ассемблерной подпрограмме до сего времени оставалось загадкой. Оказалось все очень просто: После таблички с описанием классов (помните я писал [5290EC], кстати, это не правильно для новой версии, там адрес другой) есть табличка с ассемблерными подпрограммами. Только формат у нее какой-то корявый. Содержит 21 (хоть убейте не знаю почему именно столько, но проверяется на такое число) запись по 16 байт, начиная от [5290EC]+48H. Соответственно каждая 16-байтная запись содержит 4 записи по 4 байта, из которых первая дает адрес перехода, а последняя адрес списка подпрограмм, для которых этот переход выполняется.
Последняя запись указывает на последнюю запись в списке подпрограмм. Там просто идут названия подпрограмм, по 32 байта каждая (кстати это ограничение на длину названия). Находится нужная подпрограмма сзади наперед и запоминается ее номер (последняя ноль, предпоследняя 1 итд). Он и передается в стеке подпрограмме-обработчику данного списка. По этому номеру подпрограмма определяет что ей нужно конкретно делать.
Групп подпрограмм оказалось 9: SE_, D_, SFX_, B3D_, SA_, GS_, MOV_ и две группы P_, У всех их я выяснил адреса таблиц и переходов, но вот сказать не могу, т.к. имею версию 1.1, а у вас 2.1а.
В общем случае (есть некоторые исключения), все эти группы написаны одинаково. Когда управление поступает на обработчик какой-либо группы, берется адрес подпрограммы из некоторой таблицы, но эта таблица уже своя на каждую группу. Совершенно непонятно, почему нельзя было сразу сделать таблицу на ВСЕ подпрограммы и не парится.
Кстати я думал что эта таблица (21 вход по 16 байт), что указывает на начало ассемблерных подпрограмм тоже где-нибудь лежит в виде таблицы в EXE-файле, а потом копируется на место, но оказалось все проще. ОНА ФОРМИРУЕТСЯ ПРЯМО ДВОЙНЫМИ СЛОВАМИ. То есть в подпрограмме (которая вызывается при инициализации игры) записано – записать по адресу 100 число такое-то, по адресу 104 число такое-то и так далее. Совершенно очевидно что можно было это все сразу прописать в EXE-шник. Так что или это опять чтоб мы не догадались или очередное ламерство разработчиков.
PS: За что мне столько EGP накидали, меня ж не было???
|
|
|
Shaddie
556 EGP
      Рейтинг канала: 6(438) Репутация: 118 Сообщения: 261 Откуда: Томск Зарегистрирован: 09.09.2004
 |
|
Blueboar : |
Итак, ассемблерные функции...
|
Есть два вопроса:
1. Есть ли возможность разобрать работу асм. функции?
2. Список асм. процедур можешь вытащить?
|
|
|
Shaddie
556 EGP
      Рейтинг канала: 6(438) Репутация: 118 Сообщения: 261 Откуда: Томск Зарегистрирован: 09.09.2004
 |
|
Да еще один вопрос: как вызваются процедуры obj файла из асм. процедуры?
_________________ Быстро едешь, тихо понесут... |
|
|
Blueboar
125 EGP
  Рейтинг канала: 2(12) Репутация: 20 Сообщения: 47 Откуда: Курган Зарегистрирован: 01.12.2004
 |
|
2Shaddie:
Вытащил все ассемблерные процедуры. Теперь осталось только выяснить как они работают. В основном думаю займусь группой SE_. А OBJ файлы скорее всего из ассемблерных программ вообще никак не вызываются.
|
|
|
Shaddie
556 EGP
      Рейтинг канала: 6(438) Репутация: 118 Сообщения: 261 Откуда: Томск Зарегистрирован: 09.09.2004
 |
|
Blueboar : |
Вытащил все ассемблерные процедуры.
|
В смысле список или уже коды.
Blueboar : |
Теперь осталось только выяснить как они работают.
|
Могу подсказать для некоторых, что есть на входе и на выходе, а так же как должны работать.
Blueboar : |
А OBJ файлы скорее всего из ассемблерных программ вообще никак не вызываются.
|
Должны, но конечно не из всех. Я думаю таких процедур вообще мало (попробую найти такую).
|
|
|
CheckerTwo
550 EGP
     Рейтинг канала: 4(90) Репутация: 103 Сообщения: 412 Откуда: Tomsk Зарегистрирован: 18.08.2004
 |
|
Блин, даже не знаю в какую тему постить. В канале ХТ - потому что здесь обсуждение obj? Или в Х2 - к которому это ближе.
Но все же.
Shaddie : |
Должны, но конечно не из всех. Я думаю таких процедур вообще мало (попробую найти такую).
|
Вот в Х2 похоже нашлась такая возможность. В bob-сценах встречаются команды для обеспечения интеракива с игроком (диалоги и кут-сцены). Причем интерпретация этих команд выполняется в obj-скрипте. Искать по строке "callback" "fadein" "startmusic" и прочие. Т.е. возможно при загрузке кут-сцены по SA_LoadCutScene выполняются процедуры из obj (см процедуру TObj084B.CutEvent).
Вторая возможность - можно покопать команду SA_SetEventObject. Возможно, что это нечто похожее на события-прерывания. Эта процедура есть и в ХТ.
To Blueboar, а ты в Х2 копался? Там внутренние структуры exe намного сложнее?
|
|
|
Blueboar
125 EGP
  Рейтинг канала: 2(12) Репутация: 20 Сообщения: 47 Откуда: Курган Зарегистрирован: 01.12.2004
 |
|
2Shaddie: Вытащил все коды полностью, а также список процедур и начала их кодов. Вот только версия у меня 1.1, так что не могу дать их вам.
2CheckerTwo: В X2 не копался, у меня его нету
|
|
|
Blueboar
125 EGP
  Рейтинг канала: 2(12) Репутация: 20 Сообщения: 47 Откуда: Курган Зарегистрирован: 01.12.2004
 |
|
Покопался в подпрограммах SE_. Что выяснил:
- В таблице названий есть две подпрограммы SE_PUTS и SE_PUTI, для которых нет адреса подпрограмм (видимо не успели их дописать )
- Подпрограммы группы SE_ARRAY... активно используют ячейку [005290EC+198], а SE_TABLE... [005290EC+1B0]
- В SE_TABLE... удалось частично разобраться. В ячейке [005290EC+1B0] записан адрес. По этому адресу есть 3 DWORD'а: Адрес начала списка адресов таблиц, число таблиц в списке и число записей в таблицах (как вы понимаете бывают таблицы не только из одной записи). Каждая запись таблицы состоит из 3 DWORD'ов: адрес следующей записи (если это не конец таблицы), номер записи (записи нумеруются независимо от таблиц) и адрес собственно с данными. Вот с данными я пока не разобрался.
- Удалось узнать число параметров у ряда подпрограмм.
- SE_TRACE, SE_SETPROFILING и SE_ASSERT похожи на заглущки и скорее всего ничего не делают
- Подпрограммы SE_DPRINTF и SE_PRINTF; SE_SPRINTF и SE_STRINGSPRINTF; SE_VSPRINTF и SE_STRINGVSPRINTF указывают на одно и то же место и, соответственно, делают одно и то же. Зачем по два названия неясно.
|
|
|
Shaddie
556 EGP
      Рейтинг канала: 6(438) Репутация: 118 Сообщения: 261 Откуда: Томск Зарегистрирован: 09.09.2004
 |
|
Blueboar : |
Вытащил все коды полностью, а также список процедур и начала их кодов. Вот только версия у меня 1.1, так что не могу дать их вам.
|
Конечно плохо, что версия XT у тебя старая, но по моему асм. процедуры версии 1.1 не сильно отличаются от 2.1. Так если есть возможность брось мне на мыло (и код процедуры для примера).
Blueboar : |
- Удалось узнать число параметров у ряда подпрограмм.
|
В принципе для асм. процедур, вызываемых из obj, количество параметров задается последним значением стека.
|
|
|
Blueboar
125 EGP
  Рейтинг канала: 2(12) Репутация: 20 Сообщения: 47 Откуда: Курган Зарегистрирован: 01.12.2004
 |
|
Цитата: |
Конечно плохо, что версия XT у тебя старая, но по моему асм. процедуры версии 1.1 не сильно отличаются от 2.1. Так если есть возможность брось мне на мыло (и код процедуры для примера).
|
Адреса скоро брошу. А пример не получится - он там сильно разветвленный - из каждой процедуры вызываются десятки, а то и больше других. Но одну какую-нибудь маленькую брошу.
Цитата: |
В принципе для асм. процедур, вызываемых из obj, количество параметров задается последним значением стека.
|
Хмм. Действительно.
|
|
|
xmagnat
280 EGP
   Рейтинг канала: 5(106) Репутация: 54 Сообщения: 1244 Откуда: Екатеринбург Зарегистрирован: 06.12.2003
 |
|
Добавлю свои 5 копеек...
Адреса нахождения значений гонорара за сбитый корабль:
М1 0x0DCA00
M2 0x0DCA2E
M3 0x0DCA5C
M4 0x0DCA8A
TS 0x0DCAB8
M5 0x0DCAE6
Адреса нахождения значений стоимости наема TL:
Argon 0x0D 0184, 0x0D 0162, 0x0D 0140, 0x0D 011E
Split 0x0D 02C8, 0x0D 02A6, 0x0D 0284, 0x0D 0262
Paranid 0x0D 036A, 0x0D 0348, 0x0D 0326, 0x0D 0304
Boron 0x0D 0226, 0x0D 0204, 0x0D 01E2, 0x0D 01C0
Teladi 0x0D 040C, 0x0D 03EA, 0x0D 03C8, 0x0D 03A6
Пользуйтесь !
P.S. Что-то эта тема как-то медленно развивается - а так ведь хорошо начали. Неужто пропал интерес к ней ?
_________________ Я вернулся ! |
|
|
CheckerTwo
550 EGP
     Рейтинг канала: 4(90) Репутация: 103 Сообщения: 412 Откуда: Tomsk Зарегистрирован: 18.08.2004
 |
|
Мда, что-то совсем зачахло...
Небольшое дополнение по секция VARS:
Первые два, как уже писали - порядковый номер переменной в текущем классе и указатель на имя переменной в STRG.
Третьим параметром стоит значение переменной по умолчанию - это начальная инициализация.
PS:
В Х2 добавлен еще один параметр - тип переменной. Переменные могут быть следующих типов INT, STRING, ARRAY, TABLE.
Осталось невыясненым функционирование подсистемы отслеживания патчей (секция PTCH) и можно ли ее как-то использовать.
Это к тому, что в тексте встречаются вызовы процедур (по команде 0057), которые нигде не описаны. Возможно, что это следствие работы патчей, а возможно что где-то, что-то не так...
Например:
GetSerial
GetObjectId
SetLatency
Debug
MenuExit (а ExitMenu - есть!)
IsDisabled
AbortMenu
FollowLeaderAndKillLeaderAttacker
AddMaxRockets (а AddMaxRocket - есть)
Причем оказалось, что имена процедур/переменных регистронезависимые.
Т.е. GetId и getID одно и тоже.
|
|
|
xmagnat
280 EGP
   Рейтинг канала: 5(106) Репутация: 54 Сообщения: 1244 Откуда: Екатеринбург Зарегистрирован: 06.12.2003
 |
|
Объясните мне, что делает команда 00 08 ?
_________________ Я вернулся ! |
|
|
Shaddie
556 EGP
      Рейтинг канала: 6(438) Репутация: 118 Сообщения: 261 Откуда: Томск Зарегистрирован: 09.09.2004
 |
|
xmagnat : |
Объясните мне, что делает команда 00 08 ?
|
0008 - get_from_array
Получить значение из указанной позиции массива.
До применения команды get_from_array в стеке два значения: позиция и массив, после в стеке значение из массива.
Код: |
push 1 ;позиция значения в массиве
readvar global.ga_Races ;массив созданный командой create_array (002F)
get_from_array ;возвращает значение первой записи в массиве global.ga_Races - Argon |
|
|
|
xmagnat
280 EGP
   Рейтинг канала: 5(106) Репутация: 54 Сообщения: 1244 Откуда: Екатеринбург Зарегистрирован: 06.12.2003
 |
|
То Shaddie: Спасибо.
P.S.
Как думаете, что делает эта процедура ?
Код: |
TSTATION.AddShield:
0009A906: 0055 0005 | setmem 5 ; 5
0009A90A: 003C | get_object
0009A90C: 000A | push 1 ; 1
0009A90E: 0001 07E0 | push 07E0h ; 2016d
0009A912: 0059 0004D204 0000979E | call59 TSTATION.RemoveStationFromShieldReloader ;
0009A91C: 002C | pop
0009A91E: 0005 0004 | push SP[3]
0009A922: 0009 | push 0 ; 0
0009A924: 003F | sub SP[0],SP[1]
0009A926: 0006 000A | read TSTATION.st_Shields ; [0Ah ; 10d]
0009A92A: 0008 | get_from_array
0009A92C: 0005 0006 | push SP[5]
0009A930: 003E | add SP[0],SP[1]
0009A932: 0005 0005 | push SP[4]
0009A936: 0009 | push 0 ; 0
0009A938: 003F | sub SP[0],SP[1]
0009A93A: 0006 000A | read TSTATION.st_Shields ; [0Ah ; 10d]
0009A93E: 002D | put_to_array
|
Она ставит на станцию 5*125 Мв. Щиты ! А теперь вопрос - что здесь надо поменять, чтобы на станцию ставилось 6*25 Мв Щитов ?
_________________ Я вернулся ! |
|
|
xmagnat
280 EGP
   Рейтинг канала: 5(106) Репутация: 54 Сообщения: 1244 Откуда: Екатеринбург Зарегистрирован: 06.12.2003
 |
|
Представляю мой вариант решения поставленной задачи.
Код: |
| TSTATION.AddShield:
0009A906: 0055 0005 | 0000 setmem 5 ; 5
0009A90A: 003C | 0000 get_object
0009A90C: 000A | 0001 push 1 ; 1
0009A90E: 0001 07E0 | 0002 push 07E0h ; 2016d
0009A912: 0059 0004D204 0000979E | 0003 call59 TSTATION.RemoveStationFromShieldReloader ;
0009A91C: 002C | 0001 pop
0009A91E: 0005 0004 | 0000 push SP[3]
0009A922: 0009 | 0001 push 0 ; 0
0009A924: 003F | 0002 sub SP[0],SP[1]
0009A926: 0006 000A | 0001 read TSTATION.st_Shields ; [0Ah ; 10d]
0009A92A: 0008 | 0002 get_from_array
0009A92C: 0005 0006 | 0001 push SP[5]
0009A930: 0009 | 0002 push 0 ; 0
0009A932: 002E 0003 | 0003 popx 3 ; 3
0009A936: 000F | 0000 push 6 ; 6
0009A938: 000B | 0001 push 2 ; 2
0009A93A: 0006 000A | 0002 read TSTATION.st_Shields ; [0Ah ; 10d]
0009A93E: 002D | 0003 put_to_array
|
0009A936 - количество щитов
0009A938 - тип щита ( 0 - 1 МВ, 1 - 5 МВ, 2 - 25 МВ, 3 - 125 МВ )
Вуаля
P.S. Пользуйтесь.
_________________ Я вернулся ! |
|
|
xmagnat
280 EGP
   Рейтинг канала: 5(106) Репутация: 54 Сообщения: 1244 Откуда: Екатеринбург Зарегистрирован: 06.12.2003
 |
|
Что делает команда 003С ? Вот примеры:
Код: |
000AE970: 0055 0004 | 0000 setmem 4 ; 4
000AE974: 0005 0004 | 0000 push SP[3]
000AE978: 000F | 0001 push 6 ; 6
000AE97A: 000B | 0002 push 2 ; 2
000AE97C: 003C | 0003 get_object
000AE97E: 0057 0000974E | 0004 call ___SetVar ; 0000974E
000AE984: 002C | 0001 pop
000AE986: 0009 | 0000 push 0 ; 0
000AE988: 0035 | 0001 ret
|
и еще
Код: |
000AE98A: 0055 0003 | 0000 setmem 3 ; 3
000AE98E: 000F | 0000 push 6 ; 6
000AE990: 000A | 0001 push 1 ; 1
000AE992: 003C | 0002 get_object
000AE994: 0057 00009775 | 0003 call ___GetVar ; 00009775
000AE99A: 0035 | 0001 ret
|
Вот еще нашел команду 00 58:
Код: |
000AE9FE: 0006 001D | 0000 read TSHIP.sh_PilotID ; [1Dh ; 29d]
000AEA02: 0009 | 0001 push 0 ; 0
000AEA04: 0006 000A | 0002 read TSHIP.sh_Owner ; [0Ah ; 10d]
000AEA08: 0057 00000399 | 0003 call GetID ; 00000399
000AEA0E: 003C | 0002 get_object
000AEA10: 0050 | 0003 neg SP[0]
000AEA12: 000C | 0003 push 3 ; 3
000AEA14: 0058 00017F40 0000091B | 0004 call58 global.GetPilotName ; 00017F40, 0000091B
000AEA1E: 0035 | 0001 ret
|
Сколько параметров у нее может быть ?
_________________ Я вернулся ! |
|
|
CheckerTwo
550 EGP
     Рейтинг канала: 4(90) Репутация: 103 Сообщения: 412 Откуда: Tomsk Зарегистрирован: 18.08.2004
 |
|
xmagnat : |
Что делает команда 003С ? Вот примеры:
|
Эта команда заносит в стек идентификатор текущего класса. Т.е. фактически эквивалентна делфийскому SELF или С++ THIS. А вот что может означать последовательность команд get_object / neg SP[0] - этого я сказать не смогу. Потому как это не очень понятно. Возможно, что таким образом формируется псевдослучайная комбинация?
xmagnat : |
Вот еще нашел команду 00 58: Сколько параметров у нее может быть ?
|
У нее два параметра типа long. Первый параметр - абсолютный адрес функции, по которому будет переход. Второй - адрес имени в секции STRG.
|
|
|
xmagnat
280 EGP
   Рейтинг канала: 5(106) Репутация: 54 Сообщения: 1244 Откуда: Екатеринбург Зарегистрирован: 06.12.2003
 |
|
Вот еще вопрос: есть такие глобальные переменные, главная особенность которых заключается в том, что их значения можно увидеть в игре.
Код: |
gs_DebugDump : undefined = 80000000h ; -2147483648d;
; gs_DebugInit : undefined = 80000000h ; -2147483648d;
; gs_DebugInput : undefined = 80000000h ; -2147483648d;
; gs_DebugLogic : undefined = 80000000h ; -2147483648d;
; gs_DebugHTML : undefined = 80000000h ; -2147483648d;
; gs_DebugLogbook : undefined = 80000000h ; -2147483648d;
; gs_DebugComp : undefined = 80000000h ; -2147483648d;
; gs_DebugTrade : undefined = 80000000h ; -2147483648d;
; gs_DebugCreateObject : undefined = 80000000h ; -2147483648d;
; gs_DebugKilled : undefined = 80000000h ; -2147483648d;
; gs_DebugHangarStart : undefined = 80000000h ; -2147483648d;
; gs_DebugDialog : undefined = 80000000h ; -2147483648d;
; gs_DebugMenu : undefined = 80000000h ; -2147483648d;
; gs_DebugAudio : undefined = 80000000h ; -2147483648d;
|
Для чего они нужны ? ( можно ли их использовать по своему усмотрению )
_________________ Я вернулся ! |
|
|
CheckerTwo
550 EGP
     Рейтинг канала: 4(90) Репутация: 103 Сообщения: 412 Откуда: Tomsk Зарегистрирован: 18.08.2004
 |
|
xmagnat : |
есть такие глобальные переменные, главная особенность которых заключается в том, что их значения можно увидеть в игре.
|
То есть - "увидеть"? Имеешь ввиду, что дизассемблер выдал значения этих переменных? Так это просто начальная инициализация. Эти значения хранятся в таблицах VARS. Вероятнее всего, в КС языке обявление таких переменных могло бы выглядеть примерно так:
int gs_DebugDump = 0x80000000;
.....
Или ты про другое?
xmagnat : |
Для чего они нужны ? ( можно ли их использовать по своему усмотрению )
|
Практического значения эти переменные вряд ли имеют, потому как большинство из них не используется в тексте obj-модулей. Возможно, что они нужны были на этапе тестирования. При релизной трансляции этот отладочный код вырезали. С другой стороны никто не может сказать наверняка - есть ли доступ к этим переменным из движка игрухи. Т.е. проверяет exe-шник их значение или нет.
|
|
|
|
|
|
Канал X-Tension/X-BTF: «Структура данных X-Tension» |
|