Я под линукс писать только учусь
, поэтому пишу
, можно сказать
, все
, что под руку попадется, вот и взялся читер для игрушек писать по типу artmoney под виндой.
В общем
, ситуация такая
: я решил
, для начала
, попробовать
, как оно все работает
: чтение и запись в память другого процесса, но без особых наворотов в пробном варианте.
Написал простенькую прогу
, которую потом трассирую
, и другую
, которой выполняю трассировку, но тут неожиданная проблема появилась
: вычитываю я значения из трассируемого процесса корректно
, зато с записью происходит не пойми что.
Помогите пожалуйста разобраться
, что не так.
Вот исходник трассируемого процесса
#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;
}
А вот трассирующий, заранее прошу прощения за бардак
, просто очень долго его карячу
многое расплылось до неузнаваемости.
#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;
}
добавил коментариев чтобы читалось, хотя похоже даже это не спасет отца русской демократии
вы уж простите за пожованость