2008-08-14 23 views
16

मै मैक ओएस एक्स पर अन्य प्रक्रियाओं की स्मृति को पढ़ने के तरीके को समझने की कोशिश कर रहा हूं, लेकिन मुझे बहुत भाग्य नहीं है। मैंने ptracePEEKDATA के साथ 10 का उपयोग करके ऑनलाइन कई उदाहरण देखे हैं और ऐसे में, हालांकि इसमें बीएसडी [man ptrace] पर यह विकल्प नहीं है।ओएस एक्स में अन्य प्रक्रिया 'मेमोरी पढ़ना?

int pid = fork(); 
if (pid > 0) { 
    // mess around with child-process's memory 
} 

मैक ओएस एक्स पर किसी अन्य प्रक्रिया की स्मृति को पढ़ने और लिखना कैसे संभव है?

+1

मुझे विशेष रूप से उस मामले में दिलचस्पी है जहां मैं दूसरी प्रक्रिया को नियंत्रित नहीं करता हूं - यानी यह देखने के लिए कि यह क्या कर रहा है, किसी और के कार्यक्रम के अंदर घूम रहा है। (संभावित रूप से [एएसएलआर को अक्षम करने के बाद] (http://stackoverflow.com/questions/6325537/disabling-aslr-in-mac-os-x-now-leopard)।) –

+0

मुझे समझ में नहीं आता कि आप किस प्रक्रिया का हिस्सा हैं पढ़ना चाहते हैं। क्या आप कोर डंप फाइलों के रूप में दीवार प्रक्रिया पता स्थान प्राप्त करने के लिए करते हैं? आपको धागे और (कभी-कभी) साझा पुस्तकालयों को संभालने के लिए कोड की आवश्यकता होती है। उदाहरण के लिए राम में प्रोग्राम बाइनरी को देखने के लिए आपको (ज्यादातर) इस कोड की आवश्यकता नहीं है। – user2284570

+0

@ user2284570 मुझे एक प्रक्रिया की कामकाजी स्मृति को देखने या छेड़छाड़ करने में दिलचस्पी है, निष्पादन योग्य कोड नहीं। –

उत्तर

9

मटासैनो चार्जन ने कुछ समय पहले ओएस एक्स को कुछ डीबगिंग कोड पोर्ट करने पर एक अच्छी पोस्ट की थी, जिसमें सीखना था कि कैसे एक और प्रक्रिया (अन्य चीजों के साथ) में स्मृति को पढ़ने और लिखना सीखना शामिल है।

It has to work, otherwise GDB wouldn't:

यह पता चला एप्पल, उनके अनंत ज्ञान में, ptrace() निराश था। ओएस एक्स आदमी पेज निम्नलिखित अनुरोध कोड को सूचीबद्ध करता है:

  • PT_ATTACH - एक प्रक्रिया लेने के लिए
  • PT_DENY_ATTACH डिबग करने के लिए - तो प्रक्रियाओं डिबग किया जा रहा से खुद को रोक सकता है
    [...]

मेमोरी या रजिस्टरों को पढ़ने या लिखने का कोई उल्लेख नहीं है। जो मैन पेज ने PT_GETREGS, PT_SETREGS, PT_GETFPREGS, और PT_SETFPREGS त्रुटि कोड अनुभाग में भी उल्लेख नहीं किया था, जो निराशाजनक होता। इसलिए, मैंने ptrace.h चेक किया। वहाँ मैंने पाया:

  • PT_READ_I - पढ़ने के लिए डेटा शब्द
  • PT_READ_U - - अनुदेश शब्द
  • PT_READ_D पढ़ने के लिए यू क्षेत्र डेटा पढ़ने के लिए अगर आप काफी पुरानी याद करने के लिए क्या कर रहे हैं यू क्षेत्र
    है [...]

एक समस्या हल हो गई है। मैं ब्रेकपॉइंट्स के लिए मेमोरी पढ़ और लिख सकता हूं। लेकिन मुझे अभी भी रजिस्टरों तक पहुंच नहीं मिल सकती है, और मुझे ईआईपी के साथ गड़बड़ करने में सक्षम होना चाहिए।

0

अपनी पीठ के पीछे एक प्रक्रिया की याददाश्त में छेड़छाड़ करना एक बुरी बात है और खतरे से भरा हुआ है। यही कारण है कि मैक ओएस एक्स (किसी भी यूनिक्स सिस्टम की तरह) ने स्मृति की रक्षा की है, और प्रक्रियाओं को एक-दूसरे से अलग रखती है।

बेशक यह किया जा सकता है: स्पष्ट रूप से सहयोग करने वाली प्रक्रियाओं के बीच साझा स्मृति के लिए सुविधाएं हैं। अन्य प्रक्रियाओं के पते की जगहों में हेरफेर करने के तरीके भी हैं जब तक कि प्रक्रिया करने के लिए ऐसा करने का स्पष्ट अधिकार है (जैसा कि सुरक्षा ढांचे द्वारा दिया गया है)। लेकिन यह उन लोगों के लिए है जो उपयोग करने के लिए डिबगिंग टूल लिख रहे हैं। मैक ओएस एक्स

+0

मुझे लगता है कि आप बहुत सी सुनते हैं 'कृपया सीट लें .. 'चुटकुले टाइप करें, है ना? : पी – horseyguy

11

task_for_pid() या लक्ष्य प्रक्रिया के कार्य पोर्ट को प्राप्त करने के लिए अन्य विधियों का उपयोग करें, यह ऐसा कुछ नहीं है जो सामान्य या दुर्लभ हो। उसके बाद, आप सीधे vm_read(), vm_write(), और अन्य का उपयोग कर प्रक्रिया की पता स्थान में हेरफेर कर सकते हैं।

+0

'vm_remap' भी है जो आपको एक विदेशी प्रक्रिया मेमोरी को अपने स्वयं के वीएम में मैप करने की अनुमति देगा। –

+0

प्रक्रिया 'कार्य बंदरगाह प्राप्त करने के बाद, मैं अपना पता स्थान कैसे प्राप्त करूं? और मैं एक विशिष्ट स्ट्रिंग के लिए पता स्थान में आगे कैसे खोजूं? क्या आप एक उदाहरण दे सकते हैं? – snakeninny

5

यह आप प्रक्रियाओं के बीच स्मृति के भाग साझा करने में सक्षम होने के लिए देख रहे हैं, तो आपको shm_open (2) और mmap (2) देखना चाहिए। एक प्रक्रिया में स्मृति का एक हिस्सा आवंटित करना बहुत आसान है और पथ (shm_open के लिए) को दूसरे में पारित करना और दोनों एक साथ पागल हो सकते हैं। क्रिस हैनसन का उल्लेख है कि यह किसी अन्य प्रक्रिया के पता स्थान में चारों ओर घूमने से कहीं अधिक सुरक्षित है। बेशक, यदि आपके पास दोनों प्रक्रियाओं पर नियंत्रण नहीं है, तो यह आपको बहुत अच्छा नहीं करेगा।

(ध्यान रखें कि shm_open के लिए अधिकतम पथ लंबाई 26 बाइट्स प्रतीत होता हो, हालांकि यह कहीं भी प्रलेखित किया जाना प्रतीत नहीं होता।)

// Create shared memory block 
void* sharedMemory = NULL; 
size_t shmemSize = 123456; 
const char* shmName = "mySharedMemPath";   
int shFD = shm_open(shmName, (O_CREAT | O_EXCL | O_RDWR), 0600); 
if (shFD >= 0) { 
    if (ftruncate(shFD, shmemSize) == 0) { 
     sharedMemory = mmap(NULL, shmemSize, (PROT_READ | PROT_WRITE), MAP_SHARED, shFD, 0); 
     if (sharedMemory != MAP_FAILED) { 
      // Initialize shared memory if needed 
      // Send 'shmemSize' & 'shmemSize' to other process(es) 
     } else handle error 
    } else handle error 
    close(shFD);  // Note: sharedMemory still valid until munmap() called 
} else handle error 

... 
Do stuff with shared memory 
... 

// Tear down shared memory 
if (sharedMemory != NULL) munmap(sharedMemory, shmemSize); 
if (shFD >= 0) shm_unlink(shmName); 





// Get the shared memory block from another process 
void* sharedMemory = NULL; 
size_t shmemSize = 123456;    // Or fetched via some other form of IPC 
const char* shmName = "mySharedMemPath";// Or fetched via some other form of IPC 
int shFD = shm_open(shmName, (O_RDONLY), 0600); // Can be R/W if you want 
if (shFD >= 0) { 
    data = mmap(NULL, shmemSize, PROT_READ, MAP_SHARED, shFD, 0); 
    if (data != MAP_FAILED) { 
     // Check shared memory for validity 
    } else handle error 
    close(shFD);  // Note: sharedMemory still valid until munmap() called 
} else handle error 


... 
Do stuff with shared memory 
... 

// Tear down shared memory 
if (sharedMemory != NULL) munmap(sharedMemory, shmemSize); 
// Only the creator should shm_unlink() 
+3

shm_open के उपयोग पर कई प्रतिबंध हैं; पथ की लंबाई के मुद्दे के अलावा, मैकोज़क्स जहाज एक कर्नेल राज्य सेटिंग के साथ है जो प्रक्रिया की साझा मेमोरी के आकार को 4 एमबी तक सीमित करता है। आप कमांड लाइन पर 'sysctl -A' निष्पादित करके और 'kern.sysv.shmmax' खोजकर इस सेटिंग को देख सकते हैं। – fixermark

+0

बिल्कुल नहीं, ऐसा लगता है कि ~ 4 एमबी सीमा केवल सिस्टम वी आईपीसी ftok/shmget/shmat funtions को प्रभावित करती है, यदि आप POSIX shm_open/ftruncate/mmap समाधान (ऊपर वर्णित) का उपयोग कर रहे हैं तो सीमा लगभग 16 एमबी (!) हो सकती है। (शायद कर्नेल के आधार पर) हम समस्याओं के बिना ओएसएक्स 10.5-10.9 (पहले भी 10.4 पर) पर 16 एमबी ब्लॉक का उपयोग कर रहे हैं। – Hofi

1

सामान्य तौर पर, मैं सुझाव है कि आप नियमित रूप से खुला का उपयोग() एक अस्थायी फ़ाइल खोलने के लिए। एक बार यह दोनों प्रक्रियाओं में खुलने के बाद, आप इसे फाइल सिस्टम से अनलिंक कर सकते हैं और आप जैसे ही आप shm_open का उपयोग करेंगे, उतना ही स्थापित किया जाएगा। प्रक्रिया shm_open के लिए स्कॉट मार्सी द्वारा निर्दिष्ट एक के समान ही है।

इस दृष्टिकोण का नुकसान यह है कि यदि प्रक्रिया अनलिंक() क्रैश कर रही है, तो आप एक अप्रयुक्त फ़ाइल के साथ समाप्त हो जाते हैं और किसी भी प्रक्रिया को इसे साफ करने की ज़िम्मेदारी नहीं है। यह नुकसान shm_open के साथ साझा किया जाता है, क्योंकि यदि किसी दिए गए नाम को shm_unlinks कुछ भी नहीं है, तो नाम साझा मेमोरी स्पेस में रहता है, जो भविष्य की प्रक्रियाओं द्वारा shm_opened होने के लिए उपलब्ध है।

1

आप साझा मेमोरी विधि के साथ इंटर-प्रोसेस-संचार करना चाहते हैं। अन्य कॉमन्स विधि का एक सारांश के लिए, here

यह मुझे लंबे समय तक नहीं लिया क्या आप इस book में की जरूरत है जो सभी API जो आज (जो कई की तुलना में अधिक मैंने सोचा) सभी UNIXes के लिए आम हैं शामिल हैं खोजने के लिए देखते हैं। आपको इसे भविष्य में खरीदना चाहिए। यह पुस्तक (कई सौ) मुद्रित मैन पेजों का एक सेट है जो आधुनिक मशीनों पर शायद ही कभी स्थापित हैं। प्रत्येक मैन पेज एक सी समारोह का विवरण देता है।

यह मेरे समय लगेगा Shmat()shmctl() खोजने के लिए नहीं किया था; shmdt() और shmget() इसमें। मैंने बड़े पैमाने पर खोज नहीं की, शायद और भी कुछ है।

यह थोड़ा पुराना दिखता था, लेकिन: हाँ, आधुनिक यूनिक्स ओएस का मूल उपयोगकर्ता-स्थान एपीआई पुराना 80 के दशक में वापस आ गया।

अद्यतन: पुस्तक में वर्णित अधिकांश फ़ंक्शन POSIX C शीर्षलेख का हिस्सा हैं, आपको कुछ भी इंस्टॉल करने की आवश्यकता नहीं है। कुछ अपवाद हैं, जैसे कि "शाप", मूल पुस्तकालय।

+0

@ जेरेमीबैंक्स मुझे आपकी टिप्पणी के साथ एक और जवाब लिखने की ज़रूरत है, लेकिन मेरे पास कुछ प्रश्न हैं: क्या आप जानते हैं कि उपयोगकर्ता प्रक्रिया बिंदु से वर्चुअल एड्रेसिंग क्या है (नोट: विकिपीडिया इस बारे में वास्तविक स्पष्टीकरण नहीं देता है)? क्या आप प्रक्रिया अलगाव और आईपीसी से कैसे निपटते हैं? यह * मेमोरी स्पेस अलगाव * देने के लिए ओएस की आधार सेवा है: कल्पना करें कि व्यवस्थापक अधिकारों के बिना चल रही प्रक्रिया किसी अन्य प्रक्रिया पर अनएन्क्रिप्टेड पासवर्ड पढ़ सकती है। [Ring0] में एक ड्राइवर को लॉन्च करना (https://en.wikipedia.org/ विकी/रिंग_ (computer_security)) इसे प्राप्त करने के लिए समुद्री डाकू का लक्ष्य था। – user2284570

+0

@ जेरेमीबैंक्स: कुछ ऐसा है जो मैं भूल गया: हाँ आप इसे/dev/mem और/dev/kmem कर सकते हैं, लेकिन मैक ओएस एक्स के x86 संस्करण के साथ शुरुआत करते हुए, सेब ने उन उपकरणों को सुरक्षा सहित कई कारणों से हटा दिया। लिनक्स ने कॉन्फ़िगर संकलन समय विकल्प के साथ कुछ ऐसा किया जो अधिकांश लिनक्स डाइट्रो सक्षम है: यह/dev/mem (रूट के लिए भी) की पूर्ण पहुंच को अक्षम करता है और इसे केवल पतों प्रोग्राम (जैसे Xorg) उपयोगों तक सीमित करता है। – user2284570

+0

मुझे आधुनिक ऑपरेटिंग सिस्टम में यह कैसे काम करता है, इस बारे में जानकारी जानने के लिए वर्चुअल मेमोरी के बारे में पर्याप्त जानकारी नहीं है, लेकिन मैं समझता हूं कि यह स्मृति अलगाव का उल्लंघन करता है और यदि संभव हो तो व्यवस्थापक अधिकारों की आवश्यकता होगी। मैं एक सी प्रोग्राम में 'स्थिर int' को संशोधित करने का सबसे सरल मामला इमेजिंग कर रहा था, जो (शायद?) को उसी स्मृति स्थान पर असाइन किया जाएगा, या जो किसी भी तरह से स्थित हो सकता है। मैं कल्पना करता हूं कि इस तरह के खेल बॉट जो गेम के राज्य में दिखते हैं, काम कर सकते हैं। अगर यह संभव था तो मुझे पूरी तरह से यकीन नहीं था। –

2

मुझे निश्चित रूप से आपको आवश्यकतानुसार एक छोटा कार्यान्वयन मिला है (केवल एक स्रोत फ़ाइल (main.c))। यह विशेष रूप से एक्सएनयू के लिए डिज़ाइन किया गया है।

यह

साथ निम्नांकित खोजशब्दों «डंप प्रक्रिया स्मृति ओएस एक्स» गूगल खोज के शीर्ष दस परिणाम में है स्रोत कोड here

लेकिन है वर्चुअल ऐड्रेस स्पेस बिंदु डी Vue के एक सख्त बिंदु से आप इस सवाल के साथ अधिक रुचि होना चाहिए: OS X: Generate core dump without bringing down the process? (यह भी देखने this)

आप gcore स्रोत कोड को देखते हैं, यह काफी यह करने के लिए जटिल है क्योंकि आप ट्रेड्स और उनके राज्य के साथ सौदा करने की आवश्यकता है ...

अधिकांश लिनक्स वितरण पर, गकोर प्रोग्राम अब जीडीबी पैकेज का हिस्सा है। मुझे लगता है कि ओएसएक्स संस्करण एक्सकोड/विकास उपकरण के साथ स्थापित है।

अद्यतन: wxHexEditor एक संपादक है जो डिवाइस संपादित कर सकता है। यह नियमित रूप से फ़ाइलों के लिए प्रक्रिया मेमोरी को उसी तरह संपादित भी कर सकता है। यह सभी यूनिक्स मशीनों पर काम करता है।

+0

ब्याज सामान, मैं एक नज़र रखूंगा। धन्यवाद। –

4

मैं जानता हूँ कि इस सूत्र 100 साल पुराना है, लेकिन एक खोज इंजन से यहाँ आने के लिए लोगों को:

xnumem वास्तव में आप के लिए क्या देख रहे है, हेरफेर और अंतर-प्रक्रिया स्मृति पढ़ें।

// Create new xnu_proc instance 
xnu_proc *Process = new xnu_proc(); 

// Attach to pid (or process name) 
Process->Attach(getpid()); 

// Manipulate memory 
int i = 1337, i2 = 0; 
i2 = process->memory().Read<int>((uintptr_t)&i); 

// Detach from process 
Process->Detach(); 
+0

वह लिंक 404 है। मुझे लगता है कि यह https://github.com/gordio/xnumem पर ले जाया गया है –