2012-02-17 16 views
11

के लिए ट्रैम्पोलिन फ़ंक्शन कैसे बनाएं I hooking में दिलचस्पी है और मैंने यह देखने का फैसला किया कि मैं कुछ फ़ंक्शंस को हुक कर सकता हूं या नहीं। मुझे लाइब्रेरी जैसे लाइब्रेरी का उपयोग करने में दिलचस्पी नहीं थी क्योंकि मैं इसे अपने आप करने का अनुभव करना चाहता हूं। इंटरनेट पर मिले कुछ स्रोतों के साथ, मैं नीचे कोड बनाने में सक्षम था। यह बुनियादी है, लेकिन यह ठीक काम करता है। हालांकि जब कई धागे द्वारा बुलाए जाने वाले कार्यों को हुकिंग करना बेहद अस्थिर साबित होता है। यदि लगभग दो कॉल एक ही समय में किए जाते हैं, तो यह क्रैश हो जाएगा। कुछ शोध के बाद मुझे लगता है कि मुझे ट्रामपोलिन फ़ंक्शन बनाने की आवश्यकता है। घंटों की तलाश करने के बाद मैं कुछ भी नहीं ढूंढ पाया जो कि ट्रैम्पोलिन पर एक सामान्य विवरण था। मुझे विशेष रूप से ट्रैम्पोलिन फ़ंक्शन लिखने के बारे में कुछ भी नहीं मिला, या वे वास्तव में कैसे काम करते थे। अगर कोई मुझे लिखने में मदद कर सकता है, कुछ स्रोत पोस्ट कर सकता है, या कम से कम मुझे कुछ लेख, साइट्स, किताबें इत्यादि की सिफारिश करके सही दिशा में इंगित कर सकता है। मैं इसकी सराहना करता हूं।हुक

नीचे कोड मैंने लिखा है। यह वास्तव में बुनियादी है लेकिन मुझे उम्मीद है कि अन्य लोग इससे सीख सकते हैं।

test.cpp

#include "stdafx.h" 

Hook hook; 

typedef int (WINAPI *tMessageBox)(HWND hWnd, LPCTSTR lpText, LPCTSTR lpCaption, UINT uType); 

DWORD hMessageBox(HWND hWnd, LPCTSTR lpText, LPCTSTR lpCaption, UINT uType) 
{ 
    hook.removeHook(); 
    tMessageBox oMessageBox = (tMessageBox)hook.funcPtr; 
    int ret =oMessageBox(hWnd, lpText, "Hooked!", uType); 
    hook.applyHook(&hMessageBox); 

    return ret; 
} 

void hookMessageBox() 
{ 
    printf("Hooking MessageBox...\n"); 
    if(hook.findFunc("User32.dll", "MessageBoxA")) 
    { 
     if(hook.applyHook(&hMessageBox)) 
     { 
      printf("hook applied! \n\n"); 
     } else printf("hook could not be applied\n"); 
    } 
} 

hook.cpp

#include "stdafx.h" 

bool Hook::findFunc(char* libName, char* funcName) 
{ 
    Hook::funcPtr = (void*)GetProcAddress(GetModuleHandleA(libName), funcName); 
    return (Hook::funcPtr != NULL); 
} 

bool Hook::removeHook() 
{ 
    DWORD dwProtect; 
    if(VirtualProtect(Hook::funcPtr, 6, PAGE_EXECUTE_READWRITE, &dwProtect)) 
     { 
     WriteProcessMemory(GetCurrentProcess(), (LPVOID)Hook::funcPtr, Hook::origData, 6, 0); 
     VirtualProtect(Hook::funcPtr, 6, dwProtect, NULL); 
     return true; 
    } else return false; 
} 

bool Hook::reapplyHook() 
{ 
    DWORD dwProtect; 
    if(VirtualProtect(funcPtr, 6, PAGE_EXECUTE_READWRITE, &dwProtect)) 
     { 
     WriteProcessMemory(GetCurrentProcess(), (LPVOID)funcPtr, Hook::hookData, 6, 0); 
     VirtualProtect(funcPtr, 6, dwProtect, NULL); 
     return true; 
    } else return false; 
} 

bool Hook::applyHook(void* hook) 
{ 
    return setHookAtAddress(Hook::funcPtr, hook); 
} 

bool Hook::setHookAtAddress(void* funcPtr, void* hook) 
{ 
    Hook::funcPtr = funcPtr; 
    BYTE jmp[6] = { 0xE9, //jmp 
        0x00, 0x00, 0x00, 0x00, //address 
        0xC3 //retn 
       }; 

    DWORD dwProtect; 

    if(VirtualProtect(funcPtr, 6, PAGE_EXECUTE_READWRITE, &dwProtect)) // make memory writable 
    { 

     ReadProcessMemory(GetCurrentProcess(), (LPVOID)funcPtr, Hook::origData, 6, 0); // save old data 
     DWORD offset = ((DWORD)hook - (DWORD)funcPtr - 5); //((to)-(from)-5) 
     memcpy(&jmp[1], &offset, 4); // write address into jmp 
     memcpy(Hook::hookData, jmp, 6); // save hook data 
     WriteProcessMemory(GetCurrentProcess(), (LPVOID)funcPtr, jmp, 6, 0); // write jmp 
     VirtualProtect(funcPtr, 6, dwProtect, NULL); // reprotect 

     return true; 
    } else return false; 
} 
+0

मैं जीडी के लिए एक लिंक पोस्ट करने जा रहा था, लेकिन मैंने अभी देखा है कि आप वहां भी सदस्य हैं। क्या आपने अपने खोज फ़ंक्शन का उपयोग करने का प्रयास किया है? यह कई उदाहरणों के साथ आता है :) –

+0

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

+0

@ टॉम नैपन मैंने पोस्ट करने से पहले जीडी, एमपीजी और कुछ अन्य साइटों की खोज की। जीडी पर 'ट्रैम्पोलिन' खोजना कुछ थोड़ा-संबंधित पोस्ट देता है लेकिन जो मैं ढूंढ रहा हूं वह नहीं। – Stratus

उत्तर

7

आप जब एक से अधिक थ्रेड से बुलाया अपने हुक सुरक्षित बनाना चाहते हैं, तो आप नहीं लगातार unhooking और rehooking होना चाहते हैं मूल एपीआई।

एक ट्रैम्पोलिन केवल आपके द्वारा उत्पन्न कोड का एक छोटा सा हिस्सा है जो मूल एपीआई के पहले कुछ बाइट्स (जिसे आप अपनी कूद से ओवरराइट करते हैं) की कार्यक्षमता को दोहराते हैं, फिर बाइट्स को ओवरराइट करने के बाद एपीआई में कूदते हैं।

एपीआई को खोलने की बजाय, इसे बुलाकर और इसे फिर से देखकर आप ट्रैम्पोलिन को कॉल करते हैं।

यह x86 पर सामान्य रूप से जटिल है क्योंकि आपको निर्देश सीमाओं को खोजने के लिए (काफी कम) डिस्सेबलर की आवश्यकता है। आपको यह भी जांचना होगा कि जिस कोड को आप अपनी ट्रैम्पोलिन में कॉपी करते हैं वह निर्देश सूचक (जैसे एक jmp, शाखा या कॉल) से संबंधित कुछ भी नहीं करता है।

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

x64 पर ऐसा करना अधिक अधिक जटिल है। आप केवल 64-बिट दूर कूद के साथ फ़ंक्शन को पैच नहीं कर सकते (क्योंकि वहां कोई नहीं है, और इसे अनुकरण करने के निर्देश अक्सर बहुत लंबे होते हैं)। और, आपके ट्रैम्पोलिन के आधार पर, आपको इसे ओएस के ढेर में जानकारी को खोलने की आवश्यकता हो सकती है।

मुझे आशा है कि यह बहुत सामान्य नहीं है।

+0

धन्यवाद, लेकिन यह काफी कुछ था जो मुझे पहले से मिला था और मुझे लिखने में मदद नहीं करता है। – Stratus

+0

@Stratus: आप क्या खो रहे हैं? कुछ निष्पादन योग्य स्मृति आवंटित करें। फ़ंक्शन प्रोलॉग से आवंटित मेमोरी में एन बाइट्स कॉपी करें और प्रोजेक्ट + n पर फ़ंक्शन के साथ कूदें। n फ़ंक्शन प्रोलॉग में कम से कम 5 बाइट्स को फ्री-अप करने के लिए आपको कॉपी करने के लिए आवश्यक निर्देशों का आकार है। यह एक ट्रैम्पोलिन है। कुछ अन्य झुर्रियाँ हैं (जैसे आईपी को संशोधित करने वाले निर्देशों की प्रतिलिपि न लें) लेकिन यह मूल रूप से है। – arx

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