#include "progwrp.h" #include "export.h" #include "implementations.h" #ifdef _M_IX86 _allmul() { __asm { pop ebx ; assembler was adding push ebx by default, so adding this mov eax, [esp+8] mov ecx, [esp+16] or ecx, eax mov ecx, [esp+12] jnz hard mov eax, [esp+4] mul ecx ret 16 hard: push ebx mul ecx mov ebx, eax mov eax, [esp+8] mul dword ptr [esp+20] add ebx, eax mov eax, [esp+8] mul ecx add edx, ebx pop ebx ret 16 } } _aulldiv() { __asm { pop ebx pop esi push ebx push esi mov eax, [esp+24] or eax, eax jnz hard mov ecx, [esp+20] mov eax, [esp+16] xor edx, edx div ecx mov ebx, eax mov eax, [esp+12] div ecx mov edx, ebx jmp result hard: mov ecx, eax mov ebx, [esp+20] mov edx, [esp+16] mov eax, [esp+12] loop_shr: shr ecx, 1 rcr ebx, 1 shr edx, 1 rcr eax, 1 or ecx, ecx jnz loop_shr div ebx mov esi, eax mul dword ptr [esp+24] mov ecx, eax mov eax, [esp+20] mul esi add edx, ecx jb decrement cmp edx, [esp+10] ja decrement jb xor_edx cmp eax, [esp+12] jbe xor_edx decrement: dec esi xor_edx: xor edx, edx mov eax, esi result: pop esi pop ebx ret 16 } } #endif HANDLE WINAPI Implementation_CreateRemoteThreadEx( HANDLE hProcess, LPSECURITY_ATTRIBUTES lpThreadAttributes, SIZE_T dwStackSize, LPTHREAD_START_ROUTINE lpStartAddress, LPVOID lpParameter, DWORD dwCreationFlags, LPPROC_THREAD_ATTRIBUTE_LIST lpAttributeList, LPDWORD lpThreadId ) /* Only difference is the use of thread attributes. Not applicable in XP and below... I could add support for a few of the attributes (ideal processor, inherited handles, nested job objects> - unless I can attach them to generic handles). */ { return CreateRemoteThread(hProcess, lpThreadAttributes, dwStackSize, lpStartAddress, lpParameter, dwCreationFlags, lpThreadId); } // Flags to indicate if an attribute is present in the list. // I believe these are used so that Windows doesn't have to scan the complete list to see if an attribute is present. #define PARENT_PROCESS (1 << ProcThreadAttributeParentProcess) #define EXTENDED_FLAGS (1 << ProcThreadAttributeExtendedFlags) #define HANDLE_LIST (1 << ProcThreadAttributeHandleList) #define GROUP_AFFINITY (1 << ProcThreadAttributeGroupAffinity) #define PREFERRED_NODE (1 << ProcThreadAttributePreferredNode) #define IDEAL_PROCESSOR (1 << ProcThreadAttributeIdealProcessor) #define UMS_THREAD (1 << ProcThreadAttributeUmsThread) #define MITIGATION_POLICY (1 << ProcThreadAttributeMitigationPolicy) // This structure stores the value for each attribute typedef struct _PROC_THREAD_ATTRIBUTE_ENTRY { DWORD_PTR Attribute; // PROC_THREAD_ATTRIBUTE_xxx SIZE_T cbSize; PVOID lpValue; } PROC_THREAD_ATTRIBUTE_ENTRY, *LPPROC_THREAD_ATTRIBUTE_ENTRY; // This structure contains a list of attributes that have been added using UpdateProcThreadAttribute typedef struct _PROC_THREAD_ATTRIBUTE_LIST { DWORD dwFlags; ULONG Size; ULONG Count; ULONG Reserved; PULONG Unknown; PROC_THREAD_ATTRIBUTE_ENTRY Entries[ANYSIZE_ARRAY]; } PROC_THREAD_ATTRIBUTE_LIST, *LPPROC_THREAD_ATTRIBUTE_LIST; BOOL WINAPI Implementation_InitializeProcThreadAttributeList( LPPROC_THREAD_ATTRIBUTE_LIST lpAttributeList, DWORD dwAttributeCount, DWORD dwFlags, PSIZE_T lpSize ) { if(!lpSize) { SetLastError(ERROR_INVALID_PARAMETER); return FALSE; } *lpSize = sizeof(PROC_THREAD_ATTRIBUTE_LIST)+ (sizeof(PROC_THREAD_ATTRIBUTE_ENTRY) * dwAttributeCount); if(!lpAttributeList) return FALSE; else { lpAttributeList->Count = dwAttributeCount; lpAttributeList->Size = *lpSize; return TRUE; } return FALSE; } BOOL WINAPI Implementation_UpdateProcThreadAttribute( LPPROC_THREAD_ATTRIBUTE_LIST lpAttributeList, DWORD dwFlags, DWORD_PTR Attribute, PVOID lpValue, SIZE_T cbSize, PVOID lpPreviousValue, PSIZE_T lpReturnSize ) { if(dwFlags || !lpAttributeList) { SetLastError(ERROR_INVALID_PARAMETER); return FALSE; } switch(Attribute) { case PROC_THREAD_ATTRIBUTE_HANDLE_LIST: lpAttributeList->Entries[0].Attribute = Attribute; lpAttributeList->dwFlags |= 1; lpAttributeList->Entries[0].lpValue = lpValue; return TRUE; break; } return FALSE; } void WINAPI Implementation_DeleteProcThreadAttributeList( LPPROC_THREAD_ATTRIBUTE_LIST lpAttributeList ) { ; } BOOL WINAPI Implementation_QueryFullProcessImageNameW( HANDLE hProcess, DWORD dwFlags, LPWSTR lpExeName, PDWORD lpdwSize ) { return FALSE; } BOOL WINAPI Implementation_QueryFullProcessImageNameA( HANDLE hProcess, DWORD dwFlags, LPSTR lpExeName, PDWORD lpdwSize ) { return FALSE; } BOOL WINAPI Implementation_QueryThreadCycleTime( HANDLE ThreadHandle, PULONG64 CycleTime ) { LARGE_INTEGER QpcFirst; LARGE_INTEGER QpcLast; LARGE_INTEGER CtFreq; ULONG64 TscFirst; ULONG64 TscLast; ULONG64 TscFreq; ULONG64 Delta; ULONG64 Dividend; DWORD OldTp; ULONG64 CreationTime, ExitTime, KernelTime, UserTime; if(!CycleTime) { SetLastError(ERROR_INVALID_PARAMETER); return FALSE; } OldTp = GetThreadPriority(GetCurrentThread()); SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_HIGHEST); TscFirst = __rdtsc(); QueryPerformanceCounter(&QpcFirst); TscLast = __rdtsc(); QueryPerformanceCounter(&QpcLast); SetThreadPriority(GetCurrentThread(), OldTp); QueryPerformanceFrequency(&CtFreq); if(!CtFreq.QuadPart) CtFreq.QuadPart = 1000; Delta = QpcLast.QuadPart - QpcFirst.QuadPart; Dividend = Delta / CtFreq.QuadPart; if(!Dividend) Dividend = 1; TscFreq = (TscLast - TscFirst) / Dividend; if(!GetThreadTimes(ThreadHandle, &CreationTime, &ExitTime, &KernelTime, &UserTime)) return FALSE; *CycleTime = ((KernelTime + UserTime) / 10000000) * TscFreq; return TRUE; } BOOL WINAPI Implementation_QueryProcessCycleTime( HANDLE ProcessHandle, PULONG64 CycleTime ) { LARGE_INTEGER QpcFirst; LARGE_INTEGER QpcLast; LARGE_INTEGER CtFreq; ULONG64 TscFirst; ULONG64 TscLast; ULONG64 TscFreq; ULONG64 Delta; ULONG64 Dividend; DWORD OldTp; ULONG64 CreationTime, ExitTime, KernelTime, UserTime; if(!CycleTime) { SetLastError(ERROR_INVALID_PARAMETER); return FALSE; } OldTp = GetThreadPriority(GetCurrentThread()); SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_HIGHEST); TscFirst = __rdtsc(); QueryPerformanceCounter(&QpcFirst); TscLast = __rdtsc(); QueryPerformanceCounter(&QpcLast); SetThreadPriority(GetCurrentThread(), OldTp); QueryPerformanceFrequency(&CtFreq); if(!CtFreq.QuadPart) CtFreq.QuadPart = 1000; Delta = QpcLast.QuadPart - QpcFirst.QuadPart; Dividend = Delta / CtFreq.QuadPart; if(!Dividend) Dividend = 1; TscFreq = (TscLast - TscFirst) / Dividend; if(!GetProcessTimes(ProcessHandle, &CreationTime, &ExitTime, &KernelTime, &UserTime)) return FALSE; *CycleTime = ((KernelTime + UserTime) / 10000000) * TscFreq; return TRUE; } BOOL WINAPI Implementation_GetNamedPipeServerProcessId( HANDLE Pipe, PULONG ServerProcessId ) { return FALSE; } BOOL WINAPI Implementation_GetNamedPipeClientProcessId( HANDLE Pipe, PULONG ClientProcessId ) { return FALSE; } BOOL WINAPI Implementation_Wow64GetThreadContext( HANDLE hThread, PWOW64_CONTEXT lpContext ) { return FALSE; } #define ThreadBasicInformation 0 typedef struct _THREAD_BASIC_INFORMATION { NTSTATUS ExitStatus; PVOID TebBaseAddress; CLIENT_ID ClientId; KAFFINITY AffinityMask; KPRIORITY Priority; KPRIORITY BasePriority; } THREAD_BASIC_INFORMATION, *PTHREAD_BASIC_INFORMATION; DWORD WINAPI Implementation_GetThreadId( HANDLE Thread ) { THREAD_BASIC_INFORMATION tbi; NTSTATUS Status = NtQueryInformationThread(Thread, ThreadBasicInformation, (PVOID)&tbi, sizeof(THREAD_BASIC_INFORMATION), NULL); if(Status) { BaseSetLastNTError(Status); return 0; } return (DWORD)tbi.ClientId.UniqueThread; } #ifdef _M_IX86 NTSTATUS NTAPI NtSetInformationProcess(HANDLE ProcessHandle, ULONG ProcessInfoClass, PVOID ProcessInformation, ULONG InfoLength); BOOL WINAPI Implementation_SetProcessDEPPolicy(DWORD dwFlags) { DWORD dwFlagscpy; NTSTATUS Status; dwFlagscpy = dwFlags; if ( (dwFlags & 0xFFFFFFFC) != 0 ) //check that only bits 0 and 1 are set { BaseSetLastNTError(STATUS_INVALID_PARAMETER); return FALSE; } if ( (dwFlags & PROCESS_DEP_ENABLE) != 0 ) { dwFlags = 9; if ( (dwFlagscpy & PROCESS_DEP_DISABLE_ATL_THUNK_EMULATION) != 0 ) dwFlags = 13; } else { if ( (dwFlags & PROCESS_DEP_DISABLE_ATL_THUNK_EMULATION) != 0 ) { BaseSetLastNTError(STATUS_INVALID_PARAMETER); return FALSE; } dwFlags = 2; // Set DEP to be disabled for the process } Status = NtSetInformationProcess((HANDLE)-1, 0x22, (PVOID)&dwFlags,(ULONG) 4); //class ProcessExecuteFlags if ( Status < 0 ) { BaseSetLastNTError(Status); return FALSE; } return TRUE; } #else BOOL WINAPI Implementation_SetProcessDEPPolicy(DWORD dwFlags) { BaseSetLastNTError(0xC00000BB); return FALSE; } #endif DWORD WINAPI Implementation_GetProcessId( HANDLE Process ) { PROCESS_BASIC_INFORMATION pbi; NTSTATUS Status = NtQueryInformationProcess(Process, ProcessBasicInformation, (PVOID)&pbi, sizeof(PROCESS_BASIC_INFORMATION), NULL); if(Status) { BaseSetLastNTError(Status); return 0; } return (DWORD)pbi.UniqueProcessId; } BOOL WINAPI Implementation_GetProcessHandleCount( HANDLE hProcess, PDWORD pdwHandleCount ) { ULONG ulProcessHandleCount; if(!pdwHandleCount) { BaseSetLastNTError(ERROR_INVALID_PARAMETER); return FALSE; } NTSTATUS Status = NtQueryInformationProcess(hProcess, 20, (PVOID)&ulProcessHandleCount, sizeof(ULONG), NULL); if(Status) { BaseSetLastNTError(Status); return FALSE; } *pdwHandleCount = ulProcessHandleCount; return TRUE; } BOOL WINAPI Implementation_IsProcessInJob( HANDLE ProcessHandle, HANDLE JobHandle, PBOOL Result ) { int i; DWORD dwProcessId; PJOBOBJECT_BASIC_PROCESS_ID_LIST jbpil; JOBOBJECT_BASIC_ACCOUNTING_INFORMATION jbai; if(!Result || !QueryInformationJobObject(JobHandle, JobObjectBasicAccountingInformation, &jbai, sizeof(JOBOBJECT_BASIC_ACCOUNTING_INFORMATION), NULL)) return FALSE; *Result = FALSE; jbpil = (PJOBOBJECT_BASIC_PROCESS_ID_LIST)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(JOBOBJECT_BASIC_PROCESS_ID_LIST) * (sizeof(ULONG_PTR)* jbai.TotalProcesses)); if(QueryInformationJobObject(JobHandle, JobObjectBasicProcessIdList, &jbpil, sizeof(JOBOBJECT_BASIC_PROCESS_ID_LIST) * (sizeof(ULONG_PTR)* jbai.TotalProcesses), NULL)) { dwProcessId = Implementation_GetProcessId(ProcessHandle); for(i = 0; i < jbpil->NumberOfProcessIdsInList; i++) { if(dwProcessId == jbpil->ProcessIdList[i]) { *Result = TRUE; HeapFree(GetProcessHeap(), 0, jbpil); return FALSE; } } HeapFree(GetProcessHeap(), 0, jbpil); return TRUE; } else { HeapFree(GetProcessHeap(), 0, jbpil); return FALSE; } } BOOL WINAPI Implementation_IsWow64Process( HANDLE hProcess, PBOOL Wow64Process ) { if(!Wow64Process) return FALSE; *Wow64Process = TRUE; return TRUE; } BOOL WINAPI Implementation_DuplicateHandle( HANDLE hSourceProcessHandle, HANDLE hSourceHandle, HANDLE hTargetProcessHandle, LPHANDLE lpTargetHandle, DWORD dwDesiredAccess, BOOL bInheritHandle, DWORD dwOptions ) { typedef BOOL(WINAPI* pfnDuplicateHandle)(HANDLE, HANDLE, HANDLE, LPHANDLE, DWORD, BOOL, DWORD); pfnDuplicateHandle pDuplicateHandle = (pfnDuplicateHandle)Implementation_GetProcAddress(GetModuleHandleA("kernel32.dll"), "DuplicateHandle"); if (dwDesiredAccess & PROCESS_QUERY_LIMITED_INFORMATION) { dwDesiredAccess &= ~PROCESS_QUERY_LIMITED_INFORMATION; dwDesiredAccess |= PROCESS_QUERY_INFORMATION; } return pDuplicateHandle(hSourceProcessHandle, hSourceHandle, hTargetProcessHandle, lpTargetHandle, dwDesiredAccess, bInheritHandle, dwOptions); }