Покажи Публикации - st0ne
* Виж публикациите на потр. | Виж темите на потр. | Виж прикачените файлове на потр
Страници: [1]
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 да сменя стойностите, но не съм сигурен дали ще се получи.
Страници: [1]