LINUX.ORG.RU

Поставил точку останова с помощью PTRACE, снимаю получаю ошибку сегментации

 ,


1

2

С помощью ptrace подключаюсь к программе и ставлю в начало функции asd3() точку останова, меняю push rbp на int3.

Далее продолжаю работу программы PTRACE_CONT . Программа тормозит на точке останова(радуюсь что сработало) . Возвращаю в памяти все на свои места. Получаю регистры, вычитаю из регистра rip единицу, загружаю регистры с измененным регистром rip, продолжаю работу программы иии… ошибка сегментации ..

После нескольких попыток исправить код, найти ошибку, проверить туда ли я записал точку останова, туда ли она записалась, и все в таком духе, ничего не помогло. Я даже не понимаю в чем проблема потому что все на своих местах!

Вот код файла с ptrace:

int main()
{
  int pid = 16227;
  long addr = 0x555AA7B7D1E3;
  struct user_regs_struct regs;
  
  cout << "attach " << ptrace(PTRACE_ATTACH, pid, NULL, NULL)<<endl;
  wait(NULL);
  
  cout << "ставим точку останова " << ptrace(PTRACE_POKETEXT, pid, addr, 0xCC) << endl;

cout << "снимаем процесс с паузы и ждем точки останова "<<ptrace(PTRACE_CONT, pid, NULL, NULL) << endl;
  wait(NULL);
  
  cout << "стоим на точке останова, получаем регистры "<< ptrace(PTRACE_GETREGS, pid, NULL, &regs)<< endl;
  
  
  cout << "удаляем точку останова " << ptrace(PTRACE_POKETEXT, pid, addr, 0x55) << endl;
  
  regs.rip -= 1 ;
  cout << "загружаем регистры с rip -1 " <<  ptrace(PTRACE_SETREGS, pid, NULL, &regs)<< endl;
  
  cout << "пробуем продолжить процесс (CONT) " <<ptrace(PTRACE_CONT, pid, NULL, NULL) << endl; 
  
}

Вывод с этого файла:

attach 0
ставим точку останова 0
снимаем процесс с паузы и ждем точки останова 0
стоим на точке останова, получаем регистры 0
удаляем точку останова 0
загружаем регистры с rip -1 0
пробуем продолжить процесс (CONT) 0

Код программы к которой присоединяюсь:

#include <iostream>
#include <thread>
#define sleep(val) std::this_thread::sleep_for(val * 1000 ##ms)
using namespace std;

void asd()
{
  cout << "asd" << endl;
}

void asd2()
{
  cout << "asd2" << endl;
}

void asd3()
{
  cout << "asd3" << endl;
}


int main()
{
  while(1)
  {
    asd();
    sleep(0.1);
    
    asd2();
    sleep(0.1);
    
    asd3();
    sleep(0.1);
  }
}

Вывод:

asd
asd2
Ошибка сегментирования

В чем проблема? Что я делаю не так?

Ты скомпилировал вторую прогу, запустил её в gdb, посмотрел адрес функции asd3, увидел что он 0x555AA7B7D1E3 (выглядит странно)?

Потом, я не знаю точно как работает ptrace, нов мане написано что POKETEXT пишет слово, вроде бы слово это не байт, то есть он запишет по указанному адресу 4 или 8 байт, первый из которых будет 0xCC, остальные нули? Или нет?

Ну и ты уверен что int3 останавливается с rip после инструкции а не на ней?

firkax ★★★★★
()
Ответ на: комментарий от firkax

" Ты скомпилировал вторую прогу, запустил её в gdb, посмотрел адрес функции asd3, увидел что он 0x555AA7B7D1E3 (выглядит странно)? " Не, я зашел в нее и заменил ее начало, то есть push rbp, ставлю бряк не на вызове а внутри самой функции в начале

helpanite
() автор топика
Ответ на: комментарий от firkax

Запустил программу, подключился через отладчик, нашел функцию, перешел на нее, скопировал адрес первой команды функции. С бряком получается что программа останавливается не на вызове функции, а сразу же после вызова функции, то есть на первой команде функции

helpanite
() автор топика
Ответ на: комментарий от firkax

Нет, каждый раз когда после ошибок крашилась программа я ее запускал, подключал отладчик и смотрел адрес функции, и он был разный. Конечно можно было написать код который бы ее находил но мне было лень

helpanite
() автор топика