में ढेर के साथ खिलवाड़ मैं निम्नलिखित करना चाहते हैं:विधानसभा और C++
मुझे लगता है कि मेरा नहीं है एक समारोह है (यह वास्तव में बात यहाँ नहीं है लेकिन सिर्फ इतना कहना है कि मैं नियंत्रण अपने हाथ में नहीं है यह) और मैं पैच करना चाहता हूं ताकि यह मेरा कार्य कह सके, तर्क सूची को संरक्षित करना (कूदना एक विकल्प नहीं है)।
जो मैं करने की कोशिश कर रहा हूं वह है कि स्टैक पॉइंटर डालने के लिए, जैसा कि उस समारोह से पहले था और फिर मेरा कॉल करें (जैसे वापस जाकर और फिर एक ही काम के साथ)। यह सीधे काम नहीं करता है क्योंकि ढेर गड़बड़ हो जाता है। मेरा मानना है कि जब मैं कॉल करता हूं तो यह वापसी पते को बदल देता है। इसलिए, मैंने वैश्विक स्तर पर इसे सहेजने वाले रिटर्न पते को संरक्षित करने के लिए एक कदम उठाया और यह काम करता है लेकिन यह ठीक नहीं है क्योंकि मैं इसे पुनर्संरचना का विरोध करना चाहता हूं और आपको पता है कि मेरा क्या मतलब है। वैसे भी, मैं असेंबली में नौसिखिया हूं इसलिए मैं यहां हूं।
कृपया मुझे ऐसा करने के लिए पहले से ही बनाए गए सॉफ़्टवेयर के बारे में न बताएं क्योंकि मैं चीजों को अपना रास्ता बनाना चाहता हूं।
बेशक, यह कोड संकलक और अनुकूलन स्वतंत्र होना चाहिए।
मेरे कोड (यदि यह क्या स्वीकार्य है से बड़ा है तो कृपया मुझे यह कैसे पोस्ट करने के लिए बता):
// A function that is not mine but to which I have access and want to patch so that it calls a function of mine with its original arguments
void real(int a,int b,int c,int d)
{
}
// A function that I want to be called, receiving the original arguments
void receiver(int a,int b,int c,int d)
{
printf("Arguments %d %d %d %d\n",a,b,c,d);
}
long helper;
// A patch to apply in the "real" function and on which I will call "receiver" with the same arguments that "real" received.
__declspec(naked) void patch()
{
_asm
{
// This first two instructions save the return address in a global variable
// If I don't save and restore, the program won't work correctly.
// I want to do this without having to use a global variable
mov eax, [ebp+4]
mov helper,eax
push ebp
mov ebp, esp
// Make that the stack becomes as it were before the real function was called
add esp, 8
// Calls our receiver
call receiver
mov esp, ebp
pop ebp
// Restores the return address previously saved
mov eax, helper
mov [ebp+4],eax
ret
}
}
int _tmain(int argc, _TCHAR* argv[])
{
FlushInstructionCache(GetCurrentProcess(),&real,5);
DWORD oldProtection;
VirtualProtect(&real,5,PAGE_EXECUTE_READWRITE,&oldProtection);
// Patching the real function to go to my patch
((unsigned char*)real)[0] = 0xE9;
*((long*)((long)(real) + sizeof(unsigned char))) = (char*)patch - (char*)real - 5;
// calling real function (I'm just calling it with inline assembly because otherwise it seems to works as if it were un patched
// that is strange but irrelevant for this
_asm
{
push 666
push 1337
push 69
push 100
call real
add esp, 16
}
return 0;
}
प्रिंटों (और है के लिए):
तर्क 100 69 1337 666
संपादित करें:
कोड मैं Vlad सुझाव निम्न परीक्षण कर रहा हूँ (एसटीआई ll काम नहीं कर रहा)
// A patch to apply in the real function and on which I will call receiver with the same arguments that "real" received.
__declspec(naked) void patch()
{
_asm
{
jmp start
mem:
nop
nop
nop
nop
start :
// This first two instructions save the return address in a global variable
// If I don't save and restore the program won't work correctly.
// I want to do this without having to use a global variable
mov eax, [ebp+4]
mov mem, eax
push ebp
mov ebp, esp
// Make that the stack becomes as it were before the real function was called
add esp, 8
// Calls our receiver
call receiver
mov esp, ebp
pop ebp
// Restores the return address previously saved
mov eax, mem
mov [ebp+4],eax
ret
}
}
एएसएम में स्पष्ट कॉल के बिना, आपका फ़ंक्शन शायद कंपाइलर द्वारा रेखांकित किया गया है। यही कारण है कि इसे बुलाया नहीं गया था। – Vlad
मुझे यह सोचने के लिए बुरा महसूस करने के लिए धन्यवाद: डी। मजाक कर रहा हूं। धन्यवाद, समझ में आता है। – user246100
आपका फ़ंक्शन 'असली' वास्तव में खाली है? यदि ऐसा है, तो यह 5 बाइट से छोटा हो सकता है, इसलिए आपका पैच अगले फ़ंक्शन को ओवरराइट कर सकता है। – Vlad