Probleme bei C++ Objekten im prozessübergreifenden, globalen Speicher.



  • [quote="Techel"]Und Linux zaubert jetzt oder wie?
    Wenn du es wirklich durchziehen möchtest: MSVC bietet eine bestimmte Direktive, die VTable direkt im Objekt selbst zu speicher.[/quote]
    Wie könnte das aussehen?
    Könntest du mir ein Beispiel geben?



  • Oh, hab da was verwechselt, das geht doch nicht wie geplant. Du müsstest dann wohl auf ein C-Interface umsteigen, zB. eine Struktur aufbauen, welche Funktionszeiger, wie bei virtuellen Funktion, enthält. Auch hier gilt, dass beide Programme komplett gleich sind bzw die gleiche Codesektion haben.



  • Techel schrieb:

    Auch hier gilt, dass beide Programme komplett gleich sind bzw die gleiche Codesektion haben.

    Wenn das schon gegeben ist, dann geht es auch mit ganz normalem Vtable.



  • Hans500 schrieb:

    @hustbear:
    Ich habe mich beim Aufruf der WinAPI-Funktionen CreateFileMapping(...) bzw. OpenFileMapping(...) und MapViewOfFile (...) exakt nach den Vorgaben aus der Mikrosoft-Dokumentation gehalten.
    Dort wird nirgendwo darauf hingewiesen, daß Mikroft da Probleme mit virtuellen Funktionen hat.

    Insgesamt ist das wirklich äußerst schwach von Mikrosoft.

    Nein, da ist gar nix schwach von Microsoft. Es bezeugt nur dass dir das Verständnis fehl, dafür was man mit C++ machen kann und was nicht.
    Der C++ Standard weiss einfach nichts von Prozessen und schon gar nicht von "shared memory".
    Da muss überhaupt gar nichts funktionieren.
    Nächstens versucht du noch ein Speicherabbild eines Objekts in ein File zu schreiben, dann in einem wildfremden Prozess reinzuladen und es hat dann gefälligst zu funktionieren.
    Wird es aber nicht.

    Hans500 schrieb:

    Mir bleibt wohl nix anderes übrig als auf LINUX umzusteigen.

    OK, wenn du meinst.



  • hustbaer schrieb:

    Techel schrieb:

    Auch hier gilt, dass beide Programme komplett gleich sind bzw die gleiche Codesektion haben.

    Wenn das schon gegeben ist, dann geht es auch mit ganz normalem Vtable.

    Jaja, da sieht man den Wald vor lauter Bäumen nicht.



  • Und wozu das ganze? Wenn du irgendeinen IPC Mechanismus implementieren willst, gibts doch quasi unendlich viele Möglichkeiten, auch viele einfachere.



  • Hallo,

    der Unterschied zwischen XP und 7, 8, ... wird hier wohl ASLR sein. Das sorgt dafür, dass die Images nicht immer an derselben Startadresse geladen werden, was dazu führt, dass die Methodenpointer von DLL Code, der über Prozess 1 geladen wird nicht an derselben Stelle zu liegen kommen wie beim nächsten Prozess, der die DLL lädt.
    Das ist ein Sicherheitsfeature und gibt es _auch_ unter aktuellen Linuxen 😃

    Könnte man theoretisch ausschalten (global über Registry/Wahnsinn, lokal über Linkereinstellung/auch keine gute Idee).

    Offensichtlich versuchst Du hier IPC. Kann man schon über gesharte Daten in MMFs machen (Zugriff korrekt synchronisieren!) - aber ich würde hier dringend raten, Daten und Code zu trennen.

    Matthias



  • Auch ohne ASLR ist es Zufall.



  • Matthias G. schrieb:

    ... wird hier wohl ASLR sein. ...
    Das ist ein Sicherheitsfeature und gibt es _auch_ unter aktuellen Linuxen 😃

    Bei FreeBSD scheint Shared-Memory nicht mit ASLR geschützt zu sein. Auch in der aktuellsten Version nicht ...

    https://wiki.freebsd.org/AddressSpaceLayoutRandomization



  • @Matthias G., Mechanics, merano:
    ASLR kann man in in visual cpp 2010 mit der Linkeroption /DYNAMICBASE:NO und mit /FIXED abschalten.
    Trotzdem tritt der Fehler bei Windows 7 Professional, 64 Bit, Service Pack 1
    noch auf.

    Hier der Programmcode

    Prozess 1:
    --------------

    #include <windows.h>
    #include <stdio.h>
    #include <conio.h>
    #include <new>
    #include <sys/stat.h>
    #include "..\..\include\classA.h"

    #include <new>

    int main()
    {
    DWORD lastError (0);

    HANDLE mapFileHdl (CreateFileMapping(
    INVALID_HANDLE_VALUE, // use paging file
    NULL, // default security
    PAGE_EXECUTE_READWRITE, // read/write/execute access
    0, // maximum object size
    sizeof A1, // maximum object size
    mappingFileName)); // name of mapping object

    if (mapFileHdl == NULL)
    {
    lastError = GetLastError();
    printf("CreateFileMapping(...) war nicht erfolgreich, GetLastError() = (%d).\n", lastError);

    return 1;
    }

    # ifdef FIXEDMAPPING
    void (*pBuffer) (MapViewOfFileEx (mapFileHdl, FILE_MAP_ALL_ACCESS,
    0, 0, 0, (void *)GLOBMEMBASEADDRESSE));
    # else
    void (*pBuffer) (MapViewOfFile (mapFileHdl, FILE_MAP_ALL_ACCESS,
    0, 0, 0));
    # endif

    if (pBuffer == NULL)
    {
    lastError = GetLastError();
    printf("MapViewOfFile(...) war nicht erfolgreich, GetLastError() = (%d).\n", lastError);

    CloseHandle(mapFileHdl);

    return 1;
    }

    A1 a1;
    A0 (*pA00)(&a1);
    pA00->SetId(1);

    memset (pBuffer, 0x99, sizeof (A1));
    *(void **) pBuffer = 0L;
    A0 (*pA0) (new (pBuffer) A1(&a1));
    pA0->SetId(-1);
    __int64 id (pA0->GetId());

    A1 xx,yy,zz;

    int c (_getch());

    UnmapViewOfFile(pBuffer);

    CloseHandle(mapFileHdl);

    return 0;
    }

    Prozess 2:
    --------------

    #include <windows.h>
    #include <stdio.h>
    #include "..\..\include\classA.h"

    int main()
    {
    DWORD lastError(0);

    HANDLE mapFileHdl (OpenFileMapping(
    FILE_MAP_ALL_ACCESS, // read/write access
    FALSE, // do not inherit the name
    mappingFileName)); // name of mapping object

    if (mapFileHdl == NULL)
    {
    lastError = GetLastError();
    printf("OpenFileMapping(...) war nicht erfolgreich, GetLastError() = (%d).\n", lastError);

    return 1;
    }

    # ifdef FIXEDMAPPING
    void (*pBuffer) (MapViewOfFileEx (mapFileHdl, FILE_MAP_ALL_ACCESS,
    0, 0, 0, (void *)GLOBMEMBASEADDRESSE));
    # else
    void (*pBuffer) (MapViewOfFile (mapFileHdl, FILE_MAP_ALL_ACCESS,
    0, 0, 0));
    # endif

    if (pBuffer == NULL)
    {
    lastError = GetLastError();
    printf("MapViewOfFile(...) war nicht erfolgreich, GetLastError() = (%d).\n", lastError);

    CloseHandle(mapFileHdl);

    return 1;
    }

    A0 (*pA0) ((A0 😉 (pBuffer));
    __int64 id0 (pA0->GetId());

    UnmapViewOfFile(pBuffer);

    CloseHandle(mappingFileName);

    return 0;

    gemeinsames Includefile classA.h:
    ------------------------

    //#define FIXEDMAPPING
    #define GLOBMEMBASEADDRESSE 0x52000000

    char mappingFileName[]=("mappingFileName");

    class A0
    {
    public:
    A0() {}
    virtual __int64 GetId() = 0;
    virtual void SetId(__int64 i) = 0;
    };

    class A1 : public A0
    {
    private:
    __int64 i;
    public:
    A1()
    :A0(),
    i(0)
    {
    };

    A1(A1 *pa)
    :A0(),
    i(pa->i)
    {
    };

    A1(A1 &ra)
    :A0(),
    i(ra.i)
    {
    };

    void SetId(__int64 id)
    {
    i = id;
    }
    __int64 GetId()
    {
    return i;
    }
    };


Anmelden zum Antworten