Comments 7
Если вы хотите поразвлекаться, создавая случайные глюки в ваших любимых играх для Dendy, могу предложить вам небольшую программу на C#, которая предназначена именно для этого. Программа учитывает особенности формата iNES и вносит случайные изменения только в программный код.
Для использования нужно запускать в консоли команды вида:
Для использования нужно запускать в консоли команды вида:
mutator in.nes out.nes keyword 100
, где keyword используется как randseed (то есть для одного и того же слова будет один и тот же набор случайных мутаций), а число задаёт количество мутаций (конкретно сколько байт будет испорчено).Программа для создания мутаций
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
class NesFile
{
public string FileName;
public byte[] Header;
public byte[] Trainer;
public List<byte[]> PRG;
public List<byte[]> CHR;
public byte[] Attach;
public NesFile(string filename)
{
FileName = filename;
var ROM = File.ReadAllBytes(FileName);
if (ROM[0] != 'N' || ROM[1] != 'E' || ROM[2] != 'S' || ROM[3] != 0x1A)
{
throw new Exception("Invalid iNES header");
}
Header = new byte[16];
Array.Copy(ROM, 0, Header, 0, 16);
var offset = 16;
if ((Header[6] & 0x04) != 0)
{
Trainer = new byte[512];
Array.Copy(ROM, offset, Trainer, 0, Trainer.Length);
offset += Trainer.Length;
}
PRG = new List<byte[]>();
for (var i = 0; i < Header[4]; i++)
{
PRG.Add(new byte[16384]);
Array.Copy(ROM, offset, PRG[i], 0, PRG[i].Length);
offset += PRG[i].Length;
}
CHR = new List<byte[]>();
for (var i = 0; i < Header[5]; i++)
{
CHR.Add(new byte[8192]);
Array.Copy(ROM, offset, CHR[i], 0, CHR[i].Length);
offset += CHR[i].Length;
}
if (ROM.Length > offset)
{
Attach = new byte[ROM.Length - offset];
Array.Copy(ROM, offset, Attach, 0, Attach.Length);
}
}
public void PrepareHeader()
{
Header[4] = (byte)PRG.Count;
Header[5] = (byte)CHR.Count;
}
public void Save(string filename = null)
{
PrepareHeader();
if (filename != null)
{
FileName = filename;
}
using (var fs = File.OpenWrite(FileName))
{
fs.Write(Header, 0, Header.Length);
if (Trainer != null)
{
fs.Write(Trainer, 0, Trainer.Length);
}
for (var i = 0; i < PRG.Count; i++)
{
fs.Write(PRG[i], 0, PRG[0].Length);
}
for (var i = 0; i < CHR.Count; i++)
{
fs.Write(CHR[i], 0, CHR[0].Length);
}
if (Attach != null)
{
fs.Write(Attach, 0, Attach.Length);
}
}
}
}
class Mutagen
{
static void Main(string[] args)
{
if (args.Length < 4) return;
var nes = new NesFile(args[0]);
var rnd = new Random(args[2].GetHashCode());
var crb = Int32.Parse(args[3]);
for (int i = 0; i < crb; i++)
{
var prg = rnd.Next(nes.PRG.Count);
var pos = rnd.Next(nes.PRG[prg].Length);
var shift = rnd.Next(-2, +2);
int value = nes.PRG[prg][pos] + shift;
nes.PRG[prg][pos] = (byte)(value & 0xFF);
}
nes.Save(args[1]);
}
}
+4
UFO just landed and posted this here
Всё же «ампутация», на мой взгляд, больше подходит к отрезанию каких-то внешних вещей, не относящихся непосредственно к коду. В статье выше упоминается удаление некоторых тайлов в CHR ROM для того, чтобы сделать нарисованные ими элементы невидимыми.
Ежели у Вас селекция, то у нас — ампутация.Не понял, почему вы говорите, что у меня селекция. Я сам занимался именно реверс-инжинирингом оригинальной менюшки, и в статье об этом сказано. Поскольку кода было немного (всего 16 килобайт), получилось разобраться в её работе на 100%, и на её основе сделать демку.
0
Как же теперь легко будет матери объяснить пользу ГМО. Спасибо.
+2
Заходил несколько дней назад к вам на сайт, увидел обновление к Unchained Nostalgia, думаю, наверняка скоро и интересная статья появится, и вот она!
Есть какие-то предположения, сколько потребовалось проб и ошибок для создания такого хака? Это все, полагаю, вручную проверялось?
Есть какие-то предположения, сколько потребовалось проб и ошибок для создания такого хака? Это все, полагаю, вручную проверялось?
+1
Сколько именно времени ушло на создание хака — не знаю. Но его автор выкладывает и другие подобные хаки. Например, вот пачка странных хаков игры Battle City. На мой вопрос автор этого хака ответил лаконично:
![image](https://habrastorage.org/r/w1560/getpro/habr/comment_images/f8a/10b/0ec/f8a10b0ece8a8f3f476cfd30cb84d756.png)
Я сам в детстве (15 лет назад) просто исправляя в HEX-редакторе байты, которые мне просто «не нравились», умудрился снять требование регистрации в одной из вариаций игры «О, счастливчик!» (я писал свой вариант этой игры, и взламывал «конкурента», который тоже был написан школьником). Просто очень сильно повезло. Плюс много терпения и сотни перезапусков с разными исправлениями :)
Как делал? Просто, но долго. Корруптором.Потом в процессе разговора он уточнил суть используемого им метода:
Но не всегда случайные и не всегда случайным образом. Можно определённые на определённые. Но если ты не знаешь АСМ, дебаггеры и т.д., то только так.Видимо, «случайные» правки всё же как-то были приправлены интуицией. Как видно, использованная программа позволяет задавать некоторые правила для «мутаций»:
![image](https://habrastorage.org/getpro/habr/comment_images/f8a/10b/0ec/f8a10b0ece8a8f3f476cfd30cb84d756.png)
Я сам в детстве (15 лет назад) просто исправляя в HEX-редакторе байты, которые мне просто «не нравились», умудрился снять требование регистрации в одной из вариаций игры «О, счастливчик!» (я писал свой вариант этой игры, и взламывал «конкурента», который тоже был написан школьником). Просто очень сильно повезло. Плюс много терпения и сотни перезапусков с разными исправлениями :)
0
Sign up to leave a comment.
Методы модификации машинного кода: «селекция» vs. «генная инженерия»