2013-02-14 7 views
16

डेबियन पर काम कर रहे "स्टीम फॉर लिनक्स" पाने के मेरे प्रयास में, मैंने एक समस्या में भाग लिया है। libcef (क्रोमियम एंबेडेड फ्रेमवर्क) ठीक काम करता है GLIBC_2.13 साथ (जो डेबियन परीक्षण पर eglibc प्रदान कर सकते हैं), लेकिन GLIBC_2.15 से एक परेशान थोड़ा अतिरिक्त समारोह (जो eglibc प्रदान नहीं कर सकते) की आवश्यकता है: यहाँक्या मैं libc (GLIBC_2.13) को एक प्रतीक लोड करने में ट्रिक कर सकता हूं जिसमें यह नहीं है (GLIBC_2.15 से)?

$ readelf -s libcef.so | grep -E "@GLIBC_2\.1[4567]" 
1037: 00000000  0 FUNC GLOBAL DEFAULT UND [email protected]_2.15 (49) 
2733: 00000000  0 FUNC GLOBAL DEFAULT UND [email protected]@GLIBC_2.15 

मेरे हमले की योजना LD_PRELOAD एक शिम लाइब्रेरी थी जो केवल इन कार्यों को प्रदान करता है। यह काम नहीं लग रहा है। मैं वास्तव में GLIBC_2.17 स्थापित करने से बचना चाहता हूं (क्योंकि यह डेबियन प्रयोगात्मक में है, यहां तक ​​कि डेबियन सिड में अभी भी GLIBC_2.13 है)।


यह मैंने कोशिश की है।

fdelt_chk.c मूल रूप से from the GNU C library चोरी हो जाता है:,

$ gcc -m32 -c -fPIC fdelt_chk.c -o fdelt_chk.o 
$ gcc -m32 -shared -nostartfiles -Wl,-s -Wl,--version-script Versions -o fdelt_chk.so fdelt_chk.o 

लेकिन अगर मैं:

GLIBC_2.15 { 
    __fdelt_chk; __fdelt_warn; 
}; 

मैं तो पुस्तकालय का निर्माण इस प्रकार है:

#include <sys/select.h> 

# define strong_alias(name, aliasname) _strong_alias(name, aliasname) 
# define _strong_alias(name, aliasname) \ 
    extern __typeof (name) aliasname __attribute__ ((alias (#name))); 

unsigned long int 
__fdelt_chk (unsigned long int d) 
{ 
    if (d >= FD_SETSIZE) 
    __chk_fail(); 

    return d/__NFDBITS; 
} 
strong_alias (__fdelt_chk, __fdelt_warn) 

मेरे Versions स्क्रिप्ट के रूप में निम्नानुसार लग रहा है फिर भाप चलाएं (इसे पाने के लिए अतिरिक्त सामान का एक गुच्छा के साथ , इस बिंदु पर

% readelf -s fdelt_chk.so 

Symbol table '.dynsym' contains 8 entries: 
    Num: Value Size Type Bind Vis  Ndx Name 
    0: 00000000  0 NOTYPE LOCAL DEFAULT UND 
    1: 00000000  0 FUNC GLOBAL DEFAULT UND [email protected]_2.3.4 (3) 
    2: 0000146c  0 NOTYPE GLOBAL DEFAULT ABS _edata 
    3: 0000146c  0 NOTYPE GLOBAL DEFAULT ABS _end 
    4: 00000310 44 FUNC GLOBAL DEFAULT 11 [email protected]@GLIBC_2.15 
    5: 00000310 44 FUNC GLOBAL DEFAULT 11 [email protected]@GLIBC_2.15 
    6: 00000000  0 OBJECT GLOBAL DEFAULT ABS GLIBC_2.15 
    7: 0000146c  0 NOTYPE GLOBAL DEFAULT ABS __bss_start 

मैं:

% LD_LIBRARY_PATH="/home/tinctorius/.local/share/Steam/ubuntu12_32" LD_PRELOAD=./fdelt_chk.so:./steamui.so ./steam 
./steam: /lib/i386-linux-gnu/i686/cmov/libc.so.6: version `GLIBC_2.15' not found (required by /home/tinctorius/.local/share/Steam/ubuntu12_32/libcef.so)  

हालांकि, संस्करण प्रतीक भी .so द्वारा प्रदान की जाती है मैं सिर्फ बनाया: पहली जगह में काम कर), लोडर अभी भी प्रतीक को खोजने के लिए मना कर दिया मुझे नहीं पता कि लोडर (कौन?) को मेरे प्रतीकों को चुनने के लिए मैं क्या कर सकता हूं। क्या मैं सही दिशा में जा रहा हूं?

+1

कोशिश http://www.bnikolic.co:

यदि आप के साथ निम्न CFLAGS कहा, यह अतिरिक्त जाँच के बिना एक पीछे की ओर संगत द्विआधारी का निर्माण होगा पुन: संयोजित करने में सक्षम थे .uk/ब्लॉग/linux-ld-debug.html) '= all' और जांचें, कैसे rtld (ld-linux.so)' __fdelt' और '@@ GLIBC_2.15' – osgx

+0

के लिए खोज करता है इतना लॉगस्पैम। ऐसा लगता है कि यह केवल '/ lib/i386-linux-gnu/i686/cmov/libc.so.6' को देख रहा है और तुरंत छोड़ रहा है। शायद मुझे fdelt_chk.so के लिए उचित soname चुनने की जरूरत है ... –

+0

'-Wl, -soname, libc.so.6' सेट करना सब कुछ मारता है, क्योंकि अब यह मेरी अपनी लाइब्रेरी से आगे नहीं देखेगा। क्या पूर्ण soname द्वारा वास्तविक 'libc' आयात करना संभव होगा, और अन्य सभी प्रतीकों को फिर से निर्यात करना संभव होगा? –

उत्तर

9

मैं उसी समस्या में भाग गया, हालांकि स्टीम के साथ नहीं। जो मैं चलाने की कोशिश कर रहा था fdelt_chk के लिए चाहता था जबकि मेरे सिस्टम में 2.14 था। मुझे हमारे जैसे साधारण मामलों के लिए एक समाधान मिला जहां हम लापता कार्यक्षमता के लिए आसानी से अपना कार्यान्वयन प्रदान कर सकते हैं।

मैंने कार्यक्षमता को कार्यान्वित करने और LD_PRELOAD इसे लागू करने के आपके प्रयास किए गए समाधान से शुरुआत की। LD_DEBUG=all (जैसा कि ओएसएक्सएक्स द्वारा सुझाया गया है) का उपयोग करके पता चला है कि लिंकर अभी भी 2.15 की तलाश में था, इसलिए सिर्फ सही प्रतीक पर्याप्त नहीं था और कहीं और कुछ अन्य संस्करण तंत्र था। मैंने देखा कि objdump -p और readelf -V दोनों ने 2.15 के संदर्भ दिखाए, इसलिए मैंने ईएलएफ पर प्रलेखन देखा और information on version requirements पाया।

तो मेरा नया लक्ष्य संदर्भों को 2.15 में कुछ और संदर्भों में बदलने के लिए था। यह उचित लग रहा था कि मैं केवल जैसे कुछ निचले संस्करणों को संदर्भित संरचनाओं के साथ 2.15 पर संदर्भित संरचनाओं को ओवरराइट कर सकता हूं। अंत में, कुछ परीक्षण और त्रुटि के बाद, मुझे लगता है कि .gnu.version_r में सही Elfxx_Vernaux (एसएस?) को संपादित करना पर्याप्त था, लेकिन मुझे लगता है कि चेतावनी हैकर।

.gnu.version_r अनुभाग 16-बाइट Elfxx_Verneed एस और 16-बाइट Elfxx_Vernaux एस की सूची है।प्रत्येक Elfxx_Verneed प्रविष्टि के बाद Elfxx_Vernaux es संबंधित है। जहां तक ​​मैं कह सकता हूं, vn_file वास्तव में Elfxx_Vernaux es से जुड़े कितने जुड़े हैं, भले ही दस्तावेज़ number of associated verneed array entries कहते हैं। हालांकि, यह मेरे हिस्से पर सिर्फ एक गलतफहमी हो सकती है।

तो, संपादन करने से शुरू करने के लिए, के readelf -V से जानकारी में से कुछ को देखो। मैंने उन हिस्सों को छीन लिया जिन पर हमें परवाह नहीं है।

$ readelf -V mybinary 
<snip stuff before .gnu.version_r> 
Version needs section '.gnu.version_r' contains 5 entries: 
Addr: 0x00000000000021ac Offset: 0x0021ac Link: 4 (.dynstr) 
<snip libraries that don't refer to GLIBC_2.15> 
    0x00c0: Version: 1 File: libc.so.6 Cnt: 10 
    0x00d0: Name: GLIBC_2.3 Flags: none Version: 19 
    0x00e0: Name: GLIBC_2.7 Flags: none Version: 16 
    0x00f0: Name: GLIBC_2.2 Flags: none Version: 15 
    0x0100: Name: GLIBC_2.2.4 Flags: none Version: 14 
    0x0110: Name: GLIBC_2.1.3 Flags: none Version: 13 
    0x0120: Name: GLIBC_2.15 Flags: none Version: 12 
    0x0130: Name: GLIBC_2.4 Flags: none Version: 10 
    0x0140: Name: GLIBC_2.1 Flags: none Version: 9 
    0x0150: Name: GLIBC_2.3.4 Flags: none Version: 4 
    0x0160: Name: GLIBC_2.0 Flags: none Version: 2 

इससे हम देखते हैं कि अनुभाग 0x21ac पर शुरू होता है। प्रत्येक सूचीबद्ध फ़ाइल एक Elfxx_Verneed subentries (GLIBC_2.3 की तरह) में से प्रत्येक के लिए एक Elfxx_Vernaux के बाद होगा। मुझे लगता है कि आउटपुट में जानकारी का क्रम हमेशा फ़ाइल में ऑर्डर से मेल खाता है क्योंकि readelf सिर्फ संरचनाओं को डंप कर रहा है। यहां मेरा संपूर्ण.gnu.version_r अनुभाग है।

000021A0           01 00 02 00 
000021B0 A3 0C 00 00 10 00 00 00 30 00 00 00 11 69 69 0D 
000021C0 00 00 11 00 32 0D 00 00 10 00 00 00 10 69 69 0D 
000021D0 00 00 0B 00 3C 0D 00 00 00 00 00 00 01 00 02 00 
000021E0 BE 0C 00 00 10 00 00 00 30 00 00 00 13 69 69 0D 
000021F0 00 00 08 00 46 0D 00 00 10 00 00 00 10 69 69 0D 
00002200 00 00 07 00 3C 0D 00 00 00 00 00 00 01 00 02 00 
00002210 99 0C 00 00 10 00 00 00 30 00 00 00 11 69 69 0D 
00002220 00 00 06 00 32 0D 00 00 10 00 00 00 10 69 69 0D 
00002230 00 00 05 00 3C 0D 00 00 00 00 00 00 01 00 02 00 
00002240 AE 0C 00 00 10 00 00 00 30 00 00 00 11 69 69 0D 
00002250 00 00 12 00 32 0D 00 00 10 00 00 00 10 69 69 0D 
00002260 00 00 03 00 3C 0D 00 00 00 00 00 00 01 00 0A 00 
00002270 FF 0C 00 00 10 00 00 00 00 00 00 00 13 69 69 0D 
00002280 00 00 13 00 46 0D 00 00 10 00 00 00 17 69 69 0D 
00002290 00 00 10 00 50 0D 00 00 10 00 00 00 12 69 69 0D 
000022A0 00 00 0F 00 5A 0D 00 00 10 00 00 00 74 1A 69 09 
000022B0 00 00 0E 00 64 0D 00 00 10 00 00 00 73 1F 69 09 
000022C0 00 00 0D 00 70 0D 00 00 10 00 00 00 95 91 96 06 
000022D0 00 00 0C 00 7C 0D 00 00 10 00 00 00 14 69 69 0D 
000022E0 00 00 0A 00 87 0D 00 00 10 00 00 00 11 69 69 0D 
000022F0 00 00 09 00 32 0D 00 00 10 00 00 00 74 19 69 09 
00002300 00 00 04 00 91 0D 00 00 10 00 00 00 10 69 69 0D 
00002310 00 00 02 00 3C 0D 00 00 00 00 00 00 

संक्षिप्त संरचना यहाँ के बारे में बात करने के लिए, इसे बाहर एक Elfxx_Verneed साथ शुरू होता है। दस्तावेज़ों के अनुसार, हम देख सकते हैं कि 2 Elfxx_Vernaux es, एक ऑफसेट 16 बाइट्स होगा, और अगले Elfxx_Verneed ऑफसेट 48 बाइट्स है। ये ऑफसेट वर्तमान संरचना की शुरुआत से हैं। ऐसा लगता है कि तकनीकी रूप से संबंधित Elfxx_Vernaux एस वर्तमान Elfxx_Verneed के बाद आसन्न नहीं हो सकता है, लेकिन वास्तव में यह उन सभी फ़ाइलों में था जो मैंने चारों ओर दबाए थे।

इससे हम फ़ाइल को हम चाहते हैं (libc.so.6) कुछ अलग तरीकों से। क्रॉस संदर्भ स्ट्रिंग (जिसे मैं नहीं प्राप्त करूंगा), Elfxx_Verneed0A 00 (10, ऊपर हमारे readelf आउटपुट से मेल खाने) की गिनती के साथ Elfxx_Verneed ढूंढें, या अंतिम Elfxx_Verneed ढूंढें क्योंकि यह अंतिम readelf आउटपुट है। किसी भी मामले में, मेरी फ़ाइल के लिए सही एक 0x226C पर है। इसका पहला Elfxx_Vernaux0x227C पर शुरू होता है।

हम 0C 00 का एक संस्करण के साथ Elfxx_Vernaux खोजने के लिए (12, फिर इसके बाद के संस्करण हमारे readelf उत्पादन मिलान) चाहते हैं। हम Elfxx_Vernaux देखते हैं कि मैचों 0x22CC पर है और पूरी संरचना 95 91 96 06 00 00 0C 00 7C 0D 00 00 10 00 00 00 है। हम ऑफसेट को अकेले छोड़ने के लिए पहले 12 बाइट्स ओवरराइट कर देंगे। हम केवल डेटा को संशोधित कर रहे हैं, संरचनाओं के चारों ओर नहीं चल रहे हैं, आखिरकार।

डेटा के साथ अधिलेखित करने के लिए लेने के लिए, हम सिर्फ glibc का एक संस्करण हम पूरा कर सकते हैं के लिए एक अलग Elfxx_Vernaux से इसे कॉपी। मैं 2.1 है, जो मेरी फाइल में 0x22EC में है के लिए एक उठाया, डेटा 11 69 69 0D 00 00 09 00 32 0D 00 00 10 00 00 00 साथ। तो इससे पहले 12 बाइट्स लें और उपरोक्त पहले 12 बाइट्स को ओवरराइट करें, और यह हेक्स संपादन के लिए है।

बेशक, आप के साथ सौदा करने के लिए कई संदर्भ हो सकता है। आपके प्रोग्राम में संपादित करने के लिए कई बाइनरी हो सकती हैं।

इस बिंदु पर, हमारे कार्यक्रम अभी भी नहीं चलेंगे। लेकिन GLIBC_2.15 not found जैसे कुछ कहने की बजाय इसे __fdelt_chk गुम होने की शिकायत करनी चाहिए। अब हम प्रश्न में वर्णित शिम और LD_PRELOAD आईएनजी करते हैं, हमारे कार्यान्वयन को 2.15 के रूप में संपादित करने के बजाय, हम हेक्स संपादन के दौरान उठाए गए संस्करण का उपयोग करते हैं। इस बिंदु पर कार्यक्रम चलाना चाहिए।

यह विधि जो भी गुम है, उसके लिए कार्यान्वयन प्रदान करने में सक्षम होने पर निर्भर करती है। हमारा __fdelt_chk बेहद सरल है लेकिन मुझे संदेह नहीं है कि कुछ मामलों में कार्यान्वयन प्रदान करने के बजाय सिस्टम के libc को अपग्रेड करने से कहीं अधिक कठिन हो सकता है।

+0

लिंक के लिए धन्यवाद! आपके समाधान एक हैक की तरह लगता है। क्या आप पहले और बाद में हेक्स डेटा दिखा सकते हैं और हमें विस्तार से दिखा सकते हैं, ऑफ़सेट कैसे ढूंढें? – osgx

+2

मेरा जवाब विस्तारित किया गया। यह निश्चित रूप से एक हैक है, हे। – Fyren

+0

मैंने यह जवाब स्वीकार कर लिया है, न कि क्योंकि यह एकदम सही फिट है, लेकिन क्योंकि यह विस्तार से सबसे सरल समाधान का वर्णन करता है, और मुझे लगता है कि ऐसा करने का कोई अच्छा तरीका नहीं है। धन्यवाद :) –

6

इसके लायक होने के लिए, __fdelt_chk फ़ंक्शन FORTIFY_SOURCE सुविधा से संबंधित है जो glibc 2.15 में जोड़ा गया था। यह बफर ओवरफ्लो के लिए संकलन-समय और रन-टाइम जांच को सक्षम बनाता है। ([LD_DEBUG] सक्षम करने के लिए

-U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=0 
+1

दुर्भाग्यवश कि -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE = 0 सुझाव ने __fdelt_chk प्रतीक को नहीं हटाया। मैं उन पैथ्रेड से भी जुड़ा हूं जो शायद इसका इस्तेमाल कर रहे हैं। – Matt

+0

एफडब्ल्यूआईडब्ल्यू, इसने फ्लैग की सेटिंग्स के बाद मेरे लिए समस्या हल की, फिर रीडलाइन को बदल दिया, और फिर यह: https://forums.gentoo.org/viewtopic-p-7807512.html?sid=72aae1be7e1c8994989b783fe1462ee8 –

+0

मेरे लिए काम करता है, हटा दिया गया __fdelt_chk @ GLIBC_2.15 और [email protected]_2.11 – zhaorufei

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

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