Kimapr
-
Публикации
24 -
Зарегистрирован
-
Посещение
-
Победитель дней
4
Сообщения, опубликованные пользователем Kimapr
-
-
-
И помоему мы далеко отошли от математического сеттинга. Пауки тут какие-то появились, да и знак интеграла куда убежал?
-
7 часов назад, Totoro сказал:Немного подкрутил графику, чтобы было веселее.
Эх, а я уже текстуру игрока сделал.
-
2 минуты назад, Totoro сказал:Будет, будет. ) Главное не переставать шуметь.
А ты уже потестил новую версию (номер версии я не менял)? Мне интересно твоё мнение о том, как хорошо (/плохо/ужасно/идеально и т.д) всё реализовано.
-
Я решил добавить красоты. Запилил частицы, кто-нибудь вообще играть в эту игру будет? Помоему, никто не видит этого шума.
-
1
-
-
2 минуты назад, Totoro сказал:Я тебе доступ выдал на проект - чтобы не заморачиваться с пулл-реквестами.
Реквест смерджил, вечером домой приду, потестирую детальнее.
А вообще - здорово. )
Спасибо
Скоро я еще мультиплеер сделаю.
-
Добавил врагов в игру.
-
1
-
-
Помоему, MIT тоже пермиссивный.
-
Лицензия у игры забавная...
Делайте что хотите, пока ваши измененные копии также имеют другое имя.
-
19 минут назад, Totoro сказал:Мы по такой же схеме игру делали.
Уже перестали что ли? Жаль, думал будет что-то годное... ☹️
P.s. [offtopic] Может мне тоже туда что-нибудь запилить? Врагов, например [/offtopic]
-
Добавил заставку при запуске. Открыл репозиторий на gitlab. Сейчас выложу туда то что есть. Одному скучно программировать!
-
45 минут назад, astral17 сказал:ммм, у нас походу немного разное понятие boot было, я подумал, что кинуть файл в /boot/*.lua , но вижу был не прав.
Нет, я действительно говорил про /boot/, но сам я сделал через /lib/core/boot.lua.
ЦитатаПри изменении /lib/core/boot.lua всё нормально запустилось.
Помоему если уж ты и ставишь свой скрипт в /boot/, ты должен назвать его так, чтобы он выполнялся последним, т.е. ПОСЛЕ других бутскриптов. Например, название
"zz_tprotect_init.lua" прекрасно подойдет, т.к. z - последняя (или одна из таковых) буква английского алфавита.
ЦитатаОднако основная мысль прошлого сообщения была в добавке возможности защиты частичной таблиц, т.е. чтобы только некоторые поля были readonly , что позволило бы юзеру с гораздо меньшими усилиями защититься от всего перечисленного выше. Однако хозяин - барин, автор библиотеки не я, поэтому и не я выбираю, что в ней будет, а только предлагаю.
В своей библиотеке я нарочно допустил брешь, так что если в метатаблице защищаемой таблицы (не зеркальной!) объявлена функция __newindex, то вместо ошибки будет выполнена она. Учитывая это, в __newindex можно реализовать защиту некоторых полей тем, что если их ключ совпадает с поданным в функцию ключём, то ничего не делать, или кинуть эррор.
-
А можно скриншот ошибки? Я патчил OpenOS 1.7.3, изменив /lib/core/boot.lua:
... local package = dofile("/lib/package.lua") local tprotect = dofile("/lib/tprotect.lua") do -- Unclutter global namespace now that we have the package module and a filesystem _G.component = nil _G.computer = nil _G.process = nil _G.unicode = nil -- Inject the package modules into the global namespace, as in Lua. _G.package = package -- Initialize the package module with some of our own APIs. package.loaded.tprotect = tprotect package.loaded.component = component package.loaded.computer = computer package.loaded.unicode = unicode package.loaded.buffer = dofile("/lib/buffer.lua") package.loaded.filesystem = dofile("/lib/filesystem.lua") package.loaded.color = dofile("/lib/color.lua") -- Inject the io modules _G.io = dofile("/lib/io.lua") end ... status("Initializing system...") package.loaded.component = tprotect.protect(component) package.loaded.computer = tprotect.protect(computer) package.loaded.unicode = tprotect.protect(unicode) do local loaded=package.loaded local unloadable={component=true,computer=true,unicode=true,tprotect=true,filesystem=true} local raw_type=type function package.unload(name) assert(raw_type(name)=="string","bad argument #1 to package.unload (string expected, got "..raw_type(name)..")") if not unloadable[name] then package.loaded[name]=nil end end end package.loaded=tprotect.protect(package.loaded) _G.package=tprotect.protect(package) computer.pushSignal("init") -- so libs know components are initialized. require("event").pull(1, "init") -- Allow init processing. _G.runlevel = 1 if gpu and screen then gpu.setResolution(gpu.maxResolution()) end
Здесь после всех бутскриптов запускается процесс защиты дефолтных либ OpenComputers, а также package. Сам tprotect уже себя защитил.
-
И вообще, какого чёрта мы опустились до старта системы? Я вообще просто библиотечку для защиты таблиц сделал, а как её использовать - не моё дело (если я не являюсь пользователем, при разработке Kion - я являюсь им)
-
1 час назад, astral17 сказал:Если сделать package.loaded readonly то вся система сломается к чертям, т.к. не сможет загружать новые библиотеки и т.д. и т.п., ещё проблемка в том, что нужно в таком случае защищать и _G ведь кто мешает подменить package на другую таблицу?, затем кто мешает подменить функцию require ?, заменить require на костыль, который вместо tprotect вернёт заражённую копию?, так что тут как вариант добавить readonly поля по выбору, затем функция не возвращает метатаблицу зеркала, а возвращает метатаблицу оригинала. Когда говорил, что иногда хотелось бы видеть метатаблицы, я имел ввиду через getmetatable . Ну а вообще, для другой системы может и будет внутренняя защита от таких вещей, но это нужно смотреть на то, какая структура будет.
Я такое в Kion в init поставил и все работает нормально. У библы package есть свой оригинал package.loaded, и он хранится в локальной переменной. Посмотри на код из /lib/package.lua:
local loaded = { ["_G"] = _G, ["bit32"] = bit32, ["coroutine"] = coroutine, ["math"] = math, ["os"] = os, ["package"] = package, ["string"] = string, ["table"] = table } package.loaded = loadedА защита _G сломает некоторые программы к чертям. В _G нельзя будет писать, но это ещё не всё! Просто переопределив _G
_G=tprotect.protect(_G)Ничего не получится. Защищена будет только сама переменная, но не таблица глобального окружения. Её нужно будет менять для каждой прожки. В таком случае лучше каждой программе сделать свое глобальное окружение. Это будет легче. А там пусть какую-угодно фигню творят, лишь бы out of memory не было (при должной защите, это единственный краш, который программа сможет нанести системе).
-
3 часа назад, astral17 сказал:Ну, из уязвимостей вроде бы и всё, конечно же проблема до сих пор возникает "как получить эту библиотеку, если зловред уже работает", т.е. он может спокойно подменить require , package и т.д. , т.е. даже если библиотека загружена, ты не можешь удостовериться в том, что это правда она, однако то, что сама таблица защищена уже гарантирует, что те, кто получил её не обнаружат сюрприз. Как фиксить такое фз, и это уже просто чисто для размышлений (но было бы неплохо, если можно было подтвердить).
Было бы неплохо, если сам код был под спойлером в теге "код".
Как знаешь, в таблицах, которые хочешь защитить могут находиться также и другие таблицы. Иногда хочется защитить и их (но не всегда), поэтому хотелось бы видеть функцию, которая будет рекурсивно защищать все таблицы от изменений, которые есть в защищаемой таблице. (не забудь про возможность зацикливания, например в защищаемой таблице может вдруг оказаться ссылка на её саму).
Ну и на последок, то, что в getmetatable от зеркала возвращается строка защитная, не очень хорошо, иногда хотелось бы видеть метатаблицу, оригинальной (конечно же readonly), тут тогда возникает вопрос, до какой глубины идти?, ответ: до тех пор, пока есть метатаблица у метатаблицы и она ещё не защищена (в кратце расширение к рекурсивной защите). В принципе это будет создавать дополнительные нагрузки на память, поэтому можно поставить флажок, нужно ли так делать.
Вроде бы большего ожидать от этой библиотеки смысла скорее всего нету (до тех пор, пока она касается только защиты таблиц). А за старания респект.
UPD:
короче, нужен багфикс сего чудаЕсли вкратце, то при обращении к метаметодам зеркала получается, что оно берёт сырые значения из метатаблицы (вот как раз таки причина, почему у меня не удалась та атака с __add , ну да ладно, она хотя бы показала, что в теории любая глобальная переменная может быть злом), а это может оказаться довольно довольно важной вещью таблицы (т.е. нужно сделать будет редирект всех метаметодов, либо изменить структуру работы).
Функция protect вместе с зеркалом таблицы возвращает метатаблицу зеркала (на самом деле нет, но она косвенно влияет на настоящую метатаблицу зеркала). Библиотеку нужно подгружать в начале работы системы! Можно вот такой код поместить в /boot/:
require"tprotect" package.loaded.component = tprotect.protect(component) package.loaded.computer = tprotect.protect(computer) package.loaded.unicode = tprotect.protect(unicode) do local loaded=package.loaded local unloadable={component=true,computer=true,unicode=true,tprotect=true,filesystem=true} local raw_type=type function package.unload(name) assert(raw_type(name)=="string","bad argument #1 to package.unload (string expected, got "..raw_type(name)..")") if not unloadable[name] then package.loaded[name]=nil end end end package.loaded=tprotect.protect(package.loaded) _G.package=tprotect.protect(package)
И постараться чтобы этот бутскрипт выполнился последним (предпологается, что другие бутскрипты хорошие и не вредные!). Еще можно реализовать права на файлы, как в *nix, но для этого я и пишу Kion (это ОСь такая). Чудо щас исправлю
-
Помоему выкладывать все в одну кучу как-то громоздко. Лучше выложи отдельно моды, майнкрафт (ну он у всех есть), и карту. Можешь также сделать список модов, нужных для работы карты.
-
Добрый день(/вечер/ночь/утро), форумчане! Сегодня я начинаю разработку новой ОСи, основанной на OpenOS 1.7.2. Её фичами будут:
- Защита от изменений таблиц с библиотеками (tprotect рулит!)
- Распределение прав у программ. Нормальная система пользователей (как в *nix'ах)
- Графическая оболочка
- Вытесняющая многозадачность
Пока что готов только tprotect и заставка.
-
Проблематичненько! Я даже не заметил, что можно их переопределить, как это сделал я. Шас исправим-с.
Вот патч:
local getmetatable=getmetatable -- local setmetatable=setmetatable -- local type=type -- Дополнительная зашыта local error=error -- local assert=assert --
Библиотека все еще уязвима к подмене этих функций до её загрузки. Так что её нужно загружать до загрузки чего-либо ещё опасного
-
24.01.2019 в 18:22, Kimapr сказал:Бывали ли у вас когда-нибудь такие ситуации, когда необходимо защитить какую-либо таблицу от записи? Например, вы пишите операционную систему в OpenComputers,
и хотите хоть какую-то защиту от вирусов. Бедные таблицы всегда в очень большой опасности. Как овечки. tprotect - это пастух, который защитит ваши таблицы от записи, а когда вы захотите снова в нее что-то записать, вы сможете это сделать (если не потеряете ключ). Вообщем вот ее код (он небольшой):
local tprotect={}
local raw_rawset=rawset -- Обязательно! Без этой строки вся библиотека безполезна!
local protectid=tostring(math.random(10000,99999))
local nonpi={
tostring(math.random(10000,99999)),
tostring(math.random(10000,99999)),
tostring(math.random(10000,99999)),
tostring(math.random(10000,99999))
}
local function newKey()
return {math.random(10000,99999)}
end
function _G.rawset(t,k,v) -- Ну и без этой функции тоже
local cantrawset=getmetatable(t)[protectid.."cantrawset"] or t[protectid.."cantrawset"]
local cantset=getmetatable(t)[protectid.."cantset"] or t[protectid.."cantset"]
if getmetatable(t).isOpened(protectid) or ((not tprotect.isProtected(t)) and not cantrawset) then
raw_rawset(t,k,v)
elseif not cantset then
t[k]=v
end
end
function tprotect.protect(t) -- Защитить таблицу от записи и вернуть ключ разблокировки
assert(type(t)=="table","bad argument #1 to protect (table expected, got "..type(t)..")")
local key=newKey()
local opened=false
local mto=getmetatable(t)
local mt
local mt2=setmetatable(
{
[protectid]=true,
___open=function(k)
if k==key then
opened=true
return true
end
return false
end,
___close=function(k)
if k==key then
opened=false
return true
end
end,
___isOpened=function(pi)
if pi==protectid then
return opened
else
return nil
end
end,
[nonpi[1]]=true,
[nonpi[2]]=true,
[nonpi[3]]=true,
[nonpi[4]]=true,
___unprotect=function(k)
if k==key then
return mt
else
return false
end
end
},
{__pairs=function(self)return function()end,self,nil end,
__ipairs=function(self)return function()end,self,0 end,
__newindex=function(self,k,v)end,
[protectid.."cantrawset"]=true,
[nonpi[1].."cantrawset"]=true,
[nonpi[2].."cantrawset"]=true,
[nonpi[3].."cantrawset"]=true,
[nonpi[4].."cantrawset"]=true,
[protectid.."cantset"]=true,
[nonpi[1].."cantset"]=true,
[nonpi[2].."cantset"]=true,
[nonpi[3].."cantset"]=true,
[nonpi[4].."cantset"]=true,})
mt=setmetatable({
__newindex=function(self,k,v)
if not opened then
error("table \""..tostring(self).."\" is protected, you can't write to it!")
end
if mto.__newindex then
return mto.__newindex(self,k,v)
end
return raw_rawset(self,k,v)
end,
__metatable=mt2
},{__index=mto,__newindex=function(self,k,v)
if not opened then
error("table \""..tostring.."\" is protected, you can't write to it!")
end
return raw_rawset(self,k,v)
end})
setmetatable(t,mt)
return key
end
function tprotect.open(t,k) -- "Открыть" таблицу: в неё можно будет писать. Для этого нужен ключ разблокировки, который вернул tprotect.protect
return getmetatable(t).___open(k)
end
function tprotect.close(t,k) -- "Закрыть" таблицу: она снова будет защищена от записи. Опять же, нужен ключ.
return getmetatable(t).___close(k)
end
function tprotect.unprotect(t,k) -- Разблокировка таблицы, отмена tprotect.protect. Нужен ключ, а то библиотека безполезна
local mt,mto=getmetatable(t).___unprotect(k)
if mt then
mt.__metatable=nil
setmetatable(t,mto)
return true
else
return false
end
end
function tprotect.isProtected(t) -- Защищена ли таблица?
return getmetatable(t)[protectid]
end
return tprotectА теперь документация, а то я пишу код непонятно:
function tprotect.protect(table:t):table -- Установить защиту на таблицу. После этого в нее нельзя будет записывать, не имея ключ, который эта функция и возвращает. Если у таблицы t была метатаблица, то она останется и будет работать дальше, но сменить её будет нельзя до вызова tprotect.unprotect function tprotect.open(table:t,table:key):boolean -- "Открыть" таблицу ключем. Если таблица key - это тот самый ключ, который вернула tprotect.protect, то вернёт возможность записи в таблицу. function tprotect.close(table:t,table:key):boolean -- "Закрыть" таблицу тем же ключем. Обязательно вызывайте эту функцию, после того, как закончите запись или ваша таблица будет снова в опасности. function tprotect.unprotect(table:t,table:key):boolean -- Отменяет все, что наделала функция tprotect.protect. Вызывайте её, когда вам надоест защита вашей таблицы или когда вы захотите сменить метатаблицу.
Новая версия идет! Переписано с нуля, теперь больше безопасности и меньше нерабочести! Ну и сложности тоже поменьше. А то как то сложновато.
-
Бывали ли у вас когда-нибудь такие ситуации, когда необходимо защитить какую-либо таблицу от записи? Например, вы пишите операционную систему в OpenComputers,
и хотите хоть какую-то защиту от вирусов. Бедные таблицы всегда в очень большой опасности. С tprotect ваши таблицы будут в безопасности, так как другие программы вместо оригинала таблицы получат её зеркальную копию. А когда вы захотите снова в нее что-то записать, вы сможете это сделать (оригинал же у вас?). Вообщем вот ее код :
local tprotect={}
local raw_rawset=rawset -- Сохраняем rawset для дальнейшего пользования
local raw_rawget=rawget -- Сохраняем rawget для дальнейшего пользования
local getmetatable=getmetatable --
local setmetatable=setmetatable --
local type=type -- Дополнительная зашыта
local error=error --
local assert=assert --
local protectid={}
local nextid={}
function rawget(t,k)
if type(t)=="table" and raw_rawget(t,protectid) then
error("СЕРЬЁЗНАЯ ПРОБЛЕМА БЕЗОПАСНОСТИ ДЕТЕКТЕД. УНИЧТОЖАЕМ ОПАСНОСТЬ...",2)
end
return raw_rawget(t,k)
end
local raw_next=next
-- НИКТО НЕ ДОЛЖЕН УЗНАТЬ МАСТЕР-КЛЮЧ!!!
function next(t,k)
if type(t)=="table" and raw_rawget(t,protectid) then
error("СЕРЬЁЗНАЯ ПРОБЛЕМА БЕЗОПАСНОСТИ ДЕТЕКТЕД. УНИЧТОЖАЕМ ОПАСНОСТЬ...",2)
end
local ok,k,v=xpcall(raw_next,debug.traceback,t,k)
if not ok then
error(k,0)
end
return k,v
end
local raw_ipairs=ipairs
function ipairs(...)
local f,t,z=raw_ipairs(...)
return function(t,k)
if type(t)=="table" and raw_rawget(t,protectid) then
error("СЕРЬЁЗНАЯ ПРОБЛЕМА БЕЗОПАСНОСТИ ДЕТЕКТЕД. УНИЧТОЖАЕМ ОПАСНОСТЬ...",2)
end
return f(t,k)
end,t,z
end
function rawset(t,k,v) -- Потому что в защитные копии таблиц можно было бы записывать. Хоть это бы и не отразилось бы на оригинале, но при попытке индекснуть поле защитной копии будет подложено подмененное поле в обход __index
if k==protectid then
error("СЕРЬЁЗНАЯ ПРОБЛЕМА БЕЗОПАСНОСТИ ДЕТЕКТЕД. УНИЧТОЖАЕМ ОПАСНОСТЬ...",2)
end
assert(type(t)=="table","bad argument #1 to rawset (table expected, got "..type(t)..")")
assert(type(k)~="nil","bad argument #2 to rawset (table index is nil)")
local mt=getmetatable(t)
local no_set=raw_rawget(t,protectid) or (type(mt)=="table" and raw_rawget(mt,protectid))
if no_set then
error("таблица рид-онли! Аксес дэняйд!",2)
end
raw_rawset(t,k,v)
return t
end
function tprotect.protect(t)
local tcopy={[protectid]=true}
local mto=getmetatable(t)
local tcopy_mt=type(mto)=="table" and mto or {}
local mt={[protectid]=true}
function mt:__index(k)
local x=t[k]
if tcopy_mt.__index and not x then
return tcopy_mt.__index(t,k)
end
return t[k]
end
function mt:__pairs(self)
if tcopy_mt.__pairs then
return tcopy_mt.__pairs(t)
end
local function iter(x,i)
assert(x==self)
return next(t,i)
end
return iter,self,nil
end
function mt:__ipairs(self)
if tcopy_mt.__ipairs then
return tcopy_mt.__ipairs(t)
end
local f,x,i=ipairs(self)
local function iter(self,i)
return f(t,i)
end
return iter,x,i
end
function mt:__newindex(k,v)
if tcopy_mt.__newindex then -- Мы доверяем нашим клиентам!
return tcopy_mt.__newindex(self,k,v)
end
error("СРЕДНЕНЬКАЯ ПРОБЛЕМА БЕЗОПАСНОСТИ ДЕТЕКТЕД. УНИЧТОЖАЕМ ОПАСНОСТЬ...",2)
end
mt.__metatable={"Хочешь проблем? Попытайся взломать tprotect!"}
setmetatable(mt,{__index=function(self,i)
local v=tcopy_mt
if type(v)=="function" then
return function(self,...)
return v(t,...)
end
end
return v
end})
setmetatable(tcopy,mt)
return tcopy,tcopy_mt
end
local tprotect_t,tprotect_mt=tprotect.protect(tprotect) -- Защитим нашу библиотечку
return tprotect_tА теперь документация, а то я пишу код непонятно:
function tprotect.protect(table:t):table -- Возвращает "зеркало" таблицы t и её метатаблицу (у "зеркальной" таблицы она неизменяема). "Зеркальная" таблица защищена от записи и всегда является отражением t. Если вы хотите защитить таблицу t, то на публичное (доступное для других программ, от которых вам хотелось бы защитить t) место, где вы ставите обычно таблицу t, ставьте "зеркальную" таблицу
-
6
-
-
А как теперь в личный кабинет зайти?


Разработка игры Determinant
в Программирование
Опубликовано: · Изменено пользователем Kimapr
как встроить видео?
https://www.youtube.com/watch?v=AQE4V0J47bk