2010-03-23 23 views
6

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

मूल कार्य कोड मोटे तौर पर है:

void CGuiObject::AppendMsgToBuffer(classA, unsigned long, unsigned long, int, classB); 

मेरे समारोह है:

void CGuiObject_AppendMsgToBuffer([same params, with names]); 

मैं स्मृति स्थिति मूल कार्य में रहता है, इसलिए का उपयोग कर:

DWORD OrigPos = 0x0040592C; 
DetourAttach((void*)OrigPos, CGuiObject_AppendMsgToBuffer); 

मुझे समारोह में ले जाता है। यह कोड लगभग पूरी तरह से काम करता है: मेरे फ़ंक्शन को उचित पैरामीटर के साथ बुलाया जाता है। हालांकि, निष्पादन मेरे कार्य को छोड़ देता है और मूल कोड नहीं कहा जाता है। मैंने वापस jmping करने की कोशिश की है, लेकिन यह प्रोग्राम दुर्घटनाग्रस्त हो जाता है (मुझे लगता है कि कोड हुक फिट करने के लिए स्थानांतरित हो गया है जो दुर्घटना के लिए ज़िम्मेदार है)।

संपादित करें: मैंने प्रोग्राम निष्पादन पर वापस लौटने के साथ पहले अंक को ठीक करने में कामयाब रहा है। मूल कार्य को फ़ंक्शन के रूप में कॉल करके, मैं "ट्रैम्पोलिन" फ़ंक्शन और वहां से मूल कोड पर जा सकता हूं। हालांकि, लाइनों के साथ कहीं भी रजिस्ट्रार बदल रहे हैं और जैसे ही मैं मूल कोड में वापस आ जाता हूं, प्रोग्राम को एक सेगफॉल्ट के साथ क्रैश होने का कारण बन रहा है।

EDIT2: अंतिम काम कर कोड:

class CGuiObject 
{ 
public: 
    void MyFunc([params]); 
}; 

DWORD TrueAddr = 0x0040592C; 

CGuiObject::MyFunc([params]) 
{ 
    _asm { pushad } 
    // process 
    _asm { 
     popad 
     leave 
     jmp TrueAddr 
    } 
} 

और DetourAttach में पहली परम के लिए TrueAddr का उपयोग कर।

+0

क्या आप इसे डिस्सेबलर में से आगे बढ़ा सकते हैं? –

+0

हां, मैंने डीबग में बनाया और मेरे फ़ंक्शन की शुरुआत में ब्रेक-पॉइंट सेट किया। कोड हिट करता है, मैं पुशड करता हूं, कुछ लॉगिंग करता हूं (<< ऑपरेटर) का उपयोग करके fstream को संदेश भेजता हूं, पॉपड, और jmp पते पर लौटता है। निष्पादन प्रतिलिपि सामान के माध्यम से और मूल निष्पादन योग्य में वापस चला जाता है। यह कुछ लाइनों के लिए चलता है, लेकिन जहां तक ​​मैं देख सकता हूं, ईसीएक्स को 0 पर रीसेट किया जा रहा है और इसे पॉइंटर के रूप में उपयोग किया जाता है, इसलिए segfault। अगर इससे मदद नहीं मिलती है, तो मैं एएसएम के साथ पूर्ण कोड पोस्ट कर सकता हूं। – ssube

उत्तर

1

यह देखते हुए कि आप एक सी ++ विधि कॉल को रोकने की कोशिश कर रहे हैं, तो आप मूल फ़ंक्शन को कॉल करते समय शायद एक कॉलिंग कन्वेंशन समस्या हो सकती है।

मैंने इसे व्यक्तिगत रूप से चक्कर लगाने की कोशिश नहीं की है, लेकिन यह पोस्ट कुछ ऐसी चीज को इंगित करता है जो आपकी मदद कर सकता है। C++ — Detours (Win32 API Hijacking) — Hijack Class Methods दूसरे उत्तर में लिंक देखें।

+0

यह एक दौर के रास्ते में काम किया। अंत में, मैंने एक कंकाल वर्ग बनाया जो पूरी तरह से काम करता है। यह संदेश को रोकने के लिए स्वयं को कतार में संदेश डालने या अंतिम हिस्सों को छोड़ने के लिए भी कॉल कर सकता है। लिंक के लिए धन्यवाद! :) – ssube

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