reupload this
This commit is contained in:
198
fiber.c
Normal file
198
fiber.c
Normal file
@@ -0,0 +1,198 @@
|
||||
#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;
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user