2012-10-09 16 views
6

Nota prawna: Jestem nowy w C/C++.Czy mogę uzyskać dostęp do czegokolwiek w pamięci?

Gdybym manually assign a memory address do zmiennej w C, a następnie spróbuj powtórzyć się, że wartość ... mam nieograniczony dostęp do wyświetlenia nic w pamięci czy istnieją ograniczenia w miejscu?

Na przykład:

char * p = (char *)0x28ff44; 
printf("Memory value: %c", *p); 

Zgaduję, że będzie katastrofy potwornie jeśli to, co było pod tym adresem nie pasuje do rozmiaru typu char, ale to tylko przykład. Naprawdę ciekawi mnie, czy coś takiego jest możliwe, czy systemy operacyjne nakładają ograniczenia i pozwalają tylko na dostęp do pamięci w danej pamięci?

+1

Możesz znaleźć interesujące informacje na inne pytanie dotyczące przepełnienia stosu: http://superuser.com/questions/189876/how-os-detects-memory-access-violations – fycth

+0

Wow, dzięki za wszystkie wspaniałe odpowiedzi. Pamiętam, jak próbowałem nauczyć się powrotu do liceum (około 10 lat temu, jak sądzę) i wydaje mi się, że pamiętam, że w czasie, gdy się bawiłem, zwykle istniało jedno miejsce w pamięci i mogły się w nim pojawić problemy. Dobrze jest widzieć, że teraz jest więcej ochrony dla noobów niskiego poziomu, takich jak ja. –

+1

Nota boczna, '% s' jest nieprawidłowym łańcuchem formatu dla pojedynczego znaku, potrzebujesz'% c';) – slugonamission

Odpowiedz

5

O mój, dobrze.

Technicznie, tak, możesz. W urządzeniach wbudowanych, które nie korzystają z MMU lub jakiejkolwiek formy ochrony (lub, wiesz, x86 w trybie rzeczywistym), możesz zrobić dokładnie to, co tam zamieściłeś. Możesz także zrobić to w trybie użytkownika w dowolnym systemie operacyjnym, ale szanse na trafienie w prawidłową pamięć są bardzo małe.

W rzeczywistości nie, nie można tak po prostu zrobić. Biorąc pod uwagę pamięć wirtualną i ochronę pamięci, jest bardzo prawdopodobne, że region, do którego próbujesz uzyskać dostęp, nie został zmapowany, a zatem nie powiedzie się. Ponadto, jeśli trafisz na pamięć chronioną (np. Wszystko, co należy do systemu operacyjnego), twój dostęp się nie powiedzie. Oba te scenariusze powodują błędy segmentacji.

Twoje oświadczenie jest ważne (dla różnych definicji ważnych), a program spróbuje uzyskać dostęp do żądanej pamięci. Chodzi o to, że w rzeczywistości nie można go zmapować na nic.

Warto również zauważyć, że tak działa pamięć I/O z mapowaniem pamięci. Załóżmy, że mam rejestr kontroli sprzętu, który po zapisaniu, zapisuje bajt na dołączonej linii UART/serial (i dla uproszczenia działa jak magia i nie wymaga ustawiania innych rejestrów). W C, to byłoby napisane w następujący sposób dla mojego nadmiernie uproszczonego urządzenia:

#define UART1_OUT 0xFC56 

volatile char* uart = UART1_OUT; // Definition of pointer to variable. 
            // volatile is required here. Look it up, but 
            // it basically stops your compiler optimising 
            // anything to do with this variable 

*uart = 'A';      // Write an A character to the serial line 

Oczywiście, urządzenia rzeczywistego świata są nieco bardziej skomplikowane).

+0

Myślę, że musisz wpisać wartość adresu, inaczej kompilator da błąd. –

+0

Nie, jest to domyślnie ostrzeżenie w GCC. Nie jestem pewien co do Visual C i Clang. – slugonamission

2

Zależy to od architektury komputera i systemu operacyjnego, w których działa program. Współczesne systemy operacyjne mają koncepcję pamięci protected i virtual. W przypadku pamięci wirtualnej adresy pamięci nie odnoszą się do pamięci fizycznej, lecz do wirtualnej przestrzeni pamięci przypisanej do bieżącej aplikacji. Próba odczytania lub zapisania w pamięci poza przydzielonym obszarem pamięci spowoduje w takich przypadkach błąd programu (generalnie błąd segmentacji lub błąd ochrony).

+0

Więc niektóre systemy operacyjne pozwalają na takie rażące wtargnięcie do przestrzeni pamięci innych aplikacji i/lub samego systemu operacyjnego? –

+0

http://en.wikipedia.org/wiki/Memory_protection – wroniasty

+0

Ah ok. Czy w przypadku pamięci wirtualnej nie mogłem "przypadkowo" zawiesić innych programów lub systemu operacyjnego? –

1

Systemy z modułem zarządzania pamięcią (MMU) bardzo często nie pozwalają na dostęp do dowolnej pamięci. Każdy nowoczesny system operacyjny wykorzystuje ochronę pamięci. Ale w sektorze wbudowanym istnieje wiele systemów operacyjnych, które nie wykorzystują ochrony pamięci i gdzie rzeczywiście można uzyskać dostęp do pamięci z ustawieniami adresowymi.

1

Gdybym ręcznie przypisać adres pamięci do zmiennej w C, a następnie spróbuj echo się, że wartość ... mam nieograniczony dostęp do zobaczyć coś w pamięci czy istnieją ograniczenia w miejscu ?

Język C z przyjemnością pozwoli ci to wypróbować, ale większość systemów operacyjnych nie pozwoli ci uzyskać dostępu do pamięci poza pamięcią Twojego procesu. Jeśli piszesz kod systemu wbudowanego, w którym między kodem a sprzętem nie ma zbyt wiele, prawdopodobnie będziesz mógł czytać i pisać w dowolnej lokalizacji. Jeśli jednak piszesz kod dla systemu z chronioną pamięcią, to nie tak bardzo.

Zgaduję, że będzie katastrofy potwornie jeśli to, co było pod tym adresem nie pasuje do rozmiaru typu char

Nah ... kompilator nie obchodzi, jaki typ danych jest przechowywany pod dowolnym adresem. Kiedy mówisz, że (char *)0x28ff44 mówisz, że 0x28ff44 jest char *, i to jest wystarczająco dobre dla kompilatora. Twój kod może się jednak zawiesić z innych powodów, np. Jeśli 0x28ff44 nie jest prawidłowym adresem.

Powiązane problemy