Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Asm для Linux/Unix > ljmp в ядре


Автор: Friackazoid 22.2.2010, 01:30
Доброго времени суток.

Пытаюсь провернуть такую операцию в ядре: сделать ljmp на свой сегмент и выполнить в этом сегменте функцию.  smile 

Код

__asm__ __volatile__ (
                "\tljmp $"STR(__MY_CS)", $1f\n"
                "\t1:\n"
                "\tnop\n"
                ::: "eax", "memory");


__MY_CS загружен в gdt по всем правилам. Но на это получаю general protection fault с кодом e8.

Пробую делать lcall
Код

__asm__ __volatile__ (
                "\tlcall *(%0)\n"
                ::"r"(virt_to_phys(addr)): "eax", "memory");


и тоже получаю сбой защиты но уже с кодом 3cb8

Кто нибудь пробовал сделать что нибудь в этом духе или знает что значат эти коды ошибок? 

Автор: MAKCim 22.2.2010, 14:11
что после nop'а идет?
смотрели в мануале, что означают эти коды ошибок?

Автор: Friackazoid 22.2.2010, 15:22
После nop'a только выход из функции. И сли верть ману этот код ошибки и есть селектор сегмента.

Автор: Friackazoid 22.2.2010, 21:38
После экспериментов выяснилось что если своему сегменту зменит CPL на совпадающий с текущим, в данном слуае на 00 то джамп проходит нормально. В то же время интеовский ман говорит что такие джампы единственный способ понизить привилегии кода.  smile 

Автор: MAKCim 23.2.2010, 09:51
тот сегмент, на который осуществляется переход, conforming или nonconforming?

Автор: Friackazoid 23.2.2010, 14:25
Да сегмент non-conforming. Если сделать его conforming то выполнить прыжок получается только если сменить DPL сегменту на 0 и код в сегменте начинает выполнятся с CPL 0.  :dash0 

Автор: MAKCim 24.2.2010, 09:56
в общем посмотрел я мануал
в принципе где вы нашли, что cpl можно понизить?

Автор: Friackazoid 24.2.2010, 16:01
Все разобралась, изменить CPL таким способом действительно нельзя. Просто показалось что если можно перепрыгнуть на другой сегмент то почему бы не перепрыгнуть на сегмент с меньшими привилегиями (по аналогии с сегментом данных), ан нет для сегментов кода правила более строгие. Меняю сегмент с помошью iret

Код

__asm__ __volatile__ (
                "\tpushl $"STR(__MY_DS)"\n"
                "\tpushl %%esp\n"
                "\tpushl %1\n"
                "\tpushl $STR(__MY_CS)"\n"
                "\tpushl %0\n"
                "\tiret\n"
                ::"r"(addr), "r"(flags): "eax", "memory");


Мне просто надо сменить контекст что называется на лету, чтобы один раз выполнить функция. Использовать механизм смены процеса ядра использовать во-первых не хочу ибо неоправданно для такого случая много накладных расходов, во вторых не могу потому что механизм использует то что еще не инициализованно на момент запуска функции.

Автор: MAKCim 25.2.2010, 00:03
Friackazoid, 
чем вы занимаетесь если не секрет? ;)

Автор: Friackazoid 25.2.2010, 09:21
Разработкой защитных средств для ядра) И никакого криминала  smile 

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)