Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Delphi: WinAPI и системное программирование > Достать текст из Label чужого приложения


Автор: Prospekt 23.12.2012, 13:31
Собственно вопрос озвучен, есть приложение, и у него есть несколько Label-ов. Как получить текс с них? Принимаются к рассмотрению любые извращения.

Идентицифировать (различать) Label-ы можно, например, зная или их Id (index) или их расположение.

Темы: 
http://forum.vingrad.ru/topic-94012.html#st_15_view_0
http://forum.vingrad.ru/topic-186181.html
прочитаны, задача пока актуальна.

Мне нужно именно считать текст, а не изменять.

Автор: Illusion Dolphin 23.12.2012, 18:13
TLabel - графический котрол, своего окна не имеет и данные хранит по какому-то адресу в памяти, искать его я бы не стал. 

Имхо тут поможет только OCR ( http://stackoverflow.com/questions/4043876/delphi-ocr-what-libabry-should-i-use )

Автор: Prospekt 23.12.2012, 18:32
Это было первое, что пришло мне в голову. Но почему-то кажется, что это не оптимальное решение, что найти этот самый Label всеже будет проще.
Ещё предложения?

Автор: Illusion Dolphin 23.12.2012, 18:55
Цитата

 что найти этот самый Label всеже будет

Удачи! 

Автор: northener 23.12.2012, 18:56
Цитата(Prospekt @  23.12.2012,  18:32 Найти цитируемый пост)
что найти этот самый Label всеже будет проще

Если этот самый Label это TLabel, то его нельзя "найти".

Автор: bems 23.12.2012, 19:47
попробуй перехватить api отрисовки текста, и вычислить нужную строку по хендлу окна-родителя TLabel и координатам в нём

Автор: Prospekt 23.12.2012, 21:01
Цитата

попробуй перехватить api отрисовки текста, и вычислить нужную строку по хендлу окна-родителя TLabel и координатам в нём 

А можно пример. Каким образом можно перехватить?

Автор: Ne1tr1n0 23.12.2012, 21:28
http://forum.sources.ru/index.php?showtopic=228888&st=0&#entry1907635

Автор: northener 24.12.2012, 00:11
Цитата(Prospekt @  23.12.2012,  13:31 Найти цитируемый пост)
есть приложение, и у него есть несколько Label-ов. Как получить текс с них?

Кстати сначала стоит убедиться, что это именно Label-ы. Вполне вероятно, что это стандартные Windows контролы STATIC TEXT. И хуки никакие не нужны будут.

Автор: bems 24.12.2012, 07:29
Цитата(Prospekt @  23.12.2012,  21:01 Найти цитируемый пост)
А можно пример. Каким образом можно перехватить? 

загугли "перехват api"

Автор: Prospekt 24.12.2012, 08:32
Цитата

Кстати сначала стоит убедиться, что это именно Label-ы. Вполне вероятно, что это стандартные Windows контролы STATIC TEXT. И хуки никакие не нужны будут. 


Процентов 95, что стандартные лейбы, текст изменяется при работе программы, а как я понимаю static text - это неизменяемый текст. Да и смысла городить там что-то другое нет.

Ne1tr1n0, я не разобрался. Я конечно погуглю отлавливание api, но если не сложно объясните словами, как это возможно впринципе. Залесть в цикл обработки сообщений своей программы это понятно, а вот чужой, без декомпиляции и исходного кода. Объясните идиологию такого подхода. Пока у меня непонимание и на тактическом уровне и на стратегическом.

Автор: Illusion Dolphin 24.12.2012, 09:49
Цитата

объясните словами, как это возможно впринципе.

Допустим имеется сторонняя программа, работающая от лица пользователя (ring3). 
Мы пишем программу, которая делает:
1) Запускает необходимую нам программу (для Vista, Win7, 8 - в режиме SUSPENDED, с XP тут проблемы)
2) С помощью CreateRemoteThread создаём в этой программе поток, который загружает нами написанную dll в адресное пространство программы
3) Эта длл должна просмотреть секцию импорта exe-файла и найти там выховы системных функций, в данном случае DrawTextA и DrawTextW
4) Адреса функций перезаписываются нашими функциями, которые будут принимать данные, обрабатывать и по желанию - запускать оригинальные функции
5) Профит

Трудность, с которой придётся столкнуться: нет ни одного толкового примера в интернете, работающего в XP-Win8, тем более с учётом x64, так что если надо универсальность - придётся попотеть.

Автор: Prospekt 24.12.2012, 10:44
Спасибо всем за помощь.
Вопрос снимается, прогулгил тему. Как бы так сказать, меня отталкивает даже не то, что это сложновато (для меня пока сложно), а некрасивость решения, менять чужую прогу хоть и на время, пусть и динамически - это не то.
Лучше уж действительно считывать изображение и собирать таким образом информацию, тем более что шрифт постоянен и известен, как и цвет. Плюс в большинстве случаев значением является число, проще будет по семплам разбирать картинку.

Автор: bems 24.12.2012, 10:47
Цитата(Illusion Dolphin @  24.12.2012,  09:49 Найти цитируемый пост)
Запускает необходимую нам программу (для Vista, Win7, 8 - в режиме SUSPENDED, с XP тут проблемы)
какие проблемы?

Автор: Illusion Dolphin 24.12.2012, 11:35
Проблема только для XP, делается:
CreateProcess с флагом CREATE_SUSPENDED
CreateRemoteThread
WaitForSingleObject (созданный поток)
ResumeThread (оригинальный поток приложения).
В результате имеем что программа завершает работу :( Читал форумы, люди на это наталкиваются: 
http://stackoverflow.com/questions/9695370/is-the-first-thread-that-gets-to-run-inside-a-win32-process-the-primary-thread
http://www.wasm.ru/forum/viewtopic.php?pid=308079 
http://www.gamedeception.net/threads/17964-CreateRemoteThread-CREATE_SUSPENDED-managed-process-what-the-fuck
http://bugtraq.ru/cgi-bin/forum.mcgi?type=sb&b=6&m=143610
http://forum.sources.ru/index.php?showtopic=266627 тут тоже проблемы у людей

Кто-то пишет что в XP странный загрузчик и если запускать с CREATE_SUSPENDED, то exe ещё недоинициализирован, что исправили в поздних виндах. Но если есть идеи - я могу создать отдельную ветку для обсуждения. 

Автор: Rrader 24.12.2012, 11:38
Можно через RTTI вытащить текст с TLabel. Нужно знать только имя меток в коде (типа Label1, Label2 и т.п.)

Автор: bems 24.12.2012, 12:17
Illusion Dolphin, угу, вижу. Странно что у меня это когда-то нормально работало под ХР

Автор: Чучмек 24.12.2012, 12:20
Цитата(Illusion Dolphin @  24.12.2012,  11:35 Найти цитируемый пост)
Проблема только для XP

Могу скинуть готовую программу для внедрения dll. Писал для себя. Могу и исходник поискать.

Автор: bems 24.12.2012, 12:24
Чучмек, скажи на словах как ты решаешь эту проблему

Автор: northener 24.12.2012, 12:40
Цитата(Prospekt @  24.12.2012,  08:32 Найти цитируемый пост)
Процентов 95, что стандартные лейбы, текст изменяется при работе программы, а как я понимаю static text - это неизменяемый текст. Да и смысла городить там что-то другое нет.

Стандартный лейбл для Windows это именно STATIC. А TLabel это порождение Борланда.

Автор: Prospekt 24.12.2012, 13:09
Думаю, имеет смысл "добить тему", вопрос не такой уж и редкий, кому-то пригодится. Возможно когда-нибудь даже мне.
Хотя в моем случае ОС не важна, у меня есть возможность выбора.

Так стоп, Rrader, а можно сделать не зная имен? Можно получить ВЕСЬ СПИСОК и потом из него выколупывать нужное? Можно как-нибудь перебором выявить ИМЕНА этих Label?
Т.е. поступить так:
1) долго и очень догло колупаться и узнать имена нужных меток.
2) работать с уже найденными именами.

northener, хорошо, будем надеятся, что ты прав. Как узнать Static или TLabel? Какие от меня действия? Рекурентное сканирование всего ФРЕЙМА нашло все элементы, за исключением надписей. Самый плохой варинат, если они рисуются программно "ручками", но обычно так не делают. Значит либо Static либо TLabel. Во всяком случае это что-то не являющееся окном, иначе я бы его нашел.

Автор: bems 24.12.2012, 13:35
Цитата(Prospekt @  24.12.2012,  13:09 Найти цитируемый пост)
Можно как-нибудь перебором выявить ИМЕНА этих Label?

открой экзешник редактором ресурсов с поддержкой dfm-ресурсов дельфи и посмотри там. Хотя есть вероятность что это label создаётся динамически

Автор: Чучмек 24.12.2012, 20:07
Цитата(bems @  24.12.2012,  12:24 Найти цитируемый пост)
Чучмек, скажи на словах как ты решаешь эту проблему 

Проблема??? Да не встречал. Проблема в том, что не всякую dll можно внедрять.  Из-за недоинициализации приложения на момент загрузки нашей dll не все api можно вызывать.
p.s. я другим путем пошел,наверное. createprocess-VirtualAllocEx-readprocessmemory/writeprocessmemory-ResumeThread

Добавлено @ 20:15
Цитата(Illusion Dolphin @  24.12.2012,  11:35 Найти цитируемый пост)
Но если есть идеи - я могу создать отдельную ветку для обсуждения.  

Присоединяюсь. Перехват+Внедрение

Автор: Illusion Dolphin 24.12.2012, 22:48
Цитата

Присоединяюсь. Перехват+Внедрение

http://forum.vingrad.ru/forum/topic-360472/kw-createprocess-create-suspended-createremotethread-resumethread.html

Автор: northener 25.12.2012, 00:40
Цитата(Prospekt @  24.12.2012,  13:09 Найти цитируемый пост)
northener, хорошо, будем надеятся, что ты прав. Как узнать Static или TLabel? Какие от меня действия? Рекурентное сканирование всего ФРЕЙМА нашло все элементы, за исключением надписей. Самый плохой варинат, если они рисуются программно "ручками", но обычно так не делают. Значит либо Static либо TLabel. Во всяком случае это что-то не являющееся окном, иначе я бы его нашел.

Ну если рекурсивный поиск окон был выполнен правильно и не нашел окон с таким текстом, то да это либо TLabel (если сторонняя программа сделана на Дельфи или на Билдере), либо "непомню как называется" (если сторонняя программа сделана на VB). Или это просто надписи выводимые ручками (неважно на чем сделана программа). И это точно не STATIC! Ибо статик это окно. Таким образом единственно надежный способ прочитать эти надписи программно - перехват API функций ответственных за вывод текста.

Автор: Delvish 26.12.2012, 09:50
а если действовать сродни какому-нибудь редактору ресурсов? например, Resource  Hacker разбирает Делфевое приложение по косточкам, прекрасно показывая где какой лэйбл лежит. Т.е. можно бы наверное комбинировать поиск нужной координаты текста с чтением непосредственно из экзешника зашитой инфы

Код

object Form1: TForm1
  Left = 192
  Top = 124
  Width = 252
  Height = 182
  Caption = 'Form1 caption'
  Color = clBtnFace
  Font.Charset = DEFAULT_CHARSET
  Font.Color = clWindowText
  Font.Height = -11
  Font.Name = 'MS Sans Serif'
  Font.Style = []
  OldCreateOrder = False
  PixelsPerInch = 96
  TextHeight = 13
  object Label1: TLabel
    Left = 16
    Top = 8
    Width = 71
    Height = 13
    Caption = 'Label1isThere'
  end
  object Label2: TLabel
    Left = 16
    Top = 32
    Width = 105
    Height = 13
    Caption = 'ThereIsLabelNumber2'
  end
  object Label3: TLabel
    Left = 24
    Top = 64
    Width = 24
    Height = 13
    Caption = 'Third'
  end
end

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)