Форум: "WinAPI";
Текущий архив: 2005.11.06;
Скачать: [xml.tar.bz2];
ВнизЧтение из памяти другой программы Найти похожие ветки
← →
Хинт © (2005-08-31 17:55) [0]Необходимо прочитать 2 байта из памяти другой программы. Нашел нужный адрес. В процессе работы программы он остается неизменным (изменяю в программе значение, смотрю в памяти и значения совпадают). Перезапустив программу, замечаю, что адрес уже изменился и нужные мне значения лежат уже в другом месте. Возможно ли как-нибудь определять нужный адрес? Ведь программа как-то узнает откуда ей брать значения своих переменных? Насколько я понимаю мне надо найти указатель, но как это сделать я не знаю... Помогите разобраться.
← →
Defunct © (2005-08-31 18:15) [1]Хинт © (31.08.05 17:55)
Программа ваша или чужая?
← →
Хинт © (2005-08-31 18:18) [2]Чужая. Исходных кодов нет. Только EXE файл.
← →
Defunct © (2005-08-31 19:19) [3]Ясно.
Могу помочь только отыскать Id процесса. Дальше к сожалению, я не углублялся. Возможно, тут есть народ кто знает как получить указатель на память процесса имея его Id.function GetProcessIdByWndCaption( ACaption : String ): Cardinal;
var
Hw : HWND;
S : String;
I : Integer;
begin
Result := 0;
HW := GetActiveWindow;
HW := GetWindow(HW, GW_HWNDFIRST);
repeat
SetLength( S, 256 );
HW:=GetWindow(HW, GW_HWNDNEXT);
GetWindowText(HW, @S[1], 256);
if Pos( ACaption, S) <> 0 then
begin
GetWindowThreadProcessId( HW, Result );
Break
end;
until HW = 0;
end;
← →
Хинт © (2005-08-31 19:22) [4]Спасибо за участие в проблеме, но все это я уже сделал, в том числе считывание переменных. Только оказалось, что адрес меняется :(
PS: Не проще ли воспользоваться функцией FindWindow для определения PID?
← →
Tonich © (2005-08-31 19:28) [5]ну читать из чужого АП можно так
BOOL READProcessMemory( HANDLE hProcess, PVOID pvAddressRemote, PVOTD pvBufferLocal, DWOHD dwSize, PDWORD pdwNumBytesWritten);
где hProcess хендел чужого процесса
hProcess = OpenProcess(
PROCESS_CREATE THREAD or // для CreateRemoteThread
PROCESS_VM_OPERATION or // для VirtualAllocEx/VirtualFreeEx
PROCESS_VM_READ, // для READProcessMemory
FALSE, dwProcessId);
а вот pvAddressRemote и есть адрес блока данных (ну которые хочешь прочитать)
← →
Piter © (2005-08-31 19:28) [6]Defunct © (31.08.05 19:19) [3]
Возможно, тут есть народ кто знает как получить указатель на память процесса имея его Id.
:)))
← →
Tonich © (2005-08-31 19:29) [7]
> Хинт © (31.08.05 19:22) [4]
опередил )))
← →
Piter © (2005-08-31 19:29) [8]Хинт © (31.08.05 17:55)
объясни, зачем тебе нужно читать значения из памяти другого процесса?
← →
Defunct © (2005-08-31 19:30) [9]> Не проще ли воспользоваться функцией FindWindow для определения PID?
Может быть, только в цикле imho есть свои прелести как например возможность использования LowerCase.
> Только оказалось, что адрес меняется :(
Меняется локальный адрес переменной внутри процесса?
← →
begin...end © (2005-08-31 19:36) [10]> Defunct © (31.08.05 19:19) [3]
Вообще-то, длина текста окна может превышать 256 символов...
← →
Defunct © (2005-08-31 19:41) [11]> begin...end
конечно может
← →
begin...end © (2005-08-31 19:46) [12]> Defunct © (31.08.05 19:41) [11]
В этом случае функция будет работать неправильно...
← →
Piter © (2005-08-31 19:55) [13]begin...end © (31.08.05 19:46) [12]
В этом случае функция будет работать неправильно...
с чего это ты решил?
← →
Defunct © (2005-08-31 19:57) [14]> begin...end
Возможно.
Хотя, если ACaption не будет превышать 256, тогда будет работать правильно. Там используется Pos.
(как для меня 256 символов хватало с головой)
← →
begin...end © (2005-08-31 20:05) [15]> Piter © (31.08.05 19:55) [13]
Я имел в виду, что если в качестве параметра передать строку длиной более 256 символов, то функция не найдёт окно. Да и непонятно, зачем там Pos...
> Defunct © (31.08.05 19:57) [14]
Логичнее предварительно определять длину текста окна, вызвав GetWindowTextLength.
← →
Defunct © (2005-08-31 20:38) [16]> begin...end
> Да и непонятно, зачем там Pos...
Пользователь же знает что ищет. К примеру мне нужно найти любое окно IE-Explorer, а, как вы знаете, заголовок IE формируется так: <название страницы> - Microsoft Internet Explorer, вот я и напишу в ACaption только "Microsoft Internet Explorer".
> Логичнее предварительно определять длину текста окна, вызвав GetWindowTextLength.
Это верно.
← →
Хинт © (2005-08-31 20:39) [17]Конечно интересно, как вы обсуждаете код, написанный в 3ем посте, но мне хотелось бы услышать что-нибудь по теме...
//Piter © (31.08.05 19:29) [8]
Я думаю решение вопроса не зависит от моей цели...
← →
deamon_t (2005-08-31 20:58) [18]Ну я бы запустил софтайс, поставил бряк на изменение этой ячейки, потом поискал бы в памяти строку содержащюю адрес этой переменной (если по листингу было-бы непонятно), незабывая только что в памяти он храниться задом на перёд... Ну или поищи адресс той прогой какой нашел переменную...
← →
deamon_t (2005-08-31 21:10) [19]Правда эта переменная может быть полем эксземпляра какогото класса, тогда надо искать указатель на класс, к нему прибавлять смещение поля.
← →
Хинт © (2005-08-31 21:20) [20]Переменная начинается по адресу $0015470С и состоит из 4х байт: $30 $02 $00 $00 (последний байт находится по адресу $0015470F). Значение в десятичной системе - 560. Соотетственно как должен выглядеть указатель в памяти? Какое значение искать? $0015470C?
← →
Хинт © (2005-08-31 21:21) [21]При этом значение $15470C и $15470F в памяти не находится :(
Вообще мне начинает казаться, что задача не выполнима...
← →
deamon_t (2005-08-31 21:32) [22]Попробуй поищи строку $0C $47 $15 $00, все переменные в памяти храняться задом наперед, но не факт что она найдеться, потомучто эта переменная может быть частью какогото класса, тогда надо искать указатель на начало этого класса, правда как определить где его начало я незнаю...
ЗЫ Попробуй поискать $0C $47 $15 $00 вполне вероятно что получиться
← →
Defunct © (2005-08-31 23:47) [23]Хинт © (31.08.05 21:20) [20]
А если искать по окружению переменной. Вполне возможно, что рядом с этой переменной лежат какие-то константы, с фиксированным смещением относительно искомой переменной. Можно искать их, и по ним (запомнив смещение) позиционироваться на требуемую переменную.
← →
Alex Konshin © (2005-09-01 00:44) [24]если это поле класса, то ищи меньшие адреса кратные 8.
← →
begin...end © (2005-09-01 11:08) [25]> Defunct © (31.08.05 19:30) [9]
> только в цикле imho есть свои прелести как например возможность
> использования LowerCase
FindWindow ищет регистронезависимо, вообще-то. К тому же, см. Remarks в справке по EnumWindows.
> Defunct © (31.08.05 20:38) [16]
> К примеру мне нужно найти любое окно IE-Explorer, а, как
> вы знаете, заголовок IE формируется так: <название страницы>
> - Microsoft Internet Explorer, вот я и напишу в ACaption
> только "Microsoft Internet Explorer".
Вы ищете окно IE, ориентируясь на его заголовок?
← →
alpet © (2005-09-01 11:22) [26]Хинт © (31.08.05 21:21) [21]
Очень интересно. А смысл пытаться в стеке потока ковыряться? Возьми любой взломщик игр - найди где реальное значение хранится (если оно не сильно зашифрованно). А так можно попытаться действительно поставить BreakPoint на изменение памяти (мой взломщик WGC, как впрочем и TSearch и CheatEngine - такие позволяет бряки делать), и смотри что за команды обращаются к этой ячейке, так можно найти и указатель, или понять механизм шифрования.
← →
Игорь Шевченко © (2005-09-01 11:33) [27]
> Нашел нужный адрес. В процессе работы программы он остается
> неизменным (изменяю в программе значение, смотрю в памяти
> и значения совпадают). Перезапустив программу, замечаю,
> что адрес уже изменился и нужные мне значения лежат уже
> в другом месте.
"Жаба хитра, но маленький хрущ с винтом много хитрее ее".
ЗЫ: есть предложение - по поводу взлома программ на этот форум не обращаться.
← →
Хинт © (2005-09-01 12:56) [28]Моя цель далека от взлома программ. Нужно просто автоматизировать получение значений из программы и обработку этой информации.
Нашел программу ArtMoney (много слышал об этой программе, но решил скачать только сейчас). Вот один из разделов справки:
Адреса меняются после перезапуска игры. Но игра должна знать, где её параметры поэтому существует ячейка в которой записан адрес этого параметра. Эта ячейка называется указателем на адрес, фактически она его содержит.
Адрес указателя при перезагрузке игры не меняется. То есть, если адреса в таблице привязать к указателю, то получим таблицу, значения в которой всегда актуальны. Итак, выделяем ячейку с опытом и делаем команду "Искать указатель на этот адрес". Находим этот указатель и привязываем командой "Установить указатель на все" или "на группу".
Упс, но мы ничего не находим! Это значит что указатель не на адрес с опытом, а на структуру, начало которой мы не знаем. Итак, опять выделяем ячейку с опытом и делаем команду "Искать указатель на начало блока памяти".
Тем самым мы найдем все указатели на диапазон адресов между началом блока и ячейкой с опытом. Таких указателей нашлось 50 штук.
Перезапускаем игру. Нажисаем кнопку "Отсеять" и делаем "Отсеивание указателей" на значение 650.
Такой указатель один. Если указатель не один, то перезапускаем игру и опять делаем "Отсеивание указателей". И так несколько раз. Если все равно получается несколько адресов, то выбираем любой. В левой таблице выделяем указатель, в правой таблице выделяем ячейку с опытом и делаем команду "Установить указатель на все".
Вот и всё! Мы имеем таблицу, адреса которой не меняются при перезагрузке игры.
Как раз то, что мне надо :)
← →
alpet © (2005-09-01 16:20) [29]Хинт © (01.09.05 12:56) [28]
Если ты найдешь указатель на стековое значение, это будет очень редким совпадением. Но если это значение имеет время жизни сравнимое с временем жизни процесса, и не перекрывается долгое время - его вполне можно использовать. В системах NT5+ стек как правило находится ниже основного (exe) модуля в АП процесса, но лучше об этом у Рихтера почитать.
Страницы: 1 вся ветка
Форум: "WinAPI";
Текущий архив: 2005.11.06;
Скачать: [xml.tar.bz2];
Память: 0.53 MB
Время: 0.045 c