nedoPC.org

Community of electronics hobbyists established in 2002

...
Atom Feed | View unanswered posts | View active topics It is currently 28 Jun 2017 06:41



Reply to topic  [ 33 posts ]  Go to page 1, 2, 3  Next
Пропатчить программу на VC++ 
Author Message
Supreme God
User avatar

Joined: 21 Oct 2009 11:08
Posts: 7777
Location: Россия
Reply with quote
Тут у меня проблема возникла, и помню по старым номерам журнала "Хакер",
что решение у неё есть, но вот как это делается - не помню... :(

Ситуация вот какая: предположим, что есть программа вот такого типа:

Image

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

Так вот вопрос вот в чем - есть ли возможность как-то вмешаться в работу программы
в момент вывода результата в окно, перехватить значение, подправить его
своим патчем и вывести либо в это же окно, либо куда-то ещё, если последнее затруднено?



PS. В журналах "Хакер" это, как я помню, решали для окон типа "Пароль", но мне
не это нужно, хотя принцип, как мне кажется, должен быть такой же...

_________________
iLavr


02 Feb 2015 14:13
Profile
Novelist

Joined: 24 Jan 2015 16:56
Posts: 47
Location: 178.172.216.50
Reply with quote
Post 
OllyDbg
но смотрите чтоб переписать не легче было)


02 Feb 2015 17:49
Profile
Supreme God
User avatar

Joined: 21 Oct 2009 11:08
Posts: 7777
Location: Россия
Reply with quote
Post 
awaken wrote:
но смотрите чтоб переписать не легче было)

Да переписать не легче - это я упрощенный пример нашел.

И я суть примерно помню - надо определить хэндлер нужного окна, а потом в SIce найти вызов
с записью в это окно.
После чего вызов заменяется на вызов своей подпрограммы.
Как-то так...
А вот куда в теле (или не в теле, а снаружи) приделать свою подпрограмму - я в упор
не помню.


PS. Посмотрел я, ехе-шник у меня типа PE, и как внедряются в такой файл примерно объясняется вот здесь:
http://2x2is11.blogspot.ru/2010/09/blog-post_13.html
http://www.ht-group.net/23/

_________________
iLavr


02 Feb 2015 19:31
Profile
Supreme God
User avatar

Joined: 21 Oct 2009 11:08
Posts: 7777
Location: Россия
Reply with quote
Post 
Может быть, я выше неудачный абстрактный пример выбрал, но конкретно суть следующая...

Есть вот такой Виндавозный отладчик для микроконтроллера КР1878ВЕ1, работает он довольно-таки
неплохо, все примеры для микроконтроллера я проверяю на нём.

Image

То, что обведено красным контуром в окошках - это состояние портов ввода-вывода А и В.
Так вот хотелось мне вывод в эти окна перехватить и сделать плагин для отладчика с эмуляцией
внешнего устройства, скажем, линейки светодиодов или матрицы их как в MPLAB IDE для PICxx.

Image

Если исправлять содержимое полей портов в этих окнах, то отладчик это воспринимает, как ввод с ВУ.
Можно было бы эмуляцию кнопок прицепить... а то отлаживать, видя лишь циферки, - кисло немного... :-?

_________________
iLavr


12 Feb 2015 22:25
Profile
Maniac

Joined: 05 Nov 2008 22:47
Posts: 228
Location: 81.28.208.238
Reply with quote
Post 
Есть некоторое подозрение, что эти окошки не стандартные для Win,
т.е. информация в них отрисовывается самой программй.
Стандартные окна получают информацию из сообщений, которые можно перехватить.
Вполне возможно при вводе данных в эти окошки, они принимают
стандартные сообщения (нажатие/отжатие кнопок) - туда скорее
всего возможно что-то пихать свое.
... примерно так


13 Feb 2015 05:24
Profile
Supreme God
User avatar

Joined: 21 Oct 2009 11:08
Posts: 7777
Location: Россия
Reply with quote
Post 
aav8 wrote:
Есть некоторое подозрение, что эти окошки не стандартные для Win,
т.е. информация в них отрисовывается самой программй.

Они стандартные - я этот момент проверил, иначе и не пытался бы пробовать эту задачу решить...

aav8 wrote:
Стандартные окна получают информацию из сообщений, которые можно перехватить.

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

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

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

_________________
iLavr


13 Feb 2015 11:08
Profile
Maniac

Joined: 05 Nov 2008 22:47
Posts: 228
Location: 81.28.208.238
Reply with quote
Post 
надо прицепиться к обработчику сообщений окна (но это возможно только из dll).


13 Feb 2015 12:36
Profile
Supreme God
User avatar

Joined: 21 Oct 2009 11:08
Posts: 7777
Location: Россия
Reply with quote
Post 
aav8 wrote:
надо прицепиться к обработчику сообщений окна (но это возможно только из dll).

Ну естественно, это *.dll, и программа, вызываюшая эту *.dll
Quote:
...при старте моя собственная программа вызывает на загрузку
нужную программу и сама садится в трее.

Хотелось бы какой-то понятный пример. А *.dll такого типа я писАть умею...

Вот типичный пример: моя программа EWB32.exe активизирует сам WEWB32.EXE и запускает EWBHook.dll.
В меню EWB добавляется дополнительное меню Resulsts Analysis, при клике на котором, управление передается
моей программе, вычисляющей спектр Фурье.

Image

_________________
iLavr


13 Feb 2015 13:26
Profile
Supreme God
User avatar

Joined: 21 Oct 2009 11:08
Posts: 7777
Location: Россия
Reply with quote
Post 
Я, честно говоря, писал все эти трюки более 5 лет назад и немножко подзабыл всё...

Но вот это - код EWBHook.dll :
Code:
/******************************************************************************/
/*           Ловушка WH_GETMESSAGE на сообщение нашего пункта меню            */
/******************************************************************************/
#include <windows.h>
#include <string.h> // strcat & etc. - символьные функции ---
#include "EWBHook.h"
#pragma argsused
//------------------------------------------------------------------------------
//       Отслеживаем нажатие правой кнопки мыши в трее на нашем значке      ----
//                     и сообщение нашего пункта меню                       ----
//------------------------------------------------------------------------------
#define UP 1
#define DOWN 2

int result;
int iMouseDoun;               //--- Здесь хранится состояние правой кнопки -
int iMouseUp;

HWND hMyWin;
HWND hEWBWin;
MSG* psMessageHook;           //--- Для анализа сообшений от окна ---
MOUSEHOOKSTRUCT* psMouseHook; //--- Для анализа сообшений от мыши ---

//---------------------------------------------------------------------------
//---  соглашение __stdcall означает, что вызываемая функция сама удалит из стека свои аргументы
//---  Ключевое слово __declspec с атрибутом dllexport помечает функцию как экспортируемую,
//---  имя функции добавляется в таблицу экспорта dll.

//---------------------------------------------------------------------------
//------------- Ловушка сообщения - ловим здесь ID нашего menu --------------
LRESULT CALLBACK MessageHook(int nCode,WPARAM wParam,LPARAM lParam)
{
    //
    // Note that CallNextHookEx ignores the first parameter (hhook) so
    // it is acceptable (barely) to pass in a NULL instead (hhook)hgHook.
    //
  if(nCode<0) return CallNextHookEx(NULL,nCode,wParam,lParam);

      psMessageHook=(MSG*)(lParam);
  if((psMessageHook->hwnd)==hEWBWin) //--- если сообщение WEWB32 окна ---
    {
//  PostMessage(hMyWin,WM_USER+2001, -1, (long)psMessageHook->message); //---  test  ---
      if((psMessageHook->message)==WM_COMMAND) //--- если сообщение menu ---
        {
         if((psMessageHook->wParam)==0x00000500) //---  0x00000500 ? ---
           {
           PostMessage(hMyWin,WM_USER+2001, -1,(long)psMessageHook->wParam);
           return CallNextHookEx(NULL,nCode,wParam,lParam);
           }
        }
    }
 return CallNextHookEx(NULL,nCode,wParam,lParam);
}
//---------------------------------------------------------------------------
//----------- Ловушка мыши  -------------------------------------------------
LRESULT CALLBACK MouseHook(int nCode,WPARAM wParam,LPARAM lParam)
{//--- подпрограмма анализа:   message identifier, mouse coordinates;
 if(wParam==WM_RBUTTONDOWN)
   {
   if(!(iMouseDoun==DOWN))
        iMouseDoun=DOWN;
   }
 if(wParam==WM_RBUTTONUP)
   {
   if(iMouseDoun==DOWN)
      iMouseDoun=UP;
      psMouseHook=(MOUSEHOOKSTRUCT*)(lParam);
      //--- отсигналим нашему окну сообщением WM_USER+2000 - что пора!!! ---
      PostMessage(hMyWin,WM_USER+2000, -1,(long)psMouseHook->hwnd);
   }
 return 0;
}

//---------------------------------------------------------------------------
int WINAPI DllEntryPoint(HINSTANCE hinst, unsigned long reason, void* lpReserved)
{
   if(reason==DLL_PROCESS_ATTACH) //---- Проецируем .dll на адр. простр-во ----
   {
     //--- узнаем хэндлер своего стартового окна ---
       hMyWin=FindWindow("HookWndClass","EWBHook");
      hEWBWin=FindWindow("ewb5","Electronics Workbench Professional Edition");
   if(hEWBWin==0) //--- узнаем хэндлер окна WEWB32, если оно есть...
      PostMessage(hMyWin, WM_DESTROY, NULL, NULL); //--- иначе выходим...----
   }
   return 1;
}


Как мне здесь прицепиться к обработчику сообщений окна или перехватить его?


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

_________________
iLavr


13 Feb 2015 22:43
Profile
Maniac

Joined: 05 Nov 2008 22:47
Posts: 228
Location: 81.28.208.238
Reply with quote
Post 
Quote:
Как мне здесь прицепиться к обработчику сообщений окна или перехватить его?

SetWindowLong(GWL_WNDPROC,....)
Вроде примерно так вставляется обработчик сообщений окна


14 Feb 2015 02:21
Profile
Supreme God
User avatar

Joined: 21 Oct 2009 11:08
Posts: 7777
Location: Россия
Reply with quote
Post 
aav8 wrote:
Quote:
Как мне здесь прицепиться к обработчику сообщений окна или перехватить его?

SetWindowLong(GWL_WNDPROC,....)
Вроде примерно так вставляется обработчик сообщений окна

Знаю эту функцию:
Quote:
Функция SetWindowLong
Описание:
function SetWindowLong(Wnd: HWnd; Index: Integer; NewLong: Longint): Longint;

Заменяет для окна атpибут стpуктуpы класса окна новым значением.
Параметры:

Wnd: Идентификатоp окна.
Index: Одна из следующих констант: gwl_ExStyle, gwl_Style, gwl_WndProc или
положительное смещение в байтах для доступа к дополнительным четыpехбайтным
значениям. См. "Смещения поля окна, gwl_" .
NewLong: Значение замены.

Возвpащаемое значение: Пpедыдущее значение.


Но в данном случае что-то я затрудняюсь в её применении, да и в целесообразности.

Раз уж есть *.dll, которая Hook-нула сообщения, видимо, в ней надо отслеживать функцию
SetWindowText с хэндлером искомого окна класса RICHEDIT - я так понимаю... но, возможно,
могу и ошибаться...

_________________
iLavr


14 Feb 2015 09:58
Profile
Supreme God
User avatar

Joined: 21 Oct 2009 11:08
Posts: 7777
Location: Россия
Reply with quote
Post 
Я, конечно, не великий писатель на VC, но эта программа и меня чутка удивила... :o

Впервые встречаю, что у основного окна программы в зависимости от запуска меняется класс...
Code:
Afx:400000:b:1466:6:3cf7
Afx:400000:b:1466:6:3587

Четыре последние цифры при каждом запуске разные... :(
Так что ID окна пришлось искать перебором, сравнивая текст загоровка с текстом "DebugMCT".

Дальше было веселее, не знаю уж как они запускали свои Child windows, но функция GetWindow
с параметром GW_CHILD не находит ни одного CHILD... :lol:

Пришлось искать их через EnumChildWindows...

Ну и теперь - последнее, самое интересное...

Нашел я ID текстового окна класса RICHEDIT, куда выводится содержимое RAM:

Image

А функция GetWindowTextA его текст и не ухватывает! :o

Я аж удивился... проверял же! :o Запускаю обе свои утилиты для таких целей (см.рисунок)
Так одна из них текст окна - выхватывает, а вторая - и нет! :roll:

Видимо вторая тоже юзает GetWindowTextA, как я думал... а вот первая, похоже действует иначе... 8)

Ну и самое что неприятное, это окно класса RICHEDIT вроде поддерживает редакцию
содержимого, но само же отредактировнное и отменяет... :(

_________________
iLavr


16 Feb 2015 07:53
Profile
Supreme God
User avatar

Joined: 21 Oct 2009 11:08
Posts: 7777
Location: Россия
Reply with quote
Post 
Lavr wrote:
Нашел я ID текстового окна класса RICHEDIT, куда выводится содержимое RAM:
http://www.nedopc.org/nedopc/upload/debugMCTPIC.gif
А функция GetWindowTextA его текст и не ухватывает! :o


Shaos, когда ты нам приводишь статистику языков, глядя на нее никогда не поверишь,
что больше всего все программируют на Delphi... :lol:
А вот когда что-то ищешь в Интернете, везде сплошное Delphi... Delphi...
А у них всё в обёртках... :(

Но вспомнил я, как ухватывают текст из RICHEDIT:
Только одну константу я до этого не знал:
Quote:
To get the selected text in a rich edit control, use the EM_GETSELTEXT message. The text is copied
to the specified character array. You must ensure that the array is large enough to hold the selected
text plus a terminating null character.


А так с RICHEDIT общаются через SendMessage(...), используя EM_SETSEL, EM_GETSEL и EM_REPLACESEL.
И я ими вполне успешно пользовался в 2-х проектах, выложенных на форуме, для добавления текста
в конец RICHEDIT.

Но Delphiйцы меня рассмешили:"из RICHEDIT можно скопировать текст лишь через
буфер обмена!
" :o

_________________
iLavr


16 Feb 2015 15:16
Profile
Supreme God
User avatar

Joined: 21 Oct 2009 11:08
Posts: 7777
Location: Россия
Reply with quote
Post 
Первая неприятность... :(
Quote:
GetWindowTextLength не может получить длину текста
поля редактирования текста в другом приложении.


А GetWindowTextLength - это по сути SendMessage(...) с параметром WM_GETTEXTLENGTH...

Остальные SendMessage(...) пока тоже не срабатывают... :(
Похоже, другое приложение им тоже не нравится...

Попробую поиграть с установкой фокуса в интересующее меня окно RAM.



PS. Но внутри DebugMCT они работают с окном RichEdit именно этими командами,
подсмотрел через Microsoft Spy++...


PРS. А вот насчет "фокуса в окне RAM", я, похоже, прав...
Quote:
There are a few issues:
1. From MSDN: The EM_GETSELTEXT message retrieves the currently selected text in a rich edit control.
2. When you click on the button that textbox will loos its focus and therefore currently selected text = ""
.

_________________
iLavr


16 Feb 2015 17:56
Profile
Supreme God
User avatar

Joined: 21 Oct 2009 11:08
Posts: 7777
Location: Россия
Reply with quote
Post 
Ухватил я, наконец, эти данные о портах из окна RAM : 8)

Image

Ну авторы настарались... :(
И окно всех параметров - модальное, отсюда не child по сути, а owner, поэтому искать
его неудобно...
И все окна такого типа - одинаковые по признакам: класс RICHEDIT, и владелец у всех -
модальное окно класса #32770.
Пришлось отличать искомое окно по размеру через GetWindowRect...

Но дальше всё правильно было: SetActiveWindow - активное основное окно,
SendMessage в найденное окно WM_SETFOCUS, после чего SendMessage ему WM_GETTEXT -
в буфер.

Хотел выделить строку и скопировать только её, но авторы еще и запретили копирование
из RICHEDIT-контрола, SendMessage с EM_GETSELTEXT не срабатывает...


Далее - план такой: ID найденного окна передаю *.dll, которая Hook-нет сообщения этому окну,
и как только в окне изменяются значения, я его содержимое - WM_GETTEXT и байты двух портов
разбираю побитно на "зажигание" светодиодов.

_________________
iLavr


17 Feb 2015 08:41
Profile
Display posts from previous:  Sort by  
Reply to topic   [ 33 posts ]  Go to page 1, 2, 3  Next

Who is online

Users browsing this forum: No registered users and 1 guest


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Powered by phpBB® Forum Software © phpBB Group
Designed by ST Software.