Правильно ли я получить адрес sys_call_table таким образом с помощью gdb? - PullRequest
1 голос
/ 24 марта 2011

Сейчас я делаю так:

(gdb) info addr system_call
Symbol "system_call" is at 0xffffffff8100b920 in a file compiled without debugging.

(gdb) x/50i 0xffffffff8100b920
0xffffffff8100b920: swapgs 
0xffffffff8100b923: nopw   0x0(%rax,%rax,1)
0xffffffff8100b929: nopl   0x0(%rax)
0xffffffff8100b930: mov    %rsp,%gs:0xb008
0xffffffff8100b939: mov    %gs:0xb508,%rsp
0xffffffff8100b942: sti    
0xffffffff8100b943: sub    $0x50,%rsp
0xffffffff8100b947: mov    %rdi,0x40(%rsp)
0xffffffff8100b94c: mov    %rsi,0x38(%rsp)
0xffffffff8100b951: mov    %rdx,0x30(%rsp)
0xffffffff8100b956: mov    %rax,0x20(%rsp)
0xffffffff8100b95b: mov    %r8,0x18(%rsp)
0xffffffff8100b960: mov    %r9,0x10(%rsp)
0xffffffff8100b965: mov    %r10,0x8(%rsp)
0xffffffff8100b96a: mov    %r11,(%rsp)
0xffffffff8100b96e: mov    %rax,0x48(%rsp)
0xffffffff8100b973: mov    %rcx,0x50(%rsp)
0xffffffff8100b978: mov    %gs:0xb508,%rcx
0xffffffff8100b981: sub    $0x1fd8,%rcx
---Type <return> to continue, or q <return> to quit---
0xffffffff8100b988: testl  $0x100001d1,0x10(%rcx)
0xffffffff8100b98f: jne    0xffffffff8100bad0
0xffffffff8100b995: cmp    $0x12a,%rax
0xffffffff8100b99b: ja     0xffffffff8100ba5a
0xffffffff8100b9a1: mov    %r10,%rcx
0xffffffff8100b9a4: callq  *-0x7ec62ec0(,%rax,8)

Тогда 0x7ec62ec0 это адрес sys_call_table, верно?

Ответы [ 2 ]

1 голос
/ 24 марта 2011

Мне нужен адрес этой таблицы, чтобы перехватить обработчик для 0x80 int.

Стоп. Что вы действительно пытаетесь сделать? Взлом обработчика прерываний - не ваша цель, это один шаг, который, как вы думаете, нужно сделать, чтобы чего-то достичь. Что бы это ни было, вы, вероятно, ошиблись.

Чтобы перехватить прерывания, вам нужно изменить таблицу дескрипторов прерываний . Я предлагаю вам взглянуть на справочные руководства Intel , чтобы выяснить, как это сделать. Это будет болезненное программирование. Но я подозреваю, что вы больше заинтересованы в системных вызовах. Кроме того, в современных системах Linux инструкция int 0x80 не является обычным способом вызова системного вызова. Это, конечно, все еще работает для обратной совместимости, но вы увидите другие инструкции, такие как sysenter (x86) или syscall (x86_64). Поэтому, если вы действительно заинтересованы в том, чтобы что-то делать с системными вызовами, не делайте этого в обработчике прерываний.

В любом случае, создайте новый вопрос, который просит совета по достижению вашей конечной цели, и сообщество здесь поможет вам в этом. Если у вас есть вопросы по конкретным частям, задайте больше вопросов и вернитесь к высокому уровню в этих новых вопросах.

(Кстати, если вам нужно подтверждение адреса, попробуйте запустить info addr sys_call_table в GDB. Или, поскольку похоже, что вы используете архитектуру x86_64, попробуйте p &sys_call_table.)

0 голосов
/ 01 июня 2011

Да, в вашем дампе 0x7ec62ec0 - это адрес sys_call_table. Чтобы получить полный sys_call_table адрес, вам нужно сделать следующее:

sys_call_table = 0xFFFFFFFF00000000 | *(unsigned int *)(0xffffffff8100b9a4 + 3);

Здесь 0xffffffff8100b9a4 - адрес инструкции callq *-0x7ec62ec0(,%rax,8), а 3 - размер. И не забывайте, что может быть несколько таблиц системных вызовов одновременно: sys_call_table и ia32_sys_call_table Итак, вам нужно обработать все возможные способы выполнения системного вызова: int $0x80, syscall/sysenter.

...