Konuyu Paylaş : facebook gplus twitter

Konuyu Oyla:
  • Derecelendirme: 5/5 - 2 oy
  • 1
  • 2
  • 3
  • 4
  • 5
Bağlı Liste & Undocumented API Hakkında (+25 .. +100)
#1
Bu sorumuz bağlı liste(Linked List) ile alakalı ve 3 aşamalı bir soru. Her aşamasının belirli bir puanı olacak ve tüm aşamaların tamamlanması durumunda 100 puan elde edilecek.

Aşama 1: Bu aşamada sizden bir dairesel bağlı liste oluşturmanız , bu bağlı listeye 4 eleman eklemeniz ve içerisinde döngü ile dolaşmanız ve X/Y değerlerini ekrana bastırmanız arzulanıyor. Kullanmanız istenen record yapısı aşağıdaki gibi olacak. (+25 puan)

  
 PLinkedList = ^TLinkedList;
 TLinkedList = record
   Prev,
   Next  : PLinkedList;
 end;

 TData = record
   List  : TLinkedList;
   X     : Byte;
   Y     : Byte;
 end;


Aşama 2: Bu aşama birinci aşama ile aynı amacı taşıyor ama kullanacağınız record yapısı aşağıdaki gibi olacak. (+30 puan)
  
 PLinkedList = ^TLinkedList;
 TLinkedList = record
   Prev,
   Next  : PLinkedList;
 end;

 TData = record
   X     : Byte;
   Y     : Byte;
   List  : TLinkedList;
 end;

Aşama 3: Linkleri Görebilmeniz İçin Giriş yap veya Üye Ol yapısı ve Linkleri Görebilmeniz İçin Giriş yap veya Üye Ol macrosunu inceleyerek, Aşama 1 ve 2'de kullandığımız kendimize ait yapıyı kullanarak ,işletim sisteminin kernel'ı kodlanır iken sıklıkla kullanılan bu yapılardan istifade ile bir dökümante edilmemiş (undocumented) API kullanın ve bu API'nin döndürdüğü Linkleri Görebilmeniz İçin Giriş yap veya Üye Ol yapısı içinde ileri geri hareket edin ve liste yapısının ana kapsayıcısı olan record'un içindeki bir kısım elemanları ekrana yazdırın. (+45 puan)

Elde edilmesi beklenen faydalar:
  • Bağlantılı liste oluşturma, yönetme, pointerların kullanımı.
  • Hafıza maniplasyonları, offset adresleri hakkında bilgi edinme.
  • Dökümante edilmemiş API'ler ile tanışma.
Bu nispeten zor soruya ilgi göstereceğinizi umuyorum. İyi eğlenceler Wink
Mal sahibi, mülk sahibi
Hani bunun ilk sahibi ?
Mal da yalan mülk de yalan
Var biraz da sen oyalan...
WWW
Cevapla
#2
1. Aşama
program Project19;

{$APPTYPE CONSOLE}

{$R *.res}

uses
  System.SysUtils;
    Type
   PLinkedList = ^TLinkedList;
 TLinkedList = record
   Prev,
   Next  : PLinkedList;
 end;
  PData= ^TData;
 TData = record
   List  : TLinkedList;
   X     : Byte;
   Y     : Byte;
 end;


 procedure    ekle ( x,y : integer; ilk: PData ) ;
 var
 D : PData;
 PTemp : PLinkedList;
 begin
  D:=new(PData);
  D.X:=x;
  D.Y:=y;

  PTemp:= @ilk.List;
  while (PTemp.Next<>nil)  do
  begin
  PTemp:=PTemp.Next;
  if(PTemp.Next=@ilk.List) then break;
  end;
  D.List.Prev:= PTemp;
  PTemp.Next:=@D.List;
  D.List.Next:=@ilk.List;
  ilk.List.Prev:=PTemp.Next;
 end;

 procedure yazdir ( ilk: PData ) ;
 var
 Temp : PData;
 PTemp : PLinkedList;
 begin
 PTemp:=PLinkedList(Pointer(Nativeint(ilk)));//ileri sar
 while true do
 begin
  Temp:=PData(Pointer(Nativeint(PTemp)));
  if(Temp<>nil)  then writeln('X:'+IntToStr( Temp.x)+',Y:'+ IntToStr( Temp.y));
  PTemp:=PTemp.Next;
  if (PTemp=@ilk.List)then break;
 end;
   PTemp:=PTemp.prev;
  while true do      //geri sar
   begin
  Temp:=PData(Pointer(Nativeint(PTemp)));
  if(Temp<>nil)  then writeln('X:'+IntToStr( Temp.x)+',Y:'+ IntToStr( Temp.y));
  PTemp:=PTemp.prev;
   if (PTemp=ilk.List.prev)then break;
 end;

 end;

var
ilk : TData;
i : integer;
begin
 ilk.X:=0;
 ilk.Y:=0;
 for I := 0 to 2 do
 begin
   ekle (i,i+1,@ilk);
 end;

yazdir(@ilk);


readln;


end.


2.Aşama
program Project19;

{$APPTYPE CONSOLE}

{$R *.res}

uses
 System.SysUtils;
   Type
   {
  PLinkedList = ^TLinkedList;
TLinkedList = record
  Prev,
  Next  : PLinkedList;
end;
 PData= ^TData;
TData = record
  List  : TLinkedList;
  X     : Byte;
  Y     : Byte; }
  PLinkedList = ^TLinkedList;
TLinkedList = record
  Prev,
  Next  : PLinkedList;
end;
  PData= ^TData;
TData = record
  X     : Byte;
  Y     : Byte;
  List  : TLinkedList;

end;


procedure    ekle (x,y : Byte;ilk : PData);
var
D : PData;
PTemp : PLinkedList;
begin
 D:=new(PData);
 D.X:=x;
 D.Y:=y;

 PTemp:= @ilk.List;
 while (PTemp.Next<>nil)  do
 begin
 PTemp:=PTemp.Next;
 if(PTemp.Next=@ilk.List) then break;
 end;
 D.List.Prev:= PTemp;
 PTemp.Next:=@D.List;
 D.List.Next:=@ilk.List;
 ilk.List.Prev:=PTemp.Next;
end;

procedure yazdir(ilk : PData);
var
Temp : PData;
PTemp : PLinkedList;
begin
PTemp:=PLinkedList(Pointer(Nativeint(ilk)+4));   //normalde buranın değeri 2 yani sizeof(byte)*2 olması lazım ama
while true do             //ileri sar            //4 ve katlarına hizalama yapıldığı için 4 byte atlamak gerekiyor
begin
 Temp:=PData(Pointer(Nativeint(PTemp)-4));
 if(Temp<>nil)  then writeln('X:'+IntToStr( Temp.x)+',Y:'+ IntToStr( Temp.y));
 PTemp:=PTemp.Next;
 if (PTemp=@ilk.List)then break;
end;
  PTemp:=PTemp.prev;
 while true do      //geri sar
  begin
 Temp:=PData(Pointer(Nativeint(PTemp)-4));
 if(Temp<>nil)  then writeln('X:'+IntToStr( Temp.x)+',Y:'+ IntToStr( Temp.y));
 PTemp:=PTemp.prev;
  if (PTemp=ilk.List.prev)then break;
end;

end;

var
ilk:TData;
i:byte;
begin
ilk.X:=0;
ilk.Y:=0;
for I := 0 to 2 do
begin
  ekle (i,i+1,@ilk);
end;

yazdir(@ilk);


readln;


end.

Not:Ölçüler 32 bit Windows'a göre
3.Aşama yarın inşallah..
Bizi Toprağa Gömdüler Fakat Tohum Olduğumuzu Bilmiyorlardı.
Cevapla
#3
Sabit ofset adresi yerine, record'un içindeki offset'i hesaplayan bir formül daha yararlı olabilirdi. Örneğin:

  Offset := Integer(@(PData(nil)^.X));
  Offset := Integer(@(PData(nil)^.Y));
  Offset := Integer(@(PData(nil)^.List));

gibi Wink

Not: Ofset değerleri hesapladığımız için herhangi bir record instance'ına ihtiyacımız olmuyor.
Mal sahibi, mülk sahibi
Hani bunun ilk sahibi ?
Mal da yalan mülk de yalan
Var biraz da sen oyalan...
WWW
Cevapla
#4
3.Aşama

program Project19;

{$APPTYPE CONSOLE}

{$R *.res}

uses
Winapi.Windows,System.SysUtils;
   Type
  PLinkedList = ^TLinkedList;
TLinkedList = record
  Prev,
  Next  : PLinkedList;
end;
  PData= ^TData;
TData = record
  X     : Byte;
  Y     : Byte;
  List  : LIST_ENTRY;

end;



function CONTAINING_RECORD(  adres,alankonum,listrecordkonum : Pointer) : Pointer;
begin
 Result :=Pointer(Integer(adres) - (integer(listrecordkonum)-integer(alankonum)));
 //kendimce  delphi'ye çevirdim,birinci parametrede ListEntry'nin adresi geliyor
 //ikinci parametre recordun ilk parametresinin konumu yani 0 noktası
 //3. paramtre ListEntry'nin konumu yani  recordun kaç byte ötesinde olduğu
 //sonuç olarak ListEntry'nin recordun kaç byte ilerisinde olduğunu bulunca
 //çıkartma yaparak 0 noktasının bulunmasıyla recordun adresi bulunur

end;

procedure InsertHeadList(baslik,giris : PListEntry);
 var
 Flink : PListEntry;
 begin
 Flink := baslik.Flink;
giris.Flink := Flink;
giris.Blink := baslik;
Flink.Blink := giris;
baslik.Flink := giris;
 end;





procedure InitializeListHead(  baslik : PListEntry) ;
begin
baslik.Flink := baslik;
 baslik.Blink := baslik;
end;


var
listebaslik,temp : PListEntry ;
data : PData;
i : integer;
begin
  listebaslik:=new(PListEntry);
InitializeListHead(listebaslik);



  for I := 0 to 3 do
    begin
    data:=new(PData);
    data.X:=i;
    data.Y:=i;
    InsertHeadList(listebaslik,@(data.List));
    end;

temp:=listebaslik;
while(listebaslik<>temp.Flink) do
begin
  temp:=temp.Flink;
   data:=CONTAINING_RECORD(temp,@PData(nil)^.X,@PData(nil).List);
      writeln('X:'+IntToStr( data.x)+',Y:'+ IntToStr( data.y));
end;


readln;
end.
Ben İkinci recordu yaptım birincisi daha kolay     CONTAINING_RECORD(temp,0,0)  yada      CONTAINING_RECORD(temp,@PData(nil).List,@PData(nil).List);
şeklinde çağırarak dolaşabiliriz.Saygılarımla...
Bizi Toprağa Gömdüler Fakat Tohum Olduğumuzu Bilmiyorlardı.
Cevapla
#5
(03-10-2017, Saat: 20:44)savasabd Adlı Kullanıcıdan Alıntı: Linkleri Görebilmeniz İçin Giriş yap veya Üye Ol3.Aşama

program Project19;

{$APPTYPE CONSOLE}

{$R *.res}

uses
Winapi.Windows,System.SysUtils;
   Type
  PLinkedList = ^TLinkedList;
TLinkedList = record
  Prev,
  Next  : PLinkedList;
end;
  PData= ^TData;
TData = record
  X     : Byte;
  Y     : Byte;
  List  : LIST_ENTRY;

end;



function CONTAINING_RECORD(  adres,alankonum,listrecordkonum : Pointer) : Pointer;
begin
 Result :=Pointer(Integer(adres) - (integer(listrecordkonum)-integer(alankonum)));
 //kendimce  delphi'ye çevirdim,birinci parametrede ListEntry'nin adresi geliyor
 //ikinci parametre recordun ilk parametresinin konumu yani 0 noktası
 //3. paramtre ListEntry'nin konumu yani  recordun kaç byte ötesinde olduğu
 //sonuç olarak ListEntry'nin recordun kaç byte ilerisinde olduğunu bulunca
 //çıkartma yaparak 0 noktasının bulunmasıyla recordun adresi bulunur

end;

procedure InsertHeadList(baslik,giris : PListEntry);
 var
 Flink : PListEntry;
 begin
 Flink := baslik.Flink;
giris.Flink := Flink;
giris.Blink := baslik;
Flink.Blink := giris;
baslik.Flink := giris;
 end;





procedure InitializeListHead(  baslik : PListEntry) ;
begin
baslik.Flink := baslik;
 baslik.Blink := baslik;
end;


var
listebaslik,temp : PListEntry ;
data : PData;
i : integer;
begin
  listebaslik:=new(PListEntry);
InitializeListHead(listebaslik);



  for I := 0 to 3 do
    begin
    data:=new(PData);
    data.X:=i;
    data.Y:=i;
    InsertHeadList(listebaslik,@(data.List));
    end;

temp:=listebaslik;
while(listebaslik<>temp.Flink) do
begin
  temp:=temp.Flink;
   data:=CONTAINING_RECORD(temp,@PData(nil)^.X,@PData(nil).List);
      writeln('X:'+IntToStr( data.x)+',Y:'+ IntToStr( data.y));
end;


readln;
end.
Ben İkinci recordu yaptım birincisi daha kolay     CONTAINING_RECORD(temp,0,0)  yada      CONTAINING_RECORD(temp,@PData(nil).List,@PData(nil).List);
şeklinde çağırarak dolaşabiliriz.Saygılarımla...

Teşekkür ederim, lâkin 3ncü aşamayı yanlış anlattım sanırım. Bu aşamada elde edilen bilgiler ışığında, dökümante edilmemiş API'lerden birisini kullanalım istemiştim. Dökümante edilmemiş API'lerin bir kısmında bu tarz liste sınıfları döndürenler var. Onlar konusunda araştırma yapmanız ve kullanımını öğrenmeniz amaçlanıyor bu aşamada Wink  (Bu API'ler genel itibarı ile Nt... ya Zw... harfleri ile başlıyor)
Mal sahibi, mülk sahibi
Hani bunun ilk sahibi ?
Mal da yalan mülk de yalan
Var biraz da sen oyalan...
WWW
Cevapla
#6
Estağfurullah,ben cümlenin başına göre yapmışım ,yanlış anlayan benim.Eksik kısmı akşama yazarım.
Bizi Toprağa Gömdüler Fakat Tohum Olduğumuzu Bilmiyorlardı.
Cevapla
#7
Aşama 1:
Dairesel Bağlı Liste, Doubly Circular Linked List diye ifade ediliyor. 
Listedeki her düğüm önceki ve sonraki düğümü gösterirken, ilk düğüm son düğümü, son düğüm de ilk düğümü gösterir.
  
type

 PLinkedList = ^TLinkedList;

 TLinkedList = record
   Prev, Next: PLinkedList;
 end;

 PData = ^TData;

 TData = record
   List: TLinkedList;
   X: Byte;
   Y: Byte;
 end;


procedure L(msg: string);
begin
  Form2.Memo1.Lines.Add(msg);
end;

procedure PrintNodes(Root: PData);
var
  Temp: PData;
  Last: PData;
begin
  Temp := Root;
  while Pointer(Temp.List.Next) <> Pointer(Root) do
  begin
    L(Format('X,Y : %d,%d', [Temp.X, Temp.Y]));
    Temp := Pointer(Temp.List.Next);
  end;
  L(Format('X,Y : %d,%d', [Temp.X, Temp.Y]));

  L('------------------');
  Last := Pointer(Root.List.Prev);
  Temp := Last;
  while Pointer(Temp.List.Prev) <> Last do
  begin
    L(Format('X,Y : %d,%d', [Temp.X, Temp.Y]));
    Temp := Pointer(Temp.List.Prev);
  end;
  L(Format('X,Y : %d,%d', [Temp.X, Temp.Y]));
end;

procedure InsertNode(var Root: PData; X, Y: Integer);
var
  NewData, Last: PData;
begin
  if Root = nil then
  begin
    Root := New(PData);
    Root.X := X;
    Root.Y := Y;
    Root.List.Prev := Pointer(Root);
    Root.List.Next := Pointer(Root);
    exit;
  end;

  Last := PData(Pointer(Root.List.Prev));

  NewData := New(PData);
  NewData.X := X;
  NewData.Y := Y;

  Last.List.Next := Pointer(NewData);

  NewData.List.Prev := Pointer(Last);
  NewData.List.Next := Pointer(Root);

  Root.List.Prev := Pointer(NewData);
end;

procedure TForm2.FormCreate(Sender: TObject);
var
  Root: PData;
begin
  Root := nil;
  InsertNode(Root, 31, 32);
  InsertNode(Root, 33, 34);
  InsertNode(Root, 35, 36);
  InsertNode(Root, 37, 38);
  PrintNodes(Root);
end;
My name is nobody.
WWW
Cevapla
#8
Uzun uğraşlar sonucunda Linkleri Görebilmeniz İçin Giriş yap veya Üye Ol  aldığım bilgilerle dökümante edilmemiş LDR_MODULE,PEB_LDR_DATA(bu dökümante  edilmiş ama eksik fieldler var) struct'ları ile  CONTAINING_RECORD macrosunu da  kullanarak  dll'leri listeleyen bir kod yazdım ama C'de bunu Delphi'ye çevirir çevirmez buraya yazacağım.Fakat recordlar(structler) kendi oluşturduğumuz(sizin yukarda oluşturduğunuz) değil anlaşılacağı gibi.Acaba  sizin oluşturduğunuz recordu apiye parametre olarak vermemiz mi gerekiyor,sizin istediğiniz bu mu yoksa windows 'ait bir yapıyı(struct,record) kullanıp bilgileri ekrana yazdırmak mı?
Bizi Toprağa Gömdüler Fakat Tohum Olduğumuzu Bilmiyorlardı.
Cevapla
#9
(04-10-2017, Saat: 23:56)savasabd Adlı Kullanıcıdan Alıntı: Linkleri Görebilmeniz İçin Giriş yap veya Üye OlUzun uğraşlar sonucunda Linkleri Görebilmeniz İçin Giriş yap veya Üye Ol  aldığım bilgilerle dökümante edilmemiş LDR_MODULE,PEB_LDR_DATA(bu dökümante  edilmiş ama eksik fieldler var) struct'ları ile  CONTAINING_RECORD macrosunu da  kullanarak  dll'leri listeleyen bir kod yazdım ama C'de bunu Delphi'ye çevirir çevirmez buraya yazacağım.Fakat recordlar(structler) kendi oluşturduğumuz(sizin yukarda oluşturduğunuz) değil anlaşılacağı gibi.Acaba  sizin oluşturduğunuz recordu apiye parametre olarak vermemiz mi gerekiyor,sizin istediğiniz bu mu yoksa windows 'ait bir yapıyı(struct,record) kullanıp bilgileri ekrana yazdırmak mı?
3. aşama sorusuna henüz bakmadım.
Mesela Linkleri Görebilmeniz İçin Giriş yap veya Üye Ol  içerisinde, LIST_ENTRY tipinde bir alan var.Bu gibi bir alana erişip okunması isteniyor.Bence.
My name is nobody.
WWW
Cevapla
#10
Evet, ismail bey'in de söylediği gibi; içerisinde LIST_ENTRY yapısını barındıran bir çok yapı var. Ve bu yapıları döndüren de bazı undocumented API'ler var. Maksadımız, bu undocumented API'lerden bir tanesini kullanarak, içeriğinde LIST_ENTRY bulunan bir yapı üzerinden liste üzerinde ilerlemek. Biraz daha ipucu, cevabı verecek korkarım  Smile
Mal sahibi, mülk sahibi
Hani bunun ilk sahibi ?
Mal da yalan mülk de yalan
Var biraz da sen oyalan...
WWW
Cevapla

Konuyu Paylaş : facebook gplus twitter



Konu ile Alakalı Benzer Konular
Konular Yazar Yorumlar Okunma Son Yorum
  Pointer Dereferencing Hakkında. ismailkocacan 7 618 24-09-2017, Saat: 15:10
Son Yorum: uparlayan
  RTTI PE Hakkında ismailkocacan 5 603 23-09-2017, Saat: 00:24
Son Yorum: ismailkocacan



Konuyu Okuyanlar: 1 Ziyaretçi