// a kernel library which writes a stackdump for each exception // // printf "#\"loadklib\"stackdumper.dll" | pput -f -c "%CSIDL_STARTUP%\stackdumper.lnk" // area free in kaiser rom // 802fa000-802fb000 // 802fc000-80300000 // 80308000-8031f000 #include #include "cenk.h" #include "printfformat.h" #include "debuglogger.h" //#include "kernelmisc.h" // HDATA: {00: fwd,back, hValue, lock, 10: ref, *CINFO, pvObj, dwInfo } // CINFO: {00: acName, 04:disp, 05:type, 06:cMethods, 08:ppfnMethods, 0c:pdwSig, 10:*PROCESS} DWORD PhysToVirt(DWORD dwPhysOffset) { // KSEG0_BASE .. KSEG1_BASE = cached kernel physical for (DWORD ixPage= 0x800 ; ixPage < 0xa00 ; ixPage++) { DWORD dwEntry= FirstPT[ixPage]; // FirstPT is defined in nkarm.h if (((dwEntry&3)==2) && ((dwEntry&0xfff00000)==(dwPhysOffset&0xfff00000))) return (dwPhysOffset&0xfffff)|(ixPage<<20); } // debug("Physical address %08lx is not mapped\n", dwPhysOffset); return 0; } DWORD PhysToVirtUC(DWORD dwPhysOffset) { return PhysToVirt(dwPhysOffset)|0x20000000; } DWORD VirtToPhys(DWORD dwAddr) { if (dwAddr==0) return INVALID_PHYSICAL_ADDRESS; if ((dwAddr<0x80000000) #if _WIN32_WCE>=400 || (IsSecureVa(dwAddr)) // IsSecureVa from pkfuncs.h #endif ) { // fedcba9876543210fedcba9876543210 // 0ssssssbbbbbbbbbpppp............ // // sectiontable[sssssss]->memblock[bbbbbbbbb]->page[pppp] // SECTION *pscn = #if _WIN32_WCE>=400 (dwAddr & 0x80000000) ? (SECTION*)KInfoTable[KINX_NKSECTION] : #endif SectionTable[dwAddr>>VA_SECTION]; DWORD ixBlock = (dwAddr >> VA_BLOCK) & BLOCK_MASK; DWORD ixPage = (dwAddr >> VA_PAGE) & PAGE_MASK; MEMBLOCK *pmb = (*pscn)[ixBlock]; if (pmb==NULL_BLOCK || pmb==RESERVED_BLOCK) return INVALID_PHYSICAL_ADDRESS; if (pmb->aPages[ixPage]==0 || pmb->aPages[ixPage]==BAD_PAGE) return INVALID_PHYSICAL_ADDRESS; return (pmb->aPages[ixPage]&0xfffff000) | (dwAddr&0xfff); } else { DWORD ixPage= (dwAddr>>20)&0xfff; DWORD dwEntry= FirstPT[ixPage]; // FirstPT is defined in nkarm.h if ((dwEntry&3)==2) { // fedcba9876543210fedcba9876543210 // ssssssssssss.................... index in 1st ptbl // // section descriptor return (dwEntry&0xfff00000)|(dwAddr&0xfffff); } else if ((dwEntry&0xfffff)==0) { return INVALID_PHYSICAL_ADDRESS; } else if ((dwEntry&3)==1) { // fedcba9876543210fedcba9876543210 // ............22222222............ index in 2nd ptbl // coarse page table entry DWORD phys_2nd_tlb= dwEntry&~0x3f; DWORD virt_2nd_tlb= PhysToVirtUC(phys_2nd_tlb); DWORD ix2ndPage= (dwAddr>>12)&0xff; DWORD dw2ndEntry= ((DWORD*)virt_2nd_tlb)[ix2ndPage]; if ((dw2ndEntry&3)==1) { // large page // // fedcba9876543210fedcba9876543210 // ............22222222............ index in 2nd ptbl // ................llllllllllllllll large page adress mask // // note that there is an overlap between used addressbits here // and used bits to index ix2ndpage. // -> virt_2nd_tlb[ix2ndPage&~0xf+i] for i= 0 ..15 must be equal return (dw2ndEntry&0xffff0000)|(dwAddr&0xffff); } else if ((dw2ndEntry&3)==2) { // small page // // fedcba9876543210fedcba9876543210 // ............22222222............ index in 2nd ptbl // ....................ssssssssssss small page adress mask // return (dw2ndEntry&0xfffff000)|(dwAddr&0xfff);; } // tiny pages should only occur in fine 2nd level pages return INVALID_PHYSICAL_ADDRESS; } else if ((dwEntry&3)==3) { // fedcba9876543210fedcba9876543210 // ............2222222222.......... index in 2nd ptbl // fine page table entry DWORD phys_2nd_tlb= dwEntry&~0xfff; DWORD virt_2nd_tlb= PhysToVirtUC(phys_2nd_tlb); DWORD ix2ndPage= (dwAddr>>10)&0x3ff; DWORD dw2ndEntry= ((DWORD*)virt_2nd_tlb)[ix2ndPage]; if ((dw2ndEntry&3)==1) { // large page // // fedcba9876543210fedcba9876543210 // ............2222222222.......... index in 2nd ptbl // ................llllllllllllllll large page adress mask // return (dw2ndEntry&0xffff0000)|(dwAddr&0xffff); } else if ((dw2ndEntry&3)==2) { // small page // // fedcba9876543210fedcba9876543210 // ............2222222222.......... index in 2nd ptbl // ....................ssssssssssss small page adress mask // return (dw2ndEntry&0xfffff000)|(dwAddr&0xfff);; } else if ((dw2ndEntry&3)==3) { // tiny page // // fedcba9876543210fedcba9876543210 // ............2222222222.......... index in 2nd ptbl // ......................tttttttttt tiny page address mask // return (dw2ndEntry&0xfffffc00)|(dwAddr&0x3ff);; } return INVALID_PHYSICAL_ADDRESS; } return INVALID_PHYSICAL_ADDRESS; } } bool isValidPtr(DWORD dwAddr) { return VirtToPhys(dwAddr)!=INVALID_PHYSICAL_ADDRESS; } void dummy() { } #define DECLARE_API(name, result, params) \ typedef result (*name##_fn) params; \ name##_fn name##_orig=(name##_fn)dummy; #define CANHOOK(apinr,callnr) \ ((SystemApiSets) && (SystemApiSets[apinr]) && (SystemApiSets[apinr]->ppfnMethods)) #define GETAPI(apinr,callnr,name) \ name##_orig = (name##_fn)SystemApiSets[apinr]->ppfnMethods[callnr]; #define HOOKFUNCTION(name,result,params) \ result name##_hook params #define SETAPI(apinr,callnr,name) \ set_api_method(apinr, callnr, (PFNVOID)name##_hook); \ NKDbgPrintf(L"hooked api(%d,%d) : %s\n", apinr, callnr, L#name); // note: all functions need to use the same nr of macro levels // otherwise one will use the name -as-is-, while the other will use // the name redefined to nameW ( as often done in windows.h for UNICODE apis ) #define DECLARE_HOOK(name, result, params) \ DECLARE_API(name,result,params) \ HOOKFUNCTION(name,result,params) #define HOOKAPI(apinr,callnr,name) \ if (CANHOOK(apinr,callnr)) { \ GETAPI(apinr,callnr,name) \ SETAPI(apinr,callnr,name) \ } \ else { \ NKDbgPrintf(L"could not hook api(%d, %d) : %s\n", apinr, callnr, L#name); \ } #define ORIGAPIX(name) name##_orig #define ORIGAPI(name) ORIGAPIX(name) #define GETAPIX(apinr,callnr,name) GETAPI(apinr,callnr,name) // use kernel versions of : // SetLastError 0 88 f000fea0 DECLARE_API(SetLastError,void,(DWORD)) // GetLastError 0 89 f000fe9c DECLARE_API(GetLastError,DWORD,()) // LeaveCriticalSection f000ff1c 0 57 LeaveCritSec DECLARE_API(LeaveCriticalSection,void, (LPCRITICAL_SECTION)) // EnterCriticalSection f000ff20 0 56 TakeCritSec DECLARE_API(EnterCriticalSection,void, (LPCRITICAL_SECTION)) // InitializeCriticalSection f000fec8 0 78 CreateCrit DECLARE_API(InitializeCriticalSection,HANDLE, (LPCRITICAL_SECTION)) // AllocPhysMem 0 168 f000fd60 DECLARE_API(AllocPhysMem,LPVOID,(DWORD cbSize, DWORD fdwProtect, DWORD dwAlignmentMask, DWORD dwFlags, PULONG pPhysicalAddress)) // GetTickCount 0 13 f000ffcc DECLARE_API(GetTickCount,DWORD,()) // memcpy - use compiler intrinsic ... how? void mymemcpy(BYTE *dst, BYTE *src, DWORD n) { while (n--) *dst++ = *src++; } #define SystemApiSets ((CINFO**)(KData.aInfo[KINX_APISETS])) // f000fef0 0 68 DECLARE_API(GetCallerProcess, HANDLE, ()) // f000ff08 0 62 DECLARE_API(IsBadPtr, BOOL, (DWORD flag, LPBYTE ptr, DWORD len)) #if 0 typedef HANDLE (*CreateFile_t)(LPCWSTR lpFileName, DWORD dwDesiredAccess, DWORD dwShareMode, LPSECURITY_ATTRIBUTES lpSecurityAttributes, DWORD dwCreationDisposition, DWORD dwFlagsAndAttributes, HANDLE hTemplateFile); CreateFile_t MyCreateFile; typedef BOOL (*CloseHandle_t)(HANDLE h); CloseHandle_t MyCloseHandle; typedef BOOL (*WriteFile_t)(HANDLE hFile, LPCVOID lpBuffer, DWORD nNumberOfBytesToWrite, LPDWORD lpNumberOfBytesWritten, LPOVERLAPPED lpOverlapped); WriteFile_t MyWriteFile; typedef BOOL (*SetFilePointer_t)(HANDLE hFile, LONG lDistanceToMove, PLONG lpDistanceToMoveHigh, DWORD dwMoveMethod); SetFilePointer_t MySetFilePointer; #endif //#define NKvDbgPrintf (*(void (*)(const WCHAR*msg, const void *lpParms))0xF000FFA4) void init(); #define dwptr(p) ((DWORD*)(p)) #define ProcessHandle(p) ((p)?(p)->hProc:0) #define ThreadHandle(p) ((p)?(p)->hTh:0) void NKDbgPrintf(const WCHAR *msg, ...); BOOL APIENTRY DllMain( HANDLE hModule, DWORD ul_reason_for_call, LPVOID lpReserved ) { #ifdef BUFFERLOGGING logmsg(L"libklog: DllMain\n"); #endif if (ul_reason_for_call==0) { init(); } NKDbgPrintf(L"libklog: hmod=%08lx reason=%d res=%08lx\n", hModule, ul_reason_for_call, lpReserved); return TRUE; } extern "C" __declspec(dllexport) void dumpstack(int r0, ...) { DWORD esp= (DWORD)(&esp)&~0x1F; DWORD stacktop= (esp|0xFFFF)+1; NKDbgPrintf(L"stackdump: r0=%08lx, &r0=%08lx, stack=%08lx-%08lx curproc=%08lx:%08lx, curthread=%08lx:%08lx\n", r0, &r0, esp, stacktop, KData.pCurPrc, ProcessHandle(KData.pCurPrc), KData.pCurThd, ThreadHandle(KData.pCurThd)); if (KData.pCurThd) { NKDbgPrintf(L"callstack: \n"); for (CALLSTACK *cs= KData.pCurThd->pcstkTop ; cs ; cs= cs->pcstkNext) { NKDbgPrintf(L" %08lx %08lx:%08lx %08lx %08lx %08lx %08lx:", cs->retAddr, cs->pprcLast,ProcessHandle(cs->pprcLast), cs->akyLast, cs->extra, cs->dwPrevSP, cs->dwPrcInfo); if (cs->dwPrevSP) NKDbgPrintf(L" %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n", dwptr(cs->dwPrevSP)[0], dwptr(cs->dwPrevSP)[1], dwptr(cs->dwPrevSP)[2], dwptr(cs->dwPrevSP)[3], dwptr(cs->dwPrevSP)[4], dwptr(cs->dwPrevSP)[5], dwptr(cs->dwPrevSP)[6], dwptr(cs->dwPrevSP)[7]); else NKDbgPrintf(L" -\n"); } } while (esp%08lx" #define APIHOOKARGS() ORIGAPI(GetCallerProcess)(), hCurProc // f000ff2c 0 53 DECLARE_HOOK(CreateProcess, BOOL, (LPCWSTR lpszImageName, LPCWSTR lpszCommandLine, LPSECURITY_ATTRIBUTES lpsaProcess, LPSECURITY_ATTRIBUTES lpsaThread, BOOL fInheritHandles, DWORD fdwCreate, LPVOID lpvEnvironment, LPWSTR lpszCurDir, LPSTARTUPINFO lpsiStartInfo, LPPROCESS_INFORMATION lppiProcInfo)) { BOOL result= ORIGAPI(CreateProcess)(lpszImageName, lpszCommandLine, lpsaProcess, lpsaThread, fInheritHandles, fdwCreate, lpvEnvironment, lpszCurDir, lpsiStartInfo, lppiProcInfo); NKDbgPrintf(APIHOOKFMT L" CreateProcess('%ls', '%ls' -> %08lx)= %08lx\n", APIHOOKARGS(), lpszImageName, lpszCommandLine, lppiProcInfo?lppiProcInfo->hProcess:0, result); return result; } // f000ffe0 0 8 LoadLibraryW // f000fdb0 0 148 LoadLibraryEx DECLARE_HOOK(LoadLibraryEx, HMODULE, (LPCSTR lpLibFileName, DWORD dwFlags, LPDWORD pdwCnt)) { HMODULE result= ORIGAPI(LoadLibraryEx)(lpLibFileName, dwFlags, pdwCnt); NKDbgPrintf(APIHOOKFMT L" LoadLibraryEx('%ls', %08lx, %08lx=%08lx)= %08lx\n", APIHOOKARGS(), lpLibFileName, dwFlags, pdwCnt, pdwCnt?*pdwCnt:0, result); return result; } // f000ffd8 0 10 GetProcAddressW // f000ff04 0 63 GetProcAddrBits // f000fdc0 0 144 GetProcAddressA DECLARE_HOOK(GetProcAddress, LPVOID, (HMODULE hMod, LPCWSTR szProcname)) { LPVOID result= ORIGAPI(GetProcAddress)(hMod, szProcname); if (DWORD(szProcname)<0x10000) NKDbgPrintf(APIHOOKFMT L" GetProcAddress(%08lx, ord_%04d)= %08lx\n", APIHOOKARGS(), hMod, szProcname, result); else NKDbgPrintf(APIHOOKFMT L" GetProcAddress(%08lx, '%ls')= %08lx\n", APIHOOKARGS(), hMod, szProcname, result); return result; } // f000fe84 0 95 DECLARE_HOOK(CreateFileMapping, HANDLE, (HANDLE hFile, LPSECURITY_ATTRIBUTES lpsa, DWORD flProtect, DWORD dwMaxSizeHigh, DWORD dwMaxSizeLow, LPCWSTR lpName)) { HANDLE result= ORIGAPI(CreateFileMapping)(hFile, lpsa, flProtect, dwMaxSizeHigh, dwMaxSizeLow, lpName); NKDbgPrintf(APIHOOKFMT L" CreateFileMapping(%08lx, %08lx, %08lx, %08lx, %08lx, %08lx:'%ls')= %08lx\n", APIHOOKARGS(), hFile, lpsa, flProtect, dwMaxSizeHigh, dwMaxSizeLow, lpName, lpName?lpName:L"", result); return result; } // f000ff48 0 46 DECLARE_HOOK(CloseProcOE, void, (DWORD bClose)) { ORIGAPI(CloseProcOE)(bClose); NKDbgPrintf(APIHOOKFMT L" CloseProcOE(%08lx)\n", APIHOOKARGS(), bClose); } // f000fef8 0 66 DECLARE_HOOK(KillAllOtherThreads, VOID, (void)) { ORIGAPI(KillAllOtherThreads)(); NKDbgPrintf(APIHOOKFMT L" KillAllOtherThreads\n", APIHOOKARGS()); } // f000fea4 0 87 DECLARE_HOOK(NKTerminateThread, void, (DWORD dwExitCode)) { ORIGAPI(NKTerminateThread)(dwExitCode); NKDbgPrintf(APIHOOKFMT L" NKTerminateThread(%08lx)\n", APIHOOKARGS(), dwExitCode); } // f000fe90 0 92 DECLARE_HOOK(CloseAllHandles, void, (void)) { ORIGAPI(CloseAllHandles)(); NKDbgPrintf(APIHOOKFMT L" CloseAllHandles\n", APIHOOKARGS()); } // f000fda4 0 151 DECLARE_HOOK(KillThreadIfNeeded, void, (void)) { ORIGAPI(KillThreadIfNeeded)(); NKDbgPrintf(APIHOOKFMT L" KillThreadIfNeeded\n", APIHOOKARGS()); } // f000ff28 0 54 DECLARE_HOOK(CreateThread, HANDLE, (LPSECURITY_ATTRIBUTES lpsa, DWORD cbStack, LPTHREAD_START_ROUTINE lpStartAddr, LPVOID lpvThreadParm, DWORD fdwCreate, LPDWORD lpIDThread)) { HANDLE result= ORIGAPI(CreateThread)(lpsa, cbStack, lpStartAddr, lpvThreadParm, fdwCreate, lpIDThread); NKDbgPrintf(APIHOOKFMT L" CreateThread(%08lx, %08lx, %08lx, %08lx, %08lx, %08lx)= %08lx\n", APIHOOKARGS(), lpsa, cbStack, lpStartAddr, lpvThreadParm, fdwCreate, lpIDThread, result); return result; } // f000ffdc 0 9 DECLARE_HOOK(FreeLibrary, BOOL, (HANDLE hInst, LPDWORD pdwCnt)) { BOOL result= ORIGAPI(FreeLibrary)(hInst, pdwCnt); NKDbgPrintf(APIHOOKFMT L" FreeLibrary(%08lx, %08lx:%08lx)=%08lx\n", APIHOOKARGS(), hInst, pdwCnt, pdwCnt?*pdwCnt:0, result); return result; } // f000fbdc 1 9 DECLARE_HOOK(TerminateThread,BOOL,(HANDLE hThread, DWORD dwExitCode)) { BOOL result= ORIGAPI(TerminateThread)(hThread, dwExitCode); NKDbgPrintf(APIHOOKFMT L" TerminateThread(%08lx,%08lx)=%08lx\n", APIHOOKARGS(), hThread, dwExitCode, result); return result; } // f000f800 2 0 DECLARE_HOOK(ProcCloseHandle,BOOL,(HANDLE hProc)) { BOOL result= ORIGAPI(ProcCloseHandle)(hProc); NKDbgPrintf(APIHOOKFMT L" ProcCloseHandle(%08lx)=%08lx\n", APIHOOKARGS(), hProc, result); return result; } // f000f7f8 2 2 DECLARE_HOOK(TerminateProcess,BOOL,(HANDLE hProc, DWORD dwExitCode)) { BOOL result= ORIGAPI(TerminateProcess)(hProc, dwExitCode); NKDbgPrintf(APIHOOKFMT L" TerminateProcess(%08lx,%08lx)=%08lx\n", APIHOOKARGS(), hProc, dwExitCode, result); return result; } // f000ffc8 0 14 DECLARE_HOOK(OutputDebugString, void, (const WCHAR*msg)) { #ifdef BUFFERLOGGING logmsg(msg); #endif ORIGAPI(OutputDebugString)(msg); } // f000ffa4 0 23 DECLARE_HOOK(NKvDbgPrintf, void, (const WCHAR*msg, const void *lpParms)) { #ifdef BUFFERLOGGING vlogmsg(msg, lpParms); #endif ORIGAPI(NKvDbgPrintf)(msg, lpParms); } #ifdef BUFFERLOGGING // f000fed8 0 74 DECLARE_HOOK(ReadDebugLog, BOOL, (BYTE *pBuf, DWORD dwBufSize, DWORD *pnRead)) { // todo: translate pbuf and pnread to kspace //NKDbgPrintf(L"ReadDebugLog(%p, 0x%x, %p)\n", pBuf, dwBufSize, pnRead); return readlog(pBuf, dwBufSize, pnRead); } #endif // f000fed8 7 11 DECLARE_HOOK(DeviceIoControl, BOOL, (HANDLE hDevice, DWORD dwIoControlCode, LPVOID lpInBuf, DWORD nInBufSize, LPVOID lpOutBuf, DWORD nOutBufSize, LPDWORD lpBytesReturned, LPOVERLAPPED lpOverlapped)) { // todo: translate pbuf and pnread to kspace //NKDbgPrintf(L"ReadDebugLog(%p, 0x%x, %p)\n", pBuf, dwBufSize, pnRead); DWORD t0= ORIGAPI(GetTickCount)(); BOOL result= ORIGAPI(DeviceIoControl)(hDevice, dwIoControlCode, lpInBuf, nInBufSize, lpOutBuf, nOutBufSize, lpBytesReturned, lpOverlapped); NKDbgPrintf(APIHOOKFMT L" DeviceIoControl(%08lx,%08lx, %08x:%04x, %08x:%04x, %08x->%04x, %08x)=%08lx - %d msec\n", APIHOOKARGS(), hDevice, dwIoControlCode, lpInBuf, nInBufSize, lpOutBuf, nOutBufSize, lpBytesReturned, isValidPtr((DWORD)lpBytesReturned) ? *lpBytesReturned : 0, lpOverlapped, result, ORIGAPI(GetTickCount)()-t0); return result; } // see line 1020 in ~/sources/wince500/PRIVATE/WINCEOS/COREOS/NK/KERNEL/ARM/mdarm.c const WCHAR akystring[]= { 'A','K','Y','=','%','8','.','8','l','x',' ','P','C','=','%','8','.','8','l','x','(','%','s','+','0','x','%','8','.','8','l','x',')',' ','R','A','=','%','8','.','8','l','x','(', //'%','s','+','0','x','%','8','.','8','l','x',')',' ','B','V','A','=','%','8','.','8','l','x',' ','F','S','R','=','%','8','.','8','l','x', }; template int compare(const T*p1, const T*p2, size_t n) { while (n && *p1==*p2) { n--; p1++; p2++; } if (n==0) return 0; if (*p1<*p2) return -1; if (*p1>*p2) return +1; return 0; } void NKDbgPrintf(const WCHAR *msg, ...) { va_list ap; va_start(ap, msg); #ifdef BUFFERLOGGING vlogmsg(msg, (const void *)ap); #endif if (ORIGAPI(NKvDbgPrintf)) ORIGAPI(NKvDbgPrintf)(msg, ap); va_end(ap); } void set_api_method(int set, int mth, PFNVOID func) { const_cast(SystemApiSets[set]->ppfnMethods[mth])= func; } //------- hd interface ULONG MyHDException( PEXCEPTION_RECORD ExceptionRecord, CONTEXT *ContextRecord, BOOLEAN SecondChance ) { dumpstack(0); return FALSE; } /* static void HDPageIn (DWORD dw, BOOL f) { } static void HDModLoad (DWORD dw) { } static void HDModUnload (DWORD dw) { } */ void init() { GETAPI(0, 88, SetLastError) GETAPI(0, 89, GetLastError) GETAPI(0, 57, LeaveCriticalSection) GETAPI(0, 56, EnterCriticalSection) GETAPI(0, 78, InitializeCriticalSection) GETAPI(0,168, AllocPhysMem) GETAPI(0, 68, GetCallerProcess) GETAPI(0, 62, IsBadPtr) GETAPI(0, 13, GetTickCount) // HOOKAPI(0,14,OutputDebugString); #ifdef BUFFERLOGGING HOOKAPI(0,23,NKvDbgPrintf); #else GETAPI(0,23,NKvDbgPrintf); #endif NKDbgPrintf(L"libklog: got many apis gettick=%08x devioctl=%08x/%08x\n", ORIGAPI(GetTickCount), &ORIGAPI(DeviceIoControl), DeviceIoControl_hook); #ifdef BUFFERLOGGING initlogging(0x800000); #endif // MyCreateFile= (CreateFile_t)SystemApiSets[20]->ppfnMethods[9]; // // problem: the following 3 ptrs are NULL // MyCloseHandle= (CloseHandle_t)SystemApiSets[7]->ppfnMethods[0]; // MyWriteFile= (WriteFile_t)SystemApiSets[7]->ppfnMethods[3]; // MySetFilePointer= (SetFilePointer_t)SystemApiSets[7]->ppfnMethods[5]; // see ~/sources/wince500/PRIVATE/WINCEOS/COREOS/NK/KERNEL/kwin32.c #ifdef HOOK_APIS HOOKAPI(0,53,CreateProcess); HOOKAPI(0,148,LoadLibraryEx); HOOKAPI(0,9,FreeLibrary); HOOKAPI(0,10,GetProcAddress); HOOKAPI(0,95,CreateFileMapping); HOOKAPI(0,46,CloseProcOE); HOOKAPI(0,66,KillAllOtherThreads); HOOKAPI(0,87,NKTerminateThread); HOOKAPI(0,92,CloseAllHandles); // HOOKAPI(0,151,KillThreadIfNeeded); ... called very often HOOKAPI(0,54,CreateThread); #else GETAPIX(0,148,LoadLibraryEx); #endif #ifdef BUFFERLOGGING HOOKAPI(0,74,ReadDebugLog); #endif // NKDbgPrintf(L"libklog: hooked several apis\n"); // HOOKAPI(7,11,DeviceIoControl); // NKDbgPrintf(L"libklog: hooked devioctl\n"); // hack: hook hd.dll exception handler, note: this only works // for the htc kaiser v1.82 rom if (((DWORD)ORIGAPI(LoadLibraryEx))==0x8003ABCC) *(DWORD*)0x80306050= (DWORD)MyHDException; // for the htc viva v1.27 rom else if (((DWORD)ORIGAPI(LoadLibraryEx))==0x8C12FB64) *(DWORD*)0x8C3D6050= (DWORD)MyHDException; // for the htc startrek v1.02 rom else if (((DWORD)ORIGAPI(LoadLibraryEx))==0x8C0AC178) *(DWORD*)0x8C2C6050= (DWORD)MyHDException; // for the htc herald v5.4.405.1 rom else if (((DWORD)ORIGAPI(LoadLibraryEx))==0x8C12DD40) *(DWORD*)0x8C386050= (DWORD)MyHDException; // for the htc photon, v1.32 rom else if (((DWORD)ORIGAPI(LoadLibraryEx))==0x815743fc) *(DWORD*)0x81916050= (DWORD)MyHDException; else { NKDbgPrintf(L"libklog::init: did not patch HDException: loadlib=%08lx nkdbgprintf=%08lx createproc=%08lx getproc=%08lx\n", ORIGAPI(LoadLibraryEx), ORIGAPI(NKvDbgPrintf), ORIGAPI(CreateProcess), ORIGAPI(GetProcAddress)); } }