557 lines
12 KiB
C
557 lines
12 KiB
C
#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);
|
|
} |