#include #include "debug.h" #include "stringutils.h" #include "args.h" #include "kernelmisc.h" #include "cever_deps.h" #include "deviceinfo.h" #include "devicedriverloader.h" // prun loadflashdrv -o 0x50000000 -l 0x0dc00000 -w x.nb // prun loadflashdrv -o 0x50000000 -l 0x10000000 -s 0x00100000 -c 0x100 // // dump kaiser flashdrv.dll memory: // // pmemdump -n filesys.exe 0x1fe4000 0x8000 -4 // // //note that the other method of getting at this driver could be to open // the BDEV handle // #define IOCTL_FMD_NAND_READ_WLAN_DATA 0x71fe8 DWORD arm_mov(int dst, int src) { return 0xe1a00000+(dst<<12)+src; } #if 0 bool finddmabuffer(BYTE ***pppbuffer, DWORD *psize, BYTE **ppbuffer2) { deviceinfo dev; if (dev.getoemname()=="Kaiser") { *psize= 0x33C4; *pppbuffer= (BYTE**)0x01FEBBA8; *ppbuffer2= (BYTE*)0x01FE6270; return true; } else if (dev.getoemname()=="HTC Touch Diamond P3700") { *psize= 0x360C; *pppbuffer= (BYTE**)0x01FD3B34; *ppbuffer2= (BYTE*)0x01FCDA48; return true; } return 0; } #endif // this finds a area to search for ADD x,y, #0x2400000 bool FindDriverOffsets(HMODULE hDll, DWORD **ppstart, DWORD *psize) { // todo: find driver in memory debug("FindDriverOffsets(%08lx)\n", hDll); ModuleInfo mi; FillModuleInfo(mi, (MODULE*)hDll); debug("module %08lx %8x %08lx %8x %s \n", mi.csegbase, mi.csegsize, mi.dsegbase, mi.dsegsize, mi.name.c_str()); // todo: search in mi.csegbase .. mi.csegsize deviceinfo dev; DWORD vpatchaddr; if (dev.getoemname()=="Kaiser") { vpatchaddr= 0x3E42610; // 03E42678 ADD R1, LR, #0x2400000 // 03E428D4 ADD R1, R3, #0x2400000 } else if (dev.getoemname()=="HTC Touch Diamond P3700") { vpatchaddr= 0x03DE8910; // 03DE8978 ADD R1, LR, #0x2400000 - in HTC_OEM_ReadNand // 03DE8BBC ADD R1, R3, #0x2400000 - in HTC_OEM_WriteNand } else if (dev.getoemname()=="X1i") { vpatchaddr= 0x03DE8960; // 03DE89CC ADD R1, LR, #0x2400000 // 03DE8C10 ADD R1, R3, #0x2400000 } else { return false; } DWORD ppatchaddr= VirtToPhys(vpatchaddr); DWORD vvpatchaddr= PhysToVirt(ppatchaddr); debug("(v)%08lx -> v2p -> (p)%08lx -> p2v -> (v)%08lx\n", vpatchaddr, ppatchaddr, vvpatchaddr); *ppstart= (DWORD*)vvpatchaddr; *psize= 0x200; return true; } DWORD *searchforinstruction(HMODULE hDll, DWORD dwMask, DWORD dwValue) { DWORD *pStart=0; DWORD dwSize=0; if (!FindDriverOffsets(hDll, &pStart, &dwSize)) return 0; debug("searching range %08lx-%08lx for %08lx.%08lx\n", pStart, pStart+dwSize/sizeof(DWORD), dwMask, dwValue); for (DWORD *p= pStart ; p>(2*RRRR) // I=0 : O.654 = shifttype // 0 LSL# iiiii 000 mmmm // MOV 00000 000 mmmm // 1 LSL ssss0 001 mmmm // 2 LSR# iiiii 010 mmmm // 3 LSR ssss0 011 mmmm // 4 ASR# iiiii 100 mmmm // 5 Asr ssss0 101 mmmm // 6 ror# iiiii 110 mmmm // RRX 00000 110 mmmm // 7 Ror ssss0 111 mmmm // ? ....1 ..1 .... not dataprocessing insn. DWORD *PatchOffset= 0; DWORD dwOldValue= 0; if (bRemoveLimit) { PatchOffset= searchforinstruction(flashdrv.hlib(), ~dwRegisterMask, dwAddInstruction); // disable nand-mpu ( phys 0xa0b00000 ) *(DWORD*)0xb1200000=0; } if (PatchOffset) { dwOldValue= *PatchOffset; DWORD dwNewValue= (dwOldValue&~dwOperandMask); // change to ADD Rx,Ry,#0 *PatchOffset= dwNewValue; debug("found %08lx at %08lx, changed to %08lx\n", dwOldValue, PatchOffset, dwNewValue); } #if 0 DWORD dmbuffersize= 0; BYTE **pdmbuffer=0; BYTE *tmpbuffer=0; finddmabuffer(&pdmbuffer, &dmbuffersize, &tmpbuffer); debug("dmabuffers: %08lx:%08lx/%04x, %08lx\n", pdmbuffer, *pdmbuffer, dmbuffersize, tmpbuffer); #endif while(dwSize) { ByteVector data; data.resize(dwSize