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.
Related
Happy new year!
This is my baby steps in C++ world.
I used an example from learn.microsoft.com to create an example Win32 Console project which uses the WaitForMultipleObjects function to persist until all worker threads have terminated. All worked great!
Things get complicated (argument of type DWORD (Thread::*)(LPVOID lpParam) is incompatible with parameter of type "LPTHREAD_START_ROUTINE")
when i start to try to port the functionality of the concept inside a class which is similar like this:
class Threads
{
private:
HANDLE comThreads[1];
DWORD WINAPI closeThreadProc(LPVOID lpParam)
{
// lpParam not used in this example.
UNREFERENCED_PARAMETER(lpParam);
printf("Thread %d exiting\n", GetCurrentThreadId());
return 1;
}
BOOL CreateThreads(void)
{
DWORD dwThreadID;
comThreads[0] = CreateThread(
NULL, // default security
0, // default stack size
closeThreadProc, // Close thread function
NULL, // no thread parameters
0, // default startup flags
&dwThreadID);
}
public:
void Init()
{
CreateThreads();
}
}
I will try to use this class to create a Dynamic-link library(DLL).
While i am searching the answer to my own question.
I would like to ask you:
Is this even possible?
If it is possible. How can i achieve this, without loosing the underlying concept?
Thank you!
Edit:
Sorry for forgetting to tell if is it possible to make this, without making DWORD WINAPI closeThreadProc(LPVOID lpParam) static!
I did try to make it static before i posted the Question and things became even more wild (I barely forced to make everything in the class static).
I think this is the C++'s way to punish a rookie.
The LPVOID argument is there for a reason. The trick is to make the callback a static member but pass this as the extra parameter. You can then cast the LPVOID argument back to your object and call the method you want to. Some code will make it clearer
static DWORD WINAPI closeThreadProcCallback(LPVOID lpParam)
{
return static_cast<Threads*>(lpParam)->closeThreadProc();
}
BOOL CreateThreads(void)
{
DWORD dwThreadID;
comThreads[0] = CreateThread(
NULL, // default security
0, // default stack size
closeThreadProcCallback, // Close thread callback function
this, // this object is the thread parameter
0, // default startup flags
&dwThreadID);
}
EDIT added WINAPI as suggested by Tomer W.
a threadStartfunction cant be _thiscall, and have to be _stdcall,
therefore i'd declare a static private method to pass your call to your object, i use the lpParameter to pass the object to the static function.
class Threads
{
private:
HANDLE comThreads[1];
static DWORD WINAPI staticThreadProc(LPVOID lpParam)
{
Threads& callingThread = *reinterpret_cast<Threads*>(lpParam);
return callingThread.closeThreadProc();
}
DWORD closeThreadProc()
{
printf("Thread %d exiting\n", GetCurrentThreadId());
return 1;
}
BOOL CreateThreads(void)
{
DWORD dwThreadID;
comThreads[0] = CreateThread(
NULL, // default security
0, // default stack size
staticThreadProc, // Close thread function
this, // no thread parameters
0, // default startup flags
&dwThreadID);
}
public:
void Init()
{
CreateThreads();
}
}
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 ....);
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?
Here is my code which contains error:
void ClassA::init()
{
HANDLE hThread;
data thread; // "thread" is an object of struct data
hThread = CreateThread(NULL, 0, C1::threadfn, &thread, 0, NULL);
}
DWORD WINAPI ClassA::threadfn(LPVOID lpParam)
{
data *lpData = (data*)lpParam;
}
Error:
error C3867: 'ClassA::threadfn': function call missing argument list; use '&ClassA::threadfn' to create a pointer to member
What is the proper way to make the worker thread working in a single class?
The thread creation functions are not aware of C++ classes; as such, your thread entry point must be either a static class member function, or a non-member function. You can pass in the this pointer as the lpvThreadParam parameter to the CreateThread() function, then have the static or non-member entry point function simply call the threadfn() function via that pointer.
If the threadfn() function is static, then make sure you put & before C1::threadfn.
Here's a simple example:
class MyClass {
private:
static DWORD WINAPI trampoline(LPVOID pSelf);
DWORD threadBody();
public:
HANDLE startThread();
}
DWORD WINAPI MyClass::trampoline(LPVOID pSelf) {
return ((MyClass)pSelf)->threadBody();
}
DWORD MyClass::threadBody() {
// Do the actual work here
}
HANDLE MyClass::startThread() {
return CreateThread(NULL, 0, &MyClass::trampoline, (LPVOID)this, 0, NULL);
}
You're using MFC, according to the tags. CreateThread is the Win32 C API, you should look at CWinThread instead.
Follow the advice in the warning error, then this should work provided the member function threadfn is static.
What happens if you do what the error says?
CreateThread(NULL, 0, &C1::threadfn, &thread, 0, NULL); // now passing pointer
This assumes that threadfn() is static.
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);