Перейти к содержанию
СофтФорум - всё о компьютерах и не только

Вопрос по указателям в C/C++/C#


Рекомендуемые сообщения

Здравствуйте. Изучал на днях указатели. Возник вопрос.

Когда мы присваиваем указателю адрес какой-либо переменной, мы можем "сместить" его значение просто прибавив или убавив это значение (например, при помощи операций инкремента ++ и декремента --). Но ведь существует какое-то нулевое (начальное) значение адреса и можем ли мы его присвоить какому-нибудь указателю? И отсюда же вопрос возникает, это нулевое значение, оно нулевое только для данной программы или для всей памяти в системе вообще? И вообще, можно ли при помощи указателя получить значение ячейки памяти из другого процесса скажем?

Заранее спасибо за ответ.

Ссылка на комментарий
Поделиться на другие сайты

Адрес, хранящийся в указателе - не реальный адрес ячейки памяти. Система выделяет каждому процессу виртуальное (то есть выдуманное ею) адресное пространство, и адреса в указателях пересчитываются в физические адреса по сложной системе, так что даже адреса, которые процесс считает соседними, могут находится в совсем разных частях физической памяти. Нулевого значения виртуальный адрес иметь не может. Если указателю присвоен виртуальный адрес, равный нулю, а это делается запросто присвоением константы NULL (которая во всех практических реализациях равна просто нулю, так что вместо нее можно просто присваивать нуль), то это имеет специальное значение - такой указатель считается ни на что не указывающим, пустым.

Относительно получения значения ячейки памяти из другого процесса - операционная система осуществляет защиту адресного пространства одного процесса от доступа к нему другого процесса, во всяком случае на уровне прав пользовательских процессов. Микропроцессоры Intel имеют четыре аппаратных уровня защиты от таких действий (кольца защиты уровней привилегий процессов), хотя в Windows из них используются только два.

  • Upvote 1
Ссылка на комментарий
Поделиться на другие сайты

Указатели - тяжкое наследие времен ассемблерного программирования. С другой стороны, когда программировали на системах, где каждый байт подконтролен, создавалось приятное ощущение власти над машиной.

Теперь принято (и в конечном итоге правильно) положение, что операционная система умнее программиста. Теперь не залезешь к ячейкам напрямую, только через посредника - ОС. И если за процессами ОС худо-бедно следит, то залететь по ошибке на другую переменную, пользуясь указателями - обычное дело. ОС следит за использованием адресного пространства, да не услеживает И по рукам бьёт - не дает полной свободы и сама не справляется. Отсюда основной источник мастдайности.

В Дельфи, в котором я в основном программирую, есть указатели и есть традиция их использовать, но это адский ад к огда ты не имеешь возможности диагностировать ошибки, спровоцированные указателями. Я прикладник, поэтому указатели использовал давненько - при разработке самопальных контроллеров. При программировании "апликух" я взял за правило указателями не пользоваться.

Ну, а аццким хацкерам без указателей никак. Вирусописателям это слаще мёда.

Ссылка на комментарий
Поделиться на другие сайты

Я C# сейчас потихоньку изучаю. Там указатели по дефолту вообще запрещены, ибо код с использованием указателей считается небезопасным. Их можно разрешить, добавив атрибут unsafe к классу и разрешив небезопасный код в свойствах проекта.

Ссылка на комментарий
Поделиться на другие сайты

  • 7 месяцев спустя...

Вот, я всё равно не могу понять:

Относительно получения значения ячейки памяти из другого процесса - операционная система осуществляет защиту адресного пространства одного процесса от доступа к нему другого процесса, во всяком случае на уровне прав пользовательских процессов. Микропроцессоры Intel имеют четыре аппаратных уровня защиты от таких действий (кольца защиты уровней привилегий процессов), хотя в Windows из них используются только два.

Как же тогда работают программы типа ArtMoney? Возможно есть какие-то API-функции в Windows для доступа к определённым ячейчкам памяти процессов?

Ссылка на комментарий
Поделиться на другие сайты

@Shadow TH, используют анализ родительского процесса, например в скриптовых языках или С++.

Берётся имя окна и используя хуки

получают прямой доступ к тому что отображается на экране или же можно использовать хуки клавиатуы/мышки.

Получается что сама программа считает что получает данные с клавиатуры, т.е. драйвера винды, но хук стоит между ОС и программой.

Это 100% хакерские методы

Управление игрой или другим ПО - Я этим сам часто пользуюсь, особенно клавиатурой или мышой, а иногда и графикой анализируя по шаблону то что выводится на экран и заменяя одно действие на другое.

P.S. Я не знаю что делает ПО ArtMoney, но проще использовать скрипты, а не писать программу на С++ - хотя всё зависит от задачи, просто на скриптовых языках это выгляди проще - в несколько строчек кода.

Изменено пользователем Indomito
Ссылка на комментарий
Поделиться на другие сайты

Indomito, это немного другое. Тот же ArtMoney к примеру умеет искать адреса ячеек по определённым параметрам (например, если известно значение переменной). Через него можно изменить значения любых переменных в запущенном процессе. Получается, что доступ к этим ячейкам памяти можно получить извне (из другого процесса). Это полезно, например, когда пишешь GUI для какого-нибудь консольного приложения.

Ссылка на комментарий
Поделиться на другие сайты

@Shadow TH, можно использовать отладчик из Microsoft Visual Studio - весьма мощное средство, правда нужен полностью установленный пакет, например Microsoft Visual Studio 2010 Pro.

А насчёт "API-функции в Windows для доступа..." - не знаю, просто не нужно было, обходился "подручными" средствами, у меня есть Win32API First Steps.chm (на русском языке) могу дать, может там что то и есть.

Изменено пользователем Indomito
Ссылка на комментарий
Поделиться на другие сайты

При программировании "апликух" я взял за правило указателями не пользоваться.

Согласен, сегодня во многих языках это вообще своего рода рудимент. И в принципе в этом есть определенная логика.

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

В общем действительно, указатели имхо нужно в системах с ограниченными ресурсами- чтобы не создавать копии при передаче функциям и в драйверах- потому что там как бы без них никак :) если только не врезками ассемблера, но и это так сказать по многим современным понятиям засорение кода. :)

Ссылка на комментарий
Поделиться на другие сайты

Shadow TH

Как же тогда работают программы типа ArtMoney? Возможно есть какие-то API-функции в Windows для доступа к определённым ячейчкам памяти процессов?

Дело в том, что защита не применяется автоматически для всех процессов. Windows может ее использовать для каких-то процессов, а может ее и не использовать. Автоматически защищаются в Windows только процессы, выполняемые ядром системы. Пользовательские процессы защищаются с помощью настраиваемых функций Windows, для этого служит служба DEP, настройки которой задаются частично еще в загрузчике системы, а частично через имеющиеся в интерфейсе Windows настройки. Когда появляется сообщение «Инструкция по адресу "..." обратилась к памяти по адресу "...". Память не может быть "read" – это как раз вмешалась программная защита процессов через службу DEP. Сама же эта служба управляет настройками менеджера виртуальной памяти. Там еще учитывается, идет обращение к участку памяти для выполнения кода в нем как программы или только для чтения или записи данных.

Так что обойти защиту пользовательских процессов программно можно. Самый простой способ - с помощью изменения настроек DEP, если они препятствуют доступу к памяти другого пользовательского процесса. Вообще система защиты Windows весьма сложно организована и использует как встроенные в микропроцессор кольца защиты, там и специальные программные компоненты Windows. Кое-что об обходе системы защиты процессов можно вкратце прочитать, например, тут. Но это сойдет только для понимания, насколько сложна эта система :)

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

Изменено пользователем Тролль
Ссылка на комментарий
Поделиться на другие сайты

@Тролль, по сути то два вопроса или две установки получается.

1. Как получить доступ к любой пользовательской программе из другой программы.

2. Как защитить свою программу от стороннего вмешательства.

1. Я честно не знаю, если глобально рассматривать - только API, но там много условий и ты прав - это болото.

2. Немного проще.

- плавающее шифрование важных переменных;

- при инсталляции своей программы следует прописать её в ключ HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\AppCompatFlags\Layers - т.е. ПО под защитой DEP, правда область данных придётся вызывать только через API

Ссылка на комментарий
Поделиться на другие сайты

  • 1 месяц спустя...

Нашёл решение по своему вопросу. В общем, за редактирование памяти других процессов отвечают функции WinAPI - WriteProcessMemory и ReadProcessMemory.

Ссылка на комментарий
Поделиться на другие сайты

@Shadow TH, да, она может + надо использовать API-функцию GetCurrentProcessid правда запись выполняется в стеке и при наличии мало-мальской защиты у модифицируемой программы возникнет переполнение стека.

Объяснение-пример Используем функцию WriteProcessMemory

Ссылка на комментарий
Поделиться на другие сайты

Для публикации сообщений создайте учётную запись или авторизуйтесь

Вы должны быть пользователем, чтобы оставить комментарий

Создать учетную запись

Зарегистрируйте новую учётную запись в нашем сообществе. Это очень просто!

Регистрация нового пользователя

Войти

Уже есть аккаунт? Войти в систему.

Войти
  • Последние посетители   0 пользователей онлайн

    • Ни одного зарегистрированного пользователя не просматривает данную страницу
×
×
  • Создать...