2011-12-17 9 views
8

हाय सब,char [] सरणी और चार * के रूप में शेलकोड घोषित करने के बीच अंतर?

मैं मूल शेलकोडिंग सीखने की कोशिश कर रहा हूं और मैंने कुछ उत्सुकता से भाग लिया है कि मुझे उम्मीद है कि कोई मुझे समझा सकता है। मैंने निम्नलिखित कोड को दो तरीकों से संकलित किया है: शेलकोड को सरणी के रूप में घोषित करना और char * के रूप में। जब मैं एक सरणी के रूप में शेलकोड घोषित करता हूं, लिनक्स पता लगाता है कि मैं डेटा निष्पादित करने की कोशिश कर रहा हूं और मुझे पहले निर्देश पर एक सेगफॉल्ट मिलता है। हालांकि, जब मैं एक शेलकोड के रूप में शेलकोड घोषित करता हूं * सभी शेलकोड निष्पादित करता है और मुझे "हैलो वर्ल्ड!" मिलता है। कंपाइलर इन दो घोषणाओं का अलग-अलग व्यवहार कैसे करता है और क्यों एक शेलकोड में समाप्त होता है जो स्मृति में रहता है जो असुरक्षित है? अग्रिम में धन्यवाद।

#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 

/* This declaration ends in a segfault */ 
//char shellcode[] = 

/* This declaration ends in successful execution */ 
char* shellcode = 

/* Shellcode prints "Hello world!" and exits */  
"\xeb\x1f\x48\x31\xc0\x48\x31\xdb\x48\x31\xc9\x48\x31\xd2\xb0\x04\xb3\x01\x59\xb2\x0c\xcd\x80\x48\x31\xc0\xb0\x01\x48\x31\xdb\xcd\x80\xe8\xdc\xff\xff\xff\x48\x65\x6c\x6c\x6f\x20\x57\x6f\x72\x6c\x64\x21"; 

int main() 
{ 
    void (*f)(); 
    f = (void (*)())shellcode; 
    (void)(*f)(); 
} 

उत्तर

8

जब आप एक char[] के रूप में यह घोषणा करते हैं, स्मृति ढेर पर है। जब आप इसे char* के रूप में घोषित करते हैं और इसे एक स्ट्रिंग अक्षरशः असाइन करते हैं, तो स्मृति निष्पादन योग्य छवि में ही होती है। लिनक्स आपको स्टैक पर कोड निष्पादित करना पसंद नहीं करता है, लेकिन निष्पादन योग्य छवि के उस हिस्से में स्मृति को निष्पादित करने के साथ ठीक है। ऐसा इसलिए है क्योंकि यह एक निश्चित प्रकार के स्टैक ओवरफ्लो हमले से बचने की कोशिश कर रहा है जहां लोग कुछ मनमानी निर्देशों के साथ ढेर को बह सकते हैं और फिर उन्हें निष्पादित कर सकते हैं।

आप स्मृति पर किसी क्षेत्र के लिए अनुमतियों को सेट करने के लिए लिनक्स पर mprotect का उपयोग कर सकते हैं या Windows पर VirtualProtectEx सेट कर सकते हैं। इस तरह आप निष्पादन योग्य होने के लिए स्मृति की अनुमतियों को स्पष्ट रूप से सेट कर सकते हैं।

3

अपने पहले मामले में:

char shellcode[] = 

इस स्ट्रिंग एक स्थानीय सरणी के रूप में स्टैक पर शाब्दिक डालता है। ढेर और ढेर मेमोरी में आमतौर पर निष्पादन अनुमति नहीं होती है (सुरक्षा के स्पष्ट कारणों के लिए)।

अपने दूसरे मामले में:

char* shellcode = 

स्ट्रिंग स्थिर स्मृति में रहता है - जो निष्पादन योग्य है - आम तौर पर कार्यक्रम द्विआधारी के बाकी के रूप में एक ही क्षेत्र में।

संबंधित मुद्दे