-
Notifications
You must be signed in to change notification settings - Fork 0
/
ABOUT-ASI
135 lines (113 loc) · 7.87 KB
/
ABOUT-ASI
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
Этот файл: сообщение о программе Asi - предшественнике программы Mini
>=========================<
Однажды мне нужно было понять, как работают сисвызовы kill и wait в гну/линуксе. я стал писать коротенькие экспериментальные
проги, чтобы разобраться, типа такой:
int main(){
int pid = fork();
if (pid == 0){
for (;;)
;
}
kill(pid, 9);
wait(NULL);
}
Запустил я эту прогу, посмотрел, изменил немного, снова запустил и т. д. Но понимания не приходило. Хотелось тестовую
прогу, с которой можно было бы взаимодействовать. Говорить ей в реальном времени, что ты хочешь, и чтоб она выполняла. И
тогда я написал что-то типа такого:
// ВНИМАНИЕ! Это всего лишь пример кода. Естественно, в реальной проге нельзя писать такой вот scanf, а то будет переполнение. Реальный код находится на http://github.com/safinaskar/mini
int main(){
char command[100];
while (scanf("%s", command) == 1){
if (strcmp(command, "fork") == 0){
int pid = fork();
if (pid == 0){
for (;;)
;
}
printf("%d\n", pid);
}else if (strcmp(command, "kill") == 0){
int pid;
scanf("%d", &pid);
kill(pid, 9);
}else if (strcmp(command, "wait") == 0){
wait(NULL);
}else{
printf("Invalid command\n");
}
}
}
И это мне действительно помогло. Я просто запустил эту прогу и стал с ней играться до просветления. Затем мне
понадобилось разобраться с какими-то другими сисвызовами и мне пришлось их добавить в свою прогу. Затем ещё и ещё. Прога
стала большой и её написание стало утомительным. Тогда я переписал её с нуля, изменив в ней суть.
Моя программа называется Asi - Askar Safin's Interpreter (сперва я её назвал slcsh -- System and Library Call SHell, но
такое труднопроизносимое название было засмеяно). Теперь у меня есть конфиг под названием "config" и есть скрипт
"genasi.sh". Скрипт читает конфиг и на его основе генерит C++-ный файл, а уж он скармливается компилятору. Вот фрагмент
конфига:
fork unistd,stdlib int line ASI-COMMAND - fork and run Asi command, for example: fork execve /bin/echo echo hello
execve unistd int word,strarray,zeroppchar FILENAME ARGV
open sys/types,sys/stat,fcntl int word,int FILENAME FLAGS
close unistd int int FD
read unistd int int,int FD COUNT
write unistd int int,line FD BUF
Вот так выглядит типичный диалог с прогой:
Welcome to Asi - system and library call interpreter. Type "quit" for quit. Type "help" for help
asi> help
quit - quit from Asi
help
fork ASI-COMMAND - fork and run Asi command, for example: fork execve /bin/echo echo hello
execve FILENAME ARGV
...
setuid UID
chroot PATH
asi> open /etc/fstab 0
3
asi> read 3 10
# /etc/fst
10
asi> close 3
0
asi> fork execve /bin/echo echo hello; wait
17870
hello
17870
asi> getcwd
/root
asi> quit
Скачать прогу можно с (тут была ссылка, но я её убрал, т. к. я asi больше не актуален; теперь актуален mini: http://github.com/safinaskar/mini )
А теперь, собственно вопрос: нужна ли миру эта прога? Если да, то я б её, пожалуй, опубликовал. Прикрутил бы к ней
autoconf, automake, написал бы доки на русском и английском, приделал бы систему контроля версий и выложил бы на
code.google.com, sourceforge, github, savannah или ещё куда-нибудь. А если нет, то юзал бы только сам.
На мой взгляд, она нужна. Она позволяет понять устройство сисвызовов, потрогать их. Хотя иногда, бывает, её можно юзать
для совсем других целей.
Я студент МГУ, у нас там есть компьютерный класс. Там компы без жёстких дисков, они при включении грузят линукс с
сервака и монтируют файловые системы по NFS. У каждого студента и препода есть свой аккаунт. Однажды мне удалось
взломать эту систему. Я грузанул один комп с флешки с линуксом, после чего смонтировал NFS. Но NFS не давал мне ничего
не читать, ни писать, потому что я был рутом. Мне нужно было сменить свой UID на какой нибудь другой (которого,
естественно, не было у меня в /etc/passwd). Ну я запустил asi и набрал там что-то типа такого:
Welcome to Asi - system and library call interpreter. Type "quit" for quit. Type "help" for help
asi> setuid 1234
0
asi> execve /bin/bash /bin/bash
4:/$
И теперь я могу писать и читать из любой папки. Если б не asi, мне бы пришлось написать наскоро C-шный файл для
setuid'а.
Воистину, asi - инструмент прогера и взломщика.
Что бы я добавил в asi? Во-первых, я бы научил asi самостоятельно парсить системные заголовочные файлы, тогда бы никакие
конфиги были б не нужны и asi бы поддерживал любой сисвызов, который есть. Во-вторых, сделал бы нормальный синтаксис,
похожий на си, с поддержкой escape-последовательностей. Например, вместо 'open /etc/fstab 0' надо было бы набрать
'open("/etc/fstab", O_RDONLY)'. И вообще сделал бы его интерпретатором си.
Какие есть альтернативы? Оказывается, в gdb тоже есть встроенный интерпретатор си!
GNU gdb (GDB) 7.1-ubuntu
...
(gdb) start
Temporary breakpoint 1 at 0x80483b7: file c.c, line 1.
Starting program: /tmp/c
Temporary breakpoint 1, main () at c.c:1
1 int main(){}
(gdb) p open("/etc/fstab", 0)
$1 = 5
(gdb)
Но gdb не умеет нормально делать fork и execve. Ещё сишные сисвызовы понимает perl. То есть запускаем perl в
интерактивном режиме и вперёд. Есть даже специальный wrapper для перла под названием perl-console, который делает
интерактивное общение с перлом удобнее. Но всё равно, перл не поддерживает по-нормальному fork и execve (вроде...).
Собственно, всё