Хранение нескольких различных файлов в одном исполняемом.
Часть II. "Анпакер"
В моей прошлой статье обсуждалась тема написания упаковщика (Packer), теперь же подробно остановимся на программе, котрая всё спрятанное будет из себя доставать. Но сначала я хотел бы обосновать своё мнение о личных форматах хранения информации, которое, возможно, было неправильно понято некоторыми читателями. Когда человек создаёт свой формат хранения информации, то только он знает как её оттуда достать. Большинство программ (например игровые) используют свои форматы хранения ресурсов (музыка, спрайты/текстуры, мультики). Быть может, взломать эти ресурсные файлы легче, так как можно декомпилить/дизассемблить исполняемый файл и понять, как и что прячет и достаёт программа, но я знаю очень мало людей способных это сделать. Если же использовать стандартные средства хранения (какой-нибудь архиватор), то любой более или менее опытный пользователь может посмотреть заголовок файла и по нему найти нужную "открывалку".
Теперь вернёмся к коду пакера. Для удобства я добавил в OnCreate формы следующую строчку:
Это сделано для удобства использования программы, так как до этого файл "Test.exe" кидался в последнюю открытую директорию и приходилось постоянно указывать путь. Так же надо добавить строчку в самый конец Button1Click:procedure TForm1.FormCreate(Sender: TObject); begin Edit3.Text:=ExtractFilePath(ParamStr(0))+'test.exe'; end;
CloseFile(f2);
Ну вот и всё, что качалось пакера. Осталось самое интересное - анпакер. Вот усовершенствованный код Unpacker'а с последующими комментариями:
program Unpacker;
uses
Classes;
const c=117248;
var mem:TmemoryStream;
i:integer;
done:integer=0;
done1:integer;
f:file;
buf:array[1..2048] of byte;
begin
mem:=TmemoryStream.Create;
mem.LoadFromFile(paramstr(0));
mem.Seek(c,soFromBeginning);
mem.ReadBuffer(i,sizeof(i));
assignfile(f,'temp1');
rewrite(f,1);
while i>=done+2048 do begin
done1:=mem.Read(buf,sizeof(buf));
blockwrite(f,buf,done1);
done:=done+done1;
end;
if i>done then begin
done1:=mem.Read(buf,i-done);
blockwrite(f,buf,done1);
end;
closefile(f);
done:=0;
mem.ReadBuffer(i,Sizeof(i));
assignfile(f,'temp2');
rewrite(f,1);
while i>done+2048 do begin
done1:=mem.Read(buf,sizeof(buf));
blockwrite(f,buf,done1);
done:=done+done1;
end;
if i>done then begin
done1:=mem.Read(buf,i-done);
blockwrite(f,buf,done1);
end;
CloseFile(f);
mem.Free;
end.
Одним из самых простых и эффективных методов работы с .exe файлами являются потоки. Тут всё просто. Сначала мы создаём поток, затем загружаем в него исполняемый файл. Далее следует очень важная строчка:
Константа "с" является размером анпакера. Значение 117248 было получено эксперементальным путём. Для этого компилим анпакер и смотрим его ТОЧНЫЙ (а не занимаемый) размер. Его-то и присвайваем "c". Далее мы считываем размер первого файла. Затем циклом копируем его содержимое "Temp1". Аналогично поступаем со вторым файлом. На выходе получаются два файла, которые мы дописали пакером в анпакер.mem.Seek(c,soFromBeginning);
Чем хорош этот анпакер? Первое и самое главное это то, что весь файл загружается в ОЗУ и извлечение происходит на максимальной скорости. Теперь чем он плох. Во первых размером. Поэтому его нельзя использовать для распаковки трояна и какой-нибудь игрушки (код запуска обоих можно добавить в самый конец (WinExec)). Так же, раз всё загружается в память, то её может не хватить (а то зашьешь в анпакер два файла по 400 метров :).
Можно пойти другим путём - использовать стандартные Delphi'ковские FileOpen, FileRead and so on :).
Вот исходник:
program Unpacker;
uses
SysUtils;
const c=41984;
var h:integer;
mas:array[1..2048] of byte;
f:file;
i,done1:integer;
done:integer=0;
begin
h:=FileOpen(paramstr(0),fmOpenRead or fmShareDenyWrite);
FileSeek(h,c,0);
FileRead(h,i,sizeof(i));
assignfile(f,'temp1');
rewrite(f,1);
while i>=done+2048 do begin
done1:=FileRead(h,mas,sizeof(mas));
blockwrite(f,mas,done1);
inc(done,done1);
end;
if i>done then begin
done1:=fileread(h,mas,i-done);
blockwrite(f,mas,done1);
end;
CloseFile(f);
done:=0;
FileRead(h,i,sizeof(i));
assignfile(f,'temp2');
rewrite(f,1);
while i>=done+2048 do begin
done1:=FileRead(h,mas,sizeof(mas));
blockwrite(f,mas,done1);
inc(done,done1);
end;
if i>done then begin
done1:=fileread(h,mas,i-done);
blockwrite(f,mas,done1);
end;
CloseFile(f);
FileClose(h);
end.
В принципе всё то же самое, что и в первом примере, только без потоков (помни про "c").
Отсюда вытекает следующее: меньше расходуется память, так как все мы берём из файла, объём анпакера сокращается до 41984 байт (у тебя может быть другая цифра). Минусы - работа с винтом и всё еще большой анпакер, так что троян записать (и кому-нибудь "подарить") проблематично.
В следующий раз мы поговорим о Windows Api и оптимизации кода анпакера.
И помни: мои примеры всегда можно подогнать под свои нужды и использовать в общественно-полезной деятельности :)))).
Copyright© 2003 Zero Ice Специально для Delphi Plus
| 2011 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 |
| 2010 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 |
| 2009 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 |
| 2008 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 |
| 2007 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 |
| 2006 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 |
| 2005 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 |
| 2004 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 |
| 2003 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 |
| 2002 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 |
| 2001 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 |
| 2000 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 |
| 1999 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 |
- Компания по разработке программного обеспечения
- Услуги аутсорсинга в области программирования
- Как продлить срок службы картриджей
- Мошенничество во Всемирной Паутине. Осторожно: фишинг!
- Web-студия
- Как легально поднять уровень индекса цитирования.
- Мы реально сможем помочь вам в управлении предприятием
- Создание сайтов – популяризация вашего замысла
- Свой сайт. Управление ресурсом
- Семантическое ядро сайта или правила подбора ключевых фраз
- Программирование в среде Delphi 8 for .NET
- Практикум по Delphi для решения прикладных задач
- Фундаментальные алгоритмы и структуры данных в Delphi
- Delphi 6. Программирование на Object Pascal
- Delphi и технология COM
- Delphi в шутку и всерьез: что умеют хакеры
- Программирование в Delphi глазами хакера
- Delphi 2005. Секреты программирования
- Искусство создания компонентов Delphi
- Приемы программирования в Delphi на основе VCL
- Программирование баз данных в Delphi 7
- Программирование баз данных в Delphi
- Программирование в среде Delphi
- Программирование в Delphi 7
- Язык SQL в Delphi 5