diff --git a/src/Makefile_Elua.am b/src/Makefile_Elua.am index c44ce1d0ea..faafc8f6d3 100644 --- a/src/Makefile_Elua.am +++ b/src/Makefile_Elua.am @@ -12,7 +12,11 @@ bin_elua_elua_CPPFLAGS = -I$(top_builddir)/src/lib/efl \ -DELUA_MODULES_DIR="\"$(datadir)/elua/modules\"" @ELUA_CFLAGS@ \ -DLOCALE_DIR=\"@LOCALE_DIR@\" \ -DPACKAGE_BUILD_DIR=\"`pwd`/$(top_builddir)\" +if HAVE_WIN32 +bin_elua_elua_LDADD = -L$(top_builddir)/src/lib/evil @ELUA_LIBS@ +else bin_elua_elua_LDADD = @ELUA_LIBS@ +endif bin_elua_elua_DEPENDENCIES = @ELUA_INTERNAL_LIBS@ eluamodulesdir = $(datadir)/elua/modules diff --git a/src/bin/elua/fork_win.c b/src/bin/elua/fork_win.c deleted file mode 100644 index 6865374901..0000000000 --- a/src/bin/elua/fork_win.c +++ /dev/null @@ -1,161 +0,0 @@ -/* an implementation of fork for Windows */ - -#include -#include - -typedef struct _OBJECT_ATTRIBUTES { - ULONG Length; - HANDLE RootDirectory; - PVOID ObjectName; - ULONG Attributes; - PVOID SecurityDescriptor; - PVOID SecurityQualityOfService; -} OBJECT_ATTRIBUTES, *POBJECT_ATTRIBUTES; - -typedef enum _MEMORY_INFORMATION_ { - MemoryBasicInformation, - MemoryWorkingSetList, - MemorySectionName, - MemoryBasicVlmInformation -} MEMORY_INFORMATION_CLASS; - -typedef struct _CLIENT_ID { - HANDLE UniqueProcess; - HANDLE UniqueThread; -} CLIENT_ID, *PCLIENT_ID; - -typedef struct _USER_STACK { - PVOID FixedStackBase; - PVOID FixedStackLimit; - PVOID ExpandableStackBase; - PVOID ExpandableStackLimit; - PVOID ExpandableStackBottom; -} USER_STACK, *PUSER_STACK; - -typedef LONG KPRIORITY; -typedef ULONG_PTR KAFFINITY; - -typedef struct _THREAD_BASIC_INFORMATION { - LONG ExitStatus; - PVOID TebBaseAddress; - CLIENT_ID ClientId; - KAFFINITY AffinityMask; - KPRIORITY Priority; - KPRIORITY BasePriority; -} THREAD_BASIC_INFORMATION, *PTHREAD_BASIC_INFORMATION; - -typedef enum _SYSTEM_INFORMATION_CLASS { - SystemHandleInformation = 0x10 -} SYSTEM_INFORMATION_CLASS; - -typedef LONG (NTAPI *ZwWriteVirtualMemory_t)(IN HANDLE, - IN PVOID, IN PVOID, IN ULONG, OUT PULONG OPTIONAL); - -typedef LONG (NTAPI *ZwCreateProcess_t)(OUT PHANDLE, - IN ACCESS_MASK, IN POBJECT_ATTRIBUTES, IN HANDLE, IN BOOLEAN, - IN HANDLE OPTIONAL, IN HANDLE OPTIONAL, IN HANDLE OPTIONAL); - -typedef LONG (WINAPI *ZwQuerySystemInformation_t)(SYSTEM_INFORMATION_CLASS, - PVOID, ULONG, PULONG); - -typedef LONG (NTAPI *ZwQueryVirtualMemory_t)(IN HANDLE, - IN PVOID, IN MEMORY_INFORMATION_CLASS, OUT PVOID, IN ULONG, - OUT PULONG OPTIONAL); - -typedef LONG (NTAPI *ZwGetContextThread_t)(IN HANDLE, - OUT PCONTEXT); - -typedef LONG (NTAPI *ZwCreateThread_t)(OUT PHANDLE, - IN ACCESS_MASK, IN POBJECT_ATTRIBUTES, IN HANDLE, OUT PCLIENT_ID, - IN PCONTEXT, IN PUSER_STACK, IN BOOLEAN); - -typedef LONG (NTAPI *ZwResumeThread_t)(IN HANDLE, OUT PULONG OPTIONAL); -typedef LONG (NTAPI *ZwClose_t)(IN HANDLE); -typedef LONG (NTAPI *ZwQueryInformationThread_t)(IN HANDLE, - IN THREAD_INFORMATION_CLASS, OUT PVOID, IN ULONG, OUT PULONG OPTIONAL); - -static ZwCreateProcess_t ZwCreateProcess; -static ZwQuerySystemInformation_t ZwQuerySystemInformation; -static ZwQueryVirtualMemory_t ZwQueryVirtualMemory; -static ZwCreateThread_t ZwCreateThread; -static ZwGetContextThread_t ZwGetContextThread; -static ZwResumeThread_t ZwResumeThread; -static ZwClose_t ZwClose; -static ZwQueryInformationThread_t ZwQueryInformationThread; -static ZwWriteVirtualMemory_t ZwWriteVirtualMemory; - -static jmp_buf jenv; -static int child_entry(void) { - longjmp(jenv, 1); - return 0; -} - -static int init_ntdll(void) { - HMODULE ntdll = GetModuleHandle("ntdll"); - if (!ntdll) return 0; - -#define FORK_WIN_GETPROC(name) name = (name##_t)GetProcAddress(ntdll, #name) - - FORK_WIN_GETPROC(ZwCreateProcess); - FORK_WIN_GETPROC(ZwQuerySystemInformation); - FORK_WIN_GETPROC(ZwQueryVirtualMemory); - FORK_WIN_GETPROC(ZwCreateThread); - FORK_WIN_GETPROC(ZwGetContextThread); - FORK_WIN_GETPROC(ZwResumeThread); - FORK_WIN_GETPROC(ZwQueryInformationThread); - FORK_WIN_GETPROC(ZwWriteVirtualMemory); - FORK_WIN_GETPROC(ZwClose); - -#undef FORK_WIN_GETPROC - - return !!ZwCreateProcess; -} - -static int fork_win(void) { - if (setjmp(jenv)) return 0; - if (!ZwCreateProcess && !init_ntdll()) return -1; - - HANDLE hproc = 0, hthread = 0; - OBJECT_ATTRIBUTES oa = { sizeof(oa) }; - ZwCreateProcess(&hproc, PROCESS_ALL_ACCESS, &oa, (HANDLE)-1, TRUE, 0, 0, 0); - - CONTEXT context = { CONTEXT_FULL | CONTEXT_DEBUG_REGISTERS - | CONTEXT_FLOATING_POINT }; - - ZwGetContextThread((HANDLE)-2, &context); - - MEMORY_BASIC_INFORMATION mbi; - -#if _WIN64 - context.Rip = (ULONG)child_entry; - ZwQueryVirtualMemory((HANDLE)-1, (PVOID)context.Rsp, MemoryBasicInformation, - &mbi, sizeof(mbi), 0); -#else - context.Eip = (ULONG)child_entry; - ZwQueryVirtualMemory((HANDLE)-1, (PVOID)context.Esp, MemoryBasicInformation, - &mbi, sizeof(mbi), 0); -#endif - - USER_STACK stack = { 0, 0, (PCHAR)mbi.BaseAddress + mbi.RegionSize, - mbi.BaseAddress, mbi.AllocationBase }; - CLIENT_ID cid; - - ZwCreateThread(&hthread, THREAD_ALL_ACCESS, &oa, hproc, &cid, &context, - &stack, TRUE); - - THREAD_BASIC_INFORMATION tbi; - ZwQueryInformationThread((HANDLE)-2, ThreadMemoryPriority, &tbi, - sizeof(tbi), 0); - PNT_TIB tib = (PNT_TIB)tbi.TebBaseAddress; - ZwQueryInformationThread(hthread, ThreadMemoryPriority, &tbi, - sizeof(tbi), 0); - ZwWriteVirtualMemory(hproc, tbi.TebBaseAddress, &tib->ExceptionList, - sizeof(tib->ExceptionList), 0); - - ZwResumeThread(hthread, 0); - - ZwClose(hthread); - ZwClose(hproc); - - return (int)cid.UniqueProcess; -} \ No newline at end of file diff --git a/src/bin/elua/io.c b/src/bin/elua/io.c index 597c7cc9a9..fbd89ea354 100644 --- a/src/bin/elua/io.c +++ b/src/bin/elua/io.c @@ -7,9 +7,6 @@ #define pipe(x, mode) pipe(x) #else #include -#include "fork_win.c" -int fork_win(void); -#define fork fork_win #define fdopen _fdopen #define execv _execv #define close _close diff --git a/src/bin/elua/main.h b/src/bin/elua/main.h index 89428ee2c0..a52f99619a 100644 --- a/src/bin/elua/main.h +++ b/src/bin/elua/main.h @@ -30,6 +30,10 @@ #include #include +#ifdef HAVE_EVIL +#include +#endif + #include #include #include diff --git a/src/lib/evil/evil_unistd.c b/src/lib/evil/evil_unistd.c index eb1c832094..0a9b6f1944 100644 --- a/src/lib/evil/evil_unistd.c +++ b/src/lib/evil/evil_unistd.c @@ -16,6 +16,8 @@ # include /* for _getcwd */ #endif +#include + #include "Evil.h" #include "evil_private.h" @@ -421,3 +423,168 @@ int execvp (const char *file EVIL_UNUSED, char *const argv[] EVIL_UNUSED) } #endif /* _WIN32_WCE */ + +/* + * Process related functions + * + */ + +#ifndef _WIN32_WCE + +typedef struct _OBJECT_ATTRIBUTES +{ + ULONG Length; + HANDLE RootDirectory; + PVOID ObjectName; + ULONG Attributes; + PVOID SecurityDescriptor; + PVOID SecurityQualityOfService; +} OBJECT_ATTRIBUTES, *POBJECT_ATTRIBUTES; + +typedef enum _MEMORY_INFORMATION_ +{ + MemoryBasicInformation, + MemoryWorkingSetList, + MemorySectionName, + MemoryBasicVlmInformation +} MEMORY_INFORMATION_CLASS; + +typedef struct _CLIENT_ID +{ + HANDLE UniqueProcess; + HANDLE UniqueThread; +} CLIENT_ID, *PCLIENT_ID; + +typedef struct _USER_STACK +{ + PVOID FixedStackBase; + PVOID FixedStackLimit; + PVOID ExpandableStackBase; + PVOID ExpandableStackLimit; + PVOID ExpandableStackBottom; +} USER_STACK, *PUSER_STACK; + +typedef LONG KPRIORITY; +typedef ULONG_PTR KAFFINITY; + +typedef struct _THREAD_BASIC_INFORMATION +{ + LONG ExitStatus; + PVOID TebBaseAddress; + CLIENT_ID ClientId; + KAFFINITY AffinityMask; + KPRIORITY Priority; + KPRIORITY BasePriority; +} THREAD_BASIC_INFORMATION, *PTHREAD_BASIC_INFORMATION; + +typedef enum _SYSTEM_INFORMATION_CLASS +{ + SystemHandleInformation = 0x10 +} SYSTEM_INFORMATION_CLASS; + +typedef LONG (NTAPI *ZwWriteVirtualMemory_t )(IN HANDLE, IN PVOID, IN PVOID, IN ULONG, OUT PULONG OPTIONAL); +typedef LONG (NTAPI *ZwCreateProcess_t )(OUT PHANDLE, IN ACCESS_MASK, IN POBJECT_ATTRIBUTES, IN HANDLE, IN BOOLEAN, IN HANDLE OPTIONAL, IN HANDLE OPTIONAL, IN HANDLE OPTIONAL); +typedef LONG (WINAPI *ZwQuerySystemInformation_t)(SYSTEM_INFORMATION_CLASS, PVOID, ULONG, PULONG); +typedef LONG (NTAPI *ZwQueryVirtualMemory_t )(IN HANDLE, IN PVOID, IN MEMORY_INFORMATION_CLASS, OUT PVOID, IN ULONG, OUT PULONG OPTIONAL); +typedef LONG (NTAPI *ZwGetContextThread_t )(IN HANDLE, OUT PCONTEXT); +typedef LONG (NTAPI *ZwCreateThread_t )(OUT PHANDLE, IN ACCESS_MASK, IN POBJECT_ATTRIBUTES, IN HANDLE, OUT PCLIENT_ID, IN PCONTEXT, IN PUSER_STACK, IN BOOLEAN); +typedef LONG (NTAPI *ZwResumeThread_t )(IN HANDLE, OUT PULONG OPTIONAL); +typedef LONG (NTAPI *ZwClose_t )(IN HANDLE); +typedef LONG (NTAPI *ZwQueryInformationThread_t)(IN HANDLE, IN THREAD_INFORMATION_CLASS, OUT PVOID, IN ULONG, OUT PULONG OPTIONAL); + +static ZwCreateProcess_t ZwCreateProcess; +static ZwQuerySystemInformation_t ZwQuerySystemInformation; +static ZwQueryVirtualMemory_t ZwQueryVirtualMemory; +static ZwCreateThread_t ZwCreateThread; +static ZwGetContextThread_t ZwGetContextThread; +static ZwResumeThread_t ZwResumeThread; +static ZwClose_t ZwClose; +static ZwQueryInformationThread_t ZwQueryInformationThread; +static ZwWriteVirtualMemory_t ZwWriteVirtualMemory; + +static jmp_buf jenv; +static int +child_entry(void) +{ + longjmp(jenv, 1); + return 0; +} + +static int +init_ntdll(void) +{ + HMODULE ntdll = GetModuleHandle("ntdll"); + if (!ntdll) return 0; + +#define FORK_WIN_GETPROC(name) name = (name##_t)GetProcAddress(ntdll, #name) + + FORK_WIN_GETPROC(ZwCreateProcess); + FORK_WIN_GETPROC(ZwQuerySystemInformation); + FORK_WIN_GETPROC(ZwQueryVirtualMemory); + FORK_WIN_GETPROC(ZwCreateThread); + FORK_WIN_GETPROC(ZwGetContextThread); + FORK_WIN_GETPROC(ZwResumeThread); + FORK_WIN_GETPROC(ZwQueryInformationThread); + FORK_WIN_GETPROC(ZwWriteVirtualMemory); + FORK_WIN_GETPROC(ZwClose); + +#undef FORK_WIN_GETPROC + + return !!ZwCreateProcess; +} + +int +evil_fork(void) +{ + if (setjmp(jenv)) + return 0; + + if (!ZwCreateProcess && !init_ntdll()) + return -1; + + HANDLE hproc = 0, hthread = 0; + OBJECT_ATTRIBUTES oa = { sizeof(oa) }; + ZwCreateProcess(&hproc, PROCESS_ALL_ACCESS, &oa, (HANDLE)-1, TRUE, 0, 0, 0); + + CONTEXT context = { CONTEXT_FULL | CONTEXT_DEBUG_REGISTERS + | CONTEXT_FLOATING_POINT }; + + ZwGetContextThread((HANDLE)-2, &context); + + MEMORY_BASIC_INFORMATION mbi; + +#if _WIN64 + context.Rip = (ULONG)child_entry; + ZwQueryVirtualMemory((HANDLE)-1, (PVOID)context.Rsp, MemoryBasicInformation, + &mbi, sizeof(mbi), 0); +#else + context.Eip = (ULONG)child_entry; + ZwQueryVirtualMemory((HANDLE)-1, (PVOID)context.Esp, MemoryBasicInformation, + &mbi, sizeof(mbi), 0); +#endif + + USER_STACK stack = { 0, 0, (PCHAR)mbi.BaseAddress + mbi.RegionSize, + mbi.BaseAddress, mbi.AllocationBase }; + CLIENT_ID cid; + + ZwCreateThread(&hthread, THREAD_ALL_ACCESS, &oa, hproc, &cid, &context, + &stack, TRUE); + + THREAD_BASIC_INFORMATION tbi; + ZwQueryInformationThread((HANDLE)-2, ThreadMemoryPriority, &tbi, + sizeof(tbi), 0); + PNT_TIB tib = (PNT_TIB)tbi.TebBaseAddress; + ZwQueryInformationThread(hthread, ThreadMemoryPriority, &tbi, + sizeof(tbi), 0); + ZwWriteVirtualMemory(hproc, tbi.TebBaseAddress, &tib->ExceptionList, + sizeof(tib->ExceptionList), 0); + + ZwResumeThread(hthread, 0); + + ZwClose(hthread); + ZwClose(hproc); + + return (int)cid.UniqueProcess; +} + +#endif /* _WIN32_WCE */ diff --git a/src/lib/evil/evil_unistd.h b/src/lib/evil/evil_unistd.h index 55b6612996..370c9421a7 100644 --- a/src/lib/evil/evil_unistd.h +++ b/src/lib/evil/evil_unistd.h @@ -318,6 +318,37 @@ EAPI int execvp( const char *file, char *const argv[]); #endif /* _WIN32_WCE */ +/* + * Process related functions + * + */ + +#ifndef _WIN32_WCE + +/** + * @brief Duplicate the calling process. + * + * @return 0 on child, the child's PID on parent. + * + * Duplicate the existing process from which it is called. You then decide + * which process you're in by checking the return value - it'll always be 0 + * for the child process and the child process' PID for the parent. + * + * Conformity: None. + * + * Supported OS: NT based Windows. + */ +EAPI int evil_fork(void); + +/** + * @def fork() + * + * Wrapper around evil_fork(). + */ +#define fork() evil_fork() + +#endif /* _WIN32_WCE */ + /** * @}