пятница, 11 января 2013 г.

Как я ебался с diff'ами

Diff из пакета mingw и winmerge не умеют делать разницу между двумя Exe.

В то же время WinRar делает solid архивы, учитывающие различия в двух почти одинаковых исполнимых файлах.

На карте rar файла мы имеем [Application1.Exe][Application2.Exe], если в Hiew убрать из rar первое приложение, то останется отличие второго от первого.

Microsoft давно что-то типа этого придумала, но для меня это в новинку.

Можно долго описывать какая лажа winmerge, не качайте это говно!

Отличия я делал для своей программы PrintWisdom, версии 2.20 и 2.21.

PrintWisdom.Exe версии 2.20 занимает 690k, diff получился 77k.

Вся фигня с diff'ами придумалась, когда на балансе 3G интернета остались деньги, но время тарифного плана истекло, т.е. можно было послать по почте что-то очень маленькое.

Hiew это замечательно, но как восстановить Application2.Exe из Diff'а? Это же не полноценный rar архив, а только его остаток?

Вручную я это сделал достаточно быстро, только небольшая ломка пока придумал как.

Затем долго исправлял программу на Си, делающую то же самое. Я пожалуй вставлю её ниже.

#include
#include
#include
#include

int myfind(FILE *f, char *s)
{
const int BUF_SIZE = 1;
char b[BUF_SIZE];
int pos = -1;
int L = strlen(s);
int fptr;
while (true)
{
int n = 0;
int matches = 0;
fptr = ftell(f);
LOOP:
fread(b, BUF_SIZE, 1, f);
if (ferror(f)) break;
if (b[0] == s[n])
{
matches++;
if (matches == L)
return fptr;
if (matches < L)
{
n++;
goto LOOP;
}
}
}
return pos;
}

int main()
{
system("copy PrintWisdom.1 PrintWisdom.2");
FILE *file1 = fopen("PrintWisdom.2", "r+b");
int random_position = 0x963;
char random_byte = 0x51;
fseek(file1, random_position, 0);
fwrite(&random_byte, 1, 1, file1);
fclose(file1);
// WinRAR should be V4.1.0!
system("\"C:\\Program Files\\WinRAR\\WinRAR.exe\" a -m5 -s PrintWisdom.rar PrintWisdom.1 PrintWisdom.2");
FILE *file2 = fopen("PrintWisdom.rar", "r+b");
int pos = myfind(file2, "PrintWisdom.2");
fseek(file2, pos-50, 0);
chsize(file2->fd, ftell(file2));
fclose(file2);
system("copy /b PrintWisdom.rar + PrintWisdom.diff my.rar");
system("rar t my.rar");
return EXIT_SUCCESS;
}

Подразумевается, что файл PrintWisdom.1 (переименованный PrintWisdom.Exe версии 2.20) у получателя почты есть.

Функция myfind ищет строку в двоичном файле, как F7 в Hiew. Используются нестандартные возможности среды Си, например chsize.

Комментариев нет:

Отправить комментарий