#include "debug.h" #include // c:/local/WINCE420/PUBLIC/COMMON/SDK/INC/kfuncs.h // SH_* // c:/local/WINCE420/PUBLIC/COMMON/OAK/INC/pkfuncs.h // KINX_* // c:/local/WINCE420/PRIVATE/WINCEOS/COREOS/NK/INC/kernel.h // CINFO, Process, Thread, HDATA, MemBlock, VA_BLOCK, FSMAP // APISET // c:/local/WINCE420/PRIVATE/WINCEOS/COREOS/NK/INC/nkarm.h // CPUCONTEXT, KDataStruct, ArmHigh // c:\local\WINCE420\PUBLIC\COMMON\OAK\INC\pehdr.h // e32_lite, o32_lite // c:/local/WINCE420/PRIVATE/WINCEOS/COREOS/NK/INC/schedule.h // EVENT, MUTEX, SEMAPHORE #include "cenk.h" #include "cever_deps.h" #include "kernelmisc.h" /* HDATA DList linkage; // 00: links for active handle list DList *fwd; // 00: forward link DList *back; // 04: backward link HANDLE hValue; // 08: Current value of handle (nonce) ACCESSLOCK lock; // 0C: access information REFINFO ref; // 10: reference information ulong count; // 10: FULLREF *pFr; // 10: ptr to ushort usRefs[MAX_PROCESSES]; const CINFO *pci; // 14: ptr to object class description structure PVOID pvObj; // 18: ptr to object (in server address space ) DWORD dwInfo; // 1C: extra handle info CINFO char acName[4]; // 00: object type ID string uchar disp; // 04: type of dispatch uchar type; // 05: api handle type ushort cMethods; // 06: # of methods in dispatch table const PFNVOID *ppfnMethods;// 08: ptr to array of methods (in server address space) const DWORD *pdwSig; // 0C: ptr to array of method signatures PPROCESS pServer; // 10: ptr to server process */ //--------------- SOCK_INFO is in wstype.h ---------------- // but it seems impossible to combine it with the kernel headers. //#include "sockinfo.h" #include "sockinfo420.h" //#include "device420.h" // fsopendev_t #if _WIN32_WCE==300 #include "filehandle300.h" #elif _WIN32_WCE==420 // this is only defined in the wce4.x sdk, not for 3.0 #include "filehandle300.h" #elif _WIN32_WCE==501 #include "filehandle300.h" #else #error "unknown windows ce version" #endif #include #include #include #include "stringutils.h" typedef std::set CInfoSet; typedef std::map CInfoMap; //HANDLE g_hFilesysProc; //HANDLE g_hDeviceProc; CInfoMap cinfomap; DWORD *GetPagesList(MEMBLOCK *p) { if (GetWinceVersion()<4) return (DWORD*)&(p->aPages); else return (DWORD*)p->aPages; } bool dumpmem(HANDLE hProc, DWORD dwOfs, DWORD dwLen, const std::string& msg) { ByteVector dw; dw.resize(dwLen); DWORD nRead; if (!ReadProcessMemory(hProc, (void*)dwOfs, vectorptr(dw), dw.size(), &nRead)) { error("dumpmem(%08lx, %08lx)", hProc, dwOfs); return false; } bighexdump(dwOfs, dw, hexdumpflags(DUMPUNIT_DWORD, 4, DUMP_HEX)|HEXDUMP_WITH_OFFSET); return true; } HANDLE GetProcessHandle(WCHAR *wszProcessName) { HANDLE hTH= CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS|TH32CS_SNAPNOHEAPS, 0); PROCESSENTRY32 pe; pe.dwSize= sizeof(PROCESSENTRY32); HANDLE hProc= INVALID_HANDLE_VALUE; if (Process32First(hTH, &pe)) { do { if (wcsicmp(wszProcessName, pe.szExeFile)==0) { hProc= OpenProcess(0, 0, pe.th32ProcessID); if (hProc != INVALID_HANDLE_VALUE && hProc!=NULL) break; } } while (Process32Next(hTH, &pe)); } CloseToolhelp32Snapshot(hTH); return hProc; } char *GetCInfoName(const CINFO *ci) { if (!isValidPtr((DWORD)ci)) { debug("GetCInfoName: INVALID PTR %08lx\n", ci); return "----"; } static char name[5]; for (int i=0 ; i<4 ; i++) name[i]= ci->acName[i]; name[4]=0; return name; } void DumpCInfo(const CINFO *pci); void RegisterCInfo(const CINFO *pci, int apiindex) { std::string name(GetCInfoName(pci)); if (apiindex>=0) debug("apiset %02x: %hs\n", apiindex, name.c_str()); cinfomap[name].insert(pci); } void DumpCInfoMap() { for (CInfoMap::iterator mi= cinfomap.begin() ; mi!=cinfomap.end() ; ++mi) { debug("....%hs....\n", (*mi).first.c_str()); for (CInfoSet::iterator si= (*mi).second.begin() ; si!=(*mi).second.end() ; ++si) { DumpCInfo(*si); } } } char *GetMethodSigString(DWORD dwSig) { static char str[256]; char *p= str; p+=sprintf(p, "("); for (int i=0 ; i<16 && dwSig ; i++) { if (i) p+=sprintf(p, ", "); switch(dwSig&3) { case 0: p+=sprintf(p, "DWORD"); break; case 1: p+=sprintf(p, "PTR"); break; case 2: p+=sprintf(p, "I64"); break; case 3: p+=sprintf(p, "???"); break; } dwSig>>=4; } p+=sprintf(p, ")"); return str; } void DumpCInfo(const CINFO *pci) { if (!isValidPtr((DWORD)pci)) { debug("DumpCInfo: INVALID PTR %08lx\n", pci); return; } debug("CINFO %08lx %-4s n=%d disp=%02x type=%02x methods=%08lx sigs=%08lx server=%08lx %ls\n", pci, GetCInfoName(pci), pci->cMethods, pci->disp, pci->type, pci->ppfnMethods, pci->pdwSig, pci->pServer, IsBadReadPtr(pci->pServer, sizeof(PROCESS))?L"-":pci->pServer->lpszProcName); const PFNVOID *ppfnMethods= IsBadReadPtr(pci->pServer, sizeof(PROCESS)) ?pci->ppfnMethods :(const PFNVOID *)MapPtrUnsecure((void*)pci->ppfnMethods, pci->pServer->hProc); const DWORD *pdwSig= IsBadReadPtr(pci->pServer, sizeof(PROCESS)) ?pci->pdwSig :(const DWORD *)MapPtrUnsecure((void*)pci->pdwSig, pci->pServer->hProc); for (int i=0 ; icMethods ; i++) { debug("apiset %-4s %3d %08lx %hs\n", GetCInfoName(pci), i, ppfnMethods[i], (pdwSig==NULL || IsBadReadPtr(pdwSig, sizeof(DWORD)*i))?"-":GetMethodSigString(pdwSig[i])); } } void DumpThreadTimes(HANDLE hThread) { FILETIME tCreate, tExit, tKernel, tUser; if (!GetThreadTimes(hThread, &tCreate, &tExit, &tKernel, &tUser)) { error("GetThreadTimes"); return; } debug(" cr= %08lx%08lx ex=%08lx%08lx k=%08lx%08lx u=%08lx%08lx\n", tCreate.dwHighDateTime, tCreate.dwLowDateTime, tExit.dwHighDateTime, tExit.dwLowDateTime, tKernel.dwHighDateTime, tKernel.dwLowDateTime, tUser.dwHighDateTime, tUser.dwLowDateTime); } void DumpHeapEntry(HEAPENTRY32 *he) { if (!isValidPtr((DWORD)he)) { debug("DumpHeapEntry: INVALID PTR %08lx\n", he); return; } debug(" %4d hBlk=%08lx addr=%08lx size=%08lx fl=%08lx lck=%d ?=%08lx pid=%08lx hid=%08lx\n", he->dwSize, he->hHandle, he->dwAddress, he->dwBlockSize, he->dwFlags, he->dwLockCount, he->dwResvd, he->th32ProcessID, he->th32HeapID); } void DumpHeap(HANDLE hTH, DWORD nProcessId, DWORD nHeapId) { HEAPENTRY32 he; DWORD dwTotal=0; __try { he.dwSize= sizeof(HEAPENTRY32); if (Heap32First(hTH, &he, nProcessId, nHeapId)) { do { //DumpHeapEntry(&he); dwTotal += he.dwBlockSize; he.dwSize= sizeof(HEAPENTRY32); } while (Heap32Next(hTH, &he)); } } __except(1) { debug("exception reading heap\n"); } error("done looping over heap - structsize=%d heapsize=%ld", sizeof(HEAPENTRY32), dwTotal); } void DumpHeapListEntry(HEAPLIST32 *le) { if (!isValidPtr((DWORD)le)) { debug("DumpHeapListEntry: INVALID PTR %08lx\n", le); return; } debug("%4d pid=%08lx hid=%08lx fl=%08lx\n", le->dwSize, le->th32ProcessID, le->th32HeapID, le->dwFlags); } void DumpHeapLists(HANDLE hTH) { HEAPLIST32 le; le.dwSize= sizeof(HEAPLIST32); if (Heap32ListFirst(hTH, &le)) { do { DumpHeapListEntry(&le); DumpHeap(hTH, le.th32ProcessID, le.th32HeapID); le.dwSize= sizeof(HEAPLIST32); } while (Heap32ListNext(hTH, &le)); } error("done looping over heap lists - structsize=%d", sizeof(HEAPLIST32)); } void DumpModuleEntry(MODULEENTRY32 *me) { if (!isValidPtr((DWORD)me)) { debug("DumpModuleEntry: INVALID PTR %08lx\n", me); return; } debug("%4d fl=%08lx mid=%08lx pid=%08lx gusg=%3d pusg=%08lx base=%08lx size=%08lx hmod=%08lx mod=%ls exe=%ls\n", me->dwSize, me->dwFlags, me->th32ModuleID, me->th32ProcessID, me->GlblcntUsage, me->ProccntUsage, me->modBaseAddr, me->modBaseSize, me->hModule, me->szModule, me->szExePath); } void DumpModules(HANDLE hTH) { MODULEENTRY32 me; me.dwSize= sizeof(MODULEENTRY32); if (Module32First(hTH, &me)) { do { DumpModuleEntry(&me); me.dwSize= sizeof(MODULEENTRY32); } while (Module32Next(hTH, &me)); } error("done looping over modules - structsize=%d", sizeof(MODULEENTRY32)); } void DumpProcessEntry(PROCESSENTRY32 *pe) { if (!isValidPtr((DWORD)pe)) { debug("DumpProcessEntry: INVALID PTR %08lx\n", pe); return; } debug("%2d usg=%d pid=%08lx hid=%08lx mid=%08lx #t=%2d ppid=%08lx pri=%08lx fl=%08lx mem=%08lx acc=%08lx %ls\n", pe->dwSize, pe->cntUsage, pe->th32ProcessID, pe->th32DefaultHeapID, pe->th32ModuleID, pe->cntThreads, pe->th32ParentProcessID, pe->pcPriClassBase, pe->dwFlags, pe->th32MemoryBase, pe->th32AccessKey, pe->szExeFile); } void DumpProcesses(HANDLE hTH) { PROCESSENTRY32 pe; pe.dwSize= sizeof(PROCESSENTRY32); if (Process32First(hTH, &pe)) { do { DumpProcessEntry(&pe); if (pe.th32DefaultHeapID) DumpHeap(hTH, pe.th32ProcessID, pe.th32DefaultHeapID); pe.dwSize= sizeof(PROCESSENTRY32); } while (Process32Next(hTH, &pe)); } error("done looping over processes - structsize=%d", sizeof(PROCESSENTRY32)); } void DumpThreadEntry(THREADENTRY32 *te) { if (!isValidPtr((DWORD)te)) { debug("DumpThreadEntry: INVALID PTR %08lx\n", te); return; } debug("%2d usg=%d tid=%08lx opid=%08lx pri=%3d dpri=%3d fl=%08lx acc=%08lx cpid=%08lx\n", te->dwSize, te->cntUsage, te->th32ThreadID, te->th32OwnerProcessID, te->tpBasePri, te->tpDeltaPri, te->dwFlags,te->th32AccessKey, te->th32CurrentProcessID); } void DumpThreads(HANDLE hTH) { THREADENTRY32 te; te.dwSize= sizeof(THREADENTRY32); if (Thread32First(hTH, &te)) { do { DumpThreadEntry(&te); DumpThreadTimes((HANDLE)te.th32ThreadID); te.dwSize= sizeof(THREADENTRY32); } while (Thread32Next(hTH, &te)); } error("done looping over threads - structsize=%d", sizeof(THREADENTRY32)); } void test() { HANDLE hTH= CreateToolhelp32Snapshot(TH32CS_SNAPALL | TH32CS_GETALLMODS, 0); debug("-------------threads-------------\n"); DumpThreads(hTH); debug("-------------process-------------\n"); DumpProcesses(hTH); debug("-------------modules-------------\n"); DumpModules(hTH); debug("-------------heaplists-------------\n"); DumpHeapLists(hTH); CloseToolhelp32Snapshot(hTH); } DWORD SetAccess(HANDLE hProc, DWORD aky) { //HANDLE hProc= (HANDLE)GetCurrentProcessId(); HDATA *pHandle= cvHandle2HDataPtr(hProc); PROCESS *proc= (PROCESS*)pHandle->pvObj; DWORD oldaky= proc->aky; proc->aky= 0xffffffff; return oldaky; } DWORD GetHandleObject(HANDLE h) { HDATA *hi= cvHandle2HDataPtr(h); return (DWORD)hi->pvObj; } TCHAR *GetProcessNameByHandle(HANDLE h) { return ((PROCESS*)GetHandleObject(h))->lpszProcName; } // !!! os dependent void DumpProcess(HANDLE hProc, PROCESS *p) { debug(" num=%d vmbase=%08lx aky=%08lx base=%08lx e32.base=%08lx %ls %ls", p->procnum, p->dwVMBase, p->aky, p->BasePtr, p->e32.e32_vbase, p->lpszProcName, p->pcmdline); /* if (p->o32_ptr) { for (int i=0 ; ie32.e32_objcnt ; i++) debug(" o32-%d : data=%08lx real=%08lx\n", p->o32_ptr[i].o32_dataptr, p->o32_ptr[i].o32_realaddr); } */ } // !!! os dependent void DumpThread(HANDLE hProc, THREAD *t) { if (!isValidPtr((DWORD)t)) { debug("DumpThread: INVALID PTR %08lx\n", t); return; } debug(" utime=%08lx ktime=%08lx proc=%08lx %ls", t->dwUserTime, t->dwKernTime, t->pOwnerProc, t->pOwnerProc->lpszProcName); } void DumpEvent(HANDLE hProc, EVENT *e) { if (!isValidPtr((DWORD)e)) { debug("DumpEvent: INVALID PTR %08lx\n", e); return; } if (e->name) debug(" %ls", e->name->name); } void DumpApiSet(HANDLE hProc, APISET *a) { if (!isValidPtr((DWORD)a)) { debug("DumpApiSet: INVALID PTR %08lx\n", a); return; } debug(" reg=%2d %-4s n=%d disp=%02x type=%02x methods=%08lx sigs=%08lx server=%08lx %ls", a->iReg, GetCInfoName(&a->cinfo), a->cinfo.cMethods, a->cinfo.disp, a->cinfo.type, a->cinfo.ppfnMethods, a->cinfo.pdwSig, a->cinfo.pServer, a->cinfo.pServer->lpszProcName); RegisterCInfo(&a->cinfo, -1); } void DumpMutex(HANDLE hProc, MUTEX* m) { if (!isValidPtr((DWORD)m)) { debug("DumpMutex: INVALID PTR %08lx\n", m); return; } debug(" %d locks", m->LockCount); if (m->name) debug(" %ls", m->name->name); } void DumpSemaphore(HANDLE hProc, SEMAPHORE* s) { if (!isValidPtr((DWORD)s)) { debug("DumpSemaphore: INVALID PTR %08lx\n", s); return; } debug(" cur=%d max=%d pend=%d", s->lCount, s->lMaxCount, s->lPending); if (s->name) debug(" %ls", s->name->name); } void DumpFSMap(HANDLE hProc, FSMAP* f) { if (!isValidPtr((DWORD)f)) { debug("DumpFSMap: INVALID PTR %08lx\n", f); return; } if (f->name) debug(" %ls", f->name->name); } std::string dwptrvaluestr(HANDLE hProc, DWORD dwOfs) { DWORD value; DWORD nRead; if (dwOfs==NULL) return "(null)"; if (!ReadProcessMemory(hProc, (void*)dwOfs, &value, sizeof(value), &nRead)) { error("dwptrvaluestr(%08lx,%08lx)", hProc, dwOfs); return "??"; } return stringformat("%08lx", value); } std::string procstring(HANDLE hProc, DWORD dwOfs) { WCHAR str[260]; DWORD nRead; if (dwOfs==NULL) return "(null)"; if (!ReadProcessMemory(hProc, (void*)dwOfs, str, sizeof(str), &nRead)) { error("procstring(%08lx, %08lx)", hProc, dwOfs); return "??"; } return ToString(str); } bool DumpHFSD(HANDLE hProc, void *p) { // 48 byte struct. struct filedesc { DWORD next; /* point to filedesc */ DWORD prev; /* point to filedesc */ DWORD pPartition; /* point to filedesc */ DWORD dw2; DWORD pfileinfo; /* point to fileinfo */ DWORD dw3; DWORD hFile; DWORD pgtgtinfo; DWORD dw4[4]; } fd; DWORD nRead; if (!ReadProcessMemory(hProc, (void*)p, &fd, sizeof(fd), &nRead)) { error("DumpHFSD(%08lx, %08lx) - reading filedesc", hProc, p); return false; } debug(" fileinfo: part=%08lx n=%d", fd.pPartition, fd.dw2); struct gtgtinfo { DWORD magic; DWORD pdgdginfo; DWORD dw2; DWORD pwstrName; DWORD pNext; DWORD pPrev; DWORD dw6; DWORD dw7; } gtgt; if (!ReadProcessMemory(hProc, (void*)fd.pgtgtinfo, >gt, sizeof(gtgt), &nRead)) { error("DumpHFSD(%08lx, %08lx) - reading gtgtinfo", hProc, fd.pgtgtinfo); return false; } debug(" gtgt(%08lx): n=%08lx p=%08lx dgdg=%08lx %hs", fd.pgtgtinfo, gtgt.pNext, gtgt.pPrev, gtgt.pdgdginfo, procstring(hProc, gtgt.pwstrName).c_str()); return true; } // wm2005: // STRG // magic // pVolume // pPartition // w4 // w5 // pnext // w7 // w8 // STRG+32 // next // prev bool DumpSTRG(HANDLE hProc, void *p) { DWORD nRead; struct storagedesc { DWORD magic; // 0x00596164 -> store handle, 0x64615900 -> partition handle DWORD pstorageinfo; DWORD ppartitioninfo; DWORD dw1[5]; DWORD pdw1[2]; } sd; if (!ReadProcessMemory(hProc, (void*)p, &sd, sizeof(sd), &nRead)) { error("DumpSTRG(%08lx, %08lx) - reading storagedesc", hProc, p); return false; } struct storageinfo { DWORD dw1[3]; // dw1[4] in wm2005 WCHAR devname[16]; WCHAR desc1[32]; WCHAR desc2[32]; WCHAR partdll[260]; WCHAR profilekey[260]; WCHAR fsname[260]; DWORD dw2[165]; WCHAR desc3[32]; DWORD dw3[29]; WCHAR driverkey[260]; DWORD dw4[11]; } si; if (!ReadProcessMemory(hProc, (void*)sd.pstorageinfo, &si, sizeof(si), &nRead)) { error("DumpSTRG(%08lx, %08lx) - reading storageinfo", hProc, sd.pstorageinfo); return false; } debug(" storagedev %ls %ls %ls", si.devname, si.desc1, si.desc2); return true; } bool DumpFFSD(HANDLE hProc, void *p) { // 48 byte struct. struct filedesc { DWORD next; DWORD prev; DWORD pPartition; DWORD dw2; DWORD pfilenameinfo; DWORD hProcess; DWORD hFile; DWORD pgtgtinfo; DWORD dw4[4]; } fd; DWORD nRead; if (!ReadProcessMemory(hProc, (void*)p, &fd, sizeof(fd), &nRead)) { error("DumpFFSD(%08lx, %08lx) - reading filedesc", hProc, p); return false; } debug(" fileinfo: part=%08lx n=%d", fd.pPartition, fd.dw2); struct filenameinfo { DWORD pfilename; DWORD pPartition; DWORD dw[6]; } fi; if (!ReadProcessMemory(hProc, (void*)fd.pfilenameinfo, &fi, sizeof(fi), &nRead)) { error("reading filesys.exe : %08lx\n", fd.pfilenameinfo); return false; } struct filename { DWORD dw; WCHAR name[260]; } fn; if (!ReadProcessMemory(hProc, (void*)fi.pfilename, &fn, sizeof(fn), &nRead)) { error("reading filesys.exe : %08lx\n", fi.pfilename); return false; } debug(" %08lx %ls", fn.dw, fn.name); return true; } bool DumpPartitionv5(HANDLE hProc, void *p) { struct partitioninfo { DWORD dw1[8]; // 0x0000 WCHAR volumename[32]; // 0x00bc WCHAR partitionname[32]; // 0x00fc DWORD dw2[5]; // 0x013c WCHAR fstype[12]; // 0x0150 } pi; DWORD nRead; if (!ReadProcessMemory(hProc, (void*)p, &pi, sizeof(pi), &nRead)) { error("DumpPart(%08lx, %08lx) - reading partitioninfo", hProc, p); return false; } debug(" partition: %ls %ls/%ls", pi.fstype, pi.volumename, pi.partitionname); return true; } bool DumpPartition(HANDLE hProc, void *p) { // todo: in wm2005 this is different struct partitioninfo { DWORD dw1[8]; WCHAR name[66]; DWORD dw2[2]; } pi; DWORD nRead; if (!ReadProcessMemory(hProc, (void*)p, &pi, sizeof(pi), &nRead)) { error("DumpPart(%08lx, %08lx) - reading partitioninfo", hProc, p); return false; } debug(" partition: %ls", pi.name); return true; } bool DumpBlockDevice(HANDLE hProc, void *p) { struct blockdev { DWORD dw1[11]; WCHAR name1[256]; DWORD dw2[13]; WCHAR name2[28]; DWORD dw3[2]; } bdev; DWORD nRead; if (!ReadProcessMemory(hProc, (void*)p, &bdev, sizeof(bdev), &nRead)) { error("DumpBlockDev(%08lx, %08lx) - reading blockdev", hProc, p); return false; } debug(" blockdev: %ls %ls", bdev.name1, bdev.name2); return true; } bool DumpW32Device(HANDLE hProc, fsopendev_t *d) { // W32D // struct fsopendev_t *nextptr; // next one in linked list // DWORD dwOpenData; // fsdev_t *lpDev; // DWORD *lpdwDevRefCnt; // since we set lpDev to NULL on device deregister // DWORD dwOpenRefCnt; // ref count for this structure // HANDLE KHandle; // kernel handle pointing to this structure // HPROCESS hProc; // process owning this handle fsopendev_t odev; DWORD nRead; // W32D struct is 0x28 bytes // this handle can only be read from the context of device.exe if (!ReadProcessMemory(hProc, (void*)d, &odev, sizeof(odev), &nRead)) { error("DumpW32Dev(%08lx, %08lx) - reading fsopendev_t", hProc, d); return false; } debug(" opendev next=%08lx data=%08lx dev=%08lx devref=%08lx->(%s) openref=%08lx h=%08lx hproc=%08lx", odev.nextptr, odev.dwOpenData, odev.lpDev, odev.lpdwDevRefCnt, dwptrvaluestr(hProc, (DWORD)odev.lpdwDevRefCnt).c_str(), odev.dwOpenRefCnt, odev.KHandle, odev.hProc); // new: c:\local\WINCE500\PRIVATE\WINCEOS\COREOS\DEVICE\INC\devmgrp.h // old: c:\local\WINCE500\PRIVATE\SERVERS\SERVICES\LIB\serv.h fsdev_t dev; if (!ReadProcessMemory(hProc, (void*)odev.lpDev, &dev, sizeof(dev), &nRead)) { error("DumpW32Dev(%08lx, %08lx) - reading fsdev_t", hProc, odev.lpDev); return false; } debug(" %c%c%c%d:", dev.type[0], dev.type[1], dev.type[2], dev.index); return true; } std::string FindNameForOid(CEOID oid); bool GetNameForOid(CEOID oid, std::string& name) { CEOIDINFO info; if (!CeOidGetInfo(oid, &info)) { return false; } switch(info.wObjType) { case OBJTYPE_INVALID: name="invalid objectid"; break; case OBJTYPE_FILE: name=stringformat("file: %ls", info.infFile.szFileName); break; case OBJTYPE_DIRECTORY: name=stringformat("dir: %ls", info.infDirectory.szDirName); break; case OBJTYPE_DATABASE: name=stringformat("db: %ls", info.infDatabase.szDbaseName); break; case OBJTYPE_RECORD: name=stringformat("rec from %hs", FindNameForOid(info.infRecord.oidParent).c_str()); break; default: name=stringformat("unknown objtype %d", info.wObjType); } return true; } std::string FindNameForOid(CEOID oid) { oid &= 0xffffff; std::string name; for (int i=0 ; i<768 ; i++) { // upto 768, since CeOidGetInfo crashes when called with oid's over 0xe0000000 if (GetNameForOid(oid | i<<22, name)) return name; } return "not found"; } bool DumpW32File(HANDLE hProc, FHANDLE *f) { struct { DWORD d[6]; } fh; DWORD nRead; // W32H struct is 0x18 bytes // this handle can only be read from the context of filesys.exe if (!ReadProcessMemory(hProc, (void*)f, &fh, sizeof(fh), &nRead)) { error("DumpW32File(%08lx, %08lx) - reading fn", hProc, f); return false; } debug(" %hs", hexdump((BYTE*)&fh, sizeof(fh)/sizeof(DWORD), 4).c_str()); debug(" %hs", FindNameForOid(fh.d[3]).c_str()); return true; } #define DBHANDLE void bool DumpDatabase(HANDLE hProc, DBHANDLE *d) { struct { DWORD d[18]; // d[5] : oid // d[4] : volume struct } dbh; DWORD nRead; // DBOA struct is 0x48 bytes // this handle can only be read from the context of filesys.exe if (!ReadProcessMemory(hProc, (void*)d, &dbh, sizeof(dbh), &nRead)) { error("DumpDatabase(%08lx, %08lx) - reading fn", hProc, d); return false; } debug(" %hs", hexdump((BYTE*)&dbh, sizeof(dbh)/sizeof(DWORD), 4).c_str()); debug(" %hs", FindNameForOid(dbh.d[5]).c_str()); return true; } bool DumpSocket(HANDLE hProc, DWORD s) { // Sock struct is ? bytes // this handle can only be read from the context of device.exe struct socketdesc { DWORD dw1[10]; DWORD pnext; DWORD dw2[2]; DWORD ptr1; DWORD pproto; DWORD dw3[44]; DWORD ptr2; DWORD dw4[1]; DWORD ptr3; DWORD ptr4; DWORD dw5[1]; DWORD ptr5; DWORD dw6[1]; DWORD ptr6; DWORD ptr7; DWORD dw7[6]; DWORD ptr8; DWORD dw8[5]; DWORD ptr9; DWORD ptr10; DWORD ptr11; DWORD dw9[2]; DWORD ptr12; DWORD ptr13; DWORD ptr14; DWORD dw10[43]; DWORD ptr15; } sd; DWORD nRead; if (!ReadProcessMemory(hProc, (void*)s, &sd, sizeof(sd), &nRead)) { error("DumpSocket(%08lx, %08lx) - reading sd", hProc, s); return false; } struct socketproto { DWORD dw1[7]; WCHAR name[20]; DWORD dw2[4]; } sp; if (!ReadProcessMemory(hProc, (void*)sd.pproto, &sp, sizeof(sp), &nRead)) { error("DumpSocket(%08lx, %08lx) - reading sp", hProc, sd.pproto); return false; } debug(" sock: next=%08lx proto=%ls", sd.pnext, sp.name); /* dumpmem(hProc, sd.ptr1, 0x40, "socketmem ptr1"); dumpmem(hProc, sd.ptr2, 0x40, "socketmem ptr2"); dumpmem(hProc, sd.ptr3, 0x40, "socketmem ptr3"); dumpmem(hProc, sd.ptr4, 0x40, "socketmem ptr4"); dumpmem(hProc, sd.ptr5, 0x40, "socketmem ptr5"); dumpmem(hProc, sd.ptr6, 0x40, "socketmem ptr6"); dumpmem(hProc, sd.ptr7, 0x40, "socketmem ptr7"); dumpmem(hProc, sd.ptr8, 0x40, "socketmem ptr8"); dumpmem(hProc, sd.ptr9, 0x40, "socketmem ptr9"); dumpmem(hProc, sd.ptr10, 0x40, "socketmem ptr10"); dumpmem(hProc, sd.ptr11, 0x40, "socketmem ptr11"); dumpmem(hProc, sd.ptr12, 0x40, "socketmem ptr12"); dumpmem(hProc, sd.ptr13, 0x40, "socketmem ptr13"); dumpmem(hProc, sd.ptr14, 0x40, "socketmem ptr14"); dumpmem(hProc, sd.ptr15, 0x40, "socketmem ptr15"); */ return true; } bool isStartPtr(HDATA *ha) { if (!isValidPtr((DWORD)ha)) { debug("isStartPtr: ha INVALID PTR %08lx\n", ha); return true; } if (!isValidPtr((DWORD)ha->pci)) { debug("isStartPtr: ha->pci INVALID PTR %08lx\n", ha->pci); return true; } return ((((DWORD)ha->hValue)&3)!=2); } /* * ha+00 8d94551c linkage.fwd * ha+04 8dddfdd4 linkage.back * ha+08 8d945542 hValue * ha+0c 00040000 lock * ha+10 0000 ref.pFr * ha+12 0001 ref.count * ha+14 8df5ba78 pci * pci+00 6b636f53 acName[4]; * pci+04 04 disp; * pci+05 0b type; * pci+06 000f cMethods; * pci+08 01c910d8 ppfnMethods * pci+0c 01c91118 pdwSig * pci+10 8c0c3840 pServer * ha+18 00361868 pvObj * ha+1c 00000000 dwInfo */ void testhandle(HANDLE h) { HDATA *hi= cvHandle2HDataPtr(h); HDATA *ha; bool bForward= true; ha=hi; do { if (!isValidPtr((DWORD)ha)) { if (bForward) { ha= (HDATA*)hi->linkage.back; bForward= false; if (!isValidPtr((DWORD)ha)) break; } else break; } if (isStartPtr(ha)) { debug("Start of Handle list: %08lx\n", ha); ha= (HDATA*)(bForward ? ha->linkage.fwd : ha->linkage.back); continue; } debug("%08lx %-4s %08lx %08lx", ha, GetCInfoName(ha->pci), ha->hValue, ha->pvObj); RegisterCInfo(ha->pci, -1); HANDLE hProc= (isValidPtr((DWORD)ha->pci) && isValidPtr((DWORD)ha->pci->pServer))? ha->pci->pServer->hProc : NULL; if (ha->pvObj && strncmp(ha->pci->acName, "PROC", 4)==0) DumpProcess(hProc, (PROCESS*)ha->pvObj); else if (ha->pvObj && strncmp(ha->pci->acName, "THRD", 4)==0) DumpThread(hProc, (THREAD*)ha->pvObj); else if (ha->pvObj && strncmp(ha->pci->acName, "APIS", 4)==0) DumpApiSet(hProc, (APISET*)ha->pvObj); else if (ha->pvObj && strncmp(ha->pci->acName, "EVNT", 4)==0) DumpEvent(hProc, (EVENT*)ha->pvObj); else if (ha->pvObj && strncmp(ha->pci->acName, "MUTX", 4)==0) DumpMutex(hProc, (MUTEX*)ha->pvObj); else if (ha->pvObj && strncmp(ha->pci->acName, "SEMP", 4)==0) DumpSemaphore(hProc, (SEMAPHORE*)ha->pvObj); else if (ha->pvObj && strncmp(ha->pci->acName, "FMAP", 4)==0) DumpFSMap(hProc, (FSMAP*)ha->pvObj); else if (ha->pvObj && strncmp(ha->pci->acName, "W32D", 4)==0) DumpW32Device(hProc, (fsopendev_t*)ha->pvObj); else if (ha->pvObj && strncmp(ha->pci->acName, "W32H", 4)==0) DumpW32File(hProc, (FHANDLE*)ha->pvObj); else if (ha->pvObj && strncmp(ha->pci->acName, "DBOA", 4)==0) DumpDatabase(hProc, (DBHANDLE*)ha->pvObj); else if (ha->pvObj && strncmp(ha->pci->acName, "Sock", 4)==0) DumpSocket(hProc, (DWORD)ha->pvObj); else if (ha->pvObj && strncmp(ha->pci->acName, "BDEV", 4)==0) DumpBlockDevice(hProc, ha->pvObj); else if (ha->pvObj && strncmp(ha->pci->acName, "PFSD", 4)==0) { // if (wm2005()) // DumpPartitionv5(hProc, ha->pvObj); // else DumpPartition(hProc, ha->pvObj); } else if (ha->pvObj && strncmp(ha->pci->acName, "HFSD", 4)==0) DumpHFSD(hProc, ha->pvObj); else if (ha->pvObj && strncmp(ha->pci->acName, "FFSD", 4)==0) DumpFFSD(hProc, ha->pvObj); else if (ha->pvObj && strncmp(ha->pci->acName, "STRG", 4)==0) DumpSTRG(hProc, ha->pvObj); //PFAT { +0x2c : char[11], (void*)+0x00 : +0x38 : long, wchar[?] } //PRdr - device.exe { +0x10 : wchar[12] } // //wm2005 handles: //DMFS - device.exe //EDBO - filesys.exe { ?, 0x12345678, ... } l=0x40 //FNOT - filesys.exe //PRdr - device.exe //ROM3 - filesys.exe //W32S - services.exe debug("\n"); ha= (HDATA*)(bForward ? ha->linkage.fwd : ha->linkage.back); } while (ha!=hi && ha!=NULL); debug("\n"); } std::string stringofmemblock(MEMBLOCK *p) { if (p==NULL_BLOCK) return "NULL_BLOCK"; else if (p==RESERVED_BLOCK) return "RESERVED_BLOCK"; else { return stringformat("%08lx: key=%08lx us=%d fl=%02x ix=%04x pf=%04x lk=%d %08lx: %hs", p, p->alk, p->cUses, p->flags, ((DWORD)p->ixBase)&0xffff, ((DWORD)p->hPf)&0xffff, p->cLocks, GetPagesList(p), hexdump((BYTE*)(GetPagesList(p)), 16, 4).c_str()); } } void DumpMemoryBlock(DWORD dwMemBlockOfs, MEMBLOCK *m) { if (m) debug("MemBlock_%08lx: %hs\n", dwMemBlockOfs, stringofmemblock(m).c_str()); } void DumpSection(DWORD dwSectionOfs, SECTION *s) { debug("Section_%08x: %08lx: %hs\n", dwSectionOfs, s, hexdump((BYTE*)s, 16, 4).c_str()); for (int j=0 ; j<0x200 ; j++) { DumpMemoryBlock(dwSectionOfs|(j< p%08lx-%08lx\n", dwStartVirt, dwAddr, dwStartPhys, dwPrevPhys+pagesize); bStarted= false; } if (bHasPhysAddr) { if (!bStarted) { bStarted= true; dwStartPhys= dwCurPhys; dwStartVirt= dwAddr; } dwPrevPhys= dwCurPhys; } dwAddr+=pagesize; pidx++; } if (bStarted) { debug("v%08lx-%08lx -> p%08lx-%08lx\n", dwStartVirt, dwAddr, dwStartPhys, dwPrevPhys+pagesize); bStarted= false; } } void SummarizePageTable() { DWORD *ptbl= (DWORD*)0xfffd0000; DWORD pagesize= 0x100000; bool bStarted= false; DWORD dwStartVirt= 0; DWORD dwStartPhys= 0; DWORD dwPrevPhys= 0; DWORD dwAddr= 0; DWORD pidx= 0; do { DWORD pe= ptbl[pidx]; DWORD dwCurPhys= 0; DWORD dwTlbPhys= 0; DWORD dwTlbPagesize= 0; bool bHasPhysAddr= false; bool bEndBlock= false; bool bHasTlb2= false; switch (pe&3) { case 0: // ignore entry bEndBlock= true; break; case 1: // coarse tlb entry dwTlbPhys= pe&0xfffffc00; dwTlbPagesize= 0x1000; bHasTlb2= true; bEndBlock= true; break; case 2: // section descriptor dwCurPhys= pe&0xfff00000; bHasPhysAddr= true; break; case 3: // fine tlb entry dwTlbPhys= pe&0xfffff000; dwTlbPagesize= 0x400; bHasTlb2= true; bEndBlock= true; break; } if (dwCurPhys-dwPrevPhys!=pagesize) bEndBlock= true; if (bStarted && bEndBlock) { debug("v%08lx-%08lx -> p%08lx-%08lx\n", dwStartVirt, dwAddr, dwStartPhys, dwPrevPhys+pagesize); bStarted= false; } if (bHasTlb2) { SummarizeTLB2(dwAddr, dwTlbPhys, dwTlbPagesize, pagesize/dwTlbPagesize); } if (bHasPhysAddr) { if (!bStarted) { bStarted= true; dwStartPhys= dwCurPhys; dwStartVirt= dwAddr; } dwPrevPhys= dwCurPhys; } dwAddr+=pagesize; pidx++; } while (dwAddr); if (bStarted) { debug("v%08lx-%08lx -> p%08lx-%08lx\n", dwStartVirt, dwAddr, dwStartPhys, dwPrevPhys+pagesize); bStarted= false; } } void SummarizeSections() { bool wince3x= GetWinceVersion() < 4 ; DWORD pagesize= 0x1000; DWORD dwStartPhys=0; DWORD dwStartVirt=0; DWORD dwPrevPhys=0; bool bStarted= false; DWORD dwAddr; for (dwAddr= 0 ; dwAddr<(wince3x?0x80000000:0xc4000000) ; dwAddr += (!wince3x && dwAddr==0x80000000) ? 0x42000000 : pagesize) { SECTION *pscn = (dwAddr & 0x80000000)? (SECTION*)KInfoTable[KINX_NKSECTION]: SectionTable[dwAddr>>VA_SECTION]; DWORD ixBlock = (dwAddr >> VA_BLOCK) & BLOCK_MASK; DWORD ixPage = (dwAddr >> VA_PAGE) & PAGE_MASK; MEMBLOCK *pmb = (*pscn)[ixBlock]; DWORD dwPhys= 0; bool bEndBlock = false; bool bHasPhysAddr= false; if (pmb==NULL_BLOCK || pmb==RESERVED_BLOCK) { bEndBlock= true; } else { DWORD dwPageentry= GetPagesList(pmb)[ixPage]; if (dwPageentry==0xfffffff0 || dwPageentry==0 ) bEndBlock= true; else { dwPhys= GetPagesList(pmb)[ixPage]&0xfffff000; bHasPhysAddr= true; if (dwPhys-dwPrevPhys!=pagesize) bEndBlock= true; } } if (bEndBlock && bStarted) { debug("v%08lx-%08lx -> p%08lx-%08lx\n", dwStartVirt, dwAddr, dwStartPhys, dwPrevPhys+pagesize); bStarted= false; } if (bHasPhysAddr) { if (!bStarted) { bStarted= true; dwStartPhys= dwPhys; dwStartVirt= dwAddr; } dwPrevPhys= dwPhys; } } if (bStarted) { debug("v%08lx-%08lx -> p%08lx-%08lx\n", dwStartVirt, dwAddr, dwStartPhys, dwPrevPhys+pagesize); bStarted= false; } } void DumpKernelInfo() { struct KDataStruct *k= (struct KDataStruct *)0xffffc800; int i; debug("%-64s %08lx\n", "0x000 Current thread local storage pointer", k->lpvTls); debug("%-64s SH_WIN32 %08lx\n", "", k->ahSys[SH_WIN32 ]); debug("%-64s SH_CURTHREAD %08lx\n", "", k->ahSys[SH_CURTHREAD]); debug("%-64s SH_CURPROC %08lx\n", "", k->ahSys[SH_CURPROC ]); debug("ahSys "); for (i=SH_CURPROC+1 ; iahSys[i]); debug("\n"); debug("%-64s %d\n", "0x084 reschedule flag", k->bResched); debug("%-64s %d\n", "0x085 kernel exception nesting", k->cNest); debug("%-64s %d\n", "0x086 TRUE during power off processing", k->bPowerOff); debug("%-64s %d\n", "0x087 TRUE if profiling enabled", k->bProfileOn); #if _WIN32_WCE==300 debug("%-64s %08lx\n", "0x088 Page Table Descriptor", k->ptDesc); #endif debug("%-64s %08lx\n", "0x08c was DiffMSec", k->rsvd2); debug("%-64s %08lx\n", "0x090 ptr to current PROCESS struct", k->pCurPrc); debug("%-64s %08lx\n", "0x094 ptr to current THREAD struct", k->pCurThd); debug("%-64s %08lx\n", "0x098 ", k->dwKCRes); debug("%-64s %08lx\n", "0x09c handle table base address", k->handleBase); debug("%-64s ", "0x0a0 section table for virtual memory"); for (i=0 ; i<64 ; i++) debug(" %08lx", k->aSections[i]); debug("\n"); debug("%-64s ", "0x1a0, 0x220 device events "); #if SYSINTR_MAX_DEVICES==0x40 for (i=0 ; ialpeIntrEvents[i]); #else for (i=0 ; ialpvIntrData[i], k->alpeIntrEvents[i]); #endif debug("\n"); debug("%-64s %08lx\n", "0x2a0 direct API return address for kernel mode", k->pAPIReturn); debug("%-64s %08lx\n", "0x2a4 ptr to MemoryMap array", k->pMap); debug("%-64s %08lx\n", "0x2a8 !0 when in debugger", k->dwInDebugger); //debug("%-64s long\n", "0x2ac - padding", k->alPad[21]); debug("%-64s %08lx\n", "aInfo[KINX_PROCARRAY]: address of process array", k->aInfo[KINX_PROCARRAY]); debug("%-64s %08lx\n", "aInfo[KINX_PAGESIZE]: system page size", k->aInfo[KINX_PAGESIZE]); debug("%-64s %08lx\n", "aInfo[KINX_PFN_SHIFT]: shift for page # in PTE", k->aInfo[KINX_PFN_SHIFT]); debug("%-64s %08lx\n", "aInfo[KINX_PFN_MASK]: mask for page # in PTE", k->aInfo[KINX_PFN_MASK]); debug("%-64s %08lx\n", "aInfo[KINX_PAGEFREE]: # of free physical pages", k->aInfo[KINX_PAGEFREE]); debug("%-64s %08lx\n", "aInfo[KINX_SYSPAGES]: # of pages used by kernel", k->aInfo[KINX_SYSPAGES]); debug("%-64s %08lx\n", "aInfo[KINX_KHEAP]: ptr to kernel heap array", k->aInfo[KINX_KHEAP]); debug("%-64s %08lx\n", "aInfo[KINX_SECTIONS]: ptr to SectionTable array", k->aInfo[KINX_SECTIONS]); debug("%-64s %08lx\n", "aInfo[KINX_MEMINFO]: ptr to system MemoryInfo struct", k->aInfo[KINX_MEMINFO]); debug("%-64s %08lx\n", "aInfo[KINX_MODULES]: ptr to module list", k->aInfo[KINX_MODULES]); debug("%-64s %08lx\n", "aInfo[KINX_DLL_LOW]: lower bound of DLL shared space", k->aInfo[KINX_DLL_LOW]); debug("%-64s %08lx\n", "aInfo[KINX_NUMPAGES]: total # of RAM pages", k->aInfo[KINX_NUMPAGES]); debug("%-64s %08lx\n", "aInfo[KINX_PTOC]: ptr to ROM table of contents", k->aInfo[KINX_PTOC]); debug("%-64s %08lx\n", "aInfo[KINX_KDATA_ADDR]: kernel mode version of KData", k->aInfo[KINX_KDATA_ADDR]); debug("%-64s %08lx\n", "aInfo[KINX_GWESHEAPINFO]: Current amount of gwes heap in use", k->aInfo[KINX_GWESHEAPINFO]); debug("%-64s %08lx\n", "aInfo[KINX_TIMEZONEBIAS]: Fast timezone bias info", k->aInfo[KINX_TIMEZONEBIAS]); debug("%-64s %08lx\n", "aInfo[KINX_PENDEVENTS]: bit mask for pending interrupt events", k->aInfo[KINX_PENDEVENTS]); debug("%-64s %08lx\n", "aInfo[KINX_KERNRESERVE]: number of kernel reserved pages", k->aInfo[KINX_KERNRESERVE]); debug("%-64s %08lx\n", "aInfo[KINX_API_MASK]: bit mask for registered api sets", k->aInfo[KINX_API_MASK]); #if _WIN32_WCE==300 debug("%-64s %08lx\n", "aInfo[KINX_NLS_OCP]: Current OEM code page", k->aInfo[KINX_NLS_OCP]); debug("%-64s %08lx\n", "aInfo[KINX_NLS_ACP]: Current ANSI code page", k->aInfo[KINX_NLS_ACP]); debug("%-64s %08lx\n", "aInfo[KINX_NLS_LOC]: Current NLS locale", k->aInfo[KINX_NLS_LOC]); #else debug("%-64s %08lx\n", "aInfo[KINX_NLS_CP]: hiword OEM code page, loword ANSI code page", k->aInfo[KINX_NLS_CP]); debug("%-64s %08lx\n", "aInfo[KINX_NLS_SYSLOC]: Default System locale", k->aInfo[KINX_NLS_SYSLOC]); debug("%-64s %08lx\n", "aInfo[KINX_NLS_USERLOC]: Default User locale", k->aInfo[KINX_NLS_USERLOC]); #endif debug("%-64s %08lx\n", "aInfo[KINX_HEAP_WASTE]: Kernel heap wasted space", k->aInfo[KINX_HEAP_WASTE]); debug("%-64s %08lx\n", "aInfo[KINX_DEBUGGER]: For use by debugger for protocol communication", k->aInfo[KINX_DEBUGGER]); debug("%-64s %08lx\n", "aInfo[KINX_APISETS]: APIset pointers", k->aInfo[KINX_APISETS]); debug("%-64s %08lx\n", "aInfo[KINX_MINPAGEFREE]: water mark of the minimum number of free pages", k->aInfo[KINX_MINPAGEFREE]); debug("%-64s %08lx\n", "aInfo[KINX_CELOGSTATUS]: CeLog status flags", k->aInfo[KINX_CELOGSTATUS]); debug("%-64s %08lx\n", "aInfo[KINX_NKSECTION]: Address of NKSection", k->aInfo[KINX_NKSECTION]); #ifdef KINX_PWR_EVTS debug("%-64s %08lx\n", "aInfo[KINX_PWR_EVTS]: Events to be set after power on", k->aInfo[KINX_PWR_EVTS]); #endif debug("%-64s %08lx\n", "aInfo[29]: ", k->aInfo[29]); debug("%-64s %08lx\n", "aInfo[30]: ", k->aInfo[30]); debug("%-64s %08lx\n", "aInfo[31]: last entry of KINFO -- signature when NK is ready", k->aInfo[31]); CINFO **apisets= (CINFO**)k->aInfo[KINX_APISETS]; for (i=0 ; i<32 ; i++) if (apisets[i]) RegisterCInfo(apisets[i], i); debug("k->aInfo "); for (i=KINX_APISETS+1 ; i<32 ; i++) debug(" %08lx", k->aInfo[i]); debug("\n"); MEMORYINFO *pmi= (MEMORYINFO*)k->aInfo[KINX_MEMINFO]; debug("meminfo: kdata=%08lx-%08lx #free entries: %d\n", pmi->pKData, pmi->pKEnd, pmi->cFi); // debug("------------------sections\n"); // // section 0 00000000-02000000: current process // // section 1 02000000-04000000: module section // // section 2-32 04000000-42000000: processes // // section 33-62 42000000-7e000000: filemappings // // section 63 7e000000-80000000: resource section // for (i=0 ; i<64 ; i++) { // DumpSection(i<aSections[i]); // } // debug("------------------kernel section\n"); // DumpSection(0xc2000000, (SECTION*)k->aInfo[KINX_NKSECTION]); /* debug("------------------section summary\n"); SummarizeSections(); debug("------------------pagetable summary\n"); SummarizePageTable(); */ } int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow) { DebugSetLogfile("testpi.log"); DebugOutputDebugString(); /* // create some open handles HANDLE hFile= CreateFile(L"\\windows\\notes.exe", GENERIC_READ, 0,NULL, OPEN_EXISTING, 0, NULL); HKEY hkey; DWORD disp; LONG res= RegCreateKeyEx(HKEY_LOCAL_MACHINE, L"Software", 0, L"??", 0, KEY_WRITE, NULL, &hkey, &disp); debug("filehandle=%08lx reghandle=%08lx\n", hFile, hkey); */ BOOL bMode = SetKMode(TRUE); DWORD dwPerm = SetProcPermissions(0xFFFFFFFF); //g_hFilesysProc= GetProcessHandle(L"filesys.exe"); //g_hDeviceProc= GetProcessHandle(L"device.exe"); debug("------------------kernel info\n"); DumpKernelInfo(); debug("------------------testhandle\n"); testhandle(hInstance); debug("------------------cinfo\n"); DumpCInfoMap(); // test(); SetProcPermissions(dwPerm); SetKMode(bMode); /* ThreadInfo ti(GetCurrentThread()); DWORD tMax= 2048; ti.GetThreadInfo(); for (DWORD iSleep= 0 ; iSleep < tMax ; iSleep = iSleep?2*iSleep:1) { DWORD t0= GetTickCount(); while(GetTickCount()-t0 < tMax) Sleep(iSleep); ti.GetThreadInfo(); debug("%6d : k%5d u%5d - k%5d u%5d\n", iSleep, ti.m_promileKernelRecent, ti.m_promileKernelTotal, ti.m_promileUserRecent, ti.m_promileUserTotal); } */ return 0; }