Bir süreçten hafıza okumaya ne dersiniz? İşletim sisteminden farklı mı?


11

Deneyimli bir web geliştirici, ama acemi bir "düşük seviye" programcı olarak, bu şeyler hala bana bir tür vudu.

Bir kişinin nasıl bir hafıza bloğu bulup sonra okumaya başlayacağını merak ediyorum (örneğin, bir mayın oyununda zamanlayıcıyı okumak)? Bu OS / OS sürümüne göre farklı mı?

Yanıtlar:


14

Bu biraz zor ve hatta karmaşık bir sorudur, bir anlamda bununla çok derine inebilirsiniz. Ancak işleri biraz basitleştirmek için:

" Bir mayın oyununda zamanlayıcıyı okuma " örneğini göz önünde bulundurarak :

İlk adım bellek adresini bulmaktır . Bu genellikle , işlem belleğindeki bir değişkenin konumunu bulmak için çeşitli yöntemler kullanabilen bellek düzenleyicisi (bazı durumlarda hata ayıklayıcı da yapar) adlı bir araçla yapılır . Genel yöntem, hedef işlemin bellek alanında belirli bir değeri (örneğin zamanlayıcının değerini) aramak, sonra hedef değeri değiştirmek (örn. Zamanlayıcıyı ilerletmek) ve eşleşmeleri tekrar aramaktır. Bu süreç, yalnızca tam değişken kalana kadar adayları her yinelemede sabitler. Bu değişkenin adresini işlemin bellek alanı içine almak, bir bellek düzenleyicisiyle sadece bir fare tıklaması meselesidir.

İkinci adım, söz konusu adresteki verileri değiştirmektir . Bunun nasıl yapılacağı işletim sistemine bağlıdır. İle Windows'un adında bir WinAPI arama var WriteProcessMemoryhedef süreci bellek alanı içinde belirli bir adrese yazma önceden tanımlanmış veri kullanılabilir. Örneğimizde, hedef süreçteki zamanlayıcı değişkenini kendi istediğiniz değerinizle üzerine yazmak ve oyunda zamanlayıcıyı etkili bir şekilde değiştirmek için bu işlevi kullanabilirsiniz.

Uygulamada, hedef işlemin işlem kimliğini bulmanız ve ardından bellek alanını değiştirme yeteneği kazanmak için hileli işleminizi hedef sürece eklemeniz gerekir . Bu oldukça önemsiz bir görev, ama soruyu cevaplamaya katkıda bulunmuyor, bu yüzden onu okuyucuya bir egzersiz olarak bıraktım. ;)


Süreç her çalıştırıldığında değişkenin konumu aynı mı olacak?
brunoqc

1
@brunoqc Hayır, neredeyse kesin olarak değil.
Dan

2

İşletim sisteminden tamamen farklı. Bazıları bunu yapmanıza izin vermez ve istediğiniz verilerin hedefin bellek alanında nerede olduğunu bilmek için bazı araçlara sahip olmanız gerekir.

Linux'ta şu şekilde yapabilirsiniz: /unix/6301/how-do-i-read-from-proc-pid-mem-under-linux


hangi işletim sistemi buna izin vermiyor? Görünüşe göre Linux ve Windows altında yapabilirsiniz
Eva

@Evan Her işletim sistemi , hata ayıklama amacıyla uzaktan işlem belleği değişikliğine izin verilmesi (güvenlik nedeniyle kısıtlanmış) araçlara izin vermelidir. Ancak, güvenlik nedenlerinden ötürü ayrıcalık uyumsuzluklarının, daha yüksek ayrıcalıklı bir işlemin işlem belleğini okuyamaması / yazamamasına neden olabileceğini unutmayın. Buna iyi bir örnek, konuk kullanıcı ayrıcalıklarına sahip bir işlemin yönetici haklarına sahip bir işlemin belleğini okuma / yazma izni vermemesidir, çünkü bu durum tüm sistemin güvenliğini tehlikeye atabilir ve konuk kullanıcının yönetici ayrıcalıkları kazanması için doğrudan bir yol olabilir. sistemi.
zxcdw

1

Bir uygulamaya işletim sistemi tarafından bir dizi bellek verilir. Genellikle, uygulamanın belleği istemesi gerekir, ancak dil nedeniyle bu işlevsellik programcıya gizlenebilir.

C gibi diller, belirli boyutlar için engelleme isteklerine izin verirken C ++, C # ve Java gibi diğer diller, gibi anahtar kelimeler kullanılarak isteklere izin verir new. Her dilin bellek ayırmanın birkaç yolu vardır, bu yüzden bu sadece kısa bir genel bakıştır. Belleği işletim sistemine geri bırakmak açık bir şekilde veya bir çöp toplayıcıyla yapılabilir.

Uygulama içindeki belleğe erişim, nasıl tahsis edildiğine bağlıdır. C ve C ++, belleğin bulunduğu yeri göstermek / izlemek için işaretçi kavramını kullanmak için en iyi bilinen yöntemdir. Aksi takdirde, bellek erişimi oluşturulan sınıf veya değişken aracılığıyla işlenir.

Çoğu zaman, programınızdaki belirli bellek erişimi hakkında endişelenmenize gerek yoktur. Dil yapıları ve işletim sistemi sizin için bu endişeyi etkili bir şekilde gizler.

Bir oyundaki zamanlayıcı örneğiniz, temeldeki bellek ayırma konusunda endişelenmenize gerek kalmayacağının harika bir örneğidir. Zamanlayıcıyı temsil eden bir değişkeniniz olacak ve değişkenden yeni okuyacaksınız.

Cevabım, uygulamayı yazarken, zxcdw'nin yanıtı başka bir uygulamaya ait belleğe erişmek için geçerlidir. LMGTFY terimleriniz bu konuyu daha ayrıntılı incelemek için "hata ayıklama" ve "tersine mühendislik" olacaktır.

Bazı ek okumalar:

  • Bilgisayar Belleği hakkındaki Wikipedia makalesi, size şeylere iyi bir genel bakış sunacaktır.
  • Ardından , devam eden işlemlerle ilgili daha derin bir anlayış elde etmek için Bellek eşlemeli G / Ç hakkındaki Wikipedia makalesine bakın .
  • Son olarak, her işletim sisteminin bellek eşlemesini diğerlerinden biraz farklı şekilde nasıl ele alacağına dair daha iyi bir yanıt almak için Sanal Bellek makalesine bakın .

mükemmel cevap, ancak evet, bu durumda daha çok kendim yazmadığım bir uygulamadan bellek okumakla ilgileniyorum. 15 temsil edeceğim anda oy vereceğim;)
Eva

@Evan - kesinlikle Sanal Bellek hakkındaki makaleyi okuyun. Bu, devam eden haritalamayı daha iyi anlamanıza yardımcı olur. Bir uygulamayı ayırmak için haritalamayı anlamalısınız. Çoğu hata ayıklayıcı, uygulamanın talimatlarını ve belleğini görmenizi sağlayan çalışan bir sürece bağlanmanıza izin verir.
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.