Есть хорошие руководства по использованию PTRACE_SYSEMU? - PullRequest
5 голосов
/ 22 марта 2011

Есть ли у кого-нибудь хорошие объяснения, учебники, книги или руководства по использованию PTRACE_SYSEMU ?

Ответы [ 2 ]

0 голосов
/ 11 марта 2017

Существует небольшой тест из источников ядра Linux, который использует PTRACE_SYSEMU:

http://code.metager.de/source/xref/linux/stable/tools/testing/selftests/x86/ptrace_syscall.c или http://lxr.free -electrons.com / источник / инструменты / тестирование / самотестирование / x86 / ptrace_syscall.c

186 struct user_regs_struct regs;
187
188 printf("[RUN]\tSYSEMU\n");
189 if (ptrace(PTRACE_SYSEMU, chld, 0, 0) != 0)
190     err(1, "PTRACE_SYSCALL");
191 wait_trap(chld);
192
193 if (ptrace(PTRACE_GETREGS, chld, 0, &regs) != 0)
194     err(1, "PTRACE_GETREGS");
195
196 if (regs.user_syscall_nr != SYS_gettid ||
197     regs.user_arg0 != 10 || regs.user_arg1 != 11 ||
198     regs.user_arg2 != 12 || regs.user_arg3 != 13 ||
199     regs.user_arg4 != 14 || regs.user_arg5 != 15) {
200     printf("[FAIL]\tInitial args are wrong (nr=%lu, args=%lu %lu %lu %lu %lu %lu)\n", (unsigned long)regs.user_syscall_nr, (unsigned long)regs.user_arg0, (unsigned long)regs.user_arg1, (unsigned long)regs.user_arg2, (unsigned long)regs.user_arg3, (unsigned long)regs.user_arg4, (unsigned long)regs.user_arg5);
201     nerrs++;
202 } else {
203     printf("[OK]\tInitial nr and args are correct\n");
204 }
205
206 printf("[RUN]\tRestart the syscall (ip = 0x%lx)\n",
207        (unsigned long)regs.user_ip);
208
209 /*
210  * This does exactly what it appears to do if syscall is int80 or
211  * SYSCALL64.  For SYSCALL32 or SYSENTER, though, this is highly
212  * magical.  It needs to work so that ptrace and syscall restart
213  * work as expected.
214  */
215 regs.user_ax = regs.user_syscall_nr;
216 regs.user_ip -= 2;
217 if (ptrace(PTRACE_SETREGS, chld, 0, &regs) != 0)
218     err(1, "PTRACE_SETREGS");
219
220 if (ptrace(PTRACE_SYSEMU, chld, 0, 0) != 0)
221     err(1, "PTRACE_SYSCALL");
222 wait_trap(chld);
223
224 if (ptrace(PTRACE_GETREGS, chld, 0, &regs) != 0)
225     err(1, "PTRACE_GETREGS");
226

Таким образом, это выглядит как очередной вызов ptrace, который позволит программе запускаться до тех пор, пока она не выполнит следующий системный вызов; затем остановите ребенка и подайте сигнал ptracer. Он может читать регистры, при необходимости изменять некоторые и перезапускать системный вызов.

Реализовано в http://lxr.free -electrons.com / source / kernel / ptrace.c? V = 4.10 # L1039 как и другие пошаговые ptrace вызовы:

1039 #ifdef PTRACE_SINGLESTEP
1040         case PTRACE_SINGLESTEP:
1041 #endif
1042 #ifdef PTRACE_SINGLEBLOCK
1043         case PTRACE_SINGLEBLOCK:
1044 #endif
1045 #ifdef PTRACE_SYSEMU
1046         case PTRACE_SYSEMU:
1047         case PTRACE_SYSEMU_SINGLESTEP:
1048 #endif
1049         case PTRACE_SYSCALL:
1050         case PTRACE_CONT:
1051                 return ptrace_resume(child, request, data);

А на странице руководства есть информация: http://man7.org/linux/man-pages/man2/ptrace.2.html

PTRACE_SYSEMU, PTRACE_SYSEMU_SINGLESTEP (начиная с Linux 2.6.14) Для PTRACE_SYSEMU продолжайте и останавливайтесь при переходе к следующему системный вызов, который не будет выполнен. Увидеть документация по системным остановкам ниже. За PTRACE_SYSEMU_SINGLESTEP, сделайте то же самое, но также и один шаг, если не системный вызов. Этот вызов используется такими программами, как Пользователь Режим Linux , который хочет эмулировать все системные вызовы трассировки. Аргумент данных обрабатывается как для PTRACE_CONT. Адрес аргумент игнорируется. Эти запросы в настоящее время поддерживаются только на x86.

Таким образом, он не является переносимым и используется только для Usermode linux (um) на платформе x86 как вариант классического PTRACE_SYSCALL. И вот тест для sysemu с некоторыми комментариями здесь: http://lxr.free -electrons.com / source / arch / um / os-Linux / start_up.c? V = 4.10 # L155

155 __uml_setup("nosysemu", nosysemu_cmd_param,
156 "nosysemu\n"
157 "    Turns off syscall emulation patch for ptrace (SYSEMU) on.\n"
158 "    SYSEMU is a performance-patch introduced by Laurent Vivier. It changes\n"
159 "    behaviour of ptrace() and helps reducing host context switch rate.\n"
160 "    To make it working, you need a kernel patch for your host, too.\n"
161 "    See http://perso.wanadoo.fr/laurent.vivier/UML/ for further \n"
162 "    information.\n\n");
163 
164 static void __init check_sysemu(void)

Ссылка в комментарии была перенаправлена ​​на секретный сайт http://sysemu.sourceforge.net/ с 2004 года:

Почему?

UML использует ptrace () и PTRACE_SYSCALL для перехвата системных вызовов. Но, по таким образом, вы не можете удалить реальный системный вызов, только отслеживать его. UML, чтобы избежать реального системного вызова и эмулировать его, заменяет настоящий системный вызов вызов getpid (). Этот метод генерирует два переключателя контекста одного. Решение

Решение состоит в том, чтобы изменить поведение ptrace (), чтобы не вызывать реальное syscall и, следовательно, нам не нужно заменять его вызовом getpid (). Как?

Добавляя новую команду в ptrace (), PTRACE_SYSEMU, которая действует как PTRACE_SYSCALL без выполнения системного вызова. Чтобы добавить эту команду нам нужно патчить ядро ​​хоста. Чтобы использовать эту новую команду в ядре UML, мы нужно также исправить ядро ​​UML.

0 голосов
/ 22 августа 2011

Что мне показалось интересным:

И библиотека программирования, которая упрощает использование ptrace:

Для pinktrace есть примеры, источники sydbox являются примером сложного варианта использования pinktrace.В общем, я нашел автора как хорошего человека, с которым можно связаться по вопросам использования и тестирования pinktrace.

...