#include "debug.h" #include #include "cenk.h" #include "cever_deps.h" #include "kernelmisc.h" #include "stringutils.h" #include "vectorutils.h" #include "ptrutils.h" #define LOADLIBEX 148 /* * this is an experiment to insert a hook into a system call handler * * currently it does not work yet. * * * other things I may try, is to add a OEMLoadModule handler * like in ./PLATFORM/EMULATOR/KERNEL/HAL/key1024.c: * * or implement the 'SH_PATCHER'-api, as used by * .\PRIVATE\WINCEOS\COREOS\NK\KERNEL\loader.c * */ void DumpApiSets() { CINFO **sets= (CINFO **)KData.aInfo[KINX_APISETS]; /* debug("\n\napisets= %08lx\n", sets); for (int apinr=0 ; apinr<32 ; apinr++) { if (sets[apinr]==NULL) { printf("CINFO=%08lx : NULL\n", sets[apinr]); continue; } debug("CINFO=%08lx '%hs' dsp=%02x tp=%02x n=%d fn=%08lx sig=%08lx svr=%08lx\n", sets[apinr], std::string(sets[apinr]->acName, sets[apinr]->acName+4).c_str(), sets[apinr]->disp, sets[apinr]->type, sets[apinr]->cMethods, sets[apinr]->ppfnMethods, sets[apinr]->pdwSig, sets[apinr]->pServer); if (sets[apinr]->ppfnMethods) { for (int callnr=0 ; callnr<10 && callnrcMethods ; callnr++) { debug(" %d=%08lx", callnr, sets[apinr]->ppfnMethods[callnr]); } } debug("\n"); } */ debug("%08lx:%08lx:fn148(%08lx)=%hs\n", sets[0], sets[0]->ppfnMethods, sets[0]->ppfnMethods[LOADLIBEX], hexdump((BYTE*)sets[0]->ppfnMethods[LOADLIBEX], 7, 4).c_str()); debug("\n\n"); } DWORD AddModuleBase(void*p) { HDATA *hd= cvHandle2HDataPtr((HANDLE)GetCurrentProcessId()); PROCESS *proc= (PROCESS*)hd->pvObj; return DWORD(p)|proc->dwVMBase; } bool setNameEquals(const CINFO* set, const char *name) { return memcmp(set->acName, name, 4)==0; } bool setNameEquals(const CINFO* set1, const CINFO *set2) { return memcmp(set1->acName, set2->acName, 4)==0; } bool FindApiSet(const char *name, PCINFO& pset, DWORD& physaddr) { CINFO **sets= (CINFO **)KData.aInfo[KINX_APISETS]; for (int i=0 ; i %08lx\n", name, &sets[i], sets[i]); return true; } debug("FindApiSet: could not find apiset %s\n", name); return false; } bool SetApiSet(const PCINFO set, DWORD physaddr) { CINFO **sets= (CINFO **)KData.aInfo[KINX_APISETS]; for (int i=0 ; icMethods*sizeof(DWORD); // todo: this does not allocate a contigeous memory block!!! newset= (CINFO*)LocalAlloc(LPTR, dwSize); if (newset==NULL) { error("DuplicateApi: LocalAlloc"); return false; } // NOTE: if newset+dwSize is on a different page than newset // this will not work. physnew= AddModuleBase(newset); debug("vmem=%08lx pmem=%08lx\n", newset, physnew); DWORD *pfnMethods= (DWORD*)&newset[1]; memcpy(newset, oldset, sizeof(CINFO)); memcpy(pfnMethods, oldset->ppfnMethods, oldset->cMethods*sizeof(DWORD)); newset->ppfnMethods= (PFNVOID*)(physnew+sizeof(CINFO)); return true; } PFNVOID ChangeHook(CINFO *newset, int apinr, PFNVOID newfn, int codesize) { PFNVOID oldfn= newset->ppfnMethods[apinr]; // NOTE: if newfn+dwSize is on a different page than newfn // this will not work. DWORD physfn= AddModuleBase(newfn); debug("vfunc: %08lx %hs\n", newfn, hexdump((BYTE*)newfn, codesize, 4).c_str()); debug("pfunc: %08lx %hs\n", physfn, hexdump((BYTE*)physfn, codesize, 4).c_str()); debug("changing %08lx at %08lx to %08lx\n", oldfn, &newset->ppfnMethods[apinr], physfn); const_cast(newset->ppfnMethods[apinr])= (PFNVOID)physfn; return oldfn; } // // bigest problem seems to be how to pass data to the kernel // address space. // // but o.t.h this 'return invalid' also does not work. // typedef HANDLE (*PFNOrigLoadLibraryEx)(LPCWSTR lpszFileName, DWORD dwFlags, LPDWORD pdwCnt); PFNOrigLoadLibraryEx OrigLoadLibraryEx; HANDLE HookLoadLibraryEx(LPCWSTR lpszFileName, DWORD dwFlags, LPDWORD pdwCnt) { return INVALID_HANDLE_VALUE; /* HANDLE hSem= CreateSemaphore(NULL, 0, 0, L"HookLoadLibCalls"); MessageBox(0, L"asada", L"qwqwqwe", 0); ReleaseSemaphore(hSem, 1, NULL); CloseHandle(hSem); return OrigLoadLibraryEx(lpszFileName, dwFlags, pdwCnt); */ } int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow) { DebugSetLogfile("hookapi.log"); KernelMode _km; DumpApiSets(); HANDLE hSem= CreateSemaphore(NULL, 0, 0, L"HookLoadLibCalls"); PCINFO oldset; DWORD physold; PCINFO newset; DWORD physnew; if (!DuplicateApi("Wn32", oldset, physold, newset, physnew)) { debug("error duplication api\n"); return 1; } debug("vold=%08lx pold=%08lx vnew=%08lx pnew=%08lx\n", oldset, physold, newset, physnew); debug("created new apiset: %d methods\n", newset->cMethods); OrigLoadLibraryEx= (PFNOrigLoadLibraryEx )ChangeHook(newset, LOADLIBEX, (PFNVOID)HookLoadLibraryEx, PTR_DIFF(HookLoadLibraryEx, WinMain)); if (!SetApiSet(newset, physnew)) { debug("error switching apiset\n"); return 1; } DumpApiSets(); HMODULE hLib= LoadLibrary(L"ril.dll"); if (hLib==NULL || hLib==INVALID_HANDLE_VALUE) error("loadlib"); else { debug("loaded lib: %08lx\n", hLib); FreeLibrary(hLib); } if (!SetApiSet(oldset, physold)) { debug("error restoring apiset\n"); return 1; } DumpApiSets(); int libs=0; while (WaitForSingleObject(hSem, 0)==WAIT_OBJECT_0) libs++; CloseHandle(hSem); debug("test %d\n", libs); return 0; }