mirror of
https://github.com/rapid7/metasploit-payloads
synced 2024-12-08 23:33:07 +01:00
fix Linux threads to actually use allocated memory
This commit is contained in:
parent
be88efcb54
commit
f95152dfc1
@ -21,17 +21,16 @@ int __futex_wake(volatile void *ftx, int count);
|
||||
* when using CriticalSections with OpenSSL on some Windows systems. Mutex's are not as optimal
|
||||
* as CriticalSections but they appear to resolve the OpenSSL deadlock issue.
|
||||
*/
|
||||
LOCK * lock_create( VOID )
|
||||
LOCK * lock_create(VOID)
|
||||
{
|
||||
LOCK * lock = (LOCK *)malloc( sizeof( LOCK ) );
|
||||
if( lock != NULL )
|
||||
LOCK * lock = calloc(1, sizeof(LOCK));
|
||||
if (lock != NULL)
|
||||
{
|
||||
memset( lock, 0, sizeof( LOCK ) );
|
||||
|
||||
#ifdef _WIN32
|
||||
lock->handle = CreateMutex( NULL, FALSE, NULL );
|
||||
lock->handle = CreateMutex(NULL, FALSE, NULL);
|
||||
#else
|
||||
pthread_mutex_init(lock->handle, NULL);
|
||||
pthread_mutex_init(&lock->handle, NULL);
|
||||
#endif
|
||||
}
|
||||
return lock;
|
||||
@ -40,32 +39,32 @@ LOCK * lock_create( VOID )
|
||||
/*
|
||||
* Destroy a lock that is no longer required.
|
||||
*/
|
||||
VOID lock_destroy( LOCK * lock )
|
||||
VOID lock_destroy(LOCK * lock)
|
||||
{
|
||||
if( lock != NULL )
|
||||
if (lock != NULL )
|
||||
{
|
||||
lock_release( lock );
|
||||
lock_release(lock);
|
||||
|
||||
#ifdef _WIN32
|
||||
CloseHandle( lock->handle );
|
||||
CloseHandle(lock->handle);
|
||||
#else
|
||||
pthread_mutex_destroy(lock->handle);
|
||||
pthread_mutex_destroy(&lock->handle);
|
||||
#endif
|
||||
|
||||
free( lock );
|
||||
free(lock);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Acquire a lock and block untill it is acquired.
|
||||
*/
|
||||
VOID lock_acquire( LOCK * lock )
|
||||
VOID lock_acquire(LOCK * lock)
|
||||
{
|
||||
if( lock != NULL ) {
|
||||
if (lock != NULL ) {
|
||||
#ifdef _WIN32
|
||||
WaitForSingleObject( lock->handle, INFINITE );
|
||||
WaitForSingleObject(lock->handle, INFINITE);
|
||||
#else
|
||||
pthread_mutex_lock(lock->handle);
|
||||
pthread_mutex_lock(&lock->handle);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
@ -73,13 +72,13 @@ VOID lock_acquire( LOCK * lock )
|
||||
/*
|
||||
* Release a lock previously held.
|
||||
*/
|
||||
VOID lock_release( LOCK * lock )
|
||||
VOID lock_release(LOCK * lock)
|
||||
{
|
||||
if( lock != NULL ) {
|
||||
if (lock != NULL ) {
|
||||
#ifdef _WIN32
|
||||
ReleaseMutex( lock->handle );
|
||||
ReleaseMutex(lock->handle);
|
||||
#else
|
||||
pthread_mutex_unlock(lock->handle);
|
||||
pthread_mutex_unlock(&lock->handle);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
@ -89,21 +88,21 @@ VOID lock_release( LOCK * lock )
|
||||
/*
|
||||
* Create a new event which can be signaled/polled/and blocked on.
|
||||
*/
|
||||
EVENT * event_create( VOID )
|
||||
EVENT * event_create(VOID)
|
||||
{
|
||||
EVENT * event = NULL;
|
||||
|
||||
event = (EVENT *)malloc( sizeof( EVENT ) );
|
||||
if( event == NULL )
|
||||
event = (EVENT *)malloc(sizeof(EVENT));
|
||||
if (event == NULL)
|
||||
return NULL;
|
||||
|
||||
memset( event, 0, sizeof( EVENT ) );
|
||||
memset(event, 0, sizeof(EVENT));
|
||||
|
||||
#ifdef _WIN32
|
||||
event->handle = CreateEvent( NULL, FALSE, FALSE, NULL );
|
||||
if( event->handle == NULL )
|
||||
event->handle = CreateEvent(NULL, FALSE, FALSE, NULL);
|
||||
if (event->handle == NULL)
|
||||
{
|
||||
free( event );
|
||||
free(event);
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
@ -114,16 +113,16 @@ EVENT * event_create( VOID )
|
||||
/*
|
||||
* Destroy an event.
|
||||
*/
|
||||
BOOL event_destroy( EVENT * event )
|
||||
BOOL event_destroy(EVENT * event)
|
||||
{
|
||||
if( event == NULL )
|
||||
if (event == NULL)
|
||||
return FALSE;
|
||||
|
||||
#ifdef _WIN32
|
||||
CloseHandle( event->handle );
|
||||
CloseHandle(event->handle);
|
||||
#endif
|
||||
|
||||
free( event );
|
||||
free(event);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
@ -131,15 +130,15 @@ BOOL event_destroy( EVENT * event )
|
||||
/*
|
||||
* Signal an event.
|
||||
*/
|
||||
BOOL event_signal( EVENT * event )
|
||||
BOOL event_signal(EVENT * event)
|
||||
{
|
||||
if( event == NULL )
|
||||
if (event == NULL)
|
||||
return FALSE;
|
||||
|
||||
#ifdef _WIN32
|
||||
dprintf( "Signalling 0x%x", event->handle );
|
||||
if( SetEvent( event->handle ) == 0 ) {
|
||||
dprintf( "Signalling 0x%x failed %u", event->handle, GetLastError() );
|
||||
dprintf("Signalling 0x%x", event->handle);
|
||||
if (SetEvent(event->handle) == 0) {
|
||||
dprintf("Signalling 0x%x failed %u", event->handle, GetLastError());
|
||||
return FALSE;
|
||||
}
|
||||
#else
|
||||
@ -154,13 +153,13 @@ BOOL event_signal( EVENT * event )
|
||||
* Poll an event to see if it has been signaled. Set timeout to -1 to block indefinatly.
|
||||
* If timeout is 0 this function does not block but returns immediately.
|
||||
*/
|
||||
BOOL event_poll( EVENT * event, DWORD timeout )
|
||||
BOOL event_poll(EVENT * event, DWORD timeout)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
if( event == NULL )
|
||||
if (event == NULL)
|
||||
return FALSE;
|
||||
|
||||
if( WaitForSingleObject( event->handle, timeout ) == WAIT_OBJECT_0 )
|
||||
if (WaitForSingleObject(event->handle, timeout) == WAIT_OBJECT_0)
|
||||
return TRUE;
|
||||
|
||||
return FALSE;
|
||||
@ -170,13 +169,13 @@ BOOL event_poll( EVENT * event, DWORD timeout )
|
||||
// DWORD WINAPI WaitForSingleObject(
|
||||
// __in HANDLE hHandle,
|
||||
// __in DWORD dwMilliseconds
|
||||
// );
|
||||
//);
|
||||
// http://msdn.microsoft.com/en-us/library/ms687032(VS.85).aspx
|
||||
|
||||
if( event == NULL )
|
||||
if (event == NULL)
|
||||
return FALSE;
|
||||
|
||||
if(timeout) {
|
||||
if (timeout) {
|
||||
struct timespec ts;
|
||||
|
||||
// XXX, need to verify for -1. below modified from bionic/pthread.c
|
||||
@ -198,7 +197,7 @@ BOOL event_poll( EVENT * event, DWORD timeout )
|
||||
|
||||
// We should behave like an auto-reset event
|
||||
result = event->handle ? TRUE : FALSE;
|
||||
if( result )
|
||||
if (result)
|
||||
event->handle = (HANDLE)0;
|
||||
|
||||
return result;
|
||||
@ -210,7 +209,7 @@ BOOL event_poll( EVENT * event, DWORD timeout )
|
||||
/*
|
||||
* Opens and create a THREAD item for the current/calling thread.
|
||||
*/
|
||||
THREAD * thread_open( VOID )
|
||||
THREAD * thread_open(VOID)
|
||||
{
|
||||
THREAD * thread = NULL;
|
||||
#ifdef _WIN32
|
||||
@ -218,10 +217,10 @@ THREAD * thread_open( VOID )
|
||||
HMODULE hKernel32 = NULL;
|
||||
|
||||
|
||||
thread = (THREAD *)malloc( sizeof( THREAD ) );
|
||||
if( thread != NULL )
|
||||
thread = (THREAD *)malloc(sizeof(THREAD));
|
||||
if (thread != NULL)
|
||||
{
|
||||
memset( thread, 0, sizeof(THREAD) );
|
||||
memset(thread, 0, sizeof(THREAD));
|
||||
|
||||
thread->id = GetCurrentThreadId();
|
||||
thread->sigterm = event_create();
|
||||
@ -231,41 +230,41 @@ THREAD * thread_open( VOID )
|
||||
// for now.
|
||||
|
||||
// First we try to use the normal OpenThread function, available on Windows 2000 and up...
|
||||
hKernel32 = LoadLibrary( "kernel32.dll" );
|
||||
pOpenThread = (OPENTHREAD)GetProcAddress( hKernel32, "OpenThread" );
|
||||
if( pOpenThread )
|
||||
hKernel32 = LoadLibrary("kernel32.dll");
|
||||
pOpenThread = (OPENTHREAD)GetProcAddress(hKernel32, "OpenThread");
|
||||
if (pOpenThread)
|
||||
{
|
||||
thread->handle = pOpenThread( THREAD_TERMINATE|THREAD_SUSPEND_RESUME, FALSE, thread->id );
|
||||
thread->handle = pOpenThread(THREAD_TERMINATE|THREAD_SUSPEND_RESUME, FALSE, thread->id);
|
||||
}
|
||||
else
|
||||
{
|
||||
NTOPENTHREAD pNtOpenThread = NULL;
|
||||
// If we can't use OpenThread, we try the older NtOpenThread function as found on NT4 machines.
|
||||
HMODULE hNtDll = LoadLibrary( "ntdll.dll" );
|
||||
pNtOpenThread = (NTOPENTHREAD)GetProcAddress( hNtDll, "NtOpenThread" );
|
||||
if( pNtOpenThread )
|
||||
HMODULE hNtDll = LoadLibrary("ntdll.dll");
|
||||
pNtOpenThread = (NTOPENTHREAD)GetProcAddress(hNtDll, "NtOpenThread");
|
||||
if (pNtOpenThread)
|
||||
{
|
||||
_OBJECT_ATTRIBUTES oa = {0};
|
||||
_CLIENT_ID cid = {0};
|
||||
|
||||
cid.UniqueThread = (PVOID)thread->id;
|
||||
|
||||
pNtOpenThread( &thread->handle, THREAD_TERMINATE|THREAD_SUSPEND_RESUME, &oa, &cid );
|
||||
pNtOpenThread(&thread->handle, THREAD_TERMINATE|THREAD_SUSPEND_RESUME, &oa, &cid);
|
||||
}
|
||||
|
||||
FreeLibrary( hNtDll );
|
||||
FreeLibrary(hNtDll);
|
||||
}
|
||||
|
||||
FreeLibrary( hKernel32 );
|
||||
FreeLibrary(hKernel32);
|
||||
}
|
||||
|
||||
return thread;
|
||||
#else
|
||||
thread = (THREAD *)malloc( sizeof( THREAD ) );
|
||||
thread = (THREAD *)malloc(sizeof(THREAD));
|
||||
|
||||
if( thread != NULL )
|
||||
if (thread != NULL)
|
||||
{
|
||||
memset( thread, 0, sizeof(THREAD) );
|
||||
memset(thread, 0, sizeof(THREAD));
|
||||
|
||||
thread->id = gettid();
|
||||
thread->sigterm = event_create();
|
||||
@ -320,7 +319,7 @@ void *__paused_thread(void *req)
|
||||
thread = tc->thread;
|
||||
free(tc);
|
||||
|
||||
if(event_poll(thread->sigterm, 0) == TRUE) {
|
||||
if (event_poll(thread->sigterm, 0) == TRUE) {
|
||||
/*
|
||||
* In some cases, we might want to stop a thread before it does anything :/
|
||||
*/
|
||||
@ -334,23 +333,23 @@ void *__paused_thread(void *req)
|
||||
/*
|
||||
* Create a new thread in a suspended state.
|
||||
*/
|
||||
THREAD * thread_create( THREADFUNK funk, LPVOID param1, LPVOID param2, LPVOID param3 )
|
||||
THREAD * thread_create(THREADFUNK funk, LPVOID param1, LPVOID param2, LPVOID param3)
|
||||
{
|
||||
THREAD * thread = NULL;
|
||||
|
||||
if( funk == NULL )
|
||||
if (funk == NULL)
|
||||
return NULL;
|
||||
|
||||
thread = (THREAD *)malloc( sizeof( THREAD ) );
|
||||
if( thread == NULL )
|
||||
thread = (THREAD *)malloc(sizeof(THREAD));
|
||||
if (thread == NULL)
|
||||
return NULL;
|
||||
|
||||
memset( thread, 0, sizeof( THREAD ) );
|
||||
memset(thread, 0, sizeof(THREAD));
|
||||
|
||||
thread->sigterm = event_create();
|
||||
if( thread->sigterm == NULL )
|
||||
if (thread->sigterm == NULL)
|
||||
{
|
||||
free( thread );
|
||||
free(thread);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -360,12 +359,12 @@ THREAD * thread_create( THREADFUNK funk, LPVOID param1, LPVOID param2, LPVOID pa
|
||||
thread->parameter3 = param3;
|
||||
|
||||
#ifdef _WIN32
|
||||
thread->handle = CreateThread( NULL, 0, funk, thread, CREATE_SUSPENDED, &thread->id );
|
||||
thread->handle = CreateThread(NULL, 0, funk, thread, CREATE_SUSPENDED, &thread->id);
|
||||
|
||||
if( thread->handle == NULL )
|
||||
if (thread->handle == NULL)
|
||||
{
|
||||
event_destroy( thread->sigterm );
|
||||
free( thread );
|
||||
event_destroy(thread->sigterm);
|
||||
free(thread);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -381,13 +380,13 @@ THREAD * thread_create( THREADFUNK funk, LPVOID param1, LPVOID param2, LPVOID pa
|
||||
struct thread_conditional *tc;
|
||||
tc = (struct thread_conditional *) malloc(sizeof(struct thread_conditional));
|
||||
|
||||
if( tc == NULL ) {
|
||||
if (tc == NULL) {
|
||||
event_destroy(thread->sigterm);
|
||||
free(thread);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
memset( tc, 0, sizeof(struct thread_conditional));
|
||||
memset(tc, 0, sizeof(struct thread_conditional));
|
||||
|
||||
pthread_mutex_init(&tc->suspend_mutex, NULL);
|
||||
pthread_cond_init(&tc->suspend_cond, NULL);
|
||||
@ -397,7 +396,7 @@ THREAD * thread_create( THREADFUNK funk, LPVOID param1, LPVOID param2, LPVOID pa
|
||||
|
||||
thread->suspend_thread_data = (void *)(tc);
|
||||
|
||||
if(pthread_create(&(thread->pid), NULL, __paused_thread, tc) == -1) {
|
||||
if (pthread_create(&(thread->pid), NULL, __paused_thread, tc) == -1) {
|
||||
free(tc);
|
||||
event_destroy(thread->sigterm);
|
||||
free(thread);
|
||||
@ -414,13 +413,13 @@ THREAD * thread_create( THREADFUNK funk, LPVOID param1, LPVOID param2, LPVOID pa
|
||||
/*
|
||||
* Run a thread.
|
||||
*/
|
||||
BOOL thread_run( THREAD * thread )
|
||||
BOOL thread_run(THREAD * thread)
|
||||
{
|
||||
if( thread == NULL )
|
||||
if (thread == NULL)
|
||||
return FALSE;
|
||||
|
||||
#ifdef _WIN32
|
||||
if( ResumeThread( thread->handle ) < 0 )
|
||||
if (ResumeThread(thread->handle) < 0)
|
||||
return FALSE;
|
||||
|
||||
#else
|
||||
@ -440,14 +439,14 @@ BOOL thread_run( THREAD * thread )
|
||||
* Signals the thread to terminate. It is the responsibility of the thread to wait for and process this signal.
|
||||
* Should be used to signal the thread to terminate.
|
||||
*/
|
||||
BOOL thread_sigterm( THREAD * thread )
|
||||
BOOL thread_sigterm(THREAD * thread)
|
||||
{
|
||||
BOOL ret;
|
||||
|
||||
if( thread == NULL )
|
||||
if (thread == NULL)
|
||||
return FALSE;
|
||||
|
||||
ret = event_signal( thread->sigterm );
|
||||
ret = event_signal(thread->sigterm);
|
||||
|
||||
#ifndef _WIN32
|
||||
/*
|
||||
@ -456,7 +455,7 @@ BOOL thread_sigterm( THREAD * thread )
|
||||
*
|
||||
* Therefore, we need to start the thread executing before calling thread_join
|
||||
*/
|
||||
if(thread->thread_started != TRUE) {
|
||||
if (thread->thread_started != TRUE) {
|
||||
thread_run(thread);
|
||||
}
|
||||
#endif
|
||||
@ -467,13 +466,13 @@ BOOL thread_sigterm( THREAD * thread )
|
||||
/*
|
||||
* Terminate a thread. Use with caution! better to signal your thread to terminate and wait for it to do so.
|
||||
*/
|
||||
BOOL thread_kill( THREAD * thread )
|
||||
BOOL thread_kill(THREAD * thread)
|
||||
{
|
||||
if( thread == NULL )
|
||||
if (thread == NULL)
|
||||
return FALSE;
|
||||
|
||||
#ifdef _WIN32
|
||||
if( TerminateThread( thread->handle, -1 ) == 0 )
|
||||
if (TerminateThread(thread->handle, -1) == 0)
|
||||
return FALSE;
|
||||
|
||||
return TRUE;
|
||||
@ -498,18 +497,18 @@ BOOL thread_kill( THREAD * thread )
|
||||
/*
|
||||
* Blocks untill the thread has terminated.
|
||||
*/
|
||||
BOOL thread_join( THREAD * thread )
|
||||
BOOL thread_join(THREAD * thread)
|
||||
{
|
||||
if( thread == NULL )
|
||||
if (thread == NULL)
|
||||
return FALSE;
|
||||
|
||||
#ifdef _WIN32
|
||||
if( WaitForSingleObject( thread->handle, INFINITE ) == WAIT_OBJECT_0 )
|
||||
if (WaitForSingleObject(thread->handle, INFINITE) == WAIT_OBJECT_0)
|
||||
return TRUE;
|
||||
|
||||
return FALSE;
|
||||
#else
|
||||
if(pthread_join(thread->pid, NULL) == 0)
|
||||
if (pthread_join(thread->pid, NULL) == 0)
|
||||
return TRUE;
|
||||
|
||||
return FALSE;
|
||||
@ -520,20 +519,20 @@ BOOL thread_join( THREAD * thread )
|
||||
* Destroys a previously created thread. Note, this does not terminate the thread. You must signal your
|
||||
* thread to terminate and wait for it to do so (via thread_signal/thread_join).
|
||||
*/
|
||||
BOOL thread_destroy( THREAD * thread )
|
||||
BOOL thread_destroy(THREAD * thread)
|
||||
{
|
||||
if( thread == NULL )
|
||||
if (thread == NULL)
|
||||
return FALSE;
|
||||
|
||||
event_destroy( thread->sigterm );
|
||||
event_destroy(thread->sigterm);
|
||||
|
||||
#ifdef _WIN32
|
||||
CloseHandle( thread->handle );
|
||||
CloseHandle(thread->handle);
|
||||
#else
|
||||
pthread_detach(thread->pid);
|
||||
#endif
|
||||
|
||||
free( thread );
|
||||
free(thread);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
@ -44,7 +44,7 @@ typedef struct _LOCK
|
||||
#ifdef _WIN32
|
||||
HANDLE handle;
|
||||
#else
|
||||
pthread_mutex_t *handle;
|
||||
pthread_mutex_t handle;
|
||||
#endif // _WIN32
|
||||
} LOCK, * LPLOCK;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user