Ergebnis 1 bis 11 von 11

Thema: Pe Loader schreiben

  1. #1
    Registered User
    Registriert seit
    Mar 2008
    Beiträge
    17
    Renommee
    10

    Pe Loader schreiben

    Ja ich schon wieder,
    Ich wollte mich mal daran versuchen einen PE Loader zu schreiben, um so PEdateien vom speicher aus starten zu lassen.
    Aber schon ganz grundlegend habe ich einige Fragen:

    1. An welche Imagebase soll ich die Datei laden lassen?
    Ich habe mir das so gedacht, dass ich die Imagebase der Hostapplikation auf irgendwas exotisches setze ($50000000) , sodass $00400000 frei wäre. Das geht aber schon mal nicht, VirtualAlloc auf $00400000 schlägt immer fehl, bei imagebase $1000000 (calc.exe) gelingt aber das Allozieren. Wenn ich die Datei aber an eine andere Imagebase laden lassen, stimmen wahrs. einige Addressen nicht mehr und längst nicht alle Exedateien enthalten relocations

    2. Wie soll ich die in meinen Adressraum geladene Exe dann schlussendlich ausführen? Mit CreateProcess? mit CreateThread?

    danke im Voraus
    Hamtaro

  2. #2
    Moderator
    Registriert seit
    May 2002
    Beiträge
    653
    Renommee
    1014

    Re: Pe Loader schreiben

    so ganz trivial ist es nicht:
    http://grn.ath.cx/board/viewtopic.php?t=60&sid=
    Spoiler:

    Such dir ein PE-Tutorial aus (es gibt einige - von MS selbst, von Iczelion usw) und schau an, was da alles reingehört.
    Dann kannst du (am besten bei MS) nach "PE-Loader" suchen - das ist nämlich das Teil, welches in Windows die Programme in den Speicher lädt, initialisiert usw.
    Denn mit dem Cryptor wirst du ja den Code "verschlüsseln" - deswegen musst du wissen, wo dieser Bereich anfängt, wie groß dieser ist und wo man die Werte auslesen kann (PE-Format) und wie du die wiederherstellen kannst (damit die Exe nachher auch läuft) bzw was bei der Wiederherstellung zu beachten ist.

    Auch muss ein Cryptor den Code wieder entschlüsseln - deshalb wirst du eine Stub (Codeteil, der die Exe entschlüsselt) schreiben müssen. Die Stub musst du zu der Exe hinzufügen - also wiederum PE-Format Verweis (Sections und deren Flags - denn die codesection wirst du beschreibbar machen müssen, damit der Crypter wieder alles entpacken kann). Natürlich musst du nach dem Bearbeiten der Exe die PE-Werte korriegieren - für alle geänderten Bereiche -> wiederum PE-Format Kenntnisse.

    Da die Stub zu den Exen hinzugefügt werden soll, sollte dieser Code möglichst unabhängig von irgendwelchen Bibliotheken sein Wink. Idealerweise wäre es auch ein adressunabhängiger Code - den kann man mit vielen Verrenkungen in C produzieren, aber wohl nicht in Delphi.

    Damit es nicht zu einfach wird, muss man dann verschiedene Sachen wie TLS Einträge (Tls Tables) berücksichtigen, von denen z.B Borland einen ausgiebigen Gebrauch macht. Denn ein TLS-Callback sorgt dafür, dass Code schon vor dem Programmstart ausgeführt werden kann (z.B zu initialisierungszwecken, zugegebenermaßen ist es für DLLs noch nützlich, für Exen eigentlich nicht). Da es aber vor der Ausführung der Stub passiert, liegt der Code noch verschlüsselt da, klappt es nicht. Hier muss man irgendwie dafür sorgen, dass dieser Codebereich entweder nicht verschlüsselt oder vor dem Gebrauch entschlüsselt wird.

    Wenn du auch noch die Imports/Exports crypten willst, kommst du nicht um entsprechende Tutorials herum ("understandig Imports" von dzzie oder ein Teil der Tutorials von Iczelion). Auch hat man mit den ganzen Eigenarten der Linker viel Spass - Borland und MS Linker produzieren unterschiedliche Executables.

    Das PE-Format an sich ist recht umfangreich (zumindest wenn man alles berücksichtigen möchte) und wie erwähnt, manche Linker nutzen das eine oder andere - um einen halbwegs stabilen und brauchbaren Cryptor zu schreiben muss man imho schon einiges an Erfahrung mitbringen.
    Wenn es allerdings nur ein bestimmter Zielbreich ist (nur VB Compiler/ nur MS-Compiler etc) wird es schon um vieles einfacher. Oder man kann auch "Pseudocryptoren" schreiben - das ist aber eher ein Binder mit Cryptfunktion.


    Wobei: imho bringt Delphi-Quellcode (oder überhaupt irgendwelche Quellcodes) bei der Erlernung erstmal nicht viel - man muss das Format schon im groben verstanden haben, um aus dem Quellcode lernen zu können.

    PS: die Auflistung ist auch keineswegs vollständig - ich wette, mir sind noch ziemlich viele wichtige Sachen nicht eingefallen


    d.h mit mappen ist es nicht getan - erstmal müssen die Sections richtig gemappt werden (mit dem aligning und initialisierung etc.) dann IAT ausgefüllt und eventuelle Relocations abgearbeitet - das macht sich alles nicht von alleine
    Selig, wer nichts zu sagen hat und trotzdem schweigt!

  3. #3
    Registered User
    Registriert seit
    Mar 2008
    Beiträge
    17
    Renommee
    10

    Re: Pe Loader schreiben

    Erstmal danke, mir ist durchaus klar dass das keine leichte Sache ist, aber man wächst ja an seinen Aufgaben .
    Leider ist meine ursprüngliche Frage nicht beantwortet, wie kann ich eine Exe am besten immer an ihre angestammte Imagebase laden lassen? Denn relocations haben nicht alle Exedateien und das allozieren auf $00400000 schlägt immer fehl. . Kann man vielleicht die Hostanwendug irgendwie überschreiben?

    danke im Voraus
    Hamtaro

  4. #4
    Moderator
    Registriert seit
    May 2002
    Beiträge
    653
    Renommee
    1014

    Re: Pe Loader schreiben

    Hm, Du hast recht, wenn man die ImageBase in der Anwendung verschiebt, wird beim Laden trotzdem die 0x400000 mit irgendwas "besetzt". Ich habe das testweise mit einer Dummy-DLL umgangen - die DLL hatte die ImageBase 0x400000 bekommen und wurde statisch gegen die Exe mit einer ImageBase 0x1000000 gelinkt. Da es eine "dummyDLL" ist, kann man diese auch bei Bedarf vergrößeren oder verkleinern, so dass man einen Block praktisch reservieren kann. Anderseits garantiert der PE-Loader ja bei DLLs nicht, dass sie an diese Adresse kommen.
    Daher bleibt die "sauberere" Lösung imho ->
    Kann man vielleicht die Hostanwendug irgendwie überschreiben?
    also ganz normale Exe, deren SizeOfImage groß genug gewählt wurden (man kann es ja reltaiv schnell anpassen - die VirtualSize der letzten Section vergörßern und SizeOfImage anpassen.
    Diese Exe reserviert dann einen dynamischen Speicherblock und schreibt da sowohl den Entpackcode wie auch die zu ladende Exe rein. Der Entpackcode übrschreibt dann die Hostapplication. Solange diese groß genug ist, sehe ich keine prinzipiellen Schwierigkeiten. Allerdings hat das schreiben vom Adressunabhängigem Code so seine Tücken (außerdem hab ich k.A wie man das nun in Delphi bewerkstelligen sollte, eventuell hat Atho ein paar nette Links dazu ). Du könntest jedoch erstmal eine DLL mit dem Entpackcode verwenden - dann kannst Du ja erstmal ein funktionierendes System aufbauen, bevor der Code dann (wenn überhaupt erwünscht) nach Asm/"adressunabhängingem Delphi" portiert wird.
    Selig, wer nichts zu sagen hat und trotzdem schweigt!

  5. #5
    Registered User
    Registriert seit
    Mar 2008
    Beiträge
    17
    Renommee
    10

    Re: Pe Loader schreiben

    Hmm also ich habe erstmal einen Code geschrieben, der eine DLL aus einem Bytearay lädt:
    Code:
    function memLoadLibrary(FileBase : Pointer) : Pointer;
    var
    pfilentheader : PIMAGENTHEADERS;
    pfiledosheader: PIMAGEDOSHEADER;
    pphysntheader : PIMAGENTHEADERS;
    pphysdosheader: PIMAGEDOSHEADER;
    physbase  : Pointer;
    pphyssectionheader : PIMAGESECTIONHEADER;
    i : Integer;
    importsBase: Pointer;
    importDesc :  PImageImportDescriptor;
    importThunk: PImageThunkData;
    dll_handle : Cardinal;
    importbyname : pimageimportbyname;
    relocbase : Pointer;
    relocdata : PIMAGeBaseRElocation;
    relocitem : PWORD;
    reloccount : Integer;
    dllproc : TDLLEntryProc;
    id : Cardinal ;
    begin
    result := 0;
    
    pfiledosheader := filebase;
    pfilentheader  := Pointer(Cardinal(filebase) + pfiledosheader^._lfanew);
    
    
    ////////////////////////
    /////////////allozieren/
    physbase := VirtualAlloc(Pointer(pfilentheader^.OptionalHeader.ImageBase),pfilentheader^.OptionalHeader.SizeOfImage,MEM_RESERVE Or Mem_COMMIT,PAGE_READWRITE);
    if Cardinal(physbase) = 0 Then begin
    physbase := VirtualAlloc(0,pfilentheader^.OptionalHeader.SizeOfImage,MEM_RESERVE Or Mem_COMMIT,PAGE_READWRITE);
    end;
    
    
    /////////////////////////////
    /////////////header kopieren/
    CopyMemory(physbase,filebase,pfilentheader^.OptionalHeader.SizeOfHeaders);
    
    //header im memory finden & anpassen
    pphysdosheader := physbase;
    pphysntheader := Pointer(Cardinal(physbase) + pphysdosheader^._lfanew);
    pphysntheader^.OptionalHeader.ImageBase := Cardinal(physbase);
    
    
    ///////////////////////////////
    /////////////sections kopieren/
    pphyssectionheader := Pointer(Cardinal(pphysntheader) + SizeOf(TIMAGENTHEADERS));
    for i := 0 To (pphysntheader^.FileHeader.NumberOfSections - 1) do begin
      if pphyssectionheader^.SizeOfRawData = 0 Then begin
        //keine raw data
        ZeroMemory(Pointer(Cardinal(physbase) + pphyssectionheader^.VirtualAddress),pphyssectionheader^.Misc.VirtualSize);
      end else begin
        //raw data vorhanden
        CopyMemory(Pointer(Cardinal(physbase) + pphyssectionheader^.VirtualAddress),Pointer(Cardinal(filebase) + pphyssectionheader^.PointerToRawData),pphyssectionheader^.SizeOfRawData);
      end;
      pphyssectionheader^.Misc.PhysicalAddress :=  Cardinal(physbase) + pphyssectionheader^.VirtualAddress;
    
      //next one please
      pphyssectionheader :=  Pointer(Cardinal(pphyssectionheader) + SizeOf(TIMAGESECTIONHEADER));
    end;
    
    
    //////////////////////
    /////////////imports/
    importsBase := Pointer(Cardinal(physbase) + pphysntheader^.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress);
    importDesc := importsBase;
    while (importDesc.Name) <> 0 Do begin
      dll_handle := LoadLibrary(pchar(Cardinal(physbase) + importdesc.Name));
      importDesc.ForwarderChain := dll_handle;
      importThunk := Pointer(Cardinal(physbase) +  importDesc.FirstThunk);
      while importThunk.Ordinal <> 0 Do begin
        importbyname := Pointer(Cardinal(physbase) + importThunk.Ordinal);
        //Später noch überprüfen ob OriginalFirstThunk = 0
        if (importThunk.Ordinal and IMAGE_ORDINAL_FLAG32) <> 0 Then
        begin //ordinal
          importThunk.FunctionPtr := GetProcaddress(dll_handle,pchar(importThunk.Ordinal and $ffff))
        end else begin //normal
          importThunk.FunctionPtr := GetProcAddress(dll_handle,importByname.name);
        end;
      //next one, please
      importThunk := Pointer(Cardinal(importThunk) + SizeOf(TIMAGETHUNKDATA));
      end;
    //next one, please
    importDesc := Pointer(Cardinal(importDesc) + sizeOf(TIMAGEIMPORTDESCRIPTOR));
    end;
    
    
    /////////////////////
    /////////////relocs/
    relocbase := Pointer(Cardinal(physbase) + pphysntheader.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress);
    relocData := RElocbase;
    while (Cardinal(relocdata) -  Cardinal(relocbase)) < pphysntheader.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].Size do begin
      reloccount := trunc((relocdata.SizeOfBlock - 8) / 2);
      relocitem  := Pointer(Cardinal(relocdata) + 8);
      For i := 0 To (reloccount - 1) do begin
        if (relocitem^ shr 12) = IMAGE_REL_BASED_HIGHLOW Then begin
          Inc(PDWord(Cardinal(physbase) + relocdata.VirtualAddress + (relocitem^ and $FFF))^,(Cardinal(physbase) - pfilentheader.OptionalHeader.ImageBase));
        end;
        relocitem := Pointer(Cardinal(relocitem) + SizeOf(WORD));
      end;
    
      //next one please
      relocdata := Pointer(Cardinal(relocdata) + relocdata.SizeOfBlock);
    end;
    
    
    /////////////////////////////////
    ////////Section protection & so/
    pphyssectionheader := Pointer(Cardinal(pphysntheader) + SizeOf(TIMAGENTHEADERS));
    For i := 0 To (pphysntheader^.FileHeader.NumberOfSections - 1) do begin
      VirtualProtect(Pointer(Cardinal(physbase) + pphyssectionheader^.VirtualAddress),pphyssectionheader^.Misc.VirtualSize,GetSectionProtection(pphyssectionheader.Characteristics),nil);
      pphyssectionheader := Pointer(Cardinal(pphyssectionheader) + SizeOf(TIMAGESECTIONHEADER));
    end;
    
    
    ////////////////////////////////
    ////////////////Dll entry proc/
    dllEntryproc := Pointer(Cardinal(physbase) + pphysntheader.OptionalHeader.AddressOfEntryPoint);
    dllEntryproc(cardinal(physbase),DLL_PROCESS_ATTACH,nil);
    //BeginThread(nil,0,TThreadFunc(dllentryproc),0,0,id);
    result := physbase;
    end;
    Wenn ich jedoch den DLL EntryProc aufruf durch das auskommentierte BeginThread ersetze, kommt als Fehlermeldung:
    'System Error. Code: 1410.
    Klasse ist bereits vorhanden'
    Diesen Fehler interpretiere ich so, dass Windows es nicht mag wenn man 2 Prozesse im selben Adressraum ausführt, meine Frage ist jetzt: Wie kann ich eine EXE denn jetzt ausführen?
    Danke im Voraus
    Hamtaro

  6. #6
    Moderator
    Registriert seit
    May 2002
    Beiträge
    653
    Renommee
    1014

    Re: Pe Loader schreiben

    Wenn ich jedoch den DLL EntryProc aufruf durch das auskommentierte BeginThread ersetze, kommt als Fehlermeldung:
    ...
    meine Frage ist jetzt: Wie kann ich eine EXE denn jetzt ausführen?
    den Übergang zu dieser Frage verste ich irgendwie nicht
    Klappt denn der normale dllEntryproc(...) Aufruf?

    Warum bei BeginThread ein Fehler kommt: ich vermute mal stark, weil DLL-Main 3 Argumente haben möchte, bei BeginThread (was wohl eine Art Wrapper für WinAPI CreateThread zu sein scheint, zumindest nach dieser Doku [1]) aber nur 1 Paramter kommt.


    [1]http://www.delphibasics.co.uk/RTL.asp?Name=BeginThread
    Selig, wer nichts zu sagen hat und trotzdem schweigt!

  7. #7
    Registered User
    Registriert seit
    Mar 2008
    Beiträge
    17
    Renommee
    10

    Re: Pe Loader schreiben

    Achso, ja der Aufruf der DLL funktioniert, ich habe sogar ne ganze Unit geschrieben, die zusätzlich noch sowas wie GetProcAddress kennt und die DLL wieder Freeen kann. Falls Interesse besteht kann ich die hier gern mal posten.

    Und nein, dllEntryproc ist ja nur der Funktionspointer, der verschiedentlich interpretiert werden kann.

    Ich vermute eher nicht dass es daran liegt, darf man überhaupt 2 Prozesse im gleichen Prozessraum ausführen?

    //EDIT: Es lag wohl daran dass ich eine weitere Delphi Anwendung ausführen wollte, wenn ich ne Exe versuche zu starten, die vom BCB erstellt wurde, gehts zwar immer noch nicht, aber als Fehlereldung kommt erst ne AV:
    Access violation at address 00000000. Read of address 00000000.
    Und dann :
    Code: 5.
    Zugriff verweigert'.
    Ich glaube dass hat so keinen Zweck, man scheint 2 Prozesse einfach nicht nebeneinander laufen lassen zu können
    Aber wie lade ich meine Exe denn dann in einen anderen Prozess?
    Geändert von Hamtaro (19.05.2008 um 19:36 Uhr)

  8. #8
    Moderator
    Registriert seit
    May 2002
    Beiträge
    653
    Renommee
    1014

    Re: Pe Loader schreiben

    Ich vermute eher nicht dass es daran liegt, darf man überhaupt 2 Prozesse im gleichen Prozessraum ausführen?
    als Thread? Warum nicht? Es könnte höchstens "Deadlocks" geben (also die "normalen" Threadprobleme).

    Und nein, dllEntryproc ist ja nur der Funktionspointer, der verschiedentlich interpretiert werden kann.
    eine DLL Main hat normalerweise 3 Paramter:
    http://msdn.microsoft.com/en-us/libr...83(VS.85).aspx
    bei
    Code:
    dllEntryproc(cardinal(physbase),DLL_PROCESS_ATTACH,nil);
    rufst Du es ja auch mit 3 Parametern auf.
    bei
    Code:
    BeginThread(nil,0,TThreadFunc(dllentryproc),0,0,id);
    rufst Du den Wrapper für CreateThread.
    function BeginThread ( SecurityAttr : Pointer; StackSize : LongWord; ThreadFunc : TThreadFunc; Param : Pointer; CreateFlags : LongWord; var ThreadId : LongWord ) : Integer;

    When calling a BeginThread function, you are creating a new thread which executes the specified ThreadFunc function. This is a function with Param as its singles Pointer argument. The thread runs until this function ends.
    erwartet als ThreadFunktion also solche form:
    Code:
    DWORD WINAPI ThreadProc(
      __in  LPVOID lpParameter
    );
    es wird also die DLLMain mit nur 1 Paramter aufgerufen. Beim RETN in der DLL-Main wird dann zuviel vom Stack weggeräumt und demnach die falsche Adresse für den Rücksprung genutzt.
    Rein Theoretisch könntest Du es bei eigenen DLLs umgehen, in dem Du die DLLMain "anpasst" (nur 1 Parameter lässt). Dann darfst Du die DLL natürlich nicht mehr mit etwas anderem laden/einsetzen.
    Selig, wer nichts zu sagen hat und trotzdem schweigt!

  9. #9
    Registered User
    Registriert seit
    Mar 2008
    Beiträge
    17
    Renommee
    10

    Re: Pe Loader schreiben

    Achso..danke erstmal,von Threading hab ich nämlichs so gut wie keine Ahnung
    Also so?
    Code:
    ThreadEntryFunc : TthreadFunc;
    Code:
    ThreadEntryFunc := Pointer(Cardinal(physbase) + pphysntheader.OptionalHeader.AddressOfEntryPoint);
    BeginThread(nil,0,ThreadEntryFunc,0,0,id);
    Das klappt leider immer noch nicht, bei dieser Exe kommt wieder ne AV:
    'access violation at 0x7c947927: write of address 0x01020ff8'.
    Würde es irgendeinem der Debugginggötter hier helfen, wenn ich ne fertig kompilierte Version des Projekts hochlade?
    Weiß sonst wer Rat?

    Zwischen Bangen und Hoffen
    Hamtaro

  10. #10
    Registered User
    Registriert seit
    Mar 2008
    Beiträge
    17
    Renommee
    10

    Re: Pe Loader schreiben

    Hmm, es ist schon länger her, dass ich mich mit diesem Thema beschäftigt habe, aber jetzt hat sich meine schweifende Aufmerksamkeit ihm wieder zugewandt.
    Wenn ich dieses Thema allerdings nochmal lese, wird mir klar, dass ich mich wohl etwas unpräzise ausgedrückt habe.
    Also mein Ziel ist es, einen PE-Loader zu schreiben. Dies ist mir zum Teil bereits gelungen, ich kann eine DLL aus einem Bytearray laden und benutzen. Das funktioniert, indem im Prozess genügend Speicher alloziert wird, der wird dann mit den richtigen Sections, Imports und Relocations gefüllt und zum Schluss mit DLLmain() aufgerufen.
    Jetzt würde ich das gleiche natürlich auch gerne mit EXE-Dateien machen.
    Mein Versuch wäre jetzt, den gleichen Code (siehe oben) zu benutzen und nur den Start zu verändern, nämlich das DLLmain durch einen neuen Thread bei dem EntryPoint der Exe zu ersetzen.
    Code:
    ThreadEntryFunc := Pointer(Cardinal(physbase) + pphysntheader.OptionalHeader.AddressOfEntryPoint);
    BeginThread(nil,0,ThreadEntryFunc,0,0,id);
    Das führt aber leider zu folgenden Fehlermeldungen:
    Code:
    Project Project2.exe raised exception class EOSError with message 'System Error.  Code: 5.
    Und danach oder davor eine AV mit immer unterschiedlichen Zugriffsverletzungen.

    Kann man überhaupt 2 exen im gleichen prozessraum ausführen, doer merken die das irgendwie? Sollte es so nicht gehen, wie dann kann man denn dann eine Exe aus einem Bytearray starten, es gibt ja Programme die sowas machen.
    Im Anhang die komplierten Beispiele

    danke im Voraus
    Angehängte Dateien Angehängte Dateien

  11. #11
    Registered User
    Registriert seit
    Mar 2008
    Beiträge
    17
    Renommee
    10

    Re: Pe Loader schreiben

    Tja, keine Ahnung ob hier überhaupt noch wer mitliest, aber ich bin zu neuen Ergebnissen gekommen.
    Die erwähnten AVs stammten hauptsächlich daher, dass die zu ladenden exen die standard-imagebase hatten, die, wie hier im Thread auch zu lesen ist, aber immer besetzt ist.
    DAS Problem habe ich jetzt erstmal umgangen, indem ich Exen mit exotischen Imagebases benutze.
    Aber jetzt:
    Ich kann mittlerweile einfache fensterlose Anwendungen und Konsolenanwendungen (diese aber nur, wenn die startende Anwendung selber eine Konsolenanwendung ist) ausführen, allerdings nur, indem ich mit inline ASM einen jmp zum entrypoint mache. Prinzipiell kein Problem, bei Fensteranwendungen und komplexeren Anwendungen kommen aber immer noch AVs. Das scheint daran zu liegen, dass die Register (eax, ebx, ecx..) irgendwelche Ungefälligen WErte enthalten.
    Angeblich soll dies mit dem PEB zusammenhängen, der (irgendwie logisch) noch die ProzessInformationen der "Träger"-exe enthält. Vor allem in Bezug auf die Imagebase soll es hier Probleme geben. Meine Frage ist jetzt: könnt ihr das hier bestätigen, dass man am PEB arbeiten muss? Kann man auf den einfach schreibend zugreifen?

    danke im Voraus
    Hamtaro

Aktive Benutzer

Aktive Benutzer

Aktive Benutzer in diesem Thema: 1 (Registrierte Benutzer: 0, Gäste: 1)

Ähnliche Themen

  1. boot-loader
    Von Jules im Forum Windows
    Antworten: 1
    Letzter Beitrag: 22.02.2003, 20:11
  2. win2000 loader soll LILO laden
    Von syntaxo im Forum Windows
    Antworten: 11
    Letzter Beitrag: 25.09.2001, 23:46
  3. loader ueber dem 1024 Zylinder
    Von smack im Forum Windows
    Antworten: 5
    Letzter Beitrag: 23.04.2001, 18:32
  4. Failed to locate protected mode loader (DPMILOAD.EXE)
    Von robotic im Forum Systemnahe Programmierung
    Antworten: 2
    Letzter Beitrag: 02.03.2001, 23:48
  5. Loader error (0025): cannot initialize >> what the hell?!?
    Von [elix] im Forum Systemnahe Programmierung
    Antworten: 0
    Letzter Beitrag: 20.10.2000, 17:06

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •