![]() |
Модераторы: bsa |
![]() ![]() ![]() |
|
Jr13san |
|
||||
![]() Бывалый ![]() Профиль Группа: Участник Сообщений: 174 Регистрация: 29.7.2008 Где: г. Павлово Репутация: нет Всего: нет |
Приветствую всех, кто на форуме.
Как не странно, но вопрос по чтению данных по адресам "чужих" программ поднимался уже много раз на просторах интернета. У меня стоит задача по поиску строки текста в одном из запущенных процессов. Ок. Я нашёл некоторые коды, исправил под себя, разобрался кое в чём, но есть проблема. Консольное приложение очень медленно работает с поиском адресов. Примерно 4 млн. адресов цикл перебирает за 40 секунд, когда та же самая "артмани" за 6 секунд перебирает сотни миллионов адресов. Т.е. чтобы моё приложение прошлось по всем адресам, нужно примерно пол часа, а может быть и больше. Ну это просто смешно. Я хотел понять в чём секрет быстроты. Я не нахваливаю эту "артмани", просто мне хотелось бы создать свой прототип с поиском адресов. Итак, что у меня есть:
Мне подсказали, что нужно читать память целыми страницами, а затем в этом байтовом массиве искать нужную строку, а что дальше делать я не представляю. Даже если удастся считать целую страницу из памяти и поместить её в массив, то как совместить адреса и этот массив? Хотя мб через счётчики и смещение относительно начала... Мне хочется узнать как бы мне не по одному адресу считывать и проверять его содержимое, а считать целый регион памяти и искать в нём уже нужную строку. Я не пойму как с помощью ReadProcessMemory можно считать регион памяти и что для этого нужно сделать. Я знаю, что я близко, но всё равно не вижу результатов. Мне говорят, что в этом коде я хожу по одному и тому же месту 256 раз. Ещё говорят, что нужно использовать нечто вроде такого цикла:
Но тут кажется пропускается 2047 адресов и нужный не находится. Первый "break" обрывает весь цикл. Кто знает, что нужно сделать, чтобы заработала система, помогите пожалуйста. Скорей всего данная статья попадает под huck темы, которые наверное запрещено обсуждать... Единственное, что я понял - это то, что нужно попробовать зарезервировать страницу памяти и туда пересылать данные из "чужого" процесса через функцию ReadProcessMemory(). Наверное как-то так. Это сообщение отредактировал(а) Jr13san - 6.9.2011, 14:35 |
||||
|
|||||
Estranged |
|
|||
Бывалый ![]() Профиль Группа: Участник Сообщений: 158 Регистрация: 30.8.2010 Репутация: нет Всего: 3 |
Не все дозволено читать, надо бы проверять, можно ли читать эту страницу на всякий случай:
VirtualQueryEx на всякий случай, подробнее в MSDN, и еще лучше почитайте: http://habrahabr.ru/blogs/cpp/93437/ А то мне лень печатать... |
|||
|
||||
volatile |
|
||||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2107 Регистрация: 7.1.2011 Репутация: 16 Всего: 85 |
ну вобщем-то близко к истине. при продвижении на 1 байт вы считываете каждый раз 256 байт. то есть 4 млн умножаются на 256. Вторая версия вообще опасна, она выходит за пределы массива. каждый раз поиск ведется по 2048 байтам, даже если поиск начат в конце массива. Программа просто рухнет.
К тому-же зачем искать русскую 'Н' никак не пойму? |
||||
|
|||||
Jr13san |
|
||||
![]() Бывалый ![]() Профиль Группа: Участник Сообщений: 174 Регистрация: 29.7.2008 Где: г. Павлово Репутация: нет Всего: нет |
Ребята, я нашёл интересные исходники, попробую в них разобраться.
Estranged, ты прав на счёт функции VirtualQueryEx() Как я понял, нужно ходить по регионам. Т.е. если регион доступен для чтения и записи, то можно в нём искать, а если это какой-то системный или защищённый, то лучше его пропустить и идти дальше. Кстати, с этой статьи я и начинал, вообще ничего не понимал там и даже не мог исправить ошибки, сделанные автором. Но хотелось бы своё написать, используя "проверенные чужие куски кода".
На 1 адрес, а не на 1 байт. Я так думаю я прохожу счётчиком по адресам, а не по байтам чего-то... Т.е. 220000000 - это адрес, только в десятичной системе, вот к этому адресу я прибавляю 1 и как бы перехожу на следующий адрес, там считываю 256 байт. Для меня это максимальная нужная длина байтового массива. Хотя мне можно было бы считывать 6 байт по адресу. Т.е. [п][р][а][в][к][а]. Я же по адресам прохожу, а не по куче какой-то. Если я не прав, то объясните, пожалуйста, по подробнее, где я не правильно мыслю.
Массив можно увеличить до 2048 элементов. В общем когда я тестировал этот кусок кода, там безразмерный массив объявлялся прямо в этом цикле. Но опять же прикол в том, что мне пытаются доказать то, что у меня в голове не укладывается. В этом цикле пропускается 2047 адресов, а 2048 считывается, дальше опять пропускается и т.д. Поймите, мы же не из кучи считываем, как из текстового файла. От и до. А у нас каждой ячейке памяти соответствует свой номер. А чтобы считать кучу адресов и склеить их в один байтовый массив, я пока что таких функций не находил. Да, зарезервировать место можно, скопировать страницу из региона в то место тоже можно, но вот считать весь регион или хотя бы сразу кучу адресов - это для меня не виданное чудо. Мб там и не нужно считывать регион, а просто пройтись по его адресам, при условии, что этот регион не защищён? Да, извини это опечатка. Тогда подразумевался поиск в другом процессе. Там нужно было найти фразу "Новая игра". Т.е. хотя бы её тогда нужно было. Да не в этом дело, просто любую фразу хочется быстро найти, а не пол часа ждать. Если вам интересно в чём смысл вот этой программы, то могу рассказать, это даже не хакинг, а чисто помощь разработчикам своих проектов или модов. Это сообщение отредактировал(а) Jr13san - 7.9.2011, 07:50 |
||||
|
|||||
Earnest |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 5962 Регистрация: 17.6.2005 Где: Рязань Репутация: нет Всего: 183 |
Нужно дополнить "адрес конкретного байта". А прибавляя 1, ты переходишь к следующему байту. Ты сдвигаешься на 1 байт, а читаешь 256. Т.е. один и то тот же байт памяти ты читаешь до 255 раз. Куча, не куча - память это линейный массив байтов с последовательной адресацией (виртуально, конечно, но это не важно). -------------------- ... |
|||
|
||||
Jr13san |
|
|||
![]() Бывалый ![]() Профиль Группа: Участник Сообщений: 174 Регистрация: 29.7.2008 Где: г. Павлово Репутация: нет Всего: нет |
Earnest, хм, странно как-то всё...
На практике у меня совсем другая ситуация. Возьмём слово "Новая игра". Т.е. я беру адрес 200 000 000 и считываю из него 256 байт. Но они не считаются, т.к. там строка заканчивается последним байтом(буквой "а"). Т.е. считается только 10 байт. Итого на выходе: "Новая игра". Если я увеличу адрес 200 000 001 и возьму опять 256 байт, то получу следующую строку: "овая игра". Сама ситуация приведена ниже. Тогда такой вопрос, почему "артмани" выводит адрес, по которому расположена искомая строка текста? Она выводит адрес начала строки или адрес целой строки? Вот в этом, наверное, вся загвостка. С другой стороны я наткнулся на такой ответ, но сначала вопрос: Чтобы было понятнее, я на основе своей "Новой игры" Например, вот такая картина вырисовывается в моём 30-минутном чтении памяти: Адрес (десятичная система) = значение по этому адресу. 200 000 000 = Новая игра 200 000 001 = овая игра 200 000 002 = вая игра 200 000 003 = ая игра 200 000 004 = я игра 200 000 005 = игра 200 000 006 = игра 200 000 007 = гра 200 000 008 = ра 200 000 009 = а 200 000 010 = 200 000 011 = 200 000 012 = 200 000 013 = Опции 200 000 014 = пции 200 000 015 = ции 200 000 016 = ии 200 000 017 = и 200 000 018 = 200 000 019 = Один говорил это так выглядит потому что так удобнее считывать данные для разработчиков... Я вот сейчас думаю, неужели это из за того, что я 255 раз ходил по одному и тому же месту? Обрыв произошёл из за того, что адрес стал 200 000 001. Тогда другой важный вопрос: почему 256 байт не считалось, а оборвалось на 10 байте? А может быть у меня нет приоритета отладчика, чтобы считывать целые страницы памяти? Это сообщение отредактировал(а) Jr13san - 7.9.2011, 18:55 |
|||
|
||||
volatile |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2107 Регистрация: 7.1.2011 Репутация: 16 Всего: 85 |
А вы уверены что не считалось? Возможно просто при выводе встречается '\0', а это признак конца строки. но за нулем есть еще 256-10 = 246 символов. Вы их просто не видите.
явно нет. хотябы потому, что на 10 байтах не может быть границы. Граница страницы выровнена на более круглое число. Это вопрос не правильный. Адрес начала строки это и есть адрес строки. (по крайней мере в С/С++). К тому-же есть еще соображения, не относящиеся напрямую к вопросу. Вы ищите русские строки. А вы уверены что они находятся в той же кодировке что и у вас ? Они могут быть и в юникоде, да мало ли в какой. Русских кодировок вагон и маленькая тележка. Это сообщение отредактировал(а) volatile - 8.9.2011, 00:04 |
|||
|
||||
volatile |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2107 Регистрация: 7.1.2011 Репутация: 16 Всего: 85 |
Jr13san, вообще вашу проблему понял. Завтра може быть, что-нибудь накатаю в качестве отправной точки (щас просто мозги уже ничо не варят). Ну и если, конечно, до меня никто этого не сделает.
Там надо считывать блоками, и искать уже в этом блоке. Единственная проблема, строки начинающиеся в одном блоке и заканчивающиеся в другом. Тут надо просто закодировать логику этого дела. Ну и русская кодировка очень смущает... Сейчас ведь многие программы в юникоде... Добавлено через 5 минут и 32 секунды упс, только что вспомнил, завтра не смогу, только после-завтра ... |
|||
|
||||
Jr13san |
|
||||||
![]() Бывалый ![]() Профиль Группа: Участник Сообщений: 174 Регистрация: 29.7.2008 Где: г. Павлово Репутация: нет Всего: нет |
volatile, ок, буду ждать хоть какой-то разгадки это ситуации.
Ещё то, что интересно, вот такой код как раз обрывает строку как в моём случае:
Совсем другое дело:
Остаётся верить в то, что этот "\0" префикс обрыва строки меня и обманывал. В итоге набросал такой код:
Но нужно написать ещё поиск байтовой строки в байтовом массиве. Надо разбираться... Это сообщение отредактировал(а) Jr13san - 8.9.2011, 20:43 |
||||||
|
|||||||
volatile |
|
||||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2107 Регистрация: 7.1.2011 Репутация: 16 Всего: 85 |
Jr13san, правильно! Читать целый регион, это самый простой способ.
(если память позволяет) Это избавляет от необходимости писать поиск по блокам.
да именно так и было. Вы с флагами работаете не правильно. Нужно примерно так:
ну с этим я думаю проблем не будет... Это сообщение отредактировал(а) volatile - 9.9.2011, 10:13 |
||||
|
|||||
Jr13san |
|
|||
![]() Бывалый ![]() Профиль Группа: Участник Сообщений: 174 Регистрация: 29.7.2008 Где: г. Павлово Репутация: нет Всего: нет |
volatile, Спасибо, попробую.
Я сейчас только что вывел то, что мне нужно:
То, что хорошо - это то, что я не зная c++ разобрался с "середины программирования". Ещё хотелось бы куда-нибудь выложить единственный пример поиска строки в любом приложении(с комментариями). Нужно разработать ещё поиск. Если что, напишу сюда. Спасибо ещё раз всем, кто помогал разбираться, но я ещё не прощаюсь. Постараюсь дописать готовый код, а там уже можно будет опять комментировать недостатки, делать поправки и увеличивать скорость поиска. Скриншот: Это сообщение отредактировал(а) Jr13san - 9.9.2011, 10:25 Присоединённый файл ( Кол-во скачиваний: 7 ) ![]() |
|||
|
||||
volatile |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2107 Регистрация: 7.1.2011 Репутация: 16 Всего: 85 |
Здесь ссылку уже давали http://habrahabr.ru/blogs/cpp/93437/ Там есть много из того что вам нужно, в том числе и поиск подстроки байтов в массиве байтов, смотрите ф-ю: fMatchCheck (); (не самый быстрый способ, но сойдет). посмотрите там-же работу с msi.lpMinimumApplicationAddress msi.lpMaximumApplicationAddress а вот блочный поиск там абсолютно кривой, так что на него не смотрите, впрочем, это и не нужно с чтением региона целиком. |
|||
|
||||
bems |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 3400 Регистрация: 5.1.2006 Репутация: нет Всего: 88 |
В этом нет абсолютно никакого смысла. Достаточно анализа возвращаемого знаечениz ReadProcessMemory и GetLastError -------------------- Обижено школьников: 8 |
|||
|
||||
Jr13san |
|
|||
![]() Бывалый ![]() Профиль Группа: Участник Сообщений: 174 Регистрация: 29.7.2008 Где: г. Павлово Репутация: нет Всего: нет |
volatile, там на этом хабре пример какой-то кривой, в нём много ошибок + не работает.
Я злился на этот пример как только можно. Извините за выражение, но по кой хер выкладывать код, который при компиляции выдаёт 8 ошибок? Если бы автор написал рабочий код, тогда бы путём экспериментов можно было бы разобраться, а так - это бедовый топик. Легче свой код написать, хотя бы понятнее будет. Ну не с нуля, а так, используя доступные функции. Что я и сделал - я сначала разобрался в том, чего не понимал, а потом уже стараюсь сам писать. На счёт минимального и максимального адреса я понял, но у меня такой внешний помошник, который не требует отсеивания значений по адресам памяти. Т.е. я задаю в самой "игре" строку с уникальным текстом. Далее осуществляю её поиск через консольное приложение(внешнее). И как только данная строка нашлась, я сразу же обрываю весь поиск и могу обмениваться данными через эту переменную между Готикой("игрой") и соответственно внешним приложением. Сразу не понять что именно я хочу сделать, но это, как я уже говорил, - помощь "из вне" разработчикам своих проектов. Это сообщение отредактировал(а) Jr13san - 9.9.2011, 12:57 |
|||
|
||||
bems |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 3400 Регистрация: 5.1.2006 Репутация: нет Всего: 88 |
В той же SYSTEM_INFO есть dwPageSize, это размер страницы читать меньше которого нет смысла. -------------------- Обижено школьников: 8 |
|||
|
||||
![]() ![]() ![]() |
Правила форума "C/C++: Для новичков" | |
|
Запрещается! 1. Публиковать ссылки на вскрытые компоненты 2. Обсуждать взлом компонентов и делиться вскрытыми компонентами
Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, JackYF, bsa. |
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей) | |
0 Пользователей: | |
« Предыдущая тема | C/C++: Для новичков | Следующая тема » |
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |