Speicherzugriffe & Zeigerspielchen...

Schnelle objektorientierte, kompilierende Programmiersprache.
Benutzeravatar
Dirty Oerti
Beiträge: 2229
Registriert: Di Jul 08, 2008 5:05 pm
Wohnort: Thurndorf / Würzburg

Speicherzugriffe & Zeigerspielchen...

Beitrag von Dirty Oerti » Mi Jul 23, 2008 8:25 pm

Tag! :)

Aaalso:
Folgendes:

Ich hab ein gewisses Objekt. Diese Objekt möchte ich an einer bestimmten Stelle im Speicher erstellen (sagen wir an Position 0x10). Bzw: Ich möchte ein ganzes Array dieser Objekte an der Stelle im Speicher haben.

Code: Alles auswählen

struct mein_objekt
{
   int dummy;
   unsigned long einzweiterdummer;
}

//....

unsigned long *hier_her_soll_das_objekt = 0x10;
Jetzt möchte ich zum Beispiel folgendes:

Code: Alles auswählen

//...

hier_her_soll_das_objekt[5]->dummy = 10;

//...
Ich hoffe, es ist einigermaßen verständlich, was ich will.... :)

Wie mach ich das?

Hab schon einiges rumprobiert..aber so genau weiß ich nicht, wie ich das machen soll.

MfG
Daniel

P.S: Falls jemand mit "new" oder "malloc" kommt....das hab ich nicht zur Verfügung.
Bei Fragen einfach an daniel[ät]proggen[Punkt]org
Ich helfe gerne! :)
----------
Wenn du ein Licht am Ende des Tunnels siehst, freu dich nicht zu früh! Es könnte ein Zug sein, der auf dich zukommt!
----
It said: "Install Win95 or better ..." So I installed Linux.

Metamorph
Beiträge: 123
Registriert: Sa Jul 05, 2008 12:27 pm

Re: Speicherzugriffe & Zeigerspielchen...

Beitrag von Metamorph » Mi Jul 23, 2008 8:30 pm

Das, was du vorhast, ist sehr gefährlich.
Genau das soll man mit Zeigern nicht machen. So können Speicherplätze von wichtigen Routinen des Betriebssystems überschrieben werden, was zu einem Absturz führen kann.

segmentation fault (core dumped)^^

Benutzeravatar
Dirty Oerti
Beiträge: 2229
Registriert: Di Jul 08, 2008 5:05 pm
Wohnort: Thurndorf / Würzburg

Re: Speicherzugriffe & Zeigerspielchen...

Beitrag von Dirty Oerti » Mi Jul 23, 2008 8:31 pm

Metamorph hat geschrieben:Das, was du vorhast, ist sehr gefährlich.
Genau das soll man mit Zeigern nicht machen. So können Speicherplätze von wichtigen Routinen des Betriebssystems überschrieben werden, was zu einem Absturz führen kann.

segmentation fault (core dumped)^^
Wenn es das Betriebssystem selber aber macht?^^ Bzw machen muss?

Außerdem: Ein einigermaßen gut programmiertes System darf dabei nicht abschmieren.
(General Protection Fault....Und der wird dann abgefangen..)
Bei Fragen einfach an daniel[ät]proggen[Punkt]org
Ich helfe gerne! :)
----------
Wenn du ein Licht am Ende des Tunnels siehst, freu dich nicht zu früh! Es könnte ein Zug sein, der auf dich zukommt!
----
It said: "Install Win95 or better ..." So I installed Linux.

Benutzeravatar
fat-lobyte
Beiträge: 1398
Registriert: Sa Jul 05, 2008 12:23 pm
Wohnort: ::1
Kontaktdaten:

Re: Speicherzugriffe & Zeigerspielchen...

Beitrag von fat-lobyte » Mi Jul 23, 2008 8:46 pm

Das was du willst ist nicht möglich. Der ort, wo Objekte gespeichert sind ist theoretisch (also laut Standard) "Implementation Defined", und Praktisch wird es vom Betriebssystem vorgegeben.
Unter alten Linux kerneln startete der Stack bei einer bestimmten stelle, meistens bei 0xbf0000000. Neuere Kernel Starten den Stack bei einer Zufallsadresse. Dies ist eine Sicherheitsmaßnahme.

Lass dir nur sagen, dass das nicht möglich ist. Wieso willst du das eigentlic machen, wenn ich Fragen darf?
Dirty Oerti hat geschrieben:
Metamorph hat geschrieben:Das, was du vorhast, ist sehr gefährlich.
Genau das soll man mit Zeigern nicht machen. So können Speicherplätze von wichtigen Routinen des Betriebssystems überschrieben werden, was zu einem Absturz führen kann.

segmentation fault (core dumped)^^
Wenn es das Betriebssystem selber aber macht?^^ Bzw machen muss?

Außerdem: Ein einigermaßen gut programmiertes System darf dabei nicht abschmieren.
(General Protection Fault....Und der wird dann abgefangen..)
Wenn das System abschmiert hast du noch Glück gehabt. Das kommt aber nur zustande, wenn Funktionszeiger falsch überschrieben werden, oder wenn du dann auf eine ungültige Adresse zugreifst. Wenn allerdings alles zwar "Falsch", aber dennoch im erlaubten bereich ist, dann kannst du diesen Bug ausnutzen, um mit Benutzereingaben den Programmfluss zu übernehmen. Das nennt sich "Buffer Overflow". Hier gibts nen Link, der zugegebenermaßen schon etwas veraltet ist (1996), allerdings immer noch die Grundlagen vermittelt: http://www.phrack.org/issues.html?issue ... 14#article
Haters gonna hate, potatoes gonna potate.

Benutzeravatar
Dirty Oerti
Beiträge: 2229
Registriert: Di Jul 08, 2008 5:05 pm
Wohnort: Thurndorf / Würzburg

Re: Speicherzugriffe & Zeigerspielchen...

Beitrag von Dirty Oerti » Mi Jul 23, 2008 9:10 pm

fat-lobyte hat geschrieben:Das was du willst ist nicht möglich
hm...doch, glaub ich schon.
Vergiss das Betriebssystem. Und alle Beschränkungen die es auferlegt.

Was ich theoretisch nur brauche:

Wie wird ein Objekt im Speicher gespeichert?
In welcher Form?
Damit ich drauf zugreifen kann (per Zeiger)?

Stells dir vor wie in C++ mit new.
new gibt eigntl nur ne Adresse zurück.
Hinter der sich ein freier Bereich verbirgt.

Das gleiche möchte ich auch tun.
Nur möchte ich nicht wie new nach freien Bereichen suchen und dann die Adresse zurückgeben. Das KANN ich nicht.
Ich weiß, wo freier Speicher ist. Ich weiß die Adresse.
Wie das mit einem einzelnen Element gehen müsste, weiß ich:

Code: Alles auswählen

mein_objekt *objekt = 0x10;
objekt->dummy = 10;
Oder geht das so nicht?
Wieso willst du das eigentlic machen, wenn ich Fragen darf?
Betriebssystemprorammierung.
Ich muss ein Array von Objekten an einer bestimmten Stelle ablegen, damit der Prozessor das lesen kann.
Genau genommen ist das die GDT.
Bzw die IDT.
Bei Fragen einfach an daniel[ät]proggen[Punkt]org
Ich helfe gerne! :)
----------
Wenn du ein Licht am Ende des Tunnels siehst, freu dich nicht zu früh! Es könnte ein Zug sein, der auf dich zukommt!
----
It said: "Install Win95 or better ..." So I installed Linux.

Benutzeravatar
fat-lobyte
Beiträge: 1398
Registriert: Sa Jul 05, 2008 12:23 pm
Wohnort: ::1
Kontaktdaten:

Re: Speicherzugriffe & Zeigerspielchen...

Beitrag von fat-lobyte » Mi Jul 23, 2008 9:25 pm

Dirty Oerti hat geschrieben:Wie wird ein Objekt im Speicher gespeichert?
In welcher Form?
Damit ich drauf zugreifen kann (per Zeiger)?
Das kommt darauf an, welchen Typ das Objekt hat. Ein Integer wird z.B. als 4 bytes gespeichert, das niedrigstwertigste zuerst (auf x86). Structs werden je nach Alignment gespeichert, das heißt
struct {
int a;
char b;
};

Wird entweder als ein 4 bytes gefolgt von einem Gespeichert, (kein Alignment), oder als 4 bytes gefolgt von einem byte, gefolgt von 3 bytes(die nicht verwendet werden) (4 byte alignment), oder manchmal sogar als 4 bytes, nochmal 4 (nicht verwendet), einem byte, und nochmals 7 byte (nicht verwendet) (8 byte alignment)
Wie die Objekte gespeichert werden, hängt vom Typ, vom Betriebssystem, vom Compiler, von den Einstellungen, von der Bibliothek, von der CPU Architektur, vom Wetter und davon, ob heute ein gerader Wochentag ist oder nicht ab.
Der ganze "Sinn" von C ist, dass du dich nicht um solche dinge "kümmern" solltest, das bedeutet dass diese dinge für dich übernommen werden. Man darf sich in C auf manche Dinge verlassen (diese stehen im Standard), manche sind aber nicht definiert.
Dirty Oerti hat geschrieben:Stells dir vor wie in C++ mit new.
new gibt eigntl nur ne Adresse zurück.
Hinter der sich ein freier Bereich verbirgt.

Das gleiche möchte ich auch tun.
Nur möchte ich nicht wie new nach freien Bereichen suchen und dann die Adresse zurückgeben. Das KANN ich nicht.
Ich weiß, wo freier Speicher ist. Ich weiß die Adresse.
Wenn du sie Weißt, wo ist dann das Problem?
Dirty Oerti hat geschrieben:Wie das mit einem einzelnen Element gehen müsste, weiß ich:

Code: Alles auswählen

mein_objekt *objekt = 0x10;
objekt->dummy = 10;
Oder geht das so nicht?
Doch eigentlich schon.
Haters gonna hate, potatoes gonna potate.

Benutzeravatar
Dirty Oerti
Beiträge: 2229
Registriert: Di Jul 08, 2008 5:05 pm
Wohnort: Thurndorf / Würzburg

Re: Speicherzugriffe & Zeigerspielchen...

Beitrag von Dirty Oerti » Mi Jul 23, 2008 9:36 pm

Hm..also soweit ich weiß wird das ohne Alignment gespeichert.
Nehme ich jetzt einfach mal an.
Denn:
Ich weiß die genauen Bytepositionen/Längen der einzelnen Werte in der struct.
Und da ist nichts unbenutzt.
Der ganze "Sinn" von C ist, dass du dich nicht um solche dinge "kümmern" solltest, das bedeutet dass diese dinge für dich übernommen werden
Ja, übernommen vom Betriebssystem.
Und von der MMU.
Wenn aber beides nicht genutzt werden kann, weil nicht vorhanden bzw nicht initialisiert, dann braucht man Ersatzlösungen.

Ich werd jetzt mal versuchen, das Ganze wie oben kurz geschrieben zu lösen...
Wünscht mir Glück^^

*edit*
Das hier ist der Täter:

Code: Alles auswählen

struct gdt_entry
{
	unsigned short limit_low;
	unsigned short base_low;
	unsigned char base_middle;
	unsigned char access;
	unsigned char granularity;
	unsigned char base_high;
} __attribute__((packed));
Das Attribut sorgt glaub ich dafür, das kein Alignment stattfindet.

*/edit*
Bei Fragen einfach an daniel[ät]proggen[Punkt]org
Ich helfe gerne! :)
----------
Wenn du ein Licht am Ende des Tunnels siehst, freu dich nicht zu früh! Es könnte ein Zug sein, der auf dich zukommt!
----
It said: "Install Win95 or better ..." So I installed Linux.

Benutzeravatar
Xin
nur zu Besuch hier
Beiträge: 8859
Registriert: Fr Jul 04, 2008 11:10 pm
Wohnort: /home/xin
Kontaktdaten:

Re: Speicherzugriffe & Zeigerspielchen...

Beitrag von Xin » Mi Jul 23, 2008 10:25 pm

Dirty Oerti hat geschrieben: Ich hoffe, es ist einigermaßen verständlich, was ich will.... :)

Wie mach ich das?

Hab schon einiges rumprobiert..aber so genau weiß ich nicht, wie ich das machen soll.

P.S: Falls jemand mit "new" oder "malloc" kommt....das hab ich nicht zur Verfügung.
Hier die Lösung: Implementiere malloc() und free().

Aktuell hast Du weder Paging noch Speicherschutz, also ist Deine Implementation eigentlich recht einfach. Finde heraus, welche Speicherbereiche Du hast. Anschließend schreibst Du da einfach rein und zwar eine Struktur wie diese:

Code: Alles auswählen

struct MemoryBlock
{
  struct MemoryBlock * Next;
  long Size;
};
Angenommen, Dein Computer meldet Dir zwei Speicherbänke, die nicht zusammenhängen. Dann hast Du am Anfang jeden Speicherblocks eine FreeMomoryBlock-Struktur, die Dir sagt, wieviel Platz noch über ist. Das ganze verwaltest Du in einer Liste.
Nun implementierst Du malloc(), malloc sucht jetzt die Liste einen Speicherblock, der noch genug Speicher hat, dass der gewünschte Speicher und eine MemoryBlock-Struktur da rein passen. Ist der MemoryBlock gefunden, verkleinerst Du ihn um den gewünschten Speicher zuzüglich der MemoryBlock Strukturund packst am Ende in den Bereich, denn Du abgetrennt hast eine neue MemoryBlock Struktur, die die gewünschte Größe enthält. Diesen MemoryBlock setzt Du in die Liste der Speicherblöcke, die vergeben sind und erst durch free() wieder zu freien MemoryBlocks werden können.

Hervorragend geeignet, um Speicher zu fragmentieren, aber schnell implementiert.
Merke: Wer Ordnung hellt ist nicht zwangsläufig eine Leuchte.

Ich beantworte keine generellen Programmierfragen per PN oder Mail. Dafür ist das Forum da.

Benutzeravatar
Dirty Oerti
Beiträge: 2229
Registriert: Di Jul 08, 2008 5:05 pm
Wohnort: Thurndorf / Würzburg

Re: Speicherzugriffe & Zeigerspielchen...

Beitrag von Dirty Oerti » Mi Jul 23, 2008 10:43 pm

Ja..von solcher Art malloc()-Implementierungen hab ich schon viel gelesen/gesehen.
Aber was mich daran (für das spezielle Problem) stört:
Ich kann mein Array immernoch nicht dahin legen, wo ichs hinhaben will.
Außerdem...Speicherfragmentierung.

Gedacht hatte ich mir die Speicheraufteilung folgendermaßen:

Physikalischer Speicher:

>1MB = Kernel, Treiber, Programme
640KB< && <1MB = reserviert für BIOS/Grafikausgabe etc
<640KB = GDT und IDT, evtl ein Feld für DMA (später mal)

Das der Speicher unter 640KB frei ist weiß ich. und wieviel ich davon verwenden darf sagt mir GRUB.
Darein will ich nun die GDT und die IDT pflanzen.
Und natürlich so, dass ich sie im Nachhinein noch verändern kann.
(Derzeit ist es so implementiert, das jedesmal die ganze GDT neugeladen werden muss und ich doppelt so viel Speicher für die GDT brauch)
Das gleiche soll natürlich für die IDT gelten.

Wie ich das jetzt hinbekomme...ich glaub da fällt mir schon was ein (bzw ist eingefallen).

Was ich dich, Xin, aber mal frage (ich weiß nicht, wie weit du dich da auskennst etc):

Wie macht man das mit der Speicherverwaltung?
Wie würdest du das anstellen?
Ich dachte (wie schon geschrieben) an eine Art Bitmap für einen unteren Teil (z.b. 1MB bis 12 MB oder so) und an eine Art Stack für den restlichen Speicher.
Nur wie ich das genau verwalten soll weiß ich nicht.
*Etwas ratlos*
Bei Fragen einfach an daniel[ät]proggen[Punkt]org
Ich helfe gerne! :)
----------
Wenn du ein Licht am Ende des Tunnels siehst, freu dich nicht zu früh! Es könnte ein Zug sein, der auf dich zukommt!
----
It said: "Install Win95 or better ..." So I installed Linux.

Benutzeravatar
Xin
nur zu Besuch hier
Beiträge: 8859
Registriert: Fr Jul 04, 2008 11:10 pm
Wohnort: /home/xin
Kontaktdaten:

Re: Speicherzugriffe & Zeigerspielchen...

Beitrag von Xin » Do Jul 24, 2008 12:18 am

Dirty Oerti hat geschrieben:Ja..von solcher Art malloc()-Implementierungen hab ich schon viel gelesen/gesehen.
Aber was mich daran (für das spezielle Problem) stört:
Ich kann mein Array immernoch nicht dahin legen, wo ichs hinhaben will.
Wo willst Du es denn haben?
Dirty Oerti hat geschrieben:Was ich dich, Xin, aber mal frage (ich weiß nicht, wie weit du dich da auskennst etc):

Wie macht man das mit der Speicherverwaltung?
Müsste ich mich auch erst wieder einlesen.
Tanenbaum und Silberschatz rufen.
Dirty Oerti hat geschrieben:Wie würdest du das anstellen?
Lesen. Ansonsten HashTables mit Bäumen ähnlich großer freier Blöcke. Möglichkeiten, um freie Fragmente wieder zusammenzuführen.

Linux vergib afair 4kB Blöcke.
Dirty Oerti hat geschrieben:Ich dachte (wie schon geschrieben) an eine Art Bitmap für einen unteren Teil (z.b. 1MB bis 12 MB oder so) und an eine Art Stack für den restlichen Speicher.
Das wäre quasi eine FAT, die das Dateisystem.

Wie gesagt.. Silberschatz oder Tanenbaum lesen, ansonsten gibt es Anmerkungen zum Linux-Kernel.
Weiterhin Datenstrukturen pauken, um Alternativen, bzw. hochleistungsfähige Algorithmen umzusetzen.
Merke: Wer Ordnung hellt ist nicht zwangsläufig eine Leuchte.

Ich beantworte keine generellen Programmierfragen per PN oder Mail. Dafür ist das Forum da.

Antworten