Всем привет.
Возможно, некоторые из вас уже слышали о таком проекте, как Open SA-MP. Этот проект задумывался, как своего рода замена для SA-MP. В какой-то момент разработчики Open SA-MP оказались неспособны заниматься его развитием, но в сети так и остались исходники проекта.
Собственно, сами эти исходники можно найти по следующей ссылке:
Многие утверждают, что исходники Open SA-MP получены на основе обратной разработки SA-MP, но это не совсем так.
Да, отчасти это правда, что можно понять по некоторым комментариям в коде:https://github.com/Sasuke78200/open-..._amx.cpp#L2850
https://github.com/Sasuke78200/open-...labels.cpp#L32
А здесь, судя по названиям переменных и комментариям к ним, работали декомпилятором Hex-Rays Decompiler:https://github.com/Sasuke78200/open-...ppool.cpp#L149
https://github.com/Sasuke78200/open-...P/main.cpp#L83
Тем не менее, есть косвенные доказательства и того факта, что за основу были взяты оригинальные исходники SA-MP.
Например, если открыть файл "Open SAMP/amx/amx.h", то можно найти в нём следующий комментарий:Разработчик Pawn изначально пользовался системой контроля версий SVN, которая автоматически добавляла в редактируемые файлы исходного кода дату и время регистрации изменений, а также номер ревизии. Очевидно, что в SA-MP Team тоже использовали SVN.
Ещё можно кое-что найти в файле "amx.c":Примерно такой текст можно найти в обработчиках для опкодов CALL.PRI и JUMP.PRI. Вместо них поставлены заглушки, поднимающие ошибку времени выполнения в абстрактной машине, что делает эти опкоды нерабочими.PHP код:
op_jump_pri:
// Kye SA-MP Team 9/9/2009 Unsecure opcode
//PUSH((unsigned char *)cip-code);
//cip=(cell *)(code+(int)pri);
//NEXT(cip);
assert(0);
ABORT(amx,AMX_ERR_INVINSTR);
В комментариях указано, что причина таких заглушек - якобы уязвимость опкодов.
Действительно, такая уязвимость имела место - лично я не слышал ни об одном случае её применения на практике, но в теории опкоды CALL.PRI и JUMP.PRI могли использоваться для совершения атак (переход на специально подготовленный байт-код за пределами секции кода скрипта).
Уязвимость была обнаружена после релиза Pawn 3.2 и исправлена в Pawn 3.3 (коммит от 08.12.2008) - уязвимые опкоды исключены из набора инструкций и добавлена статическая проверка байт-кода при его загрузке (в функции VerifyPCode). Похоже, Kalcor тоже решил удалить эти опкоды, поставив на их место заглушки, хотя проверку байт-кода добавить не удосужился (типично), тем самым оставив множество других потенциальных уязвимостей, которые до сих пор используются в сообществе SA-MP как "фичи".
Если верить комментариям в коде Open SA-MP, исправление было совершено "9/9/2009", т.е. это было после выхода SA-MP 0.2x (20.11.2008) и перед релизом 0.3a (19.10.2009). Всё это подтверждает предположение о том, что Open SA-MP основывается на исходниках SA-MP позднее 0.2x (т.е. 0.3a или одной из бета-версий).
Что интересно, в сервере SA-MP 0.2x CALL.PRI и JUMP.PRI тоже не работают, но это можно объяснить тем, что Kalcor просто подменил архив на files.sa-mp.com, не меняя дату. Подобная подмена уже имела место после релиза 0.3.7 R2-1.
Ещё одна интересная деталь:Это отрывок таблицы нативных функций в Open SA-MP. Обратите внимание: запись для функции SetPlayerAttachedObject продублирована. Очевидно, это баг, связанный с невнимательностью при copy-paste.PHP код:
{ "GetPlayerInterior", funcGetPlayerInterior }, // 105
{ "SetPlayerAttachedObject", funcSetPlayerAttachedObject }, // 106
{ "RemovePlayerAttachedObject", funcRemovePlayerAttachedObject }, // 107
{ "SetPlayerAttachedObject", funcSetPlayerAttachedObject }, // 108
{ "IsPlayerAttachedObjectSlotUsed", funcIsPlayerAttachedObjectSlotUsed },
Если верить SA-MP wiki, функция SetPlayerAttachedObject была добавлена в 0.3c.
И вот что можно найти, дизассемблировав сервер SA-MP 0.3c R1:
Всё те же дублирующиеся записи.
Скорее всего, эта ошибка была допущена кем-то из SA-MP Team ещё до того, как исходники попали в руки к разработчикам Open SA-MP, что говорит о том, что в Open SA-MP за основу были взяты исходники, как минимум, от 0.3c R1 (либо, опять же, одной из предрелизных версий).
Конечно же, есть возможность того, что проект Open SA-MP на самом деле основывается на исходниках более ранней версии (0.3b или 0.3a), а функция SetPlayerAttachedObject была добавлена методом обратной разработки. Но зачем тогда нужно было повторять баг в "своей реализации"? Всё равно никакого эффекта от этого не будет, виртуальная машина AMX просто проигнорирует попытку повторной регистрации функции. Случайно же повторить точно такую же ошибку практически нереально. Остаётся только один вариант: разработчики Open SA-MP не заметили той опечатки, поскольку код регистрации нативных функций был взят из оригинала SA-MP и к нему особо не присматривались. Либо опечатку заметили, но забыли её исправить - или же просто проигнорировали в силу её незначительности. Кстати говоря, она не исправлена даже в последних версиях SA-MP.
Подведём итоги. Прямые доказательства вряд ли возможны здесь в принципе, но всё же есть несколько косвенных зацепок, в итоге указывающих на то, что Open SA-MP основывается на оригинальных исходниках SA-MP, как минимум, версии 0.3c или одной из бета-версий.
В этой теме я привёл исключительно своё мнение, но меня также интересует и ваше.
Можно ли по исходникам Open SA-MP судить о качестве кода в самом SA-MP? Можно ли на их основе делать какие-либо выводы о работе тех или иных систем - PVar'ов, например? Или, возможно, я в чём-то ошибаюсь в этой статье?
В любом случае буду рад услышать ваше мнение в комментариях.