Эта материал открывает цикл статей для юных программеров (и хакеров :)),
интересующихся сокрытием своей информации (а так же поиском интересной "чужой" :)). Не
секрет, что у тебя есть много того, что ты бы не хотел показывать ФСБ, друзьям, Васе Пупкину,
и прочей "мировой общественности". Конечно можно использовать запароленные архивы и прочую
лабуду (например твой сосед может не увидеть скрытый файл на
расшаренном диске :), но если задуматься, то станет ясно что, чем больше людей использует одинаковые системы защиты, тем
быстрее улучшаются методы взлома этих систем (сорри за тавтологию). У тебя ёще не появилось желание написать средство для защиты своей
ценнейшей инфы (исходников, рефератов, фоток 🙂 и т.д и т.п.) от
посторонних глаз? Ведь если ты что-то написал сам,
то только ТЫ знаешь, КАК ОНО ПРЯЧЕТСЯ И ДОСТАЁТСЯ. Наши первые программы
будут полезны как программерам, так и хакерам. Это будут Пакер и Анпакер (Packer & Unpacker).
В этой статье я опишу только пакер (темы анпакера будут затронуты в следующих статьях).
Писать мы его будем на всенародно любимом Delphi (у меня шестая версия, но работать должно и на
предыдущих).
Суть пакера заключается в следующем: в конец некоего экзешника (.exe)
дописываем размер файла, который мы потом будем из него доставать, далее следует сам файл,
потом размер второго файла, и, собственно, второй. Сразу скажу что под "неким экзешником" я
подразумеваю анпакер. Ну, что? Готов? Если да то запускай Делфи и создавай новый проект.
Первым делом назови как-нибудь форму (Caption) (пусть будет что-то типа
"Super-Puper-Mega-Packer"). Далее размести на ней OpenDialog и SaveDialog (вкладка
Dialogs).
Открой Options в Object Inspector'е и сделай поля ofPathMastExist и ofFileMastExist равными True. Всё это нужно для
того, чтобы файлы, которые мы будем прятать реально существовали. В SaveDialog'е желательно
сделать поле ofPathMastExist равным True. Так же размести на форме кнопку (Button) с
грозной надписью "GO!", 3 Edit'а (первым двум Edit'aм в поле ReadOnly надо поставить True) и
3 SpeedButton'а. У SpeedButton1 сделай поле Tag равным 1 (это понадобится в дальнейшем).
Теперь можно занятся дизайном нашего пакера (это не должно вызвать особых проблем :)). Не забудь
только загрузить рисунки в SpeedButton'ы. Отличные пикчурсы можно взять (если у тебя стоит
полная версия Delphi) из \Program Files\Common Files\Borland Shared\Images\Buttons. Я нацепил на
SpeedButton1 и SpeedButton2 Fileopen.bmp, а на SpeedButton3 - Filesave.bmp. А теперь переходим к самому интересному - к кодингу. Для начала сделаем
обработчик SpeedButton1'а OnClick и укажем его же в SpeedButton2. В нем напишем
следующий код:
procedure TForm1.SpeedButton1Click(Sender: TObject);
begin
if OpenDialog1.Execute then
if (Sender as TSpeedButton).Tag=1 then Edit1.Text:=OpenDialog1.FileName
else Edit2.Text:=OpenDialog1.FileName;
end;
Если пользователь в OpenDialog'е что-то выбрал, то посмотрим какой из
SpeedButton'ов он нажал и присвоим соответствующему Edit'у новое значение. Можно было бы
сделать два OnClick'a (у каждого SpeedButton'а свой) и написать что-то типа:
procedure TForm1.SpeedButton1Click(Sender: TObject);
begin
if OpenDialog1.Execute then Edit1.Text:=OpenDialog1.FileName;
end;
procedure TForm1.SpeedButton2Click(Sender: TObject);
begin
if OpenDialog1.Execute then Edit2.Text:=OpenDialog1.FileName;
end;
Но мне это кажется неспортивным. Да и откомпилированная прога будет жирнее
на пару байт :). Далее обратим свой взор на SpeedButton3. Сделаем обработчик OnClick в
котором:
procedure TForm1.SpeedButton3Click(Sender: TObject);
begin
if SaveDialog1.Execute then Edit3.Text:=SaveDialog1.FileName;
end;
Ну а теперь перейдём к самой интересной кнопке - "GO!". В её OnClick'е
будет сам упаковщик:
procedure TForm1.Button1Click(Sender: TObject);
var f,f2:file;
buf:array[1..1024] of byte;
done:integer;
begin
if not((FileExists(Edit1.Text))or(FileExists(Edit2.Text))) then begin
ShowMessage('Неправильно указан путь к файлу');
Exit;
end;
if not FileExists(ExtractFilePath((Application.ExeName))+'Unpacker.exe')
then begin
ShowMessage('Не могу найти Unpacker.exe');
Exit;
end;
AssignFile(f,ExtractFilePath((Application.ExeName))+'Unpacker.exe');
AssignFile(f2,Edit3.Text);
Reset(f,1);
Rewrite(f2,1);
while not eof(f) do begin
blockread(f,buf,sizeof(buf),done);
blockwrite(f2,buf,done);
end;
CloseFile(f);
AssignFile(f,Edit1.Text);
Reset(f,1);
done:=FileSize(f);
blockwrite(f2,done,4);
while not eof(f) do begin
blockread(f,buf,sizeof(buf),done);
blockwrite(f2,buf,done);
end;
CloseFile(f);
AssignFile(f,Edit2.Text);
Reset(f,1);
done:=FileSize(f);
blockwrite(f2,done,4);
while not eof(f) do begin
blockread(f,buf,sizeof(buf),done);
blockwrite(f2,buf,done);
end;
CloseFile(f);
end;
Тут всё совсем просто :). Для начала проверяем все ли необходимые для
упаковки файлы присутствуют. Далее создаем файл указанный в Edit3.Text и записываем в него
распаковщик, размер первого файла, файл, размер второго и второй соответственно
(какой-то бутерброд получается :)). Вот и всё! В результате получается .exe который может
достать из себя эти 2 файла. Но сейчас это работать не будет, так как нет Unpacker.exe. Его мы
напишем в следующий раз. Хотя для любопытных я приведу листинг альфа версии
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,$4);
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,4);
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.