198 lines
4.7 KiB
C
198 lines
4.7 KiB
C
#include "progwrp.h"
|
|
#include "export.h"
|
|
#include "implementations.h"
|
|
|
|
BOOL WINAPI Implementation_IsThreadAFiber()
|
|
// Vista uses a TEB flag to determine whether a thread is a fiber.
|
|
// XP puts the flag in a different area, and 2000 has none.
|
|
// But there is the TIB's FiberData member, which also has a "version" number assigned to it.
|
|
// On XP and Vista it is assigned 0x1E00. Anything greather than that is assumed to be fiber data.
|
|
{
|
|
PTEB_CUSTOM Teb;
|
|
|
|
Teb = (PTEB_CUSTOM)NtCurrentTeb();
|
|
|
|
if((ULONG_PTR)Teb->FiberData <= 0x1E00)
|
|
return FALSE;
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
DWORD WINAPI Implementation_FlsAlloc(
|
|
PFLS_CALLBACK_FUNCTION lpCallback
|
|
)
|
|
{
|
|
return TlsAlloc();
|
|
}
|
|
|
|
BOOL WINAPI Implementation_FlsFree(
|
|
DWORD dwFlsIndex
|
|
)
|
|
{
|
|
return TlsFree(dwFlsIndex);
|
|
}
|
|
|
|
typedef PVOID(WINAPI* pfnFlsGetValue)(DWORD);
|
|
BOOLEAN IsNt6Level = FALSE;
|
|
pfnFlsGetValue pFlsGetVal = NULL;
|
|
PVOID Test = NULL;
|
|
|
|
PVOID WINAPI Implementation_FlsGetValue(
|
|
DWORD dwFlsIndex
|
|
)
|
|
{
|
|
PTEB_CUSTOM Teb;
|
|
int i;
|
|
PLDR_DATA_TABLE_ENTRY DataTableEntry, DataTableEntryInit;
|
|
ANSI_STRING Fls;
|
|
if (!Test)
|
|
{
|
|
RtlInitAnsiString(&Fls, "FlsGetValue");
|
|
|
|
LdrGetProcedureAddress(GetModuleHandleA("kernel32.dll"), &Fls, 0, &pFlsGetVal);
|
|
RtlInitAnsiString(&Fls, "WerpInitiateRemoteRecovery");
|
|
LdrGetProcedureAddress(GetModuleHandleA("kernel32.dll"), &Fls, 0, &Test);
|
|
if (!Test) {
|
|
for (i = 0; i < TlsBasesCount; i++)
|
|
{
|
|
TLSInit_DllMain_ThreadAttach_Internal(TlsBases[i], NULL);
|
|
}
|
|
}
|
|
}
|
|
if (pFlsGetVal)
|
|
return pFlsGetVal(dwFlsIndex);
|
|
return TlsGetValue(dwFlsIndex);
|
|
}
|
|
|
|
BOOL WINAPI Implementation_FlsSetValue(
|
|
DWORD dwFlsIndex,
|
|
PVOID lpFlsData
|
|
)
|
|
{
|
|
return TlsSetValue(dwFlsIndex, lpFlsData);
|
|
}
|
|
|
|
typedef struct
|
|
{
|
|
LPVOID lpParameter;
|
|
PVOID Reserved [4];
|
|
CONTEXT Ctx;
|
|
}FIBER, *PFIBER;
|
|
|
|
LPVOID WINAPI Implementation_ConvertThreadToFiberEx(
|
|
LPVOID lpParameter,
|
|
DWORD dwFlags
|
|
)
|
|
{
|
|
PFIBER Result = (PFIBER) ConvertThreadToFiber(lpParameter);
|
|
|
|
if(Result && dwFlags & FIBER_FLAG_FLOAT_SWITCH)
|
|
{
|
|
Result->Ctx.ContextFlags |= CONTEXT_FLOATING_POINT | CONTEXT_CONTROL | CONTEXT_SEGMENTS | CONTEXT_INTEGER;
|
|
}
|
|
|
|
return (LPVOID) Result;
|
|
}
|
|
|
|
LPVOID WINAPI Implementation_CreateFiberEx(
|
|
SIZE_T dwStackCommitSize,
|
|
SIZE_T dwStackReserveSize,
|
|
DWORD dwFlags,
|
|
LPFIBER_START_ROUTINE lpStartAddress,
|
|
LPVOID lpParameter
|
|
)
|
|
{
|
|
PFIBER Result;
|
|
typedef LPVOID (WINAPI* pfnCreateFiberEx)(SIZE_T, SIZE_T, DWORD, LPFIBER_START_ROUTINE, LPVOID);
|
|
|
|
pfnCreateFiberEx pCreateFib = (pfnCreateFiberEx)Implementation_GetProcAddress(GetModuleHandleA("kernel32.dll"), "CreateFiberEx");
|
|
|
|
if(g_pfn_ConvertThreadToFiberEx == (pfnFunc_generic)Implementation_ConvertThreadToFiberEx)
|
|
{
|
|
Result = (PFIBER) pCreateFib(dwStackCommitSize, dwStackReserveSize, 0, lpStartAddress, lpParameter);
|
|
|
|
if(Result && dwFlags & FIBER_FLAG_FLOAT_SWITCH)
|
|
{
|
|
Result->Ctx.ContextFlags |= CONTEXT_FLOATING_POINT | CONTEXT_CONTROL | CONTEXT_SEGMENTS | CONTEXT_INTEGER;
|
|
}
|
|
}
|
|
else
|
|
Result = (PFIBER) pCreateFib(dwStackCommitSize, dwStackReserveSize, dwFlags, lpStartAddress, lpParameter);
|
|
|
|
return (LPVOID) Result;
|
|
}
|
|
|
|
void WINAPI Implementation_SwitchToFiber(LPVOID lpFiber)
|
|
{
|
|
|
|
/*
|
|
#ifdef _M_IX86
|
|
__asm
|
|
{
|
|
mov edx, fs:0x18 ; NtCurrentTeb()
|
|
mov eax, [edx+0x10] ; FiberData
|
|
mov [eax+0xB8], ebx
|
|
mov [eax+0xB0], edi
|
|
mov [eax+0xB4], esi
|
|
mov [eax+0xC8], ebp
|
|
cmp dword ptr [eax+0x14], 0x1000F ; Result->Ctx.ContextFlags & CONTEXT_FLOATING_POINT | CONTEXT_CONTROL | CONTEXT_SEGMENTS | CONTEXT_INTEGER
|
|
jnz SkipFloatingPoint
|
|
fstsw word ptr [eax+0x34]
|
|
fnstcw word ptr [eax+0x30]
|
|
cmp byte ptr ds:0x7FFE027A, 1 ; PF_XMMI_INSTRUCTIONS_AVAILABLE check, available since Windows 2000
|
|
jnz SkipFloatingPoint
|
|
nop ; stmxcsr dword ptr [eax+0x28]
|
|
SkipFloatingPoint:
|
|
mov [eax+0xD8], esp
|
|
mov ecx, [edx]
|
|
mov ebx, [edx+8]
|
|
mov [eax+4], ecx
|
|
mov [eax+0xC], ebx
|
|
mov ecx, [esp+4] ; lpFiber
|
|
mov [edx+0x10], ecx
|
|
mov esi, [ecx+4]
|
|
mov ebx, [ecx+8]
|
|
mov [edx], esi
|
|
mov [edx+4], ebx
|
|
mov esi, [ecx+0xC]
|
|
mov ebx, [ecx+0x10]
|
|
mov [edx+8], esi
|
|
mov [edx+0xE0C], ebx
|
|
cmp dword ptr [ecx+0x14], 1000Fh
|
|
jnz SkipFloatingPoint2
|
|
mov ebx, [eax+0x34]
|
|
cmp bx, [ecx+0x34]
|
|
jnz loc_7DD8105B
|
|
mov ebx, [eax+0x30]
|
|
cmp bx, [ecx+0x30]
|
|
jz loc_7DD81064
|
|
loc_7DD8105B:
|
|
mov word ptr [ecx+0x38], 0xFFFF
|
|
fldenv byte ptr [ecx+0x30]
|
|
loc_7DD81064:
|
|
cmp byte ptr ds:0x7FFE027A, 1
|
|
jnz SkipFloatingPoint2
|
|
nop ; ldmxcsr dword ptr [ecx+0x28]
|
|
SkipFloatingPoint2:
|
|
mov edi, [ecx+0xB0]
|
|
mov esi, [ecx+0xB4]
|
|
mov ebp, [ecx+0xC8]
|
|
mov ebx, [ecx+0xB8]
|
|
mov esp, [ecx+0xD8]
|
|
}
|
|
#endif
|
|
*/
|
|
}
|
|
|
|
BOOL WINAPI Implementation_ConvertFiberToThread()
|
|
{
|
|
PTEB_CUSTOM Teb = (PTEB_CUSTOM)NtCurrentTeb();
|
|
|
|
if((ULONG_PTR)Teb->FiberData <= 0x1E00)
|
|
return FALSE;
|
|
else
|
|
Teb->FiberData = 0x1E00;
|
|
|
|
return TRUE;
|
|
|
|
} |