尽量享受公开的乐趣.:)主页里的另外一篇说的是TDB,TDBX,千万不要被搞糊涂.:) 这段代码是从MS的KERNEL讨论组上COPY下来的.果然妙极.请大家尽量享用.:) typedef struct t_PDB { WORD Type; WORD Refcount; DWORD Unk0; DWORD Unk1; DWORD Unk2; DWORD TermStatus; DWORD Unk3; DWORD DefaultHeap; DWORD MemContext; /* Yes, 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. * Yes, works with all versions of 98/95 :) */ lpdw = (LPDWORD)((DWORD)dwMain + 8); dw1 = ((DWORD)dwMain + 12); obfuscate = (OBFUNC)(dw1+*lpdw); return(obfuscate(dwPTID)); } HANDLE WINAPI 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; }