Есть задачка - из Ring0 пропатчить пользовательскую DLL, загруженную в текущий процесс (например, kernel32.dll). При этом нужно не допустить срабатывания механизма copy-on-write. DLL должна пропатчиться во всех процессах. Как это сделать, понятно - надо - узнать физический адрес пропатчиваемого места - добавить в таблицу страниц текущего процесса запись с правом записи на этот физадрес - пропатчить по _новому_ линейному(в виндах == виртуальному) адресу. получим сквозной патч всех процессов. Я попробовал это сделать, находя свободные слоты в PDE и PTE и записывая в них записи с теми же параметрами, что и в оригинальных записях (кроме флага RW). Однако нового виртуального адреса не появляется. Знающие люди, подскажите в чем ошибка. Код следующий: Код (Text): #define dbg DbgPrint int writetomemory(void *virtaddr, void *buf, ULONG size) { ULONG i, k; int r = 1; if(!MmIsAddressValid(virtaddr)) return r; PHYSICAL_ADDRESS physaddr = MmGetPhysicalAddress(virtaddr); PHYSICAL_ADDRESS pa; void *la; PX86_PE pde0 = (PX86_PE)(0xc0300000+ (((ULONG)virtaddr & 0xffc00000)>>20)); PX86_PE pte0 = (PX86_PE)(0xc0000000+ (((ULONG)virtaddr & 0x003ff000)>>10)); PX86_PE pde = (PX86_PE)0xc0300000; PX86_PE pte = (PX86_PE)0xc0000000; if(!MmIsAddressValid(pde0) || !MmIsAddressValid(pte0)) return r; // search for free PDE for(i=0; i<1024; i++, pde++) { if(MmIsAddressValid(pde) && pde->pnpe.P == 0) { dbg("&pde=%08x\n", pde); // search for free PTE for(k = 0; k < 0x300000/4; k++, pte++) if(MmIsAddressValid(pte) && pte->pnpe.P == 0) { dbg("&pte=%08x\n", pte); // add new PDE & PTE // get phys address of PTE page pa = MmGetPhysicalAddress((void*) (0xfffff000 & (ULONG)pte) ); __asm cli pde->pde4K.P = pde0->pde4K.P; pde->pde4K.RW = 1; pde->pde4K.US = pde0->pde4K.US; pde->pde4K.PWT = pde0->pde4K.PWT; pde->pde4K.PCD = pde0->pde4K.PCD; pde->pde4K.A = pde0->pde4K.A; pde->pde4K.Reserved = pde0->pde4K.Reserved; pde->pde4K.PS = pde0->pde4K.PS; pde->pde4K.G = pde0->pde4K.G; pde->pde4K.Available = pde0->pde4K.Available; pde->pde4K.PFN = pa.LowPart >> 12; // PDE -> PTE page pte->pte4K.Available = 0; pte->pte4K.G = pte0->pte4K.G; pte->pte4K.P = pte0->pte4K.P; pte->pte4K.RW = 1; pte->pte4K.US = pte0->pte4K.US; pte->pte4K.PWT = pte0->pte4K.PWT; pte->pte4K.PCD = pte0->pte4K.PCD; pte->pte4K.A = pte0->pte4K.A; pte->pte4K.D = pte0->pte4K.D; pte->pte4K.Reserved = 0; pte->pte4K.PFN = physaddr.LowPart >> 12; __asm sti dbg("new PDE=%08x, PTE=%08x\n", pde->dValue, pte->dValue); // calc LA la = (void*)((i<<22)|(k<<12)|(0x00000fff & (ULONG)virtaddr)); dbg("Linear address=%08x\n", la); // write data // memcpy(la, virtaddr, size); // doesn't work!!! r = 0; } } } return r; }
valinor так, во ппервых, тебе нужно что , просто изменить несколько байтов или дописать кусок кода в либу ???? если последнее, то ищи свободное место в модуле и дописывай туда код из драйвера, убрав бит WP, изменения отобразятся во всех контекстах.