LINUX.ORG.RU

patch


0

1

Хочу (для себя) реализовать простой патчер, которому на вход подаётся типа

125E2 01??45 6789ABCDEF
# проверить в файле по адресу 125E2 байты 012345 и,
# если солвпадут, то записать по тому адресу 6789ABCDEF
# ?? -- любой байт
Но я не программист. На каком языке проще всего такое реализовать?

Я нашёл xdelta для патчей бинарных файлов, но файл, где находятся изменения не в текстовом формате. Это плохо.


Чем вас не устраивает hex-редактор + bsdiff/bspatch? Открываете в hex-редакторе нужный вам файл, редактируете, сохраняете с другим именем. Затем выполняете:

bsdiff oldfile newfile patchfile
Теперь чтобы применить патч к oldfile, достаточно сделать:
bspatch oldfile newfile patchfile

edigaryev ★★★★★
()
Ответ на: комментарий от edigaryev

Нужен ТЕКСТОВОЙ формат патчей. По поводу xdelta уже писал в первом посте. bsdiff установил — он тоже делает patchfile бинарным.

Hex редактор, sed не предлагать. Если такого патчера нет, то ответьте пожалуста на 1й вопрос в первом посте.

paxac
() автор топика
Ответ на: комментарий от paxac

>Нужен ТЕКСТОВОЙ формат патчей.

Теперь понятно что вы имели ввиду, а я думал что «файл где находятся изменения не в текстовом формате» — это уже отредактированный вами бинарный файл (сравнивать с которым вы собираетесь оригинал и получать из этого патч).

edigaryev ★★★★★
()

В V_Klay был похожий формат... Но он проприетарный, виндовый, рип, и вообще, не для этого предназначен.

Yareg ★★★
()

Но я не программист. На каком языке проще всего такое реализовать?

на котором умеешь прогать :)

true_admin ★★★★★
()

Я бы такое на си писал. Хотя в принципе можно на любом языке, который умеет работать с файлами.

Legioner ★★★★★
()

тю

#include <sys/types.h>
#include <stdio.h>
#include <unistd.h>

#define BUFSZ   81
extern char *__progname;

int
main(int argc, char **argv)
{
        FILE    *fd, *cd;
        char    buf[BUFSZ];
        u_long  addr;
        u_char  a, b, c;

        if (argc != 3) {
                fprintf(stderr, "usage: %s <crack> <file>\n", __progname);
                exit(1);
        }

        cd = fopen(argv[1], "r");
        fd = fopen(argv[2], "r+");

        while (fgets(buf, BUFSZ, cd)) {
                if (buf[0] == '#' || buf[0] == '\n')
                        continue;
                sscanf(buf, "%lu %hho %hho", &addr, &a, &b);
                fseek(fd, addr - 1, SEEK_SET);
                fread(&c, 1, sizeof(char), fd);
                printf("%6d: 0x%.2x -> 0x%.2x", addr, c, b);
                if (c == a) {
                        c = b;
                        fseek(fd, addr - 1, SEEK_SET);
                        fwrite(&c, 1, sizeof(char), fd);
                        puts(" Ok");
                } else
                        puts(" error");
        }

        fclose(cd);
        fclose(fd);

        return 0;
}
beastie ★★★★★
()
Ответ на: комментарий от true_admin

ни на каком толком не умею, поэтому и прошу чтобы было проще.

paxac
() автор топика
Ответ на: тю от beastie

Длина второго поля (сверяемые байты) может быть любая, должны быть маски (??). Длина третьего поля тоже любая (не обязательно равна длине второго). Знаю чуть-чуть c, perl, ruby,...

P.S. в идеале я бы хотел для личного использования иметь тулзу, чтобы patchfile был типа

# заменить (Change) по адресу 12E байты 45??78 на FF (??78 оставить)
C 12E 45??78 FF

# найти в файле все 45??78 и заменить на FF (??78 оставить)
R 45??78 FF

# вставить по адрресу 45AB байты 123456
A 45AB 123456

# и т.п.
но это пока для меня что-то запредельное. Пока хотя бы просто обычную замену делать.

Может уже велосипед изобретен?

paxac
() автор топика
Ответ на: комментарий от paxac

да, были тулзы. К сожалению не помню названий и под какую ос были(под винду, что-ли). Только вот формат данных не помню. Думаю найдёшь в хакерских архивах.

true_admin ★★★★★
()
Ответ на: комментарий от paxac

А может кто-нибудь привести пример на ruby или perl с обработкой масок? регекспами можно сделать?

paxac
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.