Экспертная система Delphi.int.ru

Сообщество программистов
Общение, помощь, обмен опытом

Логин:
Пароль:
Регистрация | Забыли пароль?

Delphi.int.ru Expert

Другие разделы портала

Переход к вопросу:

#   

Статистика за сегодня:  


Лучшие эксперты

Подробнее »



Вопрос # 6 364

/ вопрос открыт /

Доброго времени суток, уважаемые эксперты!

Есть програмка в памяти которой в процессе работы создаётся строка. Так же в процессе работы она дополняется, ну или стирается и туда пишется более длинная.
Адрес на начало строки я научился получать.

Вопрос в том что нужно считывать эту строку если она изменилась. То есть нужны события когда меняются значения в определённом диапазоне адресов
Что посоветуете на эту тему?

QWERYTY Вопрос ожидает решения (принимаются ответы, доступен мини-форум)

Вопрос задал: QWERYTY (статус: Посетитель)
Вопрос отправлен: 24 января 2013, 00:38
Состояние вопроса: открыт, ответов: 0.


Мини-форум вопроса

Всего сообщений: 17; последнее сообщение — 30 января 2013, 02:40; участников в обсуждении: 4.
QWERYTY

QWERYTY (статус: Посетитель), 24 января 2013, 00:40 [#1]:

Разумеется был в мсдн, и увидел только одну функцию которая хоть каким то боком относится к теме - GetWriteWatch
Но если я правильно понял она возвращает инфу об изменениях, но не порождает событий. А мне нужно событие, считаю я потом сам

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

Забыл указать что работа идёт из под самого процесса, поэтому огроничений связанных с адресными пространствами процессов на выбор функций нету.
ВЕРИТЬ ВО ВНЕЗЕМНЫЕ ЦИВИЛИЗАЦИИ НЕ ОЗНАЧАЕТ ВЕРИТЬ В ИНОПЛАНЕТЯН.
min@y™

min@y™ (статус: Доктор наук), 24 января 2013, 08:14 [#2]:

А на чём написана программа, в памяти которой искомая строка?
Делаю лабы и курсачи по Delphi и Turbo Pascal. За ПИВО! Пишите в личку, а лучше в аську. А ещё лучше - звоните в скайп!
QWERYTY

QWERYTY (статус: Посетитель), 24 января 2013, 09:29 [#3]:

Похоже что на C++.
Когда исследовал одно из создаваемых ей окон с помощью WndInfo, класс объекта в форме c++ Webbrowser. Как я понял это один из компонентов той студии в которой создавалась прога.

В главном окне какой то самописанный клас, инфы никакой, не гуглится.

Там анси строки, они легко находятся с помощью ArtMoney
ВЕРИТЬ ВО ВНЕЗЕМНЫЕ ЦИВИЛИЗАЦИИ НЕ ОЗНАЧАЕТ ВЕРИТЬ В ИНОПЛАНЕТЯН.
min@y™

min@y™ (статус: Доктор наук), 24 января 2013, 09:52 [#4]:

Цитата (QWERYTY):

Там анси строки, они легко находятся с помощью ArtMoney

Это понятно.
Первая мысль - надо искать не саму строку, а ячейку памяти, в которой хранится указатель на эту строку, т.к. в случае перераспределения памяти при увеличении длины строки этот указатель изменится и будет показывать на начало новой строки.
Делаю лабы и курсачи по Delphi и Turbo Pascal. За ПИВО! Пишите в личку, а лучше в аську. А ещё лучше - звоните в скайп!
QWERYTY

QWERYTY (статус: Посетитель), 24 января 2013, 10:27 [#5]:

Если указатель изменится я снова его найду. У меня фунька написанна для поиска.
И вообще такого не наблюдалось. Адрес начала строки всегда один, пока существует окно из которого интересуют данные.

Интересно как вообще может писаться строка.
Например написанно
Form1->Caption = "VASYA"

Пробовал в апи мониторе перехватывать WriteProcessMemory, но она не вызывается в момент изменения строки. Особых надежд конечно же не было, но проверить обязан был.


Насчёт перехвата записи есть какие нибудь идеи?
Как вам такая:
Установить этому региону протектед. Тогда, по моему разумению, при попытках записи в страницы региона должны быть исключения. Вот их как нибудь обработать.
ВЕРИТЬ ВО ВНЕЗЕМНЫЕ ЦИВИЛИЗАЦИИ НЕ ОЗНАЧАЕТ ВЕРИТЬ В ИНОПЛАНЕТЯН.
min@y™

min@y™ (статус: Доктор наук), 24 января 2013, 11:24 [#6]:

Цитата (QWERYTY):

WriteProcessMemory, но она не вызывается в момент изменения строки

И не должна. Внутри процесса работа с памятью идёт на низком уровне.

Цитата (QWERYTY):

Насчёт перехвата записи есть какие нибудь идеи?

К сожалению, нет. Может другие чего подскажут.
Делаю лабы и курсачи по Delphi и Turbo Pascal. За ПИВО! Пишите в личку, а лучше в аську. А ещё лучше - звоните в скайп!
Вадим К

Вадим К (статус: Академик), 24 января 2013, 15:41 [#7]:

можно попробовать стать отладчиком. и поставить точку останова для перехвата изменения памяти. Тогда можно будет получить полный контроль (не дать программе туда записать, поставить программу на паузу).
Галочка "подтверждения прочтения" - вселенское зло.
QWERYTY

QWERYTY (статус: Посетитель), 24 января 2013, 18:10 [#8]:

Чёто ни одного описания дебаг апи функций не увидел на мсдн.
Коммерческая чтоли какая нибудь документация?

Процесс будет отладчиком для самого себя?

В общем опишу немного как да что:
Запускается моя(главная программа) и внедряет специально написанную DLL в експлорер(explorer.exe). Далее эта DLL Запускает программу(в которой интересующие данные) при помощи CreateProcess. Ну и далее в эту прогу внедряется DLL из под эксплорера. Далее устанавливается "канал связи" Между моей главной программой и прогой в которой данные через эксплорер(т.е. на прямую они друг друга не видят).


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

Но где взять документацию на дебаг апи?
Модуля в делфи как я понял не будет, и все функции придётся импортировать
ВЕРИТЬ ВО ВНЕЗЕМНЫЕ ЦИВИЛИЗАЦИИ НЕ ОЗНАЧАЕТ ВЕРИТЬ В ИНОПЛАНЕТЯН.
QWERYTY

QWERYTY (статус: Посетитель), 25 января 2013, 07:40 [#9]:

CreateProcess не та похоже тема.

Пытался стать отладчиком для своего процесса используя DebugActiveProcess:
procedure DllProcessAttach(); stdcall;
begin
  if DebugActiveProcess(GetCurrentProcessId) = TRUE then ShowMessage('O ya, baby') else
  ShowMessage(IntToStr(GetLastError));
...

Но получаю ошибку под номером 5.
ERROR_ACCESS_DENIED
5 (0x5)

Access is denied.

Ну и как я понял(из мсдн) ни о каких точках останова не может быть и речи в такой ситуации.

Что тут можно с этим сделать?
ВЕРИТЬ ВО ВНЕЗЕМНЫЕ ЦИВИЛИЗАЦИИ НЕ ОЗНАЧАЕТ ВЕРИТЬ В ИНОПЛАНЕТЯН.
QWERYTY

QWERYTY (статус: Посетитель), 25 января 2013, 09:05 [#10]:

По умолчанию у процесса отключенна привелегия - SeDebugPrivilege. Использовал самопальную функцию которая включает эту привелегию. С помощью ProcessExplorer вижу что когда грузится моя DLL SeDebugPrivilege - Enabled.

Но DebugActiveProcess всё равно возвращает ту же самую ошибку(ну в смысле не возвращает, а выполняется с ошибкой)
ВЕРИТЬ ВО ВНЕЗЕМНЫЕ ЦИВИЛИЗАЦИИ НЕ ОЗНАЧАЕТ ВЕРИТЬ В ИНОПЛАНЕТЯН.
SOA

SOA (статус: Посетитель), 28 января 2013, 14:25 [#11]:

Здравствуйте QWERYTY: В вашем случае можно в интересующем приложении создать параллельный поток функцией CreateThread в качестве обработчика потока для которой указать свою функцию которая отслеживает изменения и реагирует на них.
QWERYTY

QWERYTY (статус: Посетитель), 28 января 2013, 20:38 [#12]:

"функцию которая отслеживает изменения и реагирует на них."

Вот этот момент и интересует, остальное всё понятно.
Нужен перехват этого события(желательно из под самого процесса).
Может ли процесс заметить(получить об этом информацию) что его отлаживают отладчиком пользовательского уровня?
Как то помню читал что программа не может заметить что её отлаживает отладчик ядерного уровня. ПРокоментируйте пожалуйста кто владеет темой и достаточно опытен.

Процесс как я понял не может отлаживать сам себя.
При присоединении отладчика все потоки ставятся на паузу, Соответственно я не смогу обработать событие и запустить процесс дальше.

Остаётся отладка с другой программы, но пока я должен подумать над другими вариантами.
Пока один из переспективных подмена адресов на свои в SEH.
Но там тоже много вопросов. Где брать строку которую собирались писать(я получу исключение до записи), как быть с параметрами защиты региона, разрешать в них запись и повторять операцию или записывать в другие адреса, что при этом будет(ну если записывать в другие, как будет работать программа)

В общем дела пока плохи, если у кого появилась какая идея поделитесь
ВЕРИТЬ ВО ВНЕЗЕМНЫЕ ЦИВИЛИЗАЦИИ НЕ ОЗНАЧАЕТ ВЕРИТЬ В ИНОПЛАНЕТЯН.
SOA

SOA (статус: Посетитель), 28 января 2013, 21:12 [#13]:

"функцию которая отслеживает изменения и реагирует на них."
 
 Вот этот момент и интересует, остальное всё понятно.
Сначала твоя функция для параллельного потока получает права для доступа к адресному пространству первого процесса
после этого просто зацикливается на проверку интересующего значения и при изменении значения реагирует.
QWERYTY

QWERYTY (статус: Посетитель), 28 января 2013, 23:22 [#14]:

Блин, я работаю из под процесса, туда внедрена длл.
Я не имею доступ только к регионам которые создавались с атрибутами PAGE_GUARD и PAGE_NOACCESS. Но меня такие не интересуют.

Ещё раз повторяю меня интересует как получить события когда меняются значения(самим процессом, не мной) по определённым адресам, без использования таимера.



Что значит зацикливается? Поясните по подробней идею.
Бесконечно применять GetWriteWatch(ну или просто читать строку по указателю)?

Не будет ли такая тема подгружать проц, учитывая что иногда их может быть 4(ну вот таких перехватчика)??
ВЕРИТЬ ВО ВНЕЗЕМНЫЕ ЦИВИЛИЗАЦИИ НЕ ОЗНАЧАЕТ ВЕРИТЬ В ИНОПЛАНЕТЯН.
QWERYTY

QWERYTY (статус: Посетитель), 29 января 2013, 07:42 [#15]:

function Thread1(Data: POINTER): INTEGER;
var
Count: BYTE;
begin
   repeat
   Count := Count + 1;
   Count := Count - 1;
   until 1 > 2;
end;
 
function Thread2(Data: POINTER): INTEGER;
var
Count: BYTE;
begin
   repeat
   Count := Count + 1;
   Count := Count - 1;
   until 1 > 2;
end;
 
function Thread3(Data: POINTER): INTEGER;
var
Count: BYTE;
begin
   repeat
   Count := Count + 1;
   Count := Count - 1;
   until 1 > 2;
end;
 
function Thread4(Data: POINTER): INTEGER;
var
Count: BYTE;
begin
   repeat
   Count := Count + 1;
   Count := Count - 1;
   until 1 > 2;
end;
 
 
 
procedure TForm1.FormShow(Sender: TObject);
var
Err, TId: CARDINAL;
begin
   Err := CreateThread(NIL, 0, @Thread1, NIL, 0, TId);
   if Err > 0 then Showmessage('Поток №1 запущен!');
 
   Err := CreateThread(NIL, 0, @Thread2, NIL, 0, TId);
   if Err > 0 then Showmessage('Поток №2 запущен!');
 
   Err := CreateThread(NIL, 0, @Thread3, NIL, 0, TId);
   if Err > 0 then Showmessage('Поток №3 запущен!');
 
   Err := CreateThread(NIL, 0, @Thread4, NIL, 0, TId);
   if Err > 0 then Showmessage('Поток №4 запущен!');
 
 
end;

Вот запуск 4-ёх потоков. Уже после запуска первого проц занят на сто процентов, система при этом вполне отзывчива.
При запуске всех система начинает серьёзно подтормаживать.

Не знаю насколько процу будет легче если я постоянно буду считывать строку и сверять её с предыдущей, и если изменилась то записывать её в проверочную переменную.
У меня есть подозрения что легче вообще не будет.
Я конечно знаю что если вставить в каждый поток Sleep(100) то это существенно разгрузит систему.
Но мне кажется что это всё лепилово.


Также нужно учитывать что у программы ещё 5 потоков.

Вот по этому я и ищу какой нибудь метод отслеживания без таймеров и бесконечных циклов
ВЕРИТЬ ВО ВНЕЗЕМНЫЕ ЦИВИЛИЗАЦИИ НЕ ОЗНАЧАЕТ ВЕРИТЬ В ИНОПЛАНЕТЯН.
SOA

SOA (статус: Посетитель), 30 января 2013, 00:28 [#16]:

Что значит зацикливается? Поясните по подробней идею.
 Бесконечно применять GetWriteWatch(ну или просто читать строку по указателю)?

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

Не будет ли такая тема подгружать проц, учитывая что иногда их может быть 4(ну вот таких перехватчика)??

Никто не запрещает в теле одного цикла реализовать хоть сто перехватчиков.
QWERYTY

QWERYTY (статус: Посетитель), 30 января 2013, 02:40 [#17]:

насчёт доступа не пойму зачем.

Боюсь не получится сразу сто. Окна появляются не единовременно.
Предпологалось один поток на каждое окно.
Ну тоесть я перехватил функцию CreateWindowEx. И поток будет стартовать при каждом вызове(ну после проверки естественно, что это нужное окно)
Соответственно при закрытии окна поток(за ним следящий) тоже уничтожается.
Фуньку DestroyWindow я тоже перехватил.

Ща пока времени нет, как появится сяду разбираться с SEH.
Если ничё не выйдет то тупое считывание с каким то малым промежутком времени.
ВЕРИТЬ ВО ВНЕЗЕМНЫЕ ЦИВИЛИЗАЦИИ НЕ ОЗНАЧАЕТ ВЕРИТЬ В ИНОПЛАНЕТЯН.

Чтобы оставлять сообщения в мини-форумах, Вы должны авторизироваться на сайте.

Версия движка: 2.6+ (26.01.2011)
Текущее время: 22 февраля 2025, 16:29
Выполнено за 0.03 сек.