1
|
Програмиране / Общ форум / Re: Достъп до sys_call_table в 2.6.32
|
-: Apr 10, 2010, 20:20
|
Имам известен напредък с PAE paging-а, но от вчера ударих на камък. Това е вариант за 4KB paging. Ето какво съм направил: __asm__ __volatile__ ( "movl %%cr3, %%eax\n\t"
"addl $0xc0000000, %%eax\n\t" "movl %2, %%ebx\n\t" "shrl $30, %%ebx\n\t" "movl (%%eax,%%ebx,0x8),%%ecx\n\t" "movl 0x4(%%eax,%%ebx,0x8),%%edx\n\t" "shrl $12, %%ecx \n\t" "movl %%edx, %%eax \n\t" "andl $0xfff, %%eax \n\t" "shll $20, %%eax \n\t" "addl %%eax, %%ecx \n\t" "movl %%ecx, %0 \n\t" "shrl $12, %%edx \n\t" "andl $0xff, %%edx \n\t" "movl %%edx, %1 \n\t" :"=r"(bits_low), "=r"(bits_high) :"r" (addr) :"%eax", "%ebx", "%ecx", "%edx" );
Тук addr е адреса, чиято PTE трябва да се намери. Понеже от PDPTEi се вземат 40 бита (битове 51:12) аз ги съхранявам в две променливи - bits_low и bits_high. Първата съдържа ниските 32 бита, а втората високите 8. До тук изглежда, че всичко e наред. bits_high е нула при мен, но аз имам само 2GB RAM и това ми изглежда нормално. За ниските битове получавам стойност A8C. Тази стойност използвам след това, за да прочета PDE-то на адреса. __asm__ __volatile__ ( "movl %2, %%eax\n\t" "addl $0xc0000000, %%eax\n\t" "movl %1, %%ebx\n\t" "shrl $21, %%ebx\n\t" "andl $0x1ff, %%ebx\n\t" "movl (%%eax,%%ebx, 0x8),%%ecx\n\t" "movl %%ecx, %0\n\t" :"=r"(pde_low_bits) :"r" (addr), "r"(bits_low) :"%eax", "%ebx", "%ecx" );
bits_low сочи към началото на 4KB структура от 512 64-биови записа. Битове 29:21 от адреса оказват точния PDE запис. Би трябвало в pde_low_bits да имам първите 32 бита от PDE, но стойността е нула. Ако добавя отместване от 0x4, за да взема вторите 32 бита резултата пак е нула. Не виждам грешка нито вгода, нито в логиката.
|
|
|
2
|
Програмиране / Общ форум / Re: Достъп до sys_call_table в 2.6.32
|
-: Mar 21, 2010, 17:43
|
Оказа се, че съвсем ще съм затруднен в моите начинания - процесора ми е с Intel EM64T. Тези процесори само IA-32e paging ли използват? Не съм сигурен понеже kernel release-а ми завършва на i686.PAE, а от документацията на Intel останах с впечатление, че Intel 64 използват само IA-32e paging.
|
|
|
3
|
Програмиране / Общ форум / Re: Достъп до sys_call_table в 2.6.32
|
-: Mar 21, 2010, 15:33
|
Реших, че може би ще е по-лесно направо с assembler да се обходи таблицата със страниците и да се сменят правата на подходящата страница. Ето един примерен код, който открих: void *origaddr = (void*) 0; void *origcr3 = (void*) 0; void *direntry = (void*) 0; void *mdentry = (void*) 0;
.................
original_call = sys_call_table[__NR_sync]; origaddr = &sys_call_table[__NR_sync];
.................
void myfunc(void) { __asm__ __volatile__ ( "pushl %eax\n\t" "pushl %ebx\n\t" "movl %cr3, %eax\n\t" "movl %eax, origcr3\n\t" "andl $0xfffff000, %eax\n\t" "addl $0xc0000000, %eax\n\t" "movl origaddr, %ebx\n\t" "shrl $22, %ebx\n\t" "sall $2, %ebx\n\t" "addl %ebx, %eax\n\t" "movl (%eax), %eax\n\t" "movl %eax, direntry\n\t" "andl $0xfffff000, %eax\n\t" "addl $0xc0000000, %eax\n\t" "movl origaddr, %ebx\n\t" "andl $0x003ff000, %ebx\n\t" "shrl $12, %ebx\n\t" "sall $2, %ebx\n\t" "addl %ebx, %eax\n\t" "movl %eax, %ebx\n\t" "movl (%eax), %eax\n\t" "andl $0xfffff000, %eax\n\t" "addl $0x67, %eax\n\t" "movl %eax, (%ebx)\n\t" "movl %eax, mdentry\n\t" "popl %ebx\n\t" "popl %eax\n\t" ); printk("origaddr->0x%p\n", origaddr); printk("origcr3-->0x%p\n", origcr3); printk("direntry->0x%p\n", direntry); printk("mdentry-->0x%p\n", mdentry); }
Тук myfunc() сменя правата на подходящата страница и след това може да се редактират стойностите. Кода е подходящ за 32 bit Intel/AMD с по-малко от 4G RAM. Сега съм си свалил manual-а за system development на Intel и ще се опитам да разбера какво точно става в асемблерския код. Не успях да намеря никъде обяснено как се обхожда таблицата със страниците и как се сменят права на страница.
|
|
|
4
|
Програмиране / Общ форум / Re: Достъп до sys_call_table в 2.6.32
|
-: Mar 17, 2010, 14:51
|
За експериментални цели ми е и точно за това искам да го направя без да прекомпилирам ядрото. За rootkit бих се насочил към нещо с debug регистрите, понеже доколкото съм чел то е най-трудно за откриване (като изключим концепцията за използване на хардуерна виртуализация, но поне на мен тя ми се вижда доста трудоемко начинание).
Не се бях сетил да проверя как е направено. Мога да се опитам да направя нещо подобно като гледам кода в pageattr.c, но щом казваш че е трудно не знам какъв успех ще имам. Тези дни ще пробвам и ще пиша.
А как точно работи тази проверка дали адреса е ro? Ако директно напиша някакъв асемблерски код, който сменя стойността на клетката в паметта как ще ме хване, че пипам по read-only? Извинявам се ако въпросите са малко глупави, но не открих никъде да е описано как стават тези неща.
|
|
|
5
|
Програмиране / Общ форум / Достъп до sys_call_table в 2.6.32
|
-: Mar 17, 2010, 02:11
|
От няколко дни се се опитвам да напиша LKM, с който дапроменя няколко функции от sys_call_table с чисто екпериментална и учебна цел, но нямам особен успех  Липсата на export на sys_call_table не беше проблем - вземам адреса като използвам техниката с IDT. След като имам адреса понеже тази част от паметта е read-only извиквам set_memory_rw(sys_call_table, 1), но тя ми връща 0 и паметта наистина не е достъпна за писане. Видях, че преди е ставало с change_page_attr(), но тази ф-ция вече е deprecated. Все трябва да има някакъв начин. Нали все пак съм в ring 0 и имам уш пълен достъп до всичко. Ако някой може да ми обясни как точно действа това ограничение за read-only и как да го избегна ще съм му много благодарен. Мисля да пробвам с код написан на assembler да сменя стойностите, но не съм сигурен дали ще се получи.
|
|
|
|