2011-04-12 9 views
11

मैं लोड होने और चलाने के बाद प्रक्रिया के आयात पता तालिका (आईएटी) में जानकारी को पार्स/प्रदर्शित करने का प्रयास कर रहा हूं। मैं समझता हूं कि कार्यक्रमों में एपीआई कॉल आईएटी में प्रासंगिक बिंदु पर कूदते हैं, जो तब लोड किए गए डीएलएल में वास्तविक फ़ंक्शन पर कूद जाता है।आयात तालिका (आईटी) बनाम आयात पता तालिका (आईएटी)

क्या यह सही है कि आईईटी पीई हेडर पढ़ने और वैकल्पिक हेडर। डेटा डायरेक्टरी [1] पॉइंटर का पालन करके IMAGE_IMPORT_DESCRIPTOR की सरणी में पाया जा सकता है। फिर फर्स्ट टंक पॉइंटर्स का पालन करें। जबकि OriginalFirstThunk पॉइंटर्स यहां आपको मूल आयात तालिका (आईटी) दे देंगे?

मैंने पीई हेडर में OptionalHeader.DataDirectory [12] सूचक का पालन करने का भी प्रयास किया है, लेकिन यह भी कम सफल था।

मैं किसी अन्य प्रक्रिया से ReadProcessMemory का उपयोग करके, notepad.exe (32bit) के लिए इस संरचना को पार्स करने का प्रयास करके इसका परीक्षण कर रहा हूं।

char buf[128]; 

// get first import descriptor 
readMemory(&import, procImgBase + DataDirectory[1].VirtualAddress, sizeof(IMAGE_IMPORT_DESCRIPTOR)); 

// get dll name 
readMemory(buf, import.Name + procImgBase, 127); 
printf("libname: %s\n", buf); 

// get first function name 
DWORD iltAddress = 0; 
readMemory(&iltAddress, import.FirstThunk + procImgBase, 4); 
readMemory(buf, iltAddress + procImgBase, 127); 
printf("fname: %s\n", libName + 2); // <-- the +2 for the 2byte 'hint' of import lookup table entries 

हैं, तो अंतिम पंक्ति के लिए 3 पर, मैं इसे FirstThunk के बजाय import.OriginalFirstThunk के साथ बदलें, यह सब कुछ प्रिंट होगा अपेक्षा के अनुरूप:

यहाँ मैं क्या कर रहा के लिए किसी न किसी तरह सी psuedocode है । मुझे अवधारणात्मक रूप से कुछ याद आना चाहिए, और इसलिए मैं सोच रहा था कि कोई यह स्पष्ट कर सकता है कि यह मेरे लिए क्या है?

बहुत धन्यवाद!

उत्तर

6

ऐसा लगता है कि आप सही दिशा का नेतृत्व कर रहे हैं। कुछ नोट:

  • DataDirectory आप IMAGE_IMPORT_DESCRIPTOR जो सब शून्य के एक प्रवेश द्वारा समाप्त है की एक सरणी के लिए एक ऑफसेट देता है। प्रत्येक DLL कि आयात किया जाता है
  • IMAGE_IMPORT_DESCRIPTOR के लिए एक IMAGE_IMPORT_DESCRIPTOR होगी ऑफसेट IMAGE_THUNK_DATA की से 2 सरणियों, है एक कि नाम करने के लिए ऑफसेट का कहना है आयातित कार्यों (OriginalFirstThunk) की और दूसरा वह जिसमें अब कार्य (FirstThunk)

के बाद से अपने निष्पादन योग्य चल रहा है की वास्तविक पते होते हैं, आई ए टी बल्कि करने के लिए एक RVA से समारोह की वास्तविक पते को शामिल करना चाहिए एक नाम प्रविष्टि।

आप इस के बजाय की तरह कुछ कर सकता है:

DWORD rva_to_name_of_function = 0; 
DWORD address_of_function = 0; 

// get the RVA of the IMAGE_IMPORT_BY_NAME entry 
readMemory(&rva_to_name, import.OriginalFirstThunk + procImgBase, 4); 

// copy the name of the import 
readMemory(buf, rva_to_name + procImgBase + 2, 127); 

// get the actual address that was filled in by the loader 
readMemory(&address_of_function, import.FirstThunk + procImgBase, 4); 

printf("fname: %s address: %X", buf, address_of_function); 

कुछ उपयोगी जानकारी के लिए इस लेख पर एक नज़र डालें: http://msdn.microsoft.com/en-us/magazine/cc301808.aspx

+0

धन्यवाद! अब समझ में आता है। मुझे लगता है कि मुझे एहसास होना चाहिए था कि जब मैं वापस आ रहा था, तो मान्य पते की तरह दिखता था, आरवीए नहीं। – kwytay

+0

@ एरिक रहम, क्या आप अपने पहले बुलेट पॉइंट के बारे में निश्चित हैं? 'Winnt.h' में, वैकल्पिक शीर्षलेख structs' IMAGE_DATA_DIRECTORY डेटा डायरेक्टरी [IMAGE_NUMBEROF_DIRECTORY_ENTRIES] को परिभाषित करते हैं; '' IMAGE_IMPORT_DESCRIPTOR डेटा डायरेक्टरी [IMAGE_NUMBEROF_DIRECTORY_ENTRIES] नहीं; ' –

+0

यह वह जगह है जहां मैं वर्तमान में अटक गया हूं ... मुझे डेटा प्राप्त करने के लिए तैयार है निर्देशिकाएं, लेकिन आईएटी या आईएलटी या आईएनटी से डीएलएल नाम प्राप्त करने के लिए उन्हें सही structs में लोड करने के लिए वर्तमान में मुझे अवरुद्ध कर रहा है। –

4

एरिक एक अच्छा जवाब दिया, यहाँ कुछ अतिरिक्त स्पष्टीकरण हैं:

मैं समझता हूं कि कार्यक्रमों में एपीआई कॉल आईएटी में प्रासंगिक बिंदु पर कूदते हैं, जो तब लोड किए गए डीएलएल में वास्तविक फ़ंक्शन पर कूद जाता है।[आई ए टी-पता] कि आई ए टी में कोई पता निर्धारित करने के लिए जहां कार्यक्रम रनटाइम पर है से पढ़ता है:

कार्यक्रम एक कॉल PTR डी एस का उपयोग करता है।

जबकि मूल फर्स्ट थंक पॉइंटर्स यहां आपको मूल आयात तालिका (आईटी) देंगे?

OriginalFirstThunk पॉइंटर्स आपको आयात लुकअप तालिका (आईएलटी) पर इंगित करता है। यदि आप डिस्क पर बाइनरी खोलते हैं, तो आईएलटी और आईएटी समान हैं; दोनों में आरवीए का कार्य नाम स्ट्रिंग्स होता है। एक बार कार्यक्रम लोड हो जाने के बाद, आयातित कार्यों के पते के साथ आईएटी की प्रविष्टियां (स्मृति में) ओवरराइट की जाती हैं।

मेरे अनुभव में, आयात तालिका और उसके सभी सहायक डेटा संरचनाओं की जानकारी का सबसे अच्छा स्रोत पीई विनिर्देशन ही है। यदि आप आयात पर अनुभाग के माध्यम से धैर्यपूर्वक पढ़ते हैं, तो सभी को स्पष्ट कर दिया जाएगा।

http://msdn.microsoft.com/en-us/windows/hardware/gg463125

+0

इसे स्पष्ट करने के लिए धन्यवाद। मैंने एमएसडीएन दस्तावेज को पढ़ और पढ़ा है, लेकिन मेरे दिमाग को लेखकों के लिए अलग तरीके से वायर्ड किया जाता है - मैं बस इसके इस हिस्से को समझ नहीं पाया। जिस तरह से आप चीजों को शब्द स्पष्ट करते हैं :-) – kwytay

+0

वह pecoff docx वास्तव में मुझे परेशान करता है। इसमें जानकारी का एक टन है, लेकिन इसमें कुछ वास्तव में हानिकारक अंतराल हैं ... गलत जानकारी भी। '.idata' रखने के लिए उनके" लगभग सभी निष्पादन योग्य "खंड लगभग सभी शामिल नहीं हैं ... –