Modyfikacja VMT a czyszczenie cache kodu

0

Znalazłem takie zabawne próby podstawiania virtualnych funkcji:
https://en.delphipraxis.net/topic/1922-patch-a-private-virtual-method/

oni próbują tam modyfikować bezpośrednio tablicę wirtualnych funkcji w danej klasie: VMT

Potem tam ktoś sugeruje że trzeba wyczyścić cache kodu: FlushInstructionCache

Od kiedy modyfikacja adresu, ma coś wspólnego z kodem?
Przecież to jest zwyczajna tablica wskaźników - segment danych, a nie kodu.

VMT[i] := mypointertomethod

i tyle z tym roboty.

0
nowewww napisał(a):

Znalazłem takie zabawne próby podstawiania virtualnych funkcji:
https://en.delphipraxis.net/topic/1922-patch-a-private-virtual-method/

To co zostało opisane działa w praktyce, bo ma prawo działać.

Potem tam ktoś sugeruje że trzeba wyczyścić cache kodu: FlushInstructionCache

Od kiedy modyfikacja adresu, ma coś wspólnego z kodem?

Od kiedy w grę wchodzi cache'owanie. Zmiana wskaźnika nic nie zmieni, jeśli instrukcje będą wykonywane z pamięci podręcznej. Hooki w ten sposób działają (pogooglaj a znajdziesz), więc obstawiam, że jest to konieczne i bez tego taka podmianka nie będzie działać (lub zadziała na niektórych konfiguracjach).

Zobacz na ten wątek – Kombinowanie z TypInfo i propertysami – jest w nim wyjaśnienie:

Ta funkcja służy mi głównie do podmieniania kodu, dlatego dodatkowo FlushInstructionCache(), żeby CPU zobaczył nowy kod.

0

Adresy do funkcji są powszechnie, zawsze używane.
Nie ma to nic z wspólnego z instructionCache.

Gdyby tak było to przed wywołaniem dowolnej funkcji należałoby czyścić ten cache.

FlushInstructionCache()
fun(x);
FlushInstructionCache()
gun(y);
FlushInstructionCache()
print;
FlushInstructionCache()
y := sin(x);

p = @sin;

FlushInstructionCache()
z = p(x);
0
nowewww napisał(a):

Gdyby tak było to przed wywołaniem dowolnej funkcji należałoby czyścić ten cache.

Nie. Jeśli pamięć procesu nie została zmodyfikowana w ramach jednej sesji, to cache procesora jest cały czas ważny i nie ma powodu, by go czyścić i budować od nowa.

W sumie to nie wiem po co tracisz czas na ten wątek – otwórz Delphi, napisz trochę kodu i sprawdź czy modyfikacja adresu w VMT w jakikolwiek sposób wpłynie na działanie programu, czy faktycznie CPU nie zauważy tej podmiany i wykona kod z pamięci podręcznej.

0

Po co miałby testować sprawy oczywiste?
Tablice funkcji stosowano o zawsze, np. w zwykłym c realizowano w ten sposób
to co obecnie nazywa się programowaniem obiektowym - polimorfizm, itd.

Adres funkcji na pewno nie koliduje z cache kodu;
chyba że w 'nowoczesnych' procesorach projektowanych przez 'mistrzów' tak jest, albo będzie wkrótce:
super ochrona systemu operacyjnego przed próbą zaprogramowania czegokolwiek. :)

0
nowewww napisał(a):

Po co miałby testować sprawy oczywiste?

Oczywiste, ale najwyraźniej nie dla ciebie.

Tablice funkcji stosowano o zawsze, np. w zwykłym c realizowano w ten sposób
to co obecnie nazywa się programowaniem obiektowym - polimorfizm, itd.

Jak chcesz komuś zaimponować wiedzą, to musisz się bardziej postarać, bo takie banały nie robią na nikim wrażenia.

Adres funkcji na pewno nie koliduje z cache kodu;

Na pewno nie koliduje, a wszyscy używają flusha dla hecy.

chyba że w 'nowoczesnych' procesorach projektowanych przez 'mistrzów' tak jest, albo będzie wkrótce:
super ochrona systemu operacyjnego przed próbą zaprogramowania czegokolwiek. :)

Wróć lepiej do pisania tych swoich stron w C++ i nie marnuj mojego czasu, dzieciaku.

1 użytkowników online, w tym zalogowanych: 0, gości: 1