BanMe
July 2nd, 2010, 13:06
Found it..
regards BanMe
regards BanMe
View Full Version : where is the best definition of NtCurrentTeb()->Win32ThreadInfo...
//This Structure is written to base of shared sections a code header..it contains function
//address and data for function calls..)
typedef struct _SUSPEND_OTHERS
{
RTLALLOCATEHEAP AllocateHeap;
NTQUERYSYSTEMINFORMATION sQuerySystemInformation;
NTSUSPENDTHREAD sSuspendThread;
NTOPENTHREAD sOpenThread;
ULONG Len;
NTSTATUS Status;
PVOID Buffer;
HANDLE TargetThread;
CLIENT_ID ClientId;
OBJECT_ATTRIBUTES oa;
SYSTEM_PROCESS_INFORMATION_EX *pProcesses;
}SUSPEND_OTHERS,*PSUSPEND_OTHERS;
//this code is then transfered using Rick Vielers parsex86.c from professional rootkits(2k7)...
//this can be accomplished in other ways but this is interesting...
void SuspendNormalExecution(SUSPEND_OTHERS SuspendThreads)
{
if(SuspendThreads.TargetThread != 0 && SuspendThreads.ClientId.UniqueProcess != 0)
{
SuspendThreads.Buffer = SuspendThreads.AllocateHeap(NtCurrentTeb()->ProcessEnvironmentBlock->ProcessHeap,HEAP_ZERO_MEMORY,0x40000);
SuspendThreads.pProcesses = (SYSTEM_PROCESS_INFORMATION_EX *)SuspendThreads.Buffer;
SuspendThreads.Status = SuspendThreads.sQuerySystemInformation(SystemProcessInformation,(PVOID)SuspendThreads.pProcesses,Sus pendThreads.Len,&SuspendThreads.Len);
for(;
{
if(SuspendThreads.ClientId.UniqueProcess != SuspendThreads.pProcesses->UniqueProcessId)
{
SuspendThreads.pProcesses = (PSYSTEM_PROCESS_INFORMATION_EX)(((BYTE *)SuspendThreads.pProcesses)+SuspendThreads.pProcesses->NextEntryOffset);
}
else
{
for(SuspendThreads.Len = 0;SuspendThreads.Len < SuspendThreads.pProcesses->NumberOfThreads;SuspendThreads.Len++)
{
if(SuspendThreads.TargetThread != SuspendThreads.pProcesses->Threads[SuspendThreads.Len].ClientId.UniqueThread)
{
InitializeObjectAttributes(&SuspendThreads.oa,0,0,0,0);
SuspendThreads.ClientId.UniqueThread = SuspendThreads.pProcesses->Threads[SuspendThreads.Len].ClientId.UniqueThread;
SuspendThreads.Status = SuspendThreads.sOpenThread(&SuspendThreads.TargetThread,THREAD_ALL_ACCESS,&SuspendThreads.oa,&SuspendThreads.ClientId);
if(NT_SUCCESS(SuspendThreads.Status))
{
SuspendThreads.Status = SuspendThreads.sSuspendThread(SuspendThreads.TargetThread,(PULONG)&SuspendThreads.Status);
continue;
}
else
{
break;
}
}
}
}
}
}
return;
}
case SIN_WAIT_SERVER:
{
ThisEntry = SinSrvLocateClientByPid(ApiRecvMessage.Header.ClientId.UniqueProcess);
ApiRecvMessage.ClientInfo = *ThisEntry;
if(getx86Instruction((PCHAR)SuspendNormalExecution,(PCHAR)((ULONG)ThisEntry->ClientView.ViewBase+0x4),(ULONG)GetFunctionLength(SuspendNormalExecution)))
{
memset(ThisEntry->ClientView.ViewBase,(ULONG)ApiRecvMessage.Header.ClientId.UniqueThread,sizeof(ULONG));
ApiRecvMessage.Data = ThisEntry->ClientView.ViewBase;
ApiRecvMessage.StartAddress = ((ULONG)ThisEntry->ClientView.ViewBase+0x4);
ApiRecvMessage.Status = 1;
ApiReplyMessage = ApiRecvMessage;
}
break;
}
lol I found it and its useless to me I think.. :[ Im getting returned the address 0x00000000 from fs:18h + 0x40.... sorry Kayaker the 'good stuff' takes time |
case SIN_WAIT_SERVER:
{
ThisEntry = SinSrvLocateClientByPid(ApiRecvMessage.Header.ClientId.UniqueProcess);
ApiRecvMessage.ClientInfo = *ThisEntry;
SuspendThreads.ClientId.UniqueProcess = ApiRecvMessage.Header.ClientId.UniqueProcess;
SuspendThreads.TargetThread = ApiRecvMessage.Header.ClientId.UniqueThread;
if(hkHook::SinSrvSetupSuspension(&SuspendThreads))
{
memcpy(ThisEntry->ClientView.ViewBase,&SuspendThreads,sizeof(SUSPEND_OTHERS));
if(getx86Instruction((PCHAR)hkHook::SuspendNormalExecution,(PCHAR)((ULONG)ThisEntry->ClientView.ViewBase+sizeof(SUSPEND_OTHERS)),(ULONG)GetFunctionLength(hkHook::SuspendNormalExecution) ))
{
ApiRecvMessage.Data = ThisEntry->ClientView.ViewBase;
ApiRecvMessage.StartAddress = ((ULONG)ThisEntry->ClientView.ViewBase+sizeof(SUSPEND_OTHERS));
ApiRecvMessage.Status = 1;
ApiReplyMessage = ApiRecvMessage;
break;
}
}
break;
}
bool SinSrvSetupSuspension(__inout SUSPEND_OTHERS*SuspendThreads)
{
SuspendThreads->AllocateHeap = (RTLALLOCATEHEAP)Native_GetApi(L"ntdll.dll","RtlAllocateHeap";
SuspendThreads->sQuerySystemInformation = (NTQUERYSYSTEMINFORMATION)Native_GetApi(L"ntdll.dll","NtQuerySystemInformation";
SuspendThreads->sOpenThread = (NTOPENTHREAD)Native_GetApi(L"ntdll.dll","NtOpenthread";
SuspendThreads->sSuspendThread = (NTSUSPENDTHREAD)Native_GetApi(L"ntdll.dll","NtSuspendThread";
SuspendThreads->Len = 0x40000;
if(!SuspendThreads->AllocateHeap && !SuspendThreads->sQuerySystemInformation && !SuspendThreads->sOpenThread && SuspendThreads->sSuspendThread)
{
return false;
}
return true;
}
KTHREAD->Win32Thread pointer.
In user mode TEB->Win32ThreadInfo
Programmatically – IsGuiThread(fConvert) – Whistler only
KTHREAD->ServiceTable initialized to ntkrnlmp!KeServiceDescriptorTable, replaced with ntkrnlmp!KeServiceDescriptorTableShadow(alternative differentiator)
CSRSS creates First GUI Thread
#define MAX_THREADS n
HANDLE ONLY_THESE_THREADS_SHOULD_BE_RUNNING [MAX_THREADS][1];
[0]//= Main Gui Thread
[0][1]//= Main ThreadId
...so on..