Packerların mantığı nedir ? hangi yöntemler kullanılır ?

Delphi'de kod yazma ile ilgili sorularınızı bu foruma yazabilirsiniz.
Cevapla
cLaW
Üye
Mesajlar: 46
Kayıt: 06 Eki 2008 02:16

Packerların mantığı nedir ? hangi yöntemler kullanılır ?

Mesaj gönderen cLaW »

Selamlar herkese hayırlı ramazanlar packer yapmak istediğimden bu konular hakkında bilgi almak istedim.
Benim düşündüğüm yöntem şu packerlar oluşturduğu exeye sıkıştırdığı exeyi dahil edip oluşturduğu exe içindeki sıkıştırılmış exeyi memoryde çözüp memory üzerinden açıyor doğrumu biliyorum acaba ?

Peki bu yöntem doğruysa nasıl yaapbilirim TFileStreamlar ile yapılabilirmi ? veya Taslak bi exe oluştursak onun içinde bi dosya gömülü olsa ve biz packerımızla taslak exenin içindeki gömülü exenin byte boluğunu editleyip yeni bir exeyi byte byte yazsak olurmu ? Sanırım bunu TFileStreamlarla yapıcaz %90 öyle geliyor bana ama bunu nasıl yapabilirim bilgilendirebilirmisiniz beni hepinize çok çok teşekkürler şimdiden :D
cLaW
Üye
Mesajlar: 46
Kayıt: 06 Eki 2008 02:16

Re: Packerların mantığı nedir ? hangi yöntemler kullanılır ?

Mesaj gönderen cLaW »

Sorularımı daha açık sormam anlaşılması açısından iyi olucak sanırım ilk aşamada bir dosyayı memory üzerinde nasıl çalıştırabiliriz ?

En azından kullanılacak fonksiyonlardan bahsedebilirseniz çok memnun olurum araştırması bana kalır :)
Kullanıcı avatarı
mrmarman
Üye
Mesajlar: 4741
Kayıt: 09 Ara 2003 08:13
Konum: İstanbul
İletişim:

Re: Packerların mantığı nedir ? hangi yöntemler kullanılır ?

Mesaj gönderen mrmarman »

En basit haliyle şunu yapabilirsin.

FORM barındırmayan sadece DPR projeden bir EXE program oluştur. Bu program şunu yapsın. Kendi EXE'dosyasının en son 4 BYTE'ını okusun ve bunu kullanarak sondan geriye doğru o kadar byte offset giderek konumlandığı noktadan sona kadar (son 4 byte hariç) FileStream ile okuyup ZIP paketi açarak yeni bir dosya oluşturup çalıştırsın, sonra da yeni dosyanın işi bitince silsin.

İkinci bir (Packer olarak çalışacak) projen olsun. Bu birinci EXE dosayı RESOURCE olarak bünyesine gömersin. Sonra da PACK için göstereceğin dosyayı önce ZIP sıkıştırıp FileStream ile önce resourcedaki senin ilk projen ardından ZIP'lanmış kaynak dosya ile birleştirsin. En sona da birleştirdiği kaynak dosyanın boyutunu 4 byte olarak kaydetsin.

Anlatımım açık oldu mu ?
Resim
Resim ....Resim
cLaW
Üye
Mesajlar: 46
Kayıt: 06 Eki 2008 02:16

Re: Packerların mantığı nedir ? hangi yöntemler kullanılır ?

Mesaj gönderen cLaW »

Hocam çok güzel bi şekilde anlatmışsınız doyanın boyutunu saklamada felan problem yaşayacağımı sanmıyorum ama 2.exenin içindeki resource olarak gömülü exeyi packer nasıl seçtiğim exe ile değiştirecek bunu koda dökemem diye korkuyorum. en azından bunları yapıp dosyayı diske yazıp açsam bile çok iyi bi gelişme olacak :) Yarın ilk işim denemelere başlayıp buraya bi netice yazmak olacak ilgilendiğiniz için çok teşekkür ederim.
Kullanıcı avatarı
mrmarman
Üye
Mesajlar: 4741
Kayıt: 09 Ara 2003 08:13
Konum: İstanbul
İletişim:

Re: Packerların mantığı nedir ? hangi yöntemler kullanılır ?

Mesaj gönderen mrmarman »

Yanlış anlaşılmış sanırım. Packer RESOURCE olarak senin gösterdiğin yeni dosyayı içine almayacak veya herhangi bir resource değişikliği yapmayacak.
Resource olayı, ürettiğin iki farklı projeyi aynı dosyada saklaman içindi.

Şöyle tanımlayım. Senin birinci proje A olsun. Packer programın da B. Hedef dosya ise C olsun.

B(A).EXE şekilde bir programın olacak. Burada (A) resource olarak içine gömülü.

Senin bu B(A).EXE çalışıp da C'yi gösterdiğinde ürün olarak A(C).EXE olacak. Burada ise (C) resource olarak değil EXE'nin sonuna doğrudan ulancak.

Bilmem daha açık oldu mu ? A(C).EXE'nin son 4 byte'ı olarak da C'nin FileSize'ı direkt ulanacak.
Resim
Resim ....Resim
cLaW
Üye
Mesajlar: 46
Kayıt: 06 Eki 2008 02:16

Re: Packerların mantığı nedir ? hangi yöntemler kullanılır ?

Mesaj gönderen cLaW »

Kod: Tümünü seç

program Project1;

//{$APPTYPE CONSOLE}

uses
  SysUtils, Classes, Dialogs;

var
  F:TFileStream;
  ExeName : String;
  Buffer : String;
  bufferbyte : TFileStream;
  bufferbb : AnsiString;
  SDosyaBoyut : Integer;
begin
  ExeName:=ParamStr(0);
  F:=TFileStream.Create(ExeName,fmOpenRead or fmShareDenyNone);
  F.Position:=F.Size-4;
  SetLength(Buffer,4);
  F.ReadBuffer(Pointer(Buffer)^,4);
  ShowMessage(Buffer);
  SDosyaBoyut:=StrToInt(Buffer);
  F.Position:=(F.Size-4)-SDosyaBoyut;
  bufferbyte:=TFileStream.Create(ExtractFilePath(ExeName)+'Çıkartılmış.exe',fmCreate or fmShareDenyNone);
  //bufferbyte.Size:=SDosyaBoyut;
  bufferbyte.Position:=0;
  SetLength(bufferbb,SDosyaBoyut);
  F.ReadBuffer(bufferbb,SDosyaBoyut);
  bufferbyte.WriteBuffer(bufferbb[1],Length(bufferbb));
  //ShowMessage((bufferbyte));
  bufferbyte.Free;
  F.Free;
end.
hocam buraya kadar geldim yani son 4 byte dan dosya boyutunu alıp okadar geri gidip sona doğru okuma yapmaya kadar geldim fakat okunacak veriyi hangi tip değişkene okutacağım onu bilemedim. ve sürekli hatalar aldım. ansistring ve string denedim. acaba kodları düzeltebilirmisiniz :oops:

Edit : hocam son yazınızı yein gördüm evet anladım dosyanın boyutunu son4 baytından okuyup geri gidip çıkartıcak exe packerın içnide olarak ve packerdan sıkıştırılacak exe gösterildiğinde packerin içindeki exenin içinde sıkıştırılması isteinlen dosyayı yazıcaz ve son 4 baytına ise dosyanın boyutunu yazıcaz. Ama bu takıldığım problemde beni aydınlatırsanız çok sevineceğim. yeterli ingilizcem olmadığı için yabancı kaynaklardan faydalanamıyorum sizlere teşekkür ederim.
Kullanıcı avatarı
mrmarman
Üye
Mesajlar: 4741
Kayıt: 09 Ara 2003 08:13
Konum: İstanbul
İletişim:

Re: Packerların mantığı nedir ? hangi yöntemler kullanılır ?

Mesaj gönderen mrmarman »

dWord tipinde olsun.

Kod: Tümünü seç

Var
  Boyut : dWord;
begin
..
..
  F.Seek( F.Size-4, soFromBeginning);
  F.Read( Boyut, SizeOf(Boyut) );
işini görecektir.
En son mrmarman tarafından 20 Eyl 2009 03:46 tarihinde düzenlendi, toplamda 2 kere düzenlendi.
Resim
Resim ....Resim
cLaW
Üye
Mesajlar: 46
Kayıt: 06 Eki 2008 02:16

Re: Packerların mantığı nedir ? hangi yöntemler kullanılır ?

Mesaj gönderen cLaW »

Acele edip anlaşılmayan bi şekilde anlatmışım kusura bakmayın. :P

Demek istediğim aslında şu şuan A Projesini yapıyorum.

Kod: Tümünü seç

var
  F:TFileStream;
  ExeName : String;
  Buffer : String;
  bufferbyte : TFileStream;
  bufferbb : AnsiString;
  SDosyaBoyut : Integer;
begin
  ExeName:=ParamStr(0);
  F:=TFileStream.Create(ExeName,fmOpenRead or fmShareDenyNone);
  F.Position:=F.Size-4;  // Burada Sondan 4 Byte geri gidiyorum
  SetLength(Buffer,4);
  F.ReadBuffer(Pointer(Buffer)^,Sizeof(Buffer)); // Burada ise bulunduğum pozisyondan 4 byte sonrasını okutuyorum. Ve Şuan Dosynaın boyutunu almış oldum.
  SDosyaBoyut:=StrToInt(Buffer); // Burda integer dönüştürüyorum boyutunu.
  ShowMessage(IntToStr(SDosyaBoyut));
  //SDosyaBoyut:=StrToInt(Buffer);
  F.Position:=(F.Size-4)-SDosyaBoyut; // Burada ise Son 4 byte-Dosyanınboyutu kadar geri gidiyrum yani Dosyanın başladığı pozisyona gidiyorum
  bufferbyte:=TFileStream.Create(ExtractFilePath(ExeName)+'Çıkartılmış.exe',fmCreate or fmShareDenyNone); // Burada exenin yanıdna çıkartılmış.exe oluşturdum ve okuduğum byteları bu exeye yazacağım.
  //bufferbyte.Size:=SDosyaBoyut;
  bufferbyte.Position:=0;
  SetLength(bufferbb,SDosyaBoyut); // Burda bufferbb ansistring değişkenine okutacağım için setlength yapıyorum
  F.ReadBuffer(bufferbb,SDosyaBoyut); //Ve burda okutmak istiyorum. Fakar bu kod işlendiğinde Gönderme hatası alıyorum. sanırım Ansistring tipine okutmayacağım. Burda okunan şey A.exe nin içindeki sıkıştırılmış dosya.
  bufferbyte.WriteBuffer(bufferbb[1],Length(bufferbb)); // Burada çıkartılmış.exe ye yazmak istiyorum fakat daha test edemedim önceki satırdaki hata yüzünden :)
  //ShowMessage((bufferbyte));
  bufferbyte.Free;
  F.Free;
end.
Tam olarak demek istediğmi kodların yanına yazarak açıkladım. Ansistring yerine başka bir tipemi okutmalıyım en uygunu hangisi olur veya sizce hata neden kaynaklanıyordur ? Sizide yordum verdiğiniz bilgiler için hakikaten çok teşekkür ederim. Şu ufak tefek problemleride çözdükten sonra sizin sayenizde işi rayına oturtabileceğim inşallah
Kullanıcı avatarı
mrmarman
Üye
Mesajlar: 4741
Kayıt: 09 Ara 2003 08:13
Konum: İstanbul
İletişim:

Re: Packerların mantığı nedir ? hangi yöntemler kullanılır ?

Mesaj gönderen mrmarman »

Geç oldu, yatmadan önce programı senin için hazırladım. En azından asıl yapmak istediğin kısma atlayabilirsin. RESOURCE dosyasını RES klasöründe RES.RES olarak verdim. sen kendine göre düzenlersin. KaynakDosya.EXE ve proje dosyası KaynakDosya diye bir klasörde. Resource dosyası da RES diye bir klasördedir.

Kod: Tümünü seç

KaynakDosya RCDATA ..\KaynakDosya\KaynakDosya.EXE
http://www.armantr.com/web/download?file=EXEPacker

Console Application Tarafı : KaynakDosya.EXE Bu senin (A) olacak. Resource olarak B packer projesi içine gömülecek olan hani.. :idea: Kendi kendine çalışacak ve bünyesindeki sıkıştırılmış dosyayı açacak, çalıştıracak ve işi bitince silecek olan.

Kod: Tümünü seç

program KaynakDosya;

{$APPTYPE CONSOLE}

uses
  SysUtils,
  Classes,
  Windows,
  Forms,
  ZLib;

Procedure ZIP_Ac( Kaynak, Hedef :TFileName);
Var
  CompFileStream      : TStream; // Classes
  FileStream          : TStream;
  DecompressionStream : TDecompressionStream;
  Buffer              : Array[0..4095] of Char;
  BufLen              : Integer;
begin
  CompFileStream      := TFileStream.Create(Kaynak, fmOpenRead OR fmShareDenyWrite);
  FileStream          := TFileStream.Create(Hedef, fmCreate);
  DecompressionStream := TDecompressionStream.Create(CompFileStream);
  BufLen              := DecompressionStream.Read(Buffer,SizeOf(Buffer));
  while BufLen > 0 do
  begin
    FileStream.Write(Buffer, BufLen);
    BufLen := DecompressionStream.Read(Buffer,SizeOf(Buffer));
  end;
  DecompressionStream.Free;
  FileStream.Free;
  CompFileStream.Free;
end;

// Uses ZLib eklenecek...
Var
  Kaynak, Hedef : TFileName;
  FS_Kaynak, FS_Hedef : TFileStream;
  Boyut : dWord; // Windows
begin
  try
    { TODO -oUser -cConsole Main : Insert code here }
    Kaynak := Application.ExeName; //Forms
    Hedef  := ChangeFileExt(Application.ExeName, '_(2).EXE');
    FS_Kaynak := TFileStream.Create( Kaynak, fmOpenRead OR fmShareDenyNone );
    FS_Hedef  := TFileStream.Create( Hedef, fmCreate );
    FS_Kaynak.Seek( FS_Kaynak.Size-4, soFromBeginning);
    FS_Kaynak.Read(Boyut, SizeOf(Boyut));
    FS_Kaynak.Seek( FS_Kaynak.Size-4-Boyut, soFromBeginning);
    FS_Hedef.CopyFrom( FS_Kaynak, Boyut);
    FS_Kaynak.Free;
    FS_Hedef.Free;
    ZIP_Ac(Hedef, ChangeFileExt(Application.ExeName,'_(3).EXE'));
    // Burada üretilen son dosya çalıştırılır vs. sonra da işi bitince silinir...
  except
    on E:Exception do
      Writeln(E.Classname, ': ', E.Message);
  end;
end.
EXEPacker Projesi

Kod: Tümünü seç

{$R RES\RES.RES}

// Uses ZLib eklenecek...

Procedure ZIP_Yap( Kaynak, Hedef :TFileName);
Var
  FileName            : String;
  CompFileStream      : TStream;
  CompressionStream   : TCompressionStream;
  FileStream          : TStream;
begin
  FileName            := Application.Exename;
  FileStream          := TFileStream.Create(Kaynak, fmOpenRead OR fmShareDenyWrite);
  CompFileStream      := TFileStream.Create(Hedef, fmCreate);
  CompressionStream   := TCompressionStream.Create(clDefault,CompFileStream);
  CompressionStream.CopyFrom(FileStream,0);
  CompressionStream.Free;
  CompFileStream.Free;
  FileStream.Free;
end;

procedure TForm1.BitBtn2Click(Sender: TObject);
Var
  RS : TResourceStream;
  Kaynak, Hedef : TFileName;
  FS_Kaynak, FS_Hedef : TFileStream;
  Boyut : dWord;
begin
  With TOpenDialog.Create(Nil) do begin
    if Execute then begin
      Kaynak := FileName;
    end else begin
      Free;
      Exit;
    end;
    Free;
  end;
  Hedef  := ExtractFilePath(Kaynak) + 'Hedef.EXE';
  ZIP_Yap(Kaynak, ChangeFileExt(Hedef,'.ZIP'));
  RS := TResourceStream.Create(HInstance, 'KaynakDosya', RT_RCDATA);
  FS_Kaynak := TFileStream.Create( ChangeFileExt(Hedef,'.ZIP'), fmOpenRead OR fmShareDenyNone );
  FS_Hedef  := TFileStream.Create( Hedef, fmCreate );
  RS.Seek( 0, soFromBeginning);
  FS_Hedef.CopyFrom( RS, RS.Size );
  FS_Kaynak.Seek( 0, soFromBeginning);
  FS_Hedef.CopyFrom( FS_Kaynak, FS_Kaynak.Size );
  Boyut := FS_Kaynak.Size;
  FS_Hedef.Write( Boyut, SizeOf(Boyut) );
  FS_Kaynak.Free;
  FS_Hedef.Free;
end;
Başarılar...
Resim
Resim ....Resim
cLaW
Üye
Mesajlar: 46
Kayıt: 06 Eki 2008 02:16

Re: Packerların mantığı nedir ? hangi yöntemler kullanılır ?

Mesaj gönderen cLaW »

Hocam Allah Razı olsun bugün başladım incelemeye memory üzerinden çalıştırma yapabilirmiyiz onuda araştırıp. deniyeceğim. Bu arada tüm forumun bayramı mubarek olsun.
Cevapla