C 蹦床功能崩溃
我使用我在这里看到的一些示例编写了一个简单的Hook函数,它很有效。 我设法将CreateProcess重定向到一个trampoline函数,该函数修改了一些参数,然后将控制权交还给CreateProcess 我不喜欢它,因为我使用了pop和push,这样我就可以简单地引用他们相对于ebp的地址C 蹦床功能崩溃,c,assembly,hook,C,Assembly,Hook,我使用我在这里看到的一些示例编写了一个简单的Hook函数,它很有效。 我设法将CreateProcess重定向到一个trampoline函数,该函数修改了一些参数,然后将控制权交还给CreateProcess 我不喜欢它,因为我使用了pop和push,这样我就可以简单地引用他们相对于ebp的地址 __declspec(naked) InterceptCreateProc() { LPBYTE pJmpAdr; void *inject; HMODULE hModule
__declspec(naked)
InterceptCreateProc()
{
LPBYTE pJmpAdr;
void *inject;
HMODULE hModule;
void* oldFuncAdr;
DWORD dwInject;
inject = (void* )Inject; // function that will inject this dll in every process created
dwInject = (DWORD)inject;
__asm
{
// stack frame
push ebp
mov ebp, esp
sub esp, __LOCAL_SIZE // crashes with and without this
or [ebp + 28], CREATE_SUSPENDED // dwCreationFlags | CREATE_SUSPENDED
xor eax, eax
mov eax, [ebp + 4] // return address
mov g_returnAdrCreateProc, eax // save it
mov eax, dwInject
mov [ebp + 4], eax // new return address is my Inject function
mov eax, [ebp + 44]
mov g_procInfo, eax // lpProcessInformation
};
// give control back to CreateProcess
hModule = LoadLibrary(TEXT("kernel32.dll"));
oldFuncAdr = (void* )GetProcAddress(hModule,
"CreateProcessW");
pJmpAdr = (LPBYTE)oldFuncAdr + 5;
__asm
{
jmp pJmpAdr
/*
tried push pJmpAdr
ret
no difference
*/
};
}
这将在最后一个asm块之前崩溃
我不知道我在哪里把事情搞砸了。
堆栈是否可能受到某种保护,并且当CreateProcess启动时,它会看到有人在那里写入了数据并导致应用程序崩溃
它似乎并不介意我做了大量的poping和push。
这是一个旧函数,我认为它更有可能弄乱堆栈
__declspec(naked)
InterceptCreateProc()
{
LPBYTE pJmpAdr;
LPCTSTR lpApplicationName;
LPTSTR lpCommandLine;
LPSECURITY_ATTRIBUTES lpProcessAttributes;
LPSECURITY_ATTRIBUTES lpThreadAttributes;
BOOL bInheritHandles;
DWORD dwCreationFlags;
LPVOID lpEnvironment;
LPCTSTR lpCurrentDirectory;
LPSTARTUPINFO lpStartupInfo;
LPPROCESS_INFORMATION lpProcessInformation;
DWORD retv;
void *inject;
HMODULE hModule;
void* oldFuncAdr;
inject = (void* )Inject;
__asm
{
pop retv
pop lpApplicationName
pop lpCommandLine
pop lpProcessAttributes
pop lpThreadAttributes
pop bInheritHandles
pop dwCreationFlags
pop lpEnvironment
pop lpCurrentDirectory
pop lpStartupInfo
pop lpProcessInformation
};
dwCreationFlags = dwCreationFlags | CREATE_SUSPENDED;
g_returnAdrCreateProc = retv;
retv = (DWORD)inject;
g_procInfo = lpProcessInformation;
__asm
{
push lpProcessInformation
push lpStartupInfo
push lpCurrentDirectory
push lpEnvironment
push dwCreationFlags
push bInheritHandles
push lpThreadAttributes
push lpProcessAttributes
push lpCommandLine
push lpApplicationName
push retv
};
__asm
{
push ebp
mov ebp, esp
};
hModule = LoadLibrary(TEXT("kernel32.dll"));
oldFuncAdr = (void* )GetProcAddress(hModule,
"CreateProcessW");
pJmpAdr = (LPBYTE)oldFuncAdr + 5;
__asm
{
jmp pJmpAdr
};
}
当我直接访问堆栈而不是弹出和推送堆栈时,我试图弄清楚我修改了什么,但是我找不到任何东西
\u declspec(裸体)
表示省略了prolog和epilog代码,但您没有正确设置堆栈:您没有为堆栈变量保留任何空间。它从未告诉我“ESP的值没有正确保存”,所以我认为一切正常。在堆栈帧之后,我添加了子esp,但应用程序仍然崩溃。你能看看生成的程序集吗?您正在执行inject=(void*)inject代码>在设置堆栈帧之前,所以我无法想象这会进展顺利。此外,该警告只能出现在您自己的代码中,而不能出现在裸函数中。这是有道理的。如果这是一个蹦床,我是否也应该有一个堆栈框架,用于我在其中所做的事情,然后在将控制权交还给CreateProcess之前销毁该框架?另外,这个警告“warning C4054:'type cast':从函数指针'void(u cdecl*)()到数据指针'void*”,为什么Inject在裸体时被视为u cdecl?