I am just trying to understand some source code written in C++. I am a bit familiar
with C++, however, the following code sequence is absolutley new to me. A guess would be
that here I register some thread routine with the kernel, ptest->Run(). Could that be right?
static unsigned int __stdcall ThreadProc(void *lParameter)
{
CTest *ptest;
ptest= (Ctest *)lParameter;
ptest->Run();
return 0;
}
CTest::CTest(int n)
{
...
}
A bit simplified but a thread is a function, in this case ThreadProc. When the thread starts, the function is called and when the function exits the thread dies.
In this case, someone has started a thread with CreateThread, begin_thread or something else and passed in a pointer to a class called CTest as an argument. The thread then casts it back to a CTest* (as you can see the argument is delivered by the CreateThread API as a more generic void*) and calls the CTest::Run method before exiting.
Edit: Also, except for the "__stdcall" declaration, this is not very Windows specific. Threads in C and C++ works more or less like this on all OSes.
This is a function signature that would be used to define a function that is exported from a DLL or used as a callback function. In this case it is probably going to be used a the main loop of a worker thread.
the __stdcall keyword indicates that the function call is passed on the stack using the stdcall calling convention in Windows (same as used by methods exported from the Win32 API)
OOPS: this link doesn't play nice with markdown http://msdn.microsoft.com/en-us/library/zxk0tw93(VS.80).aspx
Not quite. This is your thread function:
static unsigned int __stdcall ThreadProc(void *lParameter)
It will be executed an different thread than whatever caused it. Calling code creates an object of type CTest, creates a thread that runs ThreadProc, which in turn runs ptest->Run();
ThreadProc is just a convenience wrapper to launch ptest->Run(). (Because otherwise it is kinda hard to use pointers to member functions)
What OS? Looks like a Windows sample, if so begin_thread(), or CreateThread or...several
The code you show declares a pointer to a CTest class object, converts the input parameter into one of those, then calls its run method.
The why this is done is the tricky part. Normally you wouldn't write code like this, however, the profile of ThreadProc is that of a thread's main entry point. For one of those, Windows doesn't give you any choice for the parameter profile of it, and it can't be a class member.
What you have there is fairly standard code to convert a thread entry-point callback from the Windows' required form into a class method call.
For a full discussion of this, see my (accepted) answer for the question: Passing Function pointers in C++
Related
So I am wondering how I would go about duplicating all referenced objects/variables within the scope of a function/method from a function pointer.
A little bit more background on the issue -> I am passing a function pointer to a C++ method from VBA using the AddressOf method. The idea is to duplicate the underlying variables/objects within that VBA method so that the function can be ran on multiple threads. At the moment if I try and directly callback the function from my c++ function on more than 1 thread it instantly crashes, and I know this is because VBA runs in an STA. My though process is that if I can almost duplicate the objects that are necessary for the function, I can then avoid the issue of referencing an object at the same time (I can have more control in ensuring my code is thread safe). Another alternative I thought of would be to marshal all of the underlying objects through COM, but I have also been unsuccessful in doing this :( I think this would cause more issues anyway as VBA is technically meant to be ran on a single thread.
Any ideas/recommendations would be greatly apreciated, I have been trying to crack this code for a matter of weeks now and am reaching a bit of a brick wall.
Edit - Here is the code to get the function pointer from VBA
typedef int (WINAPI *callbackFunc_t)(int, BSTR);
callbackFunc_t callbackFunc;
__declspec(dllexport) void __stdcall setCallbackFunction(callbackFunc_t callbackFunc_)
{
callbackFunc = callbackFunc_;
}
My code calls a function from 3rd party library. Let's call this function SomeFunc
void SomeFunc(void (*callBack) (int));
As you can see SomeFunc takes a callback function parameter. Once SomeFunc is called, the calling thread will progress, and the library will execute the callback several time on a different thread -- passing it different status code.
My requirement is the thread that calls SomeFunc (aka main thread) should wait until certain status code is passed to the callback. So far I have something like this
CEvent *pEvt = NULL;
void myCallBack(int code) {
if(code == SOME_MAGIC_NUM) pEvt->SetEvent(); // signal thread waiting for this event obj they can continue
}
int main (int argc, char** argv) {
pEvt = new CEvent(FALSE, TRUE);
SomeFunc(myCallBack); // This doesn't block, main thread will progress to next line
WaitForSingleObject(pEvt, 5000); // wait here until 3rd party library call myCallBack with code SOME_MAGIC_NUM -- or if it doesn't after 5 seconds, continue
// do interesting stuff here..
return EXIT_SUCCESS;
}
Now this seem fine if I only do this on the main thread / main function like above. However if multiple thread can execute the code block in main above, my problem is they will share reference to the global pEvt variable, and it will mess up
What's the best code design approach I should take here? Ideally I would like to change the callback function signature to accept reference to the CEvent object, but since it's a 3rd party library I'm unable to do that.
You really want the equivalent of a closure in javascript. You can accomplish something similar by binding the function call to a new CEvent object every time. Take a look at std::bind1st or boost::bind.
See also this stackoverflow thread
You can only achieve this is the 3rd party provides a way to pass back a 'custom' argument to the callback. Well designed APIs allow to set up a callback and a void* value and the callback receives this argument when invoked. From this void* you can expand to anything you like, including objects and method calls, via unsafe casting. All solutions based on binding or member function address or whatever else ultimately boil down to the same issue: somehow the this* has to be passed back to the callback.
For an example, see BIO_set_callback: it allows you to set the callback and a callback arbitrary argument. Note that the callabck argument can be indirect, like for example in gnutls: the argument can be set as arbitrary data on the session via gnutls_session_set_ptr and then in the callback(s) it can be retrieved using gnutls_session_get_ptr. Your 3rd party may provide such an indirect method.
If the library does not offer such feature then you're stranded into hacks. For example you can have a collection of callbacks 'available', each one associated with a specific event (ie. different functions as address, although same code). You pick one callback and remove it from collection and place it, then wait for the event associated with that callback. When done, place the callback back into the available list. The size of the 'available' list is hard coided at compile time as you really need separate functions, one for each callback.
I'm aware of the threading issues etc that this could cause and of its dangers but I need to know how to do this for a security project I am doing at school. I need to know how to call a function in a remote address space of a given calling convention with arguments - preferably recovering the data the remote function has returned though its really not required that I do.
If I can get specifics from the remote function's function prototype at compile time, I will be able to make this method work. I need to know how big the arguments are and if the arguments are explicitly declared as pointers or not (void*, char*, int*, etc...)
I.e if I define a function prototype like:
typedef void (__cdecl *testFunc_t)(int* pData);
I would need to, at compile time, get the size of arguments at least, and if I could, which ones are pointers or not. Here we are assuming the remote function is either an stdcall or _cdecl call.
The IDE I am using is Microsoft Visual Studio 2007 in case the solution is specific to a particular product.
Here is my plan:
Create a thread in the remote process using CreateRemoteThread at the origin of the function want to call, though I would do so in a suspended state.
I would setup the stack such that the return address was that of a stub of code allocated inside of the process that would call ExitThread(eax) - as this would exit the thread with the function's return value - I would then recover this by by using GetExitCodeThread
I would also copy the arguments for the function call from my local stack to that of the newly created thread - this is where I need to know if function arguments are pointers and the size of the arguments.
Resume the thread and wait for it to exit, at which point I will return to the caller with the threads exit code.
I know that this should be doable at compile time but whether the compiler has some method I can use to do it, I'm not sure. I'm also aware all this data can be easily recovered from a PDB file created after compiling the code and that the size of arguments might change if the compiler performs optimizations. I don't need to be told how dangerous this is, as I am fully aware of it, but this is not a commercial product but a small project I must do for school.
The question:
If I have a function prototype such as
typedef void (__cdecl testFunc_t)(int pData);
Is there anyway I can get the size of this prototype's arguments at compile time(i.e in the above example, the arguments would sum to a total size of sizeof(int*) If, for example, I have a function like:
template<typename T> unsigned long getPrototypeArgLength<T>()
{
//would return size of arguments described in the prototype T
}
//when called as
getPrototypeArgLength<testFunc>()
This seems like quite a school project...
For step 3 you can use ReadProcessMemory / WriteProcessMemory (one of them). For example, the new thread could receive the address (on the calling process), during the thread creation, of the parameters on the start (begin and end). Then it could read the caller process memory from that region and copy it to its own stack.
Did you consider using COM for this whole thing? you could probably get things done much easier if you use a mechanism that was designed especially for that.
Alright, I figured out that I can use the BOOST library to get a lot of type information at compile-time. Specifically, I am using boost::function_traits however, if you look around the boost library, you will find that you can recover quite a bit of information. Here's a bit of code I wrote to demonstrate how to get the number of arguments of a function prototype.
(actually, I haven't tested the below code, its just something I'm throwing together from another function I've made and tested.)
template<typename T>
unsigned long getArgCount()
{
return boost::function_traits<boost::remove_pointer<T>::type>::arity;
}
void (*pFunc)(int, int);
2 = getArgCount<BOOST_TYPEOF(pFunc)>();
I want to make a simple worker thread inside a same class. However, there are 3 major problems that I am facing, which are:
Definition of a thread function in class header.
Thread function call.
Called thread function format.
I am also confused to use either AfxBeginThread or CreateThread function call to pass multiple thread parameters. Can anyone please provide me a simple worker thread to run in MFC based on the 3 things that I have provided above?
Definition of a thread function in class header: It has to be a static member because the usual way of putting "this" in a hidden parameter doesn't work. Since you only get one parameter, you want the parameter to be a pointer to a struct, and one member of the struct can be "this" of the class instance that your static member can call.
Thread function call: Since the function that gets called is going to use MFC, it is easiest to have the caller call AfxBeginThread. Since you say the thread will be a worker thread, call the version of AfxBeginThread that is designed for worker threads (even if it doesn't matter much).
Called thread function format. MSDN describes AfxBeginThread and says what prototype must be used for the first parameter.
Ideally, you should never be using CreateThred. And if you're using MFC, you MUST use AfxBeginThread to for creating threads.
I've given some explanation here in this discussion: http://www.daniweb.com/forums/thread249210.html
CreateThread is mainly for UI Threads but is still preferred to use the second method for AfxBeginThread. Store a reference to the threads handle in the header not the thread.
HANDLE hThread;
then in source start your thread pointing to your proc:
CWinThread *pThread;
if(!(pThread = AfxBeginThread(ThreadProc, NULL, THREAD_PRIORITY_NORMAL, 0, CREATE_SUSPENDED))) {
delete arr;
}
::DuplicateHandle(GetCurrentProcess(), pThread->m_hThread, GetCurrentProcess(), &hThread, 0, FALSE, DUPLICATE_SAME_ACCESS);
pThread->ResumeThread();
You start it suspended so you can copy the handle to the one you have stored in header. this way you can use the stored handle to check on exitcode.
I have a function with the prototype
DWORD WINAPI blah(LPVOID arg);
Which was meant to be used with CreateThread for a threaded app.
I call it with CreateThread with no problem. But then somewhere else in the code, I call it normally, just by blah(NULL). When it gets to this part, it crashes. Is this because the WINAPI part makes it __stdcall and you can't just call __stdcall functions like that?
It is not because of __stdcall. Start your program in the debugger and check which line of the code gives you a crash.
The only problem would be if blah() specifically calls TerminateThread(self) to end, instead of just returning off the bottom. The CreateThread call sets up the return address such that when blah() returns, it calls TerminateThread.
If blah() doesn't have any code like that, then an examination of the code is needed to see if it somehow does something thread specific which makes it fail. Offhand, I can't think of anything else (besides TerminateThread()) which might cause code written to be a thread which would prevent it from being called directly.