astral17
-
Публикации
76 -
Зарегистрирован
-
Посещение
-
Победитель дней
7
Сообщения, опубликованные пользователем astral17
-
-
Tree() - собирает дерево, у нас цикл в цикле, получается соберёт 10 * 5 = 50 деревьев. Судя по условиям ты считаешь, что x это номер рассматриваемого дерева, тогда что такое "a"? (
есть догадки, что это количество рядов, но учитывая, что нету кода перехода между ними, то это вряд ли правда), если убрать этот цикл, то получится код, который пробегается ровно 5 различных деревьев из изначального ряда, причём 6 раз обобрав последнее, не катит. Кстати, интересный факт, x не может быть одновременно и меньше и равным числу 5, а в коде ты это явно просишьif x < 5 then ToTree() if x == 5 then robot.turnAround() robot.forward() end end
Вообще зачем проверять тебе, меньше ли x, чем 5 не понятно, поэтому эта строчка явно лишняя, т.к. она мешает передвигаться к следующему дереву, убрав её получим код, который полностью пробежится по целому ряду в одну сторону и обратно. Но нужно помнить, что робот будет развёрнут в обратную сторону относительно момента до запуска функции.
Однако, судя по схеме между деревьями 1 блок, тогда зачем в развороте forward ?
Вообще всякие магические числа в коде для читабельности желательно избегать или хотя бы описывать, что они означают (если не совсем очевидные конечно). Ну и код без отступов больно читать.
-
Трудно что-то тут сказать, т. к. слишком мало информации. По возможности хотелось бы увидеть скрины как всё было поставлено, что внутри пк и скрин самой ошибки, список модов, которые были дополнительно установлены. Если при спавне компа командой он не был ни с чем соединён (т. е. полностью изолирован от других компонентов), и был произведён чисто запуск без смены комплектации, то возможно появился какой-то баг OpenComputers, хотя это маловероятно. Вообще единственное предположение пока возникает, что была произведена попытка запуститься с пустой дискеты (после крафта дискеты нужно потом объединить с книжкой OC, чтобы получить OpenOS).
-
1
-
-
@ArtHacker ну, там короче при загрузке защищается список таблиц, куда входит и os , однако либа filesystem не полностью загружается при загрузке из-за package.delay, например файлик boot/02_os.lua содержит в самом конце строчку
require("package").delay(os, "/lib/core/full_filesystem.lua")
а файл boot/90_filesystem.lua эту
require("package").delay(fs, "/lib/core/full_filesystem.lua")
ну, а теперь как именно работает эта функция, после её использования устанавливается временная метатаблица, которая после первого обращения к любому индексу этой таблицы самоудаляется и запускает файл, который указан вторым аргументом.
Проблема возникает из-за того, что таблица os защищается (т.е. скрипт, который запустит full_filesystem стирается до своего запуска), а filesystem нет. Фиксить эту проблему можно перед защитой искусственно обратиться к какому-то рандомному индексу проблемных таблиц, хотя, очевидно, что такой метод это дикий костыль, хоть и простой в реализации.
-
1
-
-
ммм, у нас походу немного разное понятие boot было, я подумал, что кинуть файл в /boot/*.lua , но вижу был не прав. Однако согласен, что я не заметил, что package.loaded присваивается от локальной и от неё работает, в этом моя ошибка. Однако это остаётся актуальным.
1 час назад, astral17 сказал:Предположим, что это сработало, никто до сих пор не мешает подменить функцию require и при вызове require("tprotect") заменить на своё. Или заменить _G.package на другую таблицу.
Замена _G.package может сработать против тех, кто не доверяет require и идёт напрямик. При изменении /lib/core/boot.lua всё нормально запустилось.
UPD:
И если что, я не говорю, что именно ты должен сделать эту защиту, я говорю, что ты должен помочь тем, кто захочет это сделать, ведь использовать набор методов из библиотеки гораздо проще, чем написать её с нуляЦитатаОднако основная мысль прошлого сообщения была в добавке возможности защиты частичной таблиц, т.е. чтобы только некоторые поля были readonly , что позволило бы юзеру с гораздо меньшими усилиями защититься от всего перечисленного выше. Однако хозяин - барин, автор библиотеки не я, поэтому и не я выбираю, что в ней будет, а только предлагаю.
-
51 минуту назад, Kimapr сказал:Я такое в 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 не было (при должной защите, это единственный краш, который программа сможет нанести системе).
На счёт сломается система, запускал на OpenOS 1.7.2 в boot tprotect не становился глобальной переменной, поэтому RE был, ок, заменил первую строчку на tprotect = require ... , система зависла и отказалась загружаться. Ок попробуем не из boot запустить, а как обычный файл..., ммм эпик фэйл, команды консоли сломались, можно было идти глубже но зачем, ведь предложенные строчки для другой системы (а вообще, хоть у package есть оригинал на себя, у него не хранится отдельно оригинал на package.loaded , который становится readonly , но это опустим). Предположим, что это сработало, никто до сих пор не мешает подменить функцию require и при вызове require("tprotect") заменить на своё. Или заменить _G.package на другую таблицу. Именно из-за таких проблем я и написал
6 часов назад, astral17 сказал:и это уже просто чисто для размышлений
И это также отвечает на это:
44 минуты назад, Kimapr сказал:И вообще, какого чёрта мы опустились до старта системы? Я вообще просто библиотечку для защиты таблиц сделал, а как её использовать - не моё дело (если я не являюсь пользователем, при разработке Kion - я являюсь им)
Можно и дальше перечислять проблемы, но раз меня критикуют, я пожалуй откажусь.
Однако основная мысль прошлого сообщения была в добавке возможности защиты частичной таблиц, т.е. чтобы только некоторые поля были readonly , что позволило бы юзеру с гораздо меньшими усилиями защититься от всего перечисленного выше. Однако хозяин - барин, автор библиотеки не я, поэтому и не я выбираю, что в ней будет, а только предлагаю.
-
6 минут назад, Kimapr сказал:Функция 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 (это ОСь такая). Чудо щас исправлю
Если сделать package.loaded readonly то вся система сломается к чертям, т.к. не сможет загружать новые библиотеки и т.д. и т.п., ещё проблемка в том, что нужно в таком случае защищать и _G ведь кто мешает подменить package на другую таблицу?, затем кто мешает подменить функцию require ?, заменить require на костыль, который вместо tprotect вернёт заражённую копию?, так что тут как вариант добавить readonly поля по выбору, затем функция не возвращает метатаблицу зеркала, а возвращает метатаблицу оригинала. Когда говорил, что иногда хотелось бы видеть метатаблицы, я имел ввиду через getmetatable . Ну а вообще, для другой системы может и будет внутренняя защита от таких вещей, но это нужно смотреть на то, какая структура будет.
-
Ну, из уязвимостей вроде бы и всё, конечно же проблема до сих пор возникает "как получить эту библиотеку, если зловред уже работает", т.е. он может спокойно подменить require , package и т.д. , т.е. даже если библиотека загружена, ты не можешь удостовериться в том, что это правда она, однако то, что сама таблица защищена уже гарантирует, что те, кто получил её не обнаружат сюрприз. Как фиксить такое фз, и это уже просто чисто для размышлений (но было бы неплохо, если можно было подтвердить).
Было бы неплохо, если сам код был под спойлером в теге "код".
Как знаешь, в таблицах, которые хочешь защитить могут находиться также и другие таблицы. Иногда хочется защитить и их (но не всегда), поэтому хотелось бы видеть функцию, которая будет рекурсивно защищать все таблицы от изменений, которые есть в защищаемой таблице. (не забудь про возможность зацикливания, например в защищаемой таблице может вдруг оказаться ссылка на её саму).
Ну и на последок, то, что в getmetatable от зеркала возвращается строка защитная, не очень хорошо, иногда хотелось бы видеть метатаблицу, оригинальной (конечно же readonly), тут тогда возникает вопрос, до какой глубины идти?, ответ: до тех пор, пока есть метатаблица у метатаблицы и она ещё не защищена (в кратце расширение к рекурсивной защите). В принципе это будет создавать дополнительные нагрузки на память, поэтому можно поставить флажок, нужно ли так делать.
Вроде бы большего ожидать от этой библиотеки смысла скорее всего нету (до тех пор, пока она касается только защиты таблиц). А за старания респект.
UPD:
короче, нужен багфикс сего чуда
Если вкратце, то при обращении к метаметодам зеркала получается, что оно берёт сырые значения из метатаблицы (вот как раз таки причина, почему у меня не удалась та атака с __add , ну да ладно, она хотя бы показала, что в теории любая глобальная переменная может быть злом), а это может оказаться довольно довольно важной вещью таблицы (т.е. нужно сделать будет редирект всех метаметодов, либо изменить структуру работы).
-
1
-
-
Дубль 2, короче сдаюсь в этот раз получилось гораздо качественнее, уязвимости есть, но не очень критические и легко фиксятся.
Так сказать защита rawset не очень хороша), а если точнее, то error не обязательно выходит из функции, например если сделать так, как на скрине, то сразу понятно, что код продолжит работу. Т.е. нужно либо хранить персональный error , либо дописать везде return nil или что-то похожее), похожая проблема с getmetatable и setmetatable , т.е. если их переписать, то получится, что мы сможем выхукнуть таблицы в момент их защиты.
Также это дело касается type , т.к. я могу обломать валидацию mto на таблицу и запихнуть через __metatable функцию, т.е. tcopy_mt = mto = myfunction , а если __index это функция, то при обращении к метатаблице я смогу получить и саму чистую метатаблицу, т.е. mt, а сама она никак не защищена, как сиё сделать, (цель вообще вытянуть protectid) , смотрим, нам нужно обратиться в mt к значению, которого нету например _add , а значит вызывается __index в который помещается mt, "__add" и тут мы и хукаем mt. (как вытянуть не проверялось, и писалось почти с закрытыми глазами, так что скорее всего сиё чудо только в теории, завтра чекну)
-
2
-
-
24.01.2019 в 16:22, Kimapr сказал:if getmetatable(t).isOpened(protectid)
Интересная защита), сломать функцию rawset , чтобы она не работала) т.е. она получает метатаблицу и запускает функцию в ней, во-первых если метатаблицы нету, краш), если метатаблица есть, то всё равно краш, т.к. в ней нету этой функции)
Затем tprotect.open не работает, причина проста, mto может равняться nil , т.е. если создать чистую таблицу, и её защитить, получим epic fail...
возвращаемая таблица через getmetatable(ptbl) , где было вызвано tprotect.protect(ptbl) является mt2 и её можно редактировать, такая же проблема вообще и на саму ptbl распространяется, т.к. __newindex работает только в случае, если такого ключа нету, если ключ есть, то нужно использовать __index , однако получив таблицу mt2 даже с доступом на чтение мы сможем спокойно выудить все значения, и protectid и списочек nonpi (я так и не понял, зачем он вообще нужен, как вариант посолить, чтобы сложнее было вытянуть protectid, но в таком случае слишком мало соли). Вообще protectid можно получить просто через tprotect.isProtected , т.к. там получается метатаблица у таблицы, которую мы передаём внутрь и обращается по индексу protectid , т.е. секретным назвать его трудно.
Но вернёмся к нашим баранам, mt2 допустим у неё есть __index тоже, значит we need to go deeper , смотрим на метатаблицу mt2, она не защищена, т.е. её можно спокойно изменять и мы видим спокойно все её значения
Скрытый текст
снимаем защиту на изменение mt2 -> profit
24.01.2019 в 16:22, Kimapr сказал:if getmetatable(t).isOpened(protectid) or ((not tprotect.isProtected(t)) and not cantrawset) then
возвращаемся сюда, порядок в lua слева на право, т.е. в начале оно споткнётся об nil , а потом проверит, а защищалась ли таблица вообще?, т.е. нужно поменять местами для начала
if ((not tprotect.isProtected(t)) and not cantrawset) or getmetatable(t).isOpened(protectid) then
если не защищено, то оно не будет пытать метаметод isOpened , однако mt2 мы можем спокойно редактировать, т.е. isProtected и cantrawset мы можем управлять их значениями.
Ещё можно атакуемую таблицу заменить на свою таблицу, дождаться пока её не попробуют открыть, и таким образом заполучить ключ (MitM attack)
Либо пойти более общим путём, раз getmetatable не сохраняется, то просто подменить его и вытянуть интересующие таблички в момент защиты, открытия и т.д. и т.п., либо в setmetatable сделать так, чтобы устанавливались во время защиты свои, т.е. их тоже нужно копировать и защищать)
Затем функция open немного бесполезна, т.к. получается, что таблица на момент выполнения кода не защищена, лучше сделать вариацию, где возвращается таблица, изменяя которую изменяется оригинальная, причём защищённая таблица остаётся защищённой.
Также сам tprotect тоже нужно защищать, т.к. перезаписать функции библиотеки хватит, чтобы сломать её защиту (функции хранятся в открытом виде в package, где можно спокойно подменить, и require будет возвращать её) , также require тоже нужно защищать. Т.е. по факту защита работает успешно только для защищённых ранее и не открывая доступ во время выполнения чего-то, что может иметь плохие желания.
Ладно, пока что на этом хватит, резюмируя всё выше сказанное, её ещё пилить и пилить. А вообще возникает чувство, что автор её даже не проверял, т.к. работают только 2 функции protect и unprotect , а функция rawset вообще под чистую сломана. Ну надеюсь в следующей версии автор учтёт хотя бы часть написанного тута, и следующая версия библиотеки будет лучше.
-
3
-
-
Вопрос такой, будет ли интересно, если сделать продолжение этого квеста?), прост я себе написал списочек из 10 различных идей взлома банка (+ ещё есть пару мыслей, что можно добавить) и можно тогда будет сделать часть 2, где нужно будет взламывать целый ряд банков, с различными уровнями сложности, от просто послушать трафик, до приличной серии махинаций. В принципе реализовать всё это можно за пару дней (при наличии желания), однако стоит ли?
-
1
-
-
То чувство, когда автор карты сделал 2 уязвимости, а хакнул через 3ю 🤣, потом после хака я уже понял идею, как можно было хакнуть ещё причём проще, а когда смотрел уже код, я понял, что автор имел ввиду немного не те дыры (интересно то, что все 3 дыры находятся в разных частях кода), скорее всего первую он имел ввиду ту, которую можно сразу сделать без танцев с бубном, а вторую это уже чисто удача или читать исходники. В принципе со стороны кубика, предназначенного для того, чтобы его ломали и разбирали то довольно не плохо, однако выводить в релиз как работоспособую и безопасную систему явно нельзя 😅
-
1
-
1
-
-
Скорее всего значит у тебя установлена OpenOS 1.6.1 , а значит просто тебе нужно будет подменять event.shouldInterrupt
local event = require("event") function DisableInterrupt() if _G.shouldInterruptBackup then return false end _G.shouldInterruptBackup = event.shouldInterrupt event.shouldInterrupt = function() return false; end return true end function EnableInterrupt() if type(_G.shouldInterruptBackup) ~= "function" then return false end event.shouldInterrupt = _G.shouldInterruptBackup return true endвставляешь это в начало кода, а потом, когда нужно вызываешь функцию, которая тебе нужна (думаю это и так понятно), если и это не сработает. то тогда скажи, чему равна переменная _G._OSVERSION
-
3
-
-
Ну, перед тем, как задавать вопрос желательно поискать, задавался ли он до этого и есть ли на него ответ.
http://computercraft.ru/topic/2396-kak-otklyuchit-ctrlaltc/?do=findComment&comment=35069
Если это не сработает, то нужно будет сказать, какая версия мода и OpenOS, ведь там меняли эту вещь. В начале была функция shouldInterrupt , потом её убрали и пришлось костылить, а в самой новой версии вернули возможность через обработку process.info().data.signal
хмм, прочитав код и видя строчки
for i = 1, 255 do print() endстановится больно, эмм, зачем?? и что они должны делать?, очищать экран?, temp.clear() на что?
Затем ещё табуляция есть не везде, например после while true do оно так и остаётся монотонным текстом, ну ладно, это я уже отошёл от темы.
-
1
-
1
-
-
28.11.2018 в 23:03, Kalum сказал:Хм неплохо, но маловато разнообразия.
Ну, если есть предложения, что добавить/изменить/исправить, то я с радостью приму это.
-
Только что, eu_tomat сказал:Возможно, не понял вопроса. На диск OC, разумеется. Какие ещё есть варианты? На HTTP сервер? Но как защититься от недобросовестных установщиков игры?
ну, логично что на диске, я спрашивал про путь нахождения файлов, есть 2 пока что мысли по этому поводу, либо в ту же папку, где и сама игра и таким же названием файла ток на конце .cfg (для этого нужно будет посмотреть как там определить где находится файл), либо в какой-то фиксированный глобальный путь
-
1 минуту назад, eu_tomat сказал:Ну, если тебя устраивает минимализм, можешь посмотреть, как это устроено во всё том же Far Mine, плагине для файлового менеджера. Мой скриншот как раз в нём получен. Там при входе выбор из трёх вариантов сложности, горячие клавиши кроме выше перечисленных:
F2: Restart (смена уровня сложности не предполагается до выхода из игры)
F3: Highscore
По окончании игры, если установлен рекорд, предлагается ввести имя. А в OC игра и так знает имя игрока, одним экраном будет меньше.
ну, для минимализма нужно, чтобы пользователь знал заранее на что нажимать, думаю я просто добавлю кнопки сверху(или снизу), для этого, нужно будет глянуть что из этого получится, кстати есть еще вопрос, куда лучше сохранять конфиги и рекорды?
-
6 минут назад, eu_tomat сказал:Ну, у меня проблема в том, как размещать кнопки для менюшки выбора сложности, кнопку ввхода и т.п., в принципе если нужно, то могу модифицировать с монотонных клеток на чередующуюся сетку, что скорее всего будет лучше, есть еще вещь печальная, раньше знак мины у меня был знак радиации, однако после великой обновы шрифта его больше нету, сейчас я локально заменил на два полукруга (круг в ячейке 2х1)
-
Update7(11.11.2018)
Хотелось сделать больше, а получилось как всегда, но не суть
1) Игра тетрис переписана под гуи и вроде выглядит даже нормально
2) Аналогично и с крестиками-ноликами
3) Теперь в тетрисе есть тень (которую можно включить и выключить в настройках), а также предсказание следующего блока
4) В крестиках-ноликах теперь можно выбирать требовать ли авторизацию (т.е. если идёт чужой ход, то только игрок, зарегестрированный под него может ходить)
Вообще я еще переписывал сапёр, но столкнулся об стенку, "как он должен выглядеть", и пока нету ни единой мысли об этом. Такая же (но меньше) проблема касается и Камень-Ножницы-Бумага. Наконец-то я заставил себя чуточку подредактировать главный пост и добавил план, по выполнению которого я скорее всего закончу с этой темой и уже буду заниматься другими вещами.
Либа потиху растёт помолимся за обратную совместимость после апдейта, ведь я её не чекал.Скрытый текст

-
1
-
-
Update6(27.10.2018)
Это изменение касается только игры MazeMaster
1) Добавлено меню, а также куча настроек
2) Добавлена функция "поиск пути", рабочая, однако отрисовка не доделана, если в настройках включена она, то срабатывает при нажатии "P"
3) Добавлены маркеры, установить на пробел
4) Пофикшены пара багов в генераторах, в рекурсивном теперь начинает из случайной точки, а в hunt&kill больше не может быть циклов
5) Добавлена возможность изменения точки начала и конца
6) На случай если либа, нужная не скачана, то предложит пользователю скачать её при наличии инет карты
Скрытый текст

-
4
-
-
Короче, если вопрос еще актуален, код чуть ниже предоставляет 2 функции включить и выключить, никаких модификаций в библиотеках он не требует, т.е. достаточно вставить его куда-нибудь поближе к началу. Работает за счёт переопределения computer.pullSignal блокируя все ошибки изнутри.
local computer = require("computer") local pullSignalBackup = nil local function DisableInterrupt() if pullSignalBackup ~= nil then return false end pullSignalBackup = computer.pullSignal computer.pullSignal = function(...) local tbl = {pcall(pullSignalBackup, ...)} return table.unpack(tbl, 2) end return true end local function EnableInterrupt() if pullSignalBackup == nil then return false end computer.pullSignal = pullSignalBackup pullSignalBackup = nil return true end-
2
-
-
Оффтоп:
Почему играм от программистов никогда не хватает графона?
Ну, если ты сможешь предложить, как оно должно выглядеть лучше, я буду только за, сегодня этим как раз планирую заняться.
-
Update5(17.07.2018)
Итак, я вернулся спустя приличное время, если pastebin не врёт, то я написал SameGame аж еще 25.03.2018, однако на мой взгляд он был очень не завершён или еще что-то и я решил сюда не добавлять.
1)Я и гуи злостные враги, однако чужое брать я очень не люблю, поэтому только что я завершил написание прототипа своего велосипеда лично для себя.
2)Добавлена игра SameGame и она имеет (неожиданно) меню, настройки и нормальную кнопку выхода.
К следующему разу (надеюсь завтра), я планирую запихнуть условие конца игры туда и таблицу рекордов, а также запихнуть менюшку ко всем играм(хотя код некоторых прям кричит ПЕРЕПИШИТЕ МЕНЯ)
3)Перенёс все скрины на imgur
Рандом пасты меня пугает..., что он курил, когда придумывал к SameGame строку.
А еще меня интересует, как открепить старые прикреплённые файлы от сообщения?
-
1
-
-
Можно было, но зачем? Если вся основная масса народа сидит либо с золотым, либо с алмазным.
Ну, не всем быть жирующими, можно тупо сделать и то и то, какие проблемы в этом?)
-
Я хотел предложить 1D арену, намного меньше возни, а возможности те же, что и на текущей.
а какой в этом смысл?) типа как дуэльки кто быстрее пульнёт тот и победил?) хотя впринципе можно что-нибудь такое умное реализовать типа есть несколько слоёв (допустим 5) нужно придумать такту в которой ты сможешь выстрелить и увернуться от пули врага потом как-нибудь просканировать жив ли враг, такая перестрелка получится. Как идея для UT#3 годится) правда в толщиной в 1 блок всё-таки не совсем будет место для манёвра толщины 3-5 должно хватить, также изначально роботы должны находиться спиной друг к другу, это нужно например для того чтобы если робот захотел отойти вбок,а другой решил сразу стрелять и было чтобы время отойти

Как получить случайное целое число?
в Lua
Опубликовано:
Только они чутка бракованные. В первом варианте поскольку рандом с границами генерирует включительно, иногда генерирует на 1 цифру больше, т. е. [1; 10], [10; 100] и т. д. А во втором варианте оно вообще фигню делает, [10; 18], [100; 198] и т. д.
Ну и чутка бессмысленный момент: 0 это число длины 1, а должна ли функция его генерировать?