Jump to content
СофтФорум - всё о компьютерах и не только

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


Recommended Posts

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

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

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

Link to post
Share on other sites

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

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

  • Upvote 1
Link to post
Share on other sites

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

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

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

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

Link to post
Share on other sites

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

Link to post
Share on other sites
  • 7 months later...

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

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

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

Link to post
Share on other sites

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

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

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

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

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

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

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

Edited by Indomito
Link to post
Share on other sites

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

Link to post
Share on other sites

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

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

Edited by Indomito
Link to post
Share on other sites
При программировании "апликух" я взял за правило указателями не пользоваться.

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

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

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

Link to post
Share on other sites

Shadow TH

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

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

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

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

Edited by Тролль
Link to post
Share on other sites

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

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

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

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

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

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

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

Link to post
Share on other sites
  • 1 month later...

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

Link to post
Share on other sites

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

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

Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

  • Recently Browsing   0 members

    No registered users viewing this page.

×
×
  • Create New...