
ELF बाइनरी सेक्शन डॉकिंग टूलकिट स्टेजलेस पेलोड वितरण के लिए, जो कस्टम ELF सेक्शन मैनिपुलेशन के माध्यम से इन-फील्ड पेलोड अटैचमेंट, सिग्नेचर एवेज़न और स्टैटिक/डायनामिक लोडिंग प्रतिरोध को सक्षम बनाता है।
.data जैसे सेक्शन में रखता है।payload.h:
const data[3432] = {
0x43, 0x28, 0x41, 0x11, 0xa3, 0xff,
...
0x00, 0xff, 0x23
};
मैन्युअल रूप से या bin2c या xxd -i payload.bin > payload.h जैसे टूल्स के साथ आगे हेडर समावेशन के साथ प्राप्त किया जाता है।
पेलोड को सामान्य रूप से .text और .data में संग्रहीत करना भी एक बुरा विचार है, क्योंकि लोडिंग ट्रेसिंग और निष्पादन के लिए डेटा लोड करने के व्यवहारिक अर्थशास्त्र की जांच आसान हो जाती है।
__attribute__ के माध्यम से किया जाता है। यह थोड़ा बेहतर है लेकिन फिर भी अच्छी तरह से ट्रेस करने योग्य है क्योंकि ELF कैसे बनाया और लोड किया जाता है।char stack[10000] __attribute__ ((section ("binstack"))) = {
0x43, 0x28, 0x41, 0x11, 0xa3, 0xff,
...
0x00, 0xff, 0x23 };
int init_data __attribute__ ((section ("bindata"))) = 0;
main()
{
/* Initialize stack pointer */
init_sp (stack + sizeof (stack));
/* Initialize initialized data */
memcpy (&init_data, &data, &edata - &data);
}
असेंबलर-निर्भर .incbin-जैसी निर्देश एक सेक्शन बना सकती है और एक पेलोड एम्बेड कर सकती है।
उदाहरण: gcc -c payload.s या ld -r -b payload.bin -o payload.o
.section .bindata
.global payload_start
.type payload_start, @object
.section .binddata
.balign 64
payload_start:
.incbin "payload.bin"
.balign 1
payload_end:
.byte 0
लोडर में आगे पुनर्प्राप्ति के साथ:
int main(void) {
extern uint8_t payload_start;
uint8_t *ptrPayload = &payload_start;
...
}
नोट: हम payload.bin में एक पूरी तरह से कार्यात्मक ELF शामिल कर सकते हैं, जो महत्वपूर्ण है जब "फ़ैट" बाइनरी बनाने की बात आती है, जिसमें कई टूलकिट के तत्व होते हैं।
नोट: कार्य को पूरा करने के लिए अधिक एर्गोनोमिक टूल मौजूद हैं, जैसे @graphitemaster से INCBIN [link]
इसी विषय पर एक भिन्नता इनलाइन ASM है:
/* Raw image data for all embedded images */
#undef EMBED
#define EMBED( _index, _path, _name ) \
extern char embedded_image_ ## _index ## _data[]; \
extern char embedded_image_ ## _index ## _len[]; \
__asm__ ( ".section \".rodata\", \"a\", " PROGBITS "\n\t" \
"\nembedded_image_" #_index "_data:\n\t" \
".incbin \"" _path "\"\n\t" \
"\nembedded_image_" #_index "_end:\n\t" \
".equ embedded_image_" #_index "_len, " \
"( embedded_image_" #_index "_end - " \
" embedded_image_" #_index "_data )\n\t" \
".previous\n\t" );
EMBED_ALL
/* Image structures for all embedded images */
#undef EMBED
#define EMBED( _index, _path, _name ) { \
.refcnt = REF_INIT ( ref_no_free ), \
.name = _name, \
.data = ( userptr_t ) ( embedded_image_ ## _index ## _data ), \
.len = ( size_t ) embedded_image_ ## _index ## _len, \
},
static struct image embedded_images[] = {
EMBED_ALL
};
नोट: सेक्शन की परिभाषा में PROGBITS पर ध्यान दें, यह महत्वपूर्ण होगा।
कंपाइलर/लिंकर-आधारित पेलोड बाइनरी समावेशन आदर्श नहीं है
इसमें व्यापार-नापसंद हैं:

सेक्शन का प्रकार और नए सेक्शन पर सेट किए गए फ़्लैग यह निर्धारित करते हैं कि OS लोडर निष्पादन योग्य लॉन्च होने पर इसे मेमोरी में लोड करता है या नहीं। कुछ सेक्शन स्वचालित रूप से लोड होते हैं, अन्य नहीं (जैसे .symtab, .strtab)
आक्रामक के रूप में, हम इससे क्या दक्षताएँ प्राप्त कर सकते हैं?
हम उन सेक्शन पर फ़्लैग सेट करने से बच सकते हैं जो मेमोरी में डिफ़ॉल्ट लोडिंग मानते हैं।
हम एक अलग प्रकार के सेक्शन का उपयोग कर सकते हैं जो मेमोरी में लोड नहीं होता।
एक विक्रेता या सिस्टम इंजीनियर को किसी ऑब्जेक्ट फ़ाइल को विशेष जानकारी से चिह्नित करने की आवश्यकता हो सकती है जिसे अन्य प्रोग्राम अनुरूपता या संगतता के लिए जांच सकते हैं।
SHT_NOTEप्रकार के सेक्शन औरPT_NOTEप्रकार के प्रोग्राम हेडर तत्व इस उद्देश्य के लिए उपयोग किए जा सकते हैं।
बाद के मामले में, हम सिस्टम बाइनरी में इस प्रकार के सेक्शन का उपयोग देख सकते हैं:
$ readelf --sections /bin/tar | grep NOTE
[ 2] .note.gnu.bu[...] NOTE 00000000000002c4 000002c4
[ 3] .note.ABI-tag NOTE 00000000000002e8 000002e8
और उनकी सामग्री का निरीक्षण कर सकते हैं:
$ readelf -p .note.ABI-tag /bin/tar
String dump of section '.note.ABI-tag':
[ c] GNU
SHT_NOTE सेक्शन बनाने का अंतिम परिणाम ELF में इस प्रकार दिखेगा:

बोनस: SHT_NOTE हमें संरचना देता है यदि हमें इसका उपयोग करने की आवश्यकता है (और हम आगे इसका उपयोग करेंगे):

अब तक हम एक सेक्शन बनाने, OS लोडर द्वारा इसे मेमोरी में लोड होने से बचाने में सक्षम थे। सेक्शन फिलहाल ELF छवि में प्रभावी रूप से निष्क्रिय है। हम चर्चा करेंगे कि इसे थोड़ी देर बाद कैसे लोड किया जाए। हालाँकि, एक अधिक दबाव वाला प्रश्न यह है कि हम अभी भी कंपाइलर और लिंकर स्तर पर काम कर रहे हैं, और सेक्शन एक ऑब्जेक्ट है जो अंतिम ELF की संरचना में बुना जाता है, जो लोडर कोड से संबंध और मेमोरी पते बनाता है जो इसकी सामग्री को संदर्भित करता है।

क्या होगा यदि हम एक एम्बेडेड पेलोड के साथ एक ELF सेक्शन को लोडर संकलन वर्कफ़्लो के बाहर बना सकें, और बाद में उस सेक्शन को लोडर बाइनरी से जोड़ सकें? यह लोडर कोड और सेक्शन इंटरैक्शन के बीच संबंध को तोड़ देगा। फिर हम लोडर को सिखाएंगे कि अपने विदेशी डेटा सेक्शन को कैसे खोजें और लोड करें, प्रभावी रूप से एक लोडर में एक पेलोड को ढीले युग्मित तरीके से "डॉक" करना।
अवधारणात्मक रूप से, हमारे लक्ष्य होंगे:
लोडर/पेलोड (सेक्शन में) संबंध अब इस प्रकार दिखेगा: