#include "debug.h" #include #include "cenk.h" #include "cever_deps.h" #include "kernelmisc.h" #include "stringutils.h" #include "vectorutils.h" #include "ptrutils.h" /* * 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<16 ; 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<7 ; callnr++) { debug(" %d=%08lx", callnr, sets[apinr]->ppfnMethods[callnr]); } } debug("\n"); } */ debug("fn8(%08lx)=%hs\n", sets[0]->ppfnMethods[8], hexdump((BYTE*)sets[0]->ppfnMethods[8], 7, 4).c_str()); debug("\n\n"); } 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= (DWORD)PhysToVirt(VirtToPhys((DWORD)newset)); if (physnew==0) { debug("DuplicateApi: VirtToPhys\n"); return false; } 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= (DWORD)PhysToVirt(VirtToPhys((DWORD)newfn)); if (physfn==0) { debug("ChangeHook: PhysToVirt ERROR\n"); return NULL; } 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 (*PFNOrigLoadLibrary)(LPCWSTR lpszFileName); PFNOrigLoadLibrary OrigLoadLibrary; HANDLE HookLoadLibrary(LPCWSTR lpszFileName) { 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 OrigLoadLibrary(lpszFileName); */ } int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow) { DebugSetLogfile("hookapi.log"); 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); OrigLoadLibrary= (PFNOrigLoadLibrary )ChangeHook(newset, 8, (PFNVOID)HookLoadLibrary, PTR_DIFF(HookLoadLibrary, 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; }