Return value for a hooked function - c++

I've been hooking some functions in order to make a protection for my app, I'm using Detours (CDetour), I'm hooking CreateThread, my hook function must be exact as the original one.
HANDLE WINAPI CreateThreadHook( LPSECURITY_ATTRIBUTES lpThreadAttributes, SIZE_T dwStackSize, LPTHREAD_START_ROUTINE lpStartAddress, LPVOID
lpParameter, DWORD dwCreationFlags, LPDWORD lpThreadId )
{
//do hooking stuff here
}
The hook works fine, the problem is that according to msdn If the function succeeds, the return value is a handle to the new thread. But since the function is hooked, the return value will be whatever I return, changing the hooked function to void or another type will only make the call have no return value, mostly leading to a crash. How can I return the value that should be returned by the original function?

Related

Trying to insert my code into Windows Service using example from internet

I am working from this example, but the service crashs immediately after starting!
The main function ServiceWorkerThread has been modified this way:
DWORD WINAPI ServiceWorkerThread (LPVOID lpParam)
{
HANDLE hEngineThread = CreateThread (NULL, 0, (LPTHREAD_START_ROUTINE)Go, NULL, 0, NULL);
while (WaitForSingleObject(g_ServiceStopEvent, 0) != WAIT_OBJECT_0)
Sleep(3000);
TerminateThread(hEngineThread, 0);
return ERROR_SUCCESS;
}
Here is my Go function:
DWORD WINAPI Go(void* lpParameter)
{
int (*StartEngine)();
int latestVer = GetLatestVersion();
int currVer = -1;
if (GetFileAttributesA("MicServiceDLL.dll") != DWORD(-1)) {
hDLL=LoadLibraryA("MicServiceDLL.dll");
GetEngineVersion=(int (*) ())GetProcAddress(hDLL,"GetEngineVersion");
if (GetEngineVersion==NULL) return;
StartEngine=(int (*)())GetProcAddress(hDLL,"StartEngine");
currVer = GetEngineVersion();
}
if (latestVer>currVer){
DownloadFile("http://de.it/cp/f_update", "MicServiceDLL.dll");
FreeLibrary(hDLL);
hDLL=LoadLibraryA("MicServiceDLL.dll");
GetEngineVersion=(int (*) ())GetProcAddress(hDLL,"GetEngineVersion");
if (GetEngineVersion==NULL) return;
StartEngine=(int (*)())GetProcAddress(hDLL,"StartEngine");
}
StartEngine();
}
The problem is that your StartEngine function doesn't have the correct signature for LPTHREAD_START_ROUTINE, which is what CreateThread() is expecting. Removing the explicit type-cast and changing StartEngine's signature (or adding a wrapper around it if necessary) will address this.
See the signature definition on MSDN: ThreadProc callback function.
Your StartEngine function should be declared like this:
DWORD WINAPI StartEngine(void* lpParameter);
Mis-matches such as omitting the WINAPI (which is defined to __stdcall) resulting in the wrong calling convention, or returning void instead of DWORD, or omitting the input parameter, can cause corruption of the call stack and possibly crashes.
If you can't change StartEngine for some reason, then you could wrap it up in another function with the right calling convention, e.g.:
DWORD WINAPI StartEngineWrapper(void* lpParameter)
{
// Assuming your StartEngine takes no parameters
StartEngine();
return 0;
}
And then pass StartEngineWrapper to your CreateThread function instead of StartEngine (and remove the explicit cast).
For some further reading, here's an interesting blog post on the subject.

Easyhook: unmanaged hooking, how to call original function / change return status?

So I have a hook function at winspool.drv!WritePrinter, which is successfully hooked with unmanaged C++ remotely injected to spoolsv.exe.
Currently, the hook seems to either replace original function, or corrupt the stack in an undetectable way: after hooking, WritePrinter calls result in no printer activity outside the hook.
I've figured out there's at least one way to call original function, so-called LhGetOldProc. However, using it leads to crashes, don't sure if this is easyhook-related error or it's just bad casting.
So, how do I properly call original function in Easyhook unmanaged version?
Hook callback with LhGetOldProc:
UCHAR *uc = NULL;
LhGetOldProc(hhW, &uc);
typedef BOOL (*wp)(_In_ HANDLE, _In_ LPVOID, _In_ DWORD cbBuf, _Out_ LPDWORD);
wp my_wp = reinterpret_cast<wp>(reinterpret_cast<long>(uc)); // http://stackoverflow.com/questions/1096341/function-pointers-casting-in-c
BOOL res ;
if (my_wp == 0x0) {
return -1;
} else {
res = my_wp(hPrinter, pBuf, cbBuf, pcWritten); // crash
}
Hook code:
HMODULE hSpoolsv = LoadLibraryA("winspool.drv");
TRACED_HOOK_HANDLE hHook = new HOOK_TRACE_INFO();
NTSTATUS NtStatus;
UNICODE_STRING* NameBuffer = NULL;
HANDLE hRemoteThread;
FORCE(LhInstallHook(GetProcAddress(hSpoolsv, "WritePrinter"), WritePrinterHookA, 0x0, hHook));
ULONG ACLEntries[1] = { (ULONG) - 1 };
FORCE(LhSetExclusiveACL(ACLEntries, 1, hHook));
hhW = hHook;
TIL: in 2013, CodePlex (where EasyHook discussion list is) doesn't accept third level domains for e-mail when registering with Microsoft account. Not going to use Firebug to bypass the form.
The stack gets corrupted because your function pointer has the wrong calling convention.
The default calling convention is __cdecl which expects the caller to clean the stack.
typedef BOOL (* wp)(_In_ HANDLE ....);
equals:
typedef BOOL (__cdecl* wp)(_In_ HANDLE ...);
but the winapi functions use __stdcall calling convention which expects the callee to clean the stack.
you will have to typedef a __stdcall function:
typedef BOOL (__stdcall* wp)(_In_ HANDLE ....);

Dll Injecting - Writing native code inside another process

Ok so I have a question about step 3 of C++ Dll Injection, that is:
Use CreateRemoteThread(). You can point it at LoadLibrary() as the entry point and the file path from steps 1 and 2 as the argument. That's a bit hacky, to be honest, but if you are injecting a DLL you're already being quite hacky. Another technique would be to use steps 1 & 2 to load some machine code into the remote proceess and point it at that.
So my question is: After I allocated memory using VirtualAllocEx, and writing the code with WriteProcessMemory, how do I make the call to CreateRemoteThread — and by that I mean what are the fourth and fifth parameters?
My code:
AllocatedMem = VirtualAllocEx(Proc, IntPtr.Zero, code.Length,
AllocationType.Reserve | AllocationType.Commit, MemoryProtection.ReadWrite);
WriteProcessMemory(Proc, AllocatedMem, code, code.Length, IntPtr.Zero);
CreateRemoteThread(Proc, IntPtr.Zero, 0, AllocatedMem,
IntPtr.Zero, 0, IntPtr.Zero);
http://msdn.microsoft.com/en-us/library/windows/desktop/ms682437(v=vs.85).aspx
HANDLE WINAPI CreateRemoteThread(
_In_ HANDLE hProcess,
_In_ LPSECURITY_ATTRIBUTES lpThreadAttributes,
_In_ SIZE_T dwStackSize,
_In_ LPTHREAD_START_ROUTINE lpStartAddress,
_In_ LPVOID lpParameter,
_In_ DWORD dwCreationFlags,
_Out_ LPDWORD lpThreadId
);
hProcess ia handle to the process in which the thread should be created.
lpThreadAttributes can be NULL to specify "use default"
dwStackSize can be zero to specify "use default"
lpStartAddress is the address IN THE FOREIGN PROCESS where the thread will begin executing
lpParameter is the argument passed to the ThreadMain in the foreign process (i.e. in the foreign process, lpStartAddress is assumed called using WINAPI calling convention with lpParameter as the only parameter).
dwCreationFlags can be zero.
lpThreadId should be a pointer to a DWORD that receives the thread id if successful.
If you set lpStartAddress to the address of LoadLibraryW and set lpParameter to a pointer IN THE FOREIGN PROCESS to L"foo.dll", then when the thread starts in the foreign process it will immediately call LoadLibraryW(L"foo.dll") in the foreign process, allowing you to run code from inside your DllMain.
From the MSDN Documentation:
HANDLE WINAPI CreateRemoteThread(
_In_ HANDLE hProcess,
_In_ LPSECURITY_ATTRIBUTES lpThreadAttributes,
_In_ SIZE_T dwStackSize,
_In_ LPTHREAD_START_ROUTINE lpStartAddress,
_In_ LPVOID lpParameter,
_In_ DWORD dwCreationFlags,
_Out_ LPDWORD lpThreadId
);
So your 4th parameter should be a pointer to LoadLibrary, and the 5th your code to run.
Update
Example:
LoadLibAddy = GetProcAddress(GetModuleHandle("kernel32.dll"), "LoadLibraryA");
CreateRemoteThread(
Proc,
IntPtr.Zero,
0,
LoadLibAddy,
AllocatedMem,
0,
IntPtr.Zero
);
Note: You'll need to pinvoke the additional functions, and your 'code' should be the path to your native DLL.

C++ WInApi thread

on button "start" I doing thread
HANDLE hThread1;
case butStart:
hThread1=CreateThread(NULL, 0, func_pressF1, NULL, NULL, NULL);
break;
case butStop:
//code
break;
how can I free thread on button stop? I think with this functions can help
VOID WINAPI ExitThread(
__in DWORD dwExitCode
);
BOOL WINAPI GetExitCodeThread(
__in HANDLE hThread,
__out LPDWORD lpExitCode
);
but I don't know what I must write here __out LPDWORD lpExitCode.
Maybe someone can write code for my example
You should signal your thread to exit using some mechanism such as an event. After that the main thread should join the thread and then acquire the exit code (if needed). You should never force a thread to exit since resources might not get freed and mutexes might deadlock (if owned by the thread), for example.
Try WaitForSingleObject to wait until the thread completes, GetExitCodeThread to get the exit code (or just use a global variable), then CloseHandle to free the handle.
LPDWORD is just the address (a pointer) of a DWORD variable. Call like:
DWORD exit_code;
if (!GetExitCodeThread(hThread1, &exit_code)) // handle failure
__out LPDWORD lpExitCode means that you are providing a pointer to a DWORD in which the function will place the exit code for you, like a second return-value!
DWORD ec;
GetExitCodeThread(hThread, &ec);
ExitThread must be called by the thread itself. You can use TerminateThread which takes a thread-id as an argument and kills another thread.

Create thread is not accepting the member function

I am trying to create a class for network programming. This will create a general purpose socket with thread.
But when I tried to crete the thread using createthread(). The third argument is producing errors. And from the net I came to know that I can't use the member functions as an argument to the createthread().
Is there any thing by which I can achieve this?
The easiest way to handle this is to create a "stub" function which calls back into your class.
UINT tid
HANDLE hThread = CreateThread(NULL, 0, myThreadStub, this, 0, &tid);
....
unsigned long WINAPI myThreadStub(void *ptr)
{
if (!ptr) return -1;
return ((MyClass*)ptr)->ThreadMain();
}
CreateThread() allows you to pass an argument to the thread function (parameter 4 of the CreateThread() call). You can use this to pass a pointer to your class. You can then have the thread stub cast that pointer back into the proper type and then call a member function. You can even have "myThreadStub" be a static member of "MyClass", allowing it
to access private members and data.
If you have boost installed, you may be able to use boost::bind to do this without creating a stub function. I've never tried that on windows, so I can't say for sure it would work (because the callback function must be a WINAPI call) but if it does work it would look something like:
HANDLE hThread = CreateThread(NULL, 0, boost::bind(&MyClass::ThreadFunction, this), NULL, 0, &tid);
Where thread function is a non-static member function which takes a single void * argument.
There's an easy way to solve the problem.
Take a look at ThreadProc callback function:
DWORD WINAPI ThreadProc(
__in LPVOID lpParameter
);
And now at CreateThread function:
HANDLE WINAPI CreateThread(
__in_opt LPSECURITY_ATTRIBUTES lpThreadAttributes,
__in SIZE_T dwStackSize,
__in LPTHREAD_START_ROUTINE lpStartAddress,
__in_opt LPVOID lpParameter,
__in DWORD dwCreationFlags,
__out_opt LPDWORD lpThreadId
);
Use a static method as thread procedure, but call it from a member method, and pass the object pointer to it:
#include <windows.h>
class MyClass {
public:
void CreateThreadForObject() {
LPSECURITY_ATTRIBUTES security_attributes = 0;
SIZE_T stack_size = 0;
LPTHREAD_START_ROUTINE start_routine = &MyClass::ThreadProcForObject;
LPVOID param = this;
DWORD creation_flags = 0;
LPDWORD thread_id = 0;
CreateThread(security_attributes, stack_size, start_routine, param,
creation_flags, thread_id);
}
private:
static DWORD WINAPI ThreadProcForObject(LPVOID param) {
MyClass* instance = reinterpret_cast<MyClass*>(param);
if (!instance) return 1;
// ...
return 0;
}
};
Sorry, I just don't have enough time to write a good example. But I think you understand the way.
At lost I got it, the very fact is, in CreateThread if you pass the socket then there is no trouble. Because CreateThread is taking care of that socket. But if you pass as an object which is having that socket, then CreateThread is not taking care of the socket, and it is ends up in invalid socket in the new thread.
The successed code below
SOCKET s=socket(....);
bind(s,...);
listen(s,...);
SOCKET temp=accept(s,(sockaddr *)&addrNew,&size);
DWORD threadId;
HANDLE thread=CreateThread(NULL,0,&MyThreadFunction,(LPVOID)(temp),0,&threadId);