Полагаю, что лучше было все-таки задать этот вопрос тут.. Уважаемые форумчане, помогите в разрешении одного вопроса. Мне требуется взаимодействовать с интерфейсом программы через другую. То есть считывать/записывать данные из памяти по какому-нибудь адрессу, выделенному под программу-цель. Более подробнее: некоторое значение Х , находящееся в программе лежит по следующим адресам: 01384D68 - целочисленное значение (4 байта) 0142С4D0 - его тектовое значение Подскажите как мне узнать эти адресса через свою программу? После некоторых попыток я выяснил, что одни из адрессов, например, 0142С4D0, сохраняется. То есть это значение всегда находится по этому адресу, а вот допустим его целочисленное значение уже лежит по другому адресу... Объясните новичку пожалуйста! Заранее буду очень благодарен
01374D18 вот он этот адрес! - я угадал?, нет? какая досада(((... Хм почему я назвал этот адрес? ну так мне подсказали мои телепатические способности, и как оказалось у меня хуевый дар... что ж простите, за оффтоп в оффтопе... ТС, а больше инфы выложить религия не позволяет?
Исходников программы пока не имеется, они и не к чему для ответа на вопрос Spider, потому что мне не важна практическая реализация, я хотел чтобы кто-нибуль смог бы объяснить это теоретически.. Неудачная шутка...Потрудитесь обращаться без сарказма! Суть вопроса ведь не в том, чтобы вы мне подсказали нужный адрес! Я спросил, как можно его вычислить? Есть же по-моему так называемый базовый адрес, от которого все считается? И можно ли вообще при каждом новом запуске приложения отыскать нужное значение в выделяемой под нее памяти?! Может быть я говорю сложно и не понятно?! Хотя я думаю , что на этом форуме присутствуют люди, которые точно в этом разбираются, просто предпочитают промолчать почему то Тогда так, более примитивно: Запускаю программу, с помощью перехвата ее процесса узнаю ее адрес (видимо это какой-то "базовый"?) И потом начинаю сканировать области памяти на присутствие конкретного значения Х. То как мы все это пробовали делать с помощью ArtMoney. Но при этом, чтобы определить адресс точно, из множества значени мы отсеиваем, чтобы получить одно! Вопрос мой был в следующем: Как определить без этого отсеивания адрес, данного значения? Как-то отталкивая от "базового" на какую то константу? (Скажем на 200 мб?)...
Просто почитайте про PE формат и вопросы сами по себе отпадут вместе с желанием )))))) по теме: ImageBase+Offset, если я вас правильно понимаю.
2Derec Тааак. Нет млин просто переменной. Какая она, локальная, глобальная, может память для неё в куче динамически выделяется? От этого будет зависеть, как ты будешь из другого процесса её смотреть. Общего алгоритма нет, тк от типа (тип в смысле расположения в памяти, см. ранее) переменной зависит её адресация в программе. Глобальные переменные адресуюца по абсолютным смещениям и располагаются (обычно) в отдельной секции. В этом случае всё просто : OpenProcess, ReadProcessMemory(..., addrvalue, ...). НО есть нюансы. Эти абсолютные адреса валидны только если модуль загрузился по предпочитаемому адресу загрузки, указанному в IMAGE_OPTIONAL_HEADER.ImageBase. Обычно exe по нему и грузятся, но в случае с dll всё наоборот и скорее всего она загрузиццо по адресу отличному от базы образа. Если модуль загрузился по адресу отличному от базы образа, то загрузчик патчит абсолютные адреса переменных на некоторую дельту используя информацию из директории релоков (ака перемещаемых элементов, го ту спецификация на PE формат). Другими словами чтобы прочитать или записать по константному адресу, ктр ты узнал ручками до этого, в общем случае нужно 1. найти базу образа (самое первое, что пришло в голову toolhelp api) 2. разбирать заголовок исполняемого модуля и в случае если база образа не совпала с предпочитаемой -> 3. пропатчить адрес на дельту между предпочитаемой и реальной базой образа. Если это локальная переменная, то всё несколько сложнее. Локальные переменные хранятся в стеке, а он во-первых - постоянно изменяется, во-вторых - для каждого потока свой, а в-третьих ... а вообщемто первых двух пунктов достаточно. Так что простого способа чтения извне стековых переменных нет. Тут либо трассировшик, либо внедрение своего кода. Ну и с кучей задача немного более проста. Нужно лишь перехватить соответствующую функцию (импорт, сплайсинг) и зная логику проги запомнить один из её вызовов и возвращаемое значение. ------------------------------------ таким образом три типа адресов какбэ (в свете твоего вопроса естественно) - глобальные (для глобальных переменных), начиная от верхушки стека в сторону младших адресов (для локальных) и начиная от начала блока памяти, выделенной системой посредством апишных функций (для динамики). ЗЫ. Формулируй вопрос конкретней. С твоих объяснений непонятно то ли тебе нужно с интерфейсом общаться гуишным, толи прочитать переменную по некоторому адресу, толи найти в памяти некоторое значение. Два поста и три варианта млин. И что значит... ...я так и не допер ЗЫЫ Ыыыыы ^______^
h3rmit, огромное спасибо за разъяснения! Понял, что простого способа нет. Но в принципе я его и не ждал! Ладно, мне теперь хоть есть в каком направлении копать дальше Еще раз спасибо!
Находим адрес в artmoney или плагином к олли games invader Ставим бряк аппаратный на доступ к этому значению, ждем срабатывания. Начинаем анализировать код обращающийся к этому значению. Согласен с тем что адрес в памяти может быть разный, но на эту память должен быть указатель, а он наверняка фиксированный (надеюсь ) Если так, то ReadProcessMemory читаем указатель. Затем вычисляем конечное положение искомого значения и манипулируем далее уже с ним.