typedef struct t_PDB
{
WORD Type;
WORD Refcount;
DWORD Unk0;
DWORD Unk1;
DWORD Unk2;
DWORD TermStatus;
DWORD Unk3;
DWORD DefaultHeap;
DWORD MemContext; /* Use this with ContextSwitch*/
DWORD Flags;
DWORD pPsp;
WORD PSPSelector;
WORD MTEIndex;
WORD nThreads;
WORD nThreadsNotTerm;
WORD Unk5;
WORD nR0Threads;
DWORD HeapHandle;
WORD K16TDBSel;
WORD Unk6;
DWORD Unk7;
DWORD pEDB;
DWORD pHandleTable;
struct t_PDB *ParentPDB;
DWORD MODREFList;
DWORD ThreadList;
DWORD DebugeeCB;
DWORD LHFreeHead;
DWORD InitialR0ID;
}PDB, *PPDB;
typedef struct t_TCB
{
WORD Type;
WORD RefCount;
DWORD Unk1;
DWORD pvExcept;
DWORD TopOfStack;
DWORD BaseOfStack;
WORD K16TDB;
WORD StackSel16;
DWORD Unk2;
DWORD UserPointer;
DWORD pTIB;
WORD TIBflags;
WORD Win16MutxCnt;
DWORD DebugContext;
DWORD PtrToCurPri;
DWORD MsgQueue;
DWORD pTLSarray;
PPDB pParentPDB;
DWORD SelmanList;
DWORD Unk3;
DWORD Flags;
DWORD Status;
WORD TIBsel;
WORD EmulatorSel;
DWORD HandleCount;
DWORD WaitNodeList;
DWORD R0hThread;
DWORD ptdbx;
}TCB, *PTCB;
typedef DWORD (WINAPI*OTFUNC)(HANDLE*,DWORD,void*,void*);
typedef LPVOID (WINAPI *OBFUNC)(DWORD dwPTID);
LPVOID WINAPI XORProcessThreadID(DWORD dwPTID)
{
OBFUNC obfuscate;
DWORD dwMain,*lpdw,dw1;
dwMain = (DWORD)GetTrueProcAddress(_T("KERNEL32"), _T("GetCurrentThreadId"));
/*
* this retreives the address and runs the obfuscation function directly
* using GetCurrentThreadId. since in win98 you don't seem to have access to
* the randomized obfuscation pointer.
*/
lpdw = (LPDWORD)((DWORD)dwMain + 8);
dw1 = ((DWORD)dwMain + 12);
obfuscate = (OBFUNC)(dw1+*lpdw);
return(obfuscate(dwPTID));
}
HANDLE WINAPI [url=http://www.driverdevelop.com/forum/viewthread.php?tid=61765][/url]OpenThread2(DWORD dwThreadID, BOOL bInherit)
{
HANDLE hThread,hprc;
LPDWORD lp1;
DWORD dwProcessID,dwWhere,dwTable;
BOOL b1;
PTCB lpThreadObj;
PPDB ppdb;
OSVERSIONINFO osvi;
osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
GetVersionEx(&osvi);
SetLastError(50);
if(osvi.dwPlatformId == VER_PLATFORM_WIN32_NT)
return OpenThreadNT(dwThreadID, bInherit);
ppdb = (PPDB)XORProcessThreadID(GetCurrentProcessId());
lpThreadObj = XORProcessThreadID(dwThreadID);
/* check to make sure its valid */
if(IsBadReadPtr(lpThreadObj, sizeof(TCB))) return NULL;
/* object type */
if(*(LPBYTE)lpThreadObj != 7) return NULL;
dwProcessID =
(DWORD)XORProcessThreadID((DWORD)lpThreadObj->pParentPDB);
if(dwProcessID == GetCurrentProcessId())
hprc = GetCurrentProcess();
else
{
hprc = OpenProcess(PROCESS_ALL_ACCESS,
FALSE, dwProcessID);
if(!hprc) return NULL;
}
/*
* 4 is the lowest handle in the table.
* All processes have this handle.
*/
b1 = DuplicateHandle(hprc,
(HANDLE)4,
GetCurrentProcess(),
&hThread,
THREAD_ALL_ACCESS,
bInherit, 0);
if(hprc != GetCurrentProcess())
CloseHandle(hprc);
if(!b1) return NULL;
dwWhere = ((DWORD)hThread) >> 2;
dwTable = ppdb->pHandleTable;
lp1 = (LPDWORD)(dwTable+(dwWhere*8)+8);
*lp1 = (DWORD)lpThreadObj;
return(hThread);
}
HANDLE WINAPI OpenThreadNT(DWORD dwThreadID, BOOL bInherit)
{
HANDLE hThread = NULL;
DWORD struct1[] = {0x18, 0, 0, 0, 0, 0};
DWORD struct2[] = {0,dwThreadID};
HMODULE hLib = LoadLibrary(_T("ntdll.dll"));
OTFUNC OpenThatNTThread = (OTFUNC)GetProcAddress(hLib, _T("NtOpenThread"));
struct1[3] = bInherit;
OpenThatNTThread(&hThread, THREAD_ALL_ACCESS, struct1, struct2);
FreeLibrary(hLib);
return hThread;
}
/*
* Note: The assembly for GetCurrentThreadId (not to mention probably every other
* kernel32 function) in all the versions does not start with 68h (push dword data).
* The reason I do this is because sometimes the GetProcAddress will not return the
* exact address of the actual function. The address it returns is used for
* pre-processing, and is probably only used for tracing the functions or debugging.
* It isn't needed to run the function.
*/
LPVOID WINAPI GetTrueProcAddress(LPSTR lpMod, LPTSTR lpFunc)
{
LPVOID bla = GetProcAddress(GetModuleHandle(lpMod), lpFunc);
if(!bla) return NULL;
if(*(LPBYTE)bla == 0x68)
bla = (LPVOID)*(LPDWORD)((DWORD)bla + 1);
return bla;
}