Форум программистов «Весельчак У»
  *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: [1]   Вниз
  Печать  
Автор Тема: Помогите пожалуйста разобраться с ptrace()  (Прочитано 7921 раз)
0 Пользователей и 2 Гостей смотрят эту тему.
Kotiara
Постоялец

ua
Offline Offline

« : 12-08-2012 06:17 » 

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

Код: (C++)
#include <cstdlib>
#include <stdlib.h>
#include <iostream>

using namespace std;

/*
 *
 */

int main(int argc, char** argv)
{
    char ch='i';
    int *int_ptr=new int;
    int *tmp_ptr=0;
    int tmp_int=0;
    while(ch!='q'&&ch!='Q')
    {
        switch(ch)
        {
            case 'i':
            case 'I':
                system("clear");
                cout<<"Введите значение переменной int_ptr:";
                cin>>(*int_ptr);
                break;
            case 'c':
            case 'C':
                system("clear");
                cout<<"int_ptr="<<(*int_ptr)<<" адрес int_ptr:"<<int_ptr<<endl;
                break;
            case 's':
            case 'S':
                system("clear");
                cout<<"Введите смещение :";
                cin>>tmp_int;
                tmp_ptr=(int*)((unsigned long)int_ptr+tmp_int);
                cout<<"*tmp_ptr="<<*tmp_ptr<<"tmp_ptr="<<(unsigned long)tmp_ptr<<endl;
                cout<<"*int_ptr="<<*int_ptr<<"int_ptr="<<(unsigned long)int_ptr<<endl;
                break;
        }
        //system("clear");
        cout<<"i - ввести новое значение перемнной"<<endl;
        cout<<"c - вывести на экран текущее значение переменной"<<endl;
        cout<<"s - обшаривание оперативки"<<endl;
        cout<<"q - выход"<<endl;
        cin>>ch;
    }
    delete int_ptr;
    return 0;
}

А вот трассирующий, заранее прошу прощения за бардак, просто очень долго его карячу Улыбаюсь многое расплылось до неузнаваемости.

Код: (C++)
#include <cstdlib>
#include <stdio.h>
#include <stdlib.h>
#include "get_range.h"
#include "searching_tips.h"
#include <iostream>
#include <fstream>
#include <string>
#include <sys/ptrace.h>
#include <sys/wait.h>
#define ULONG unsigned long


/*
 *
 */

int main(int argc, char** argv)
{
   
    using std::cout;
    using std::cin;
    using std::endl;
    using std::ifstream;
    using std::string;
    using std::stringstream;
    int pid=0;
    cout<<"Введите pid процесса:";
    cin>>pid;
    //цепляюсь к трассируемому процессу tmp_ptrace просто чтобы в дебаге выдеть возврат из ptrace()
    int tmp_ptrace=ptrace(PTRACE_ATTACH,pid);
    //вроде как отправляю сигнал трасируемому процессу остановится
    ptrace(PTRACE_CONT,pid,SIGSTOP,0);
    wait(0);
    //Ranges структура хранящая 4 значения начало и конец диапазонов для кучи и для стека.
    //get_range(pid) просто читает в Ranges диапазоны из /proc/pid/maps файла
    Ranges ranges=get_range(pid);
    if(ranges.heap.start&&ranges.heap.end)
    {
        //в tested буду вычитывать значения из файла
        ULONG tested=0;
        ULONG end_of_range=ranges.heap.end-sizeof(ULONG);
        //структура для хранения искомых значений, на будущее а, пока там всего одно поле int-вое
        Semples semple;
        cin>>semple.int_semple;
        stringstream path;
        //формирую путь и открываю на чтение файл /proc/pid/mem
        path<<"/proc/"<<pid<<"/mem";
        FILE *mem_file;
        mem_file=fopen(path.str().c_str(),"rb");
        if(mem_file==0)//!stream.is_open())
        {
            cout<<"не удалось открыть память процесса на чтение"<<endl;
            ptrace(PTRACE_DETACH,pid,0,0);
            return 1;
        }
        //в структуре пока тоже всего доно поле vector<unsigned long> * ints хранит адреса из памяти
       //трасируемого процесса значения которых совпали с образцом для поиска
        Results result;
        int tmp_read=0;
        //собственно перебираю адреса внутри диапазона кучи сравниваю хранимые значения с образцом
        //заполняю структруру по мере нахождения совпадений
        for(ULONG i=ranges.heap.start;i<=end_of_range;i++)
        {
            fseek(mem_file,i,SEEK_SET);
            tmp_read=fread(&tested,sizeof(tested),1,mem_file);
            //stream.seekg(i);
            //stream>>tested;
            search_int(semple,tested,result,i);
        }
/////////////////////////////////////////////////////////////////////
        ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        //Самое главное начинается здесь
        ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        //обычно находит всего одно совпадение найденый адрес я сверял с сдресом выданным трасируемым
        //процессом всегда правильный
        cout<<"найдено адресов:"<<result.ints->size()<<endl;
        //fseek(mem_file,(ULONG)result.ints->at(0),SEEK_SET);
        //tmp_read=fread(&tested,sizeof(tested),1,mem_file);
        //думал дело в знаке специально явно обьявил знаковый инт
        signed int *tmp_int_p=0;
        //пробовал читать в однобайтный массив результат был тотже
        char buf[16];//=new ULONG[2];
        //думал сожет дело в смещении адресов
///////////////////////проверяю выравнивание адреса по границе диапазона и файла все по нулям
        tmp_ptrace=result.ints->at(0)%sizeof(tested);
        cout<<"Смещение относительно начала файла ="<<tmp_ptrace<<endl;
        tmp_ptrace=(result.ints->at(0)-ranges.heap.start)%sizeof(tested);
        cout<<"Смещение относительно начала кучи ="<<tmp_ptrace<<endl;
        //вычисляю адрес куда писить с учотом смещения (которого как потом оказалось нету:) )
        ULONG write_adrr=((ULONG)result.ints->at(0))-tmp_ptrace;
        //снова переживал за знаковость обьявил знаковый лонг для вычитывания на всякий пожарный
        long data=0;
//////////думал может fread() как-то не так читает смещения там не учитывает или
        // ещо чиго стал читать ptrace-сом чтобы точно все совпадало между тем что читаю и тем что пишу
        data=ptrace(PTRACE_PEEKDATA,pid,write_adrr,0);
        //цепляюсь интовым указателм за значение типа лонг у меня 64-разнядная
        //система так что это 4 и 8 байт соответственно
        tmp_int_p=(int*)&data;
        //fseek(mem_file,write_adrr,SEEK_SET);
        //tmp_read=fread(buf,sizeof(tested),2,mem_file);
        //tested=(ULONG)buf+tmp_ptrace;
        //tmp_int_p=(int*)tested;
///////////////////////////////////////////////////////////////////////////////////////////////////////////
       //cout<<"*tmp_int_p="<<*tmp_int_p<<endl;
       //Здесь просматриваю *tmp_int_p, значение правильное переписываю вроде все норм
        *tmp_int_p=55;
        //data=22;
        //пишу в трассируемый процесс long внутри которого через интовый указатель правил интовое значение
        tmp_ptrace=ptrace(PTRACE_POKEDATA,pid,write_adrr,&data);
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        //перечитываю значение из трассируемого процесса уже фигня
        data=ptrace(PTRACE_PEEKDATA,pid,write_adrr,0);
        //write_adrr+=sizeof(ULONG);
        //tmp_ptrace=ptrace(PTRACE_POKEDATA,pid,write_adrr,&buf[8]);
        //cout<<"tmp_read="<<tmp_read<<endl;
        //tmp_read=(result.ints->at(0)-ranges.heap.start)%sizeof(tested);
        //fseek(mem_file,(ULONG)result.ints->at(0),SEEK_SET);
        //tmp_read=fread(&tested,sizeof(tested),1,mem_file);
        //data которая типа лонг мне в принципе не очень то и интерестна
        cout<<"data="<<data<<endl;
        //а вот интовая которая через указатель из нутри data как раз чочень даже но значение уже не то что я
        //отправлял в чом повторно убеждаюсь через трассируемый процесс
        cout<<"tmp_int="<<(*tmp_int_p)<<endl;
        //вроде как размораживаю трасируемый процесс, закрываю  mem файл и открепляюсь от трксируемого
        //процесса
        ptrace(PTRACE_CONT,pid,SIGCONT,0);
        fclose(mem_file);
        cin>>pid;
        //delete [] buf;
    }
    else
        cout<<"ошибка получения диапазона адресов"<<endl;
    ptrace(PTRACE_DETACH,pid,0,0);
    return 0;
}
добавил коментариев чтобы читалось, хотя похоже даже это не спасет отца русской демократии  Улыбаюсь вы уж простите за пожованость Скромно так...
« Последнее редактирование: 12-08-2012 09:31 от Kotiara » Записан
Finch
Спокойный
Администратор

il
Offline Offline
Пол: Мужской
Пролетал мимо


« Ответ #1 : 12-08-2012 16:55 » new

Под каким юзером ты запускаеш свою программу? Да кстати, а зачем читы под Linux?
Записан

Не будите спашяго дракона.
             Джаффар (Коша)
Kotiara
Постоялец

ua
Offline Offline

« Ответ #2 : 13-08-2012 10:48 » 

Под каким юзером ты запускаеш свою программу? Да кстати, а зачем читы под Linux?
1)Запускаю под своей учоткой, она у меня почти бесправная но я не думаю что дело в этом, я ведь владелец обоих процессов кто муже содержимое памяти трассируемого процесса определенно изменяется из вне.
2) У меня линукс стоит на домашней машине как основная ось,  под ней и игрушки тоже запускаю, в кризисы конечно не побалуешься но есть игры и попроще, вот для них и пригодился бы читер Улыбаюсь
Записан
Страниц: [1]   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines