Fs क्या सेट करता है: [0x28] (स्टैक कैनरी)?


13

से इस पोस्ट में यह दिखाया गया है कि FS:[0x28]एक ढेर-कनारी है। मैं इस फ़ंक्शन पर GCC का उपयोग करके समान कोड उत्पन्न कर रहा हूं,

void foo () {
    char a[500] = {};
    printf("%s", a);
}

विशेष रूप से, मुझे यह विधानसभा मिल रही है।

    0x000006b5      64488b042528.  mov rax, qword fs:[0x28]                ; [0x28:8]=0x1978 ; '(' ; "x\x19"
    0x000006be      488945f8       mov qword [local_8h], rax
...stuff...
    0x00000700      488b45f8       mov rax, qword [local_8h]
    0x00000704      644833042528.  xor rax, qword fs:[0x28]
    0x0000070d      7405           je 0x714
    0x0000070f      e85cfeffff     call sym.imp.__stack_chk_fail           ; void __stack_chk_fail(void)
    ; CODE XREF from 0x0000070d (sym.foo)
    0x00000714      c9             leave
    0x00000715      c3             ret

का मान क्या सेट कर रहा है fs:[0x28]? कर्नेल, या GCC कोड में फेंक रहा है? क्या आप कोड को कर्नेल में दिखा सकते हैं, या बाइनरी में संकलित कर सकते हैं जो सेट करता है fs:[0x28]? कैनरी पुनर्जीवित है - बूट पर, या प्रक्रिया स्पॉन? यह कहां प्रलेखित है?

जवाबों:


18

इस आरंभीकरण को ट्रैक करना आसान है, जैसा कि (लगभग) हर प्रक्रिया प्रक्रिया की straceशुरुआत के दौरान एक बहुत ही संदिग्ध सीस्कल दिखाती है:

arch_prctl(ARCH_SET_FS, 0x7fc189ed0740) = 0

यही man 2 arch_prctlकहता है:

   ARCH_SET_FS
          Set the 64-bit base for the FS register to addr.

हाँ, ऐसा लगता है कि हमें क्या चाहिए। खोजने के लिए, कौन कॉल करता है arch_prctl, आइए एक बैकट्रेस देखें:

(gdb) catch syscall arch_prctl
Catchpoint 1 (syscall 'arch_prctl' [158])
(gdb) r
Starting program: <program path>

Catchpoint 1 (call to syscall arch_prctl), 0x00007ffff7dd9cad in init_tls () from /lib64/ld-linux-x86-64.so.2
(gdb) bt
#0  0x00007ffff7dd9cad in init_tls () from /lib64/ld-linux-x86-64.so.2
#1  0x00007ffff7ddd3e3 in dl_main () from /lib64/ld-linux-x86-64.so.2
#2  0x00007ffff7df04c0 in _dl_sysdep_start () from /lib64/ld-linux-x86-64.so.2
#3  0x00007ffff7dda028 in _dl_start () from /lib64/ld-linux-x86-64.so.2
#4  0x00007ffff7dd8fb8 in _start () from /lib64/ld-linux-x86-64.so.2
#5  0x0000000000000001 in ?? ()
#6  0x00007fffffffecef in ?? ()
#7  0x0000000000000000 in ?? ()

तो, FS सेगमेंट बेस द्वारा निर्धारित किया जाता है ld-linux, जो glibcप्रोग्राम लोडिंग के दौरान (यदि प्रोग्राम स्टेटिक रूप से लिंक है, तो यह कोड बाइनरी में एम्बेडेड है)। यहीं पर यह सब होता है।

स्टार्टअप के दौरान, लोडर टीएलएस को इनिशियलाइज़ करता है । इसमें मेमोरी आवंटन और टीएलएस शुरुआत की ओर इशारा करने के लिए एफएस बेस वैल्यू सेट करना शामिल है। यह arch_prctl syscall के माध्यम से किया जाता है । टीएलएस आरंभीकरण security_init फ़ंक्शन के बाद कहा जाता है, जो स्टैक गार्ड के मूल्य को उत्पन्न करता है और इसे मेमोरी लोकेशन पर लिखता है, जो इस ओर fs:[0x28]इशारा करता है:

और संरचना में क्षेत्र 0x28की ऑफसेट है stack_guardजो टीएलएस शुरू में स्थित है।


zomfg, वास्तव में बहुत अच्छा जवाब। मैं राडार के साथ एक द्विआधारी को अलग करने की कोशिश कर रहा था। इसका वह रूप और सामग्री है जिसकी मुझे तलाश थी। अनेक अनेक धन्यवाद।
इवान कैरोल

किसी प्रक्रिया को arch_prctl(ARCH_SET_FS..)मैं इनिशियेटिव में क्या नहीं देखता? क्या वह कर्नेल कोड है?
इवान कैरोल

पोस्ट में "syscall" लिंक देखें। यह वास्तविक कॉल साइट ( git.launchpad.net/glibc/tree/sysdeps/x86_64/nptl/tls.h#n153 ) की ओर जाता है जहां syscall निष्पादित होता है। यह ld-linuxटीएलएस आरंभीकरण के दौरान निष्पादित होता है।
दानिला किवर

6

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

टीएलएस में मूल्य क्यों स्टोर करें? जैसा कि मूल्य वहां स्थित है, इसका पता सीएस, डीएस और एसएस रजिस्टरों द्वारा सुलभ नहीं है, अगर आप दुर्भावनापूर्ण कोड से स्टैक को बदलने की कोशिश कर रहे हैं तो संग्रहीत मूल्य का अनुमान लगाना बहुत मुश्किल है।


यह वह नहीं है जिसकी मुझे तलाश है, इसलिए मैंने स्पष्ट होने के प्रयास में थोड़ा स्पष्ट किया है। "स्टार्टअप पर कार्यक्रम द्वारा उत्पन्न यादृच्छिक संख्या" क्या आप दिखा सकते हैं कि एक निष्पादन योग्य में यह कहां से उत्पन्न होता है, और इसे उत्पन्न करने के लिए कोड क्या है?
इवान कैरोल
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.