Zugriff auf Grafikspeicher



  • Hi!
    Erstmal möcht' ich mich entschuldigen, dass ich wohl wieder im falschen Forum frage (weil ich einfach kein passendes finden konnte), aber irgendein Admin/Mod der sich hier auskennt wird mir da bestimmt behilflich sein 🙂

    Vorweg:
    Ich kenne mich bisher nicht all zu gut mit C++ aus (d.h. bin ein Vollnoob), weshalb ich ersteinmal so Systemnahe wie möglich programmieren möchte, um wirklich alles von Grund auf zu verstehen. Natürlich wird das nicht in allen Einzelheiten funktionieren, aber ich möchte es wenigstens versuchen. Jetzt bin ich bei dem Punkt, dass ich den Arbeitsspeicher anderer Programme verändern kann und dadurch sogut wie alles bewirken (beispielsweise kann ich ein sich selber weiterprogrammierendes Programm machen xP).

    Das Problem ist folgendes:
    Jetzt möchte ich nachdem ich den Arbeitsspeicher durchgenommen habe mich an die Grafikkarte machen und schauen, ob ich es schaffe, auch hier einen Prozess (ist der Grafikkspeicher auch in Prozesse aufgeteilt?) zu editieren. Beispielsweise die Textur eines Programmes zu verändern, ist das einfach möglich? So wie "WriteProcessMemory();" dann analog "WriteGraphicsMemory();" oder so?
    Ich hab das ganze Netz durchgekämmt und noch nichts dazu gefunden. Es kommt immer "TexMod" (ein praktisches Programm, das dabei behilflich sein könnte, weil man die "checksum" bekommt (ich denke das ist eher soetwas wie die Speicheradresse des Bildes im Grafikspeicher, als soetwas wie ein md5-Schlüssel, weil die "checksum" sich pro Bild soviel erhöht, wie das Bild in Bytes groß sein müsste))

    Freue mich schon auf Antworten



  • Installier dir Dos und benutze VGA Grafikmodi, da kannst du recht einfach auf Grafikspeicher zugreifen. f'`8k

    Autocogito

    Gruß, TGGC (Was Gamestar sagt...)



  • Also hi TGGC,
    danke für deine Antwort aber mir ist noch nicht vollkommen klar, was du damit meinst.
    Also wenn ich mit Dos und dem VGA-Grafikmodus programmiere, wieviel Wissen kann ich dabei überhaupt erlangen? Der VGA-Grafikmodus ist doch (wenn ich Googles Ergebnisse nicht missverstanden habe) nur ein Vorläufer des heute gängigen Systems oder nicht? Und wieso überhaupt Dos? Geht das mit Win XP oder 7 nicht? (oder sonst auch mit Linux Ubuntu)?
    Ich hab' hier ein Tutorial gefunden http://www.brackeen.com/vga/, soetwas meinst du doch, oder?
    Ich möchte jetzt ja niemandem auf den Geist gehen, aber bevor ich das falsche Tutorial durchnehme, würd' ich doch nochmal gerne nachfragen.
    Und jetzt nochmal explizit zum ursprünglichen Beispiel: Es gibt doch sicherlich auch einen moderneren Weg mit Win XP-7, wobei ich auch den Aufbau von heutigen Systemen nachzuvollziehen lerne oder meint ihr es ist sinnvoll diesen Umweg zu nehmen?
    Im Endeffekt würde ich ja schließlich gerne meine ganze Grafikkarte so unter Kontrolle haben, wie jetzt meinen Arbeitsspeicher und auch kleine Teile meines CPU's. Führt mich der VGA-Modus zu diesem Ziel? (Wie der TexMod zeigt muss zumindest etwas ähnliches möglich sein)

    PS: Was meintest du mit diesem Autocogito-Link? Der Bezieht sich doch nicht auf mich oder? 😕



  • Du scheinst eine andere Definition von "systemnah" zu haben als ich. Eine WinApi Funktion aufrufen die in den virtuellen Adressraum eines anderen Prozesses schreibt hat irgendwie nicht viel mit Hardware zu tun. Solange du normale Programme für ein Betriebsystem wie Windows oder Linux schreibst hast du auch keinen direkten Zugriff auf Speicher oder Hardware (Protected Mode und Paging).

    Dein Zugriff auf den Grafikkartenspeicher muss daher über irgendeine Schnittstelle erfolgen. An Grafikschnittstellen gibt es da z.B. OpenGL oder DirectX. Aber ich wüsste nicht das eine von denen gezielten Speicherzugriff erlauben.

    Das ersetzen von Texturen wird meistens über Hooks auf DirectX oder OpenGL Funktionen gemacht. Statt der echten Funktion wird dann eine manipulierte Funktion aufgerufen, die dann die echte Funktion mit geänderten Daten aufruft.



  • Der VideoRAM ist ein Sektor im RAM. Die VRam schickt die Daten an die Grafikkarte, von daher hast du eigentlich nichts damit zu tun. Aber da sich die Pixelwerte nach dem Start des Programmes (meistens) nicht mehr ändern, würde es ziemlich schwierig werden, diese dynamisch zu manipulieren. Eine eingeschränkte Möglichkeit gäbe es da allerdings noch: Wenn vor der Kompilierung klar ist, wo in dem Fenster sich die Textur befinden wird, kann man eine Art "Screenshot" machen, sich die Farbwerte der Textur holen und nach diesen Farbwerten im angefordertem Speicher suchen. Diese liessen sich dann auch wieder mit neuen Farbwerten abändern.



  • Kóyaánasqatsi schrieb:

    Der VideoRAM ist ein Sektor im RAM. Die VRam schickt die Daten an die Grafikkarte, von daher hast du eigentlich nichts damit zu tun.

    Der Grafikspeicher kann Teil des Hauptspeichers sein (z.B. bei onboard Grafikchips). Häufig ist der Grafikspeicher aber als unabhängiges Speichermodul (Video-RAM [und nicht VRAM]) realisiert. VRAM bezeichnet eine (heute eher veraltete) Speichertechnologie die von Video-RAM genutzt wurde/wird und ist kein Synonym für den Chip selbst, oder den Grafikspeicher.

    @Topic: Es gibt Heutzutage keine Möglichkeit direkt auf den Grafikspeicher zuzugreifen (es sei denn du kennst die Spezifikation des Kartenherstellers und die sind meist gut geschützt). Daher wird dir nichts anderes übrig bleiben als eine API zu verwenden, die das für dich übernimmt.



  • David_pb schrieb:

    @Topic: Es gibt Heutzutage keine Möglichkeit direkt auf den Grafikspeicher zuzugreifen (es sei denn du kennst die Spezifikation des Kartenherstellers und die sind meist gut geschützt). Daher wird dir nichts anderes übrig bleiben als eine API zu verwenden, die das für dich übernimmt.

    Oder eben altes OS benutzen. Frueher war es eine Frage von 2 Assemblerbefehlen. Es gibt auch extra Libs, die heute sowas erlauben, habe z.b. oefter schon von "Pixeltoaster" gelesen.

    Was kann man damit lernen? Ich denke mal alles das was die Grafikkarte heutzutage selbst macht. Farbraeume umwandeln. Linien rasterisieren. Texturen mappen. Sowas halt. Also interessant ist das schon. f'`8k

    Gruß, TGGC (Was Gamestar sagt...)[/quote]



  • Sorry für den monster langen Beitrag, bitte lasst euch davon nicht abschrecken! 😃

    Tobiking2 schrieb:

    Du scheinst eine andere Definition von "systemnah" zu haben als ich. Eine WinApi Funktion aufrufen die in den virtuellen Adressraum eines anderen Prozesses schreibt hat irgendwie nicht viel mit Hardware zu tun. Solange du normale Programme für ein Betriebsystem wie Windows oder Linux schreibst hast du auch keinen direkten Zugriff auf Speicher oder Hardware (Protected Mode und Paging).

    Dein Zugriff auf den Grafikkartenspeicher muss daher über irgendeine Schnittstelle erfolgen. An Grafikschnittstellen gibt es da z.B. OpenGL oder DirectX. Aber ich wüsste nicht das eine von denen gezielten Speicherzugriff erlauben.

    Ja, dass ich die Hardwareteile an sich nicht direkt manipulieren kann ist mir schon klar. Wobei ich denke, dass es doch gehen müsste, sich aber ausschließlich auf genau meine Hardware-Teile beziehen würde, sodass es auf keinem anderen System liefe... ich bin mir aber nicht sicher.
    Jedenfalls hast du recht, ich hab' da eine recht eigenwillige Definition von "systemnah" (im übrigen aber nicht von "Hardwarenah", was für mich etwas ganz anderes bedeutet), die sich nicht unbedingt auf die Hardware bezieht sondern mehr von der virtuellen interpretation der Hardware ausgeht. So ist für mich die adressierung an eine Arbeitsspeicherstelle in Assamblercode systemnahe. (Tschuldigung, dass ich mich so missverständlich ausgedrückt hatte)
    Also ist es nach meiner Definition von "systemnahe" auch gar nicht weiter schlimm, eine API zu verwenden, solange es sich nicht um Funktionen handelt, die einem versuchen vorzugaukeln, es gäbe Fenster im Computer xD
    Also wenn mir DirectX eine indirekte aber trotzdem schlüssige und nachvollziehbare Funktion bereitstellt, nehm' ich die gerne 🙂

    Tobiking2 schrieb:

    Das ersetzen von Texturen wird meistens über Hooks auf DirectX oder OpenGL Funktionen gemacht. Statt der echten Funktion wird dann eine manipulierte Funktion aufgerufen, die dann die echte Funktion mit geänderten Daten aufruft.

    Das ist ja gar keine schlechte Idee 🙂 Dazu fehlen dann aber die detailierteren Informationen, einmal wo eine solche Funktion steht und wie sie heißt (wobei das ja irrelevant ist, wenn man das in Assembler realisieren müsste), dann ob DirectX als Teil des Betriebssystems solche Zugriffe überhaupt in irgendeiner Weise gestettet und dann noch ob man das nicht auch umgekehrt machen könnte, sodass man im Programm den DirectX-Aufruf manipuliert. Wobei aber die letzte Idee wohl langfristig die unsauberste Lösung wäre, wenn man das ganze auf ein anderes Programm portieren will.
    Und zu Kóyaánasqatsis Idee noch eine Frage: Habe ich Zugriff auf den Video-RAM im RAM (ist dann doch nur eine virtuelle Sektion oder?) Und dann könnte man sich ja auch gleich die Farbwerte schon vor der Kompilierung holen und in's eigene Programm einspeisen (sofern sich die Textur nicht ändert). Und dann müsste man vielleicht nicht einmal danach suchen sondern könnte durch Hooks auch sicherlich das herausbekommen.
    Aber wenn David_pb recht hat, ist es wohl doch eher unwahrscheinlich, dass es sich dabei um eine virtuelle Sektion des RAMs handelt. Aber Zugriff hat man dann über eine API (ich denke da jetzt an DX) doch vielleicht trotzdem?
    Gibt es da vielleicht eine Funktions-Referenz? Auf dem MSDN?
    Und zum Schluss noch @TGGC: Hört sich zwar schon interessant an, aber ich hab' ja jetzt schon die Hälfte des oben genannten Tutorials abgearbeitet, worin bisher zwar schon interessante und wissenswerte Dinge besprochen wurden, die aber nichts weiter mit dem zutun haben, wie ich mir die heutige Arbeits-Struktur einer Grafikkarte vorstelle, die die meisten der Funktionen intern geregelt und praktisch verpackt hat. Und dann ist das genze für mich doch auch wieder uninteressant, weil ich schon gerne einen praktischen Nutzen aus dem ganzen hätte.

    Hat jemand vielleicht einen Passenden Vorschlag, um das Problem zu lösen?

    Und ganz zum Schluss nochmal ein großes Danke, dass ihr mir alle so nett und konstruktiv helft 🙂



  • Miikku schrieb:

    Habe ich Zugriff auf den Video-RAM im RAM

    Ja.

    Miikku schrieb:

    Und dann könnte man sich ja auch gleich die Farbwerte schon vor der Kompilierung holen

    Wie möchtest du das anstellen? Dein Programm muss doch durch die Positionsangabe die Farbwerte erst ermitteln; Mache Screenshot->Suche nach bestimmten Farbwerten an festgelegter Position->Speichere Adresse des ersten Pixels->Ersetze Adressinhalt (Pixelfarbe).



  • Hm...
    Laut David_pb ist doch normalerweise (da ja Onboard Grafikkarten denke ich nicht als normal zu bezeichnen sind für den durchschnittlichen Gebrauch), der Video-RAM gar nicht im RAM. Also bezieht sich deine Antwort jetzt auf die Möglichkeit, wenn ich die Onboard Karte nutzen würde oder hab' ich wieder etwas nicht/falsch verstanden?

    Und wieso muss denn mein Programm die Farbwerte erst ermitteln? Das kann ich doch auch manuell mit Screenshot schon vor dem Kompilieren machen, wenn ich dem Programm meine Ergebnisse einspeichere 🙂



  • Man muss in diesem Fall schon zwischen Arbeitsspeicher und Adressraum unterscheiden.

    Der Adressraum besitzt bei einem 32 Bit PC 2^32 Adressen, hinter denen sich je 1 Byte verbirgt. Man kann damit also 4 Gigabyte Daten adressieren, egal wieviel Speicher man verbaut hat. Der Speicher liegt in diesem Adressraum und wird auch darüber angesprochen. Außerdem liegen in diesem Adressraum auch andere Geräte wie z.B. die Grafikkarte. Das nennt sich Memory Mapped IO und ist einer der Gründe warum ein 32 Bit System nicht 4 Gigabyte Speicher vollständig nutzen kann.

    Desweiteren heißt das, wenn ich auf die Adresse x zugreife kann es sein, dass ich gar nicht den Arbeitsspeicher treffe, sondern ein Gerät. Es gibt auch noch io ports mit denen man z.B. steuern kann welcher Teil des Grafikspeichers auf welchen Teil des Adressraums abgebildet wird. Es macht nämlich wenig Sinn wenn eine Grafikkarte mit 1 Gigabyte Speicher immer 1 Gigabyte des Adressraums belegt. Daher nimmt man vielleicht einen 100 Megabyte Teil des Adressraums und verändert wie dies auf den Grafikkarten Speicher gemappt wird.

    Weiterhin besitzen dann die Prozesse einen virtuellen Adressraum der von dem "echten" abweicht. Das Betriebsystem entscheidet welche virtualle Adresse auf welche echte Adresse weitergeleitet wird und die Frage ist nun, ob dich das Betriebsystem auf die Adressen zugreifen lässt an denen Geräte liegen. Das ist normalerweise nicht der Fall, da du sonst einfach Unsinn machen könntest und den PC zum absturz bringen kannst.

    Das ist alles eher ein Thema für einen Grafikkarten Treiber.



  • Oh! Vielen Dank für die Erklärung, das klärt wirklich so einiges, was ich bisher niergends lesen durfte.
    Aber du stempelst jetzt so einfach ab mit "Das ist normalerweise nicht der Fall". Heißt das, es besteht überhaupt keine Hoffnung damit herumspielen zu können? Nicht auch nur die geringste Hoffnung? 😞

    Nagut... dann wird man wohl auf die Hook-Methode zurückgreifen müssen um DirectX direkt zu verändern. Weil ich einfach keinen Anhaltspunkt habe, wie ich da ansetzen soll frag' ich jetzt einfach mal ganz frech: Hat jemand vielleicht sowas schonmal gemacht oder Erfahrung mit etwas ähnlichem? Das würde mich echt interessieren!
    Ansonsten würde ich dann versuchen das Programm selber zu verändern um beim laden des Bildes schon die Parameter umzulenken... Wobei sowieso noch die Frage besteht: Dazu muss auch das Ersetzungs-Bild irgendwo im Adressraum des Programmes stehen, richtig? Muss ich also das Bild in einen "Allocateten" Bereich des Programms Bitweise reinladen? Oder wie ist das geregelt?

    *Offtopic: Hab' gerade nachgerechnet, heißt das, dass ein 64-Bit-System 18.446.744.073.709.551.615 Bytes, also 18,45 Exabytes für jedes Programm bereitstellt? o.O
    WTF! Das reicht ja für die nächsten paar Jahrhunderte!



  • Heißt das, es besteht überhaupt keine Hoffnung damit herumspielen zu können? Nicht auch nur die geringste Hoffnung?

    Unter einem Betriebssystem wie Windows oder Linux hast du - als normales Programm - keine Möglichkeit direkt auf den Grafikkarten-Speicher zuzugreifen.

    Als Treiber ginge es natürlich. Theoretisch. Bloss als Treiber hättest du noch das Problem, dass der Grafikkarten-Treiber schon glaubt, "Alleinherrscher" über den Grafikkarten-Speicher zu sein. Und dass du nicht weisst, wie genau du das Mapping des Grafikkarten-Speichers machen musst. Alles in allem wäre es nicht praktikabel.

    Und wieso überhaupt Dos?

    Weil DOS dich direkt auf die Grafikkarte zugreifen lässt. VGA deswegen, weil jede heute erhältliche Grafikkarte VGA kompatibel ist. Auf die "erweiterten" Funktionen einer Grafikkarte (3D Sachen etc.) kannst du aus DOS zwar auch zugreifen, bloss müsstest du dazu wissen wie es geht. Und die Informationen geben die Hersteller nicht einfach so raus (warum auch immer). Bzw. ist das alles auch nicht so einfach. Einfach mal ein paar Register setzen und du hast ein Dreieck am Schirm spielt es heute nimmer.



  • hustbaer schrieb:

    Heißt das, es besteht überhaupt keine Hoffnung damit herumspielen zu können? Nicht auch nur die geringste Hoffnung?

    Unter einem Betriebssystem wie Windows oder Linux hast du - als normales Programm - keine Möglichkeit direkt auf den Grafikkarten-Speicher zuzugreifen.

    Würde ich mal ne Runde im Internet suchen.
    Es gibt unter Linux sogar die Möglichkeit den "freien" Graka-Speicher als zusätzliche Swap-Partition zu verwenden. Muss man nur ein bißchen frickeln ...



  • Miikku schrieb:

    *Offtopic: Hab' gerade nachgerechnet, heißt das, dass ein 64-Bit-System 18.446.744.073.709.551.615 Bytes, also 18,45 Exabytes für jedes Programm bereitstellt? o.O
    WTF! Das reicht ja für die nächsten paar Jahrhunderte!

    Theoretisch schon, praktisch besitzen aktuelle 64 Bit Prozessoren meist nur einen 48 Bit Adressraum und und 40 Bit für den Speicherzugriff. Damit kommt man aber immer noch auf einen 256 Terabyte Adressraum und 1 Terabyte Speicher. Da könnte man sich auch überlegen den Grafikkartenspeicher komplett in den Adressraum einzublenden.

    hustbaer schrieb:

    Auf die "erweiterten" Funktionen einer Grafikkarte (3D Sachen etc.) kannst du aus DOS zwar auch zugreifen, bloss müsstest du dazu wissen wie es geht. Und die Informationen geben die Hersteller nicht einfach so raus (warum auch immer). Bzw. ist das alles auch nicht so einfach. Einfach mal ein paar Register setzen und du hast ein Dreieck am Schirm spielt es heute nimmer.

    ATI/AMD hat sogar einige Spezifikationen von ihren Chips veröffentlicht (http://www.x.org/docs/AMD/) um das schreiben freier Treiber zu ermöglichen. Intel hat glaube ich sogar Quelloffene Treiber für ihre Grafikkarten. Einfach ist es aber trotzdem nicht.

    nurf schrieb:

    Würde ich mal ne Runde im Internet suchen.
    Es gibt unter Linux sogar die Möglichkeit den "freien" Graka-Speicher als zusätzliche Swap-Partition zu verwenden. Muss man nur ein bißchen frickeln ...

    Ja, über die device files kann man in einem Programm auf Hardware zugreifen. Das müssen dann aber die Treiber anbieten. Die Vesa Treiber im Kernel bieten z.B. in /dev/fb den framebuffer an. Wenn der Vesa Modus aktiv ist kann man dort einfach einzelne Pixel reinschreiben. Die offenen Treiber die es für Intel und recht alte ATI Karten gibt dürften soetwas auch können. Bei den aktuellen properitären Treibern bin ich mir aber nicht so sicher.


  • Mod

    ob man dran kommt oder nicht haengt am meisten vom OS ab. oft hat nichtmal ein treiberprogrammierer die moeglichkeit direkt zwischen user-applikation und device memory zu mappen weil es vom betriebssystem virtualisiert ist.
    Ein grund z.B. ist dass ein betriebssystem garantieren muss, dass selbst beim absturz eines programmes fuer den treiber bzw device alles freigegeben wird.

    Auch von der treiber bzw device seite ist es oft garnicht noetig irgendwelche speicherbereiche direkt zu mappen, oft sogar kontraproduktiv, von daher wird explizit hin und her kopiert, dafuer gibt es eben die APIs die entweder lock/map und unlock/unmap haben oder direkt nur kopierbefehle unterstuetzen (z.b. cuda, ogl).

    ich weiss aber auch nicht wozu man das braeuchte.


Anmelden zum Antworten