На главную
ПРАВИЛА FAQ Помощь Участники Календарь Избранное RSS
msm.ru
! Правила раздела Visual C++ / MFC / WTL (далее Раздела)
1) На Раздел распространяются все Правила Форума.
2) Перед тем, как создать новый топик, убедитесь, что Вы читали Правила создания тем в Разделе.
3) Вопросы, не связанные с программированием (настройки MS Visual Studio, книги, библиотеки и т.д.),
обсуждаются в разделе C/C++: Прочее
4) Вопросы разработки .NET (Windows Form, C++/CLI и т.п.) приложений на Visual C++/C# обсуждаются в разделе .NET.
5) Нарушение Правил может повлечь наказание со стороны модераторов.

Полезные ссылки:
user posted image FAQ Раздела user posted image Обновления для FAQ Раздела user posted image Поиск по Разделу user posted image MSDN Library Online
Модераторы: ElcnU
  
> MVS: помогите найти место вывода переменной, или какие функции вообще искать
Привет всем!
Есть известная опенсурсная софтина CrystalDiskMark, исходник можно скачать с оф. сайта https://crystalmark.info/redirect.php?produ...stalDiskMarkSrc
Написан в Microsoft Visual Studio без единого комментария. Пока добился того, что исходник у меня на машине компилируется и затем работает. https://cloud.mail.ru/public/KG1n/6DVkZHDoB
Мне нужно забрать результаты теста и передать бекэнду сайта.
Неожиданно для себя не могу найти место, где переменная из переменной превращается в циферку... После всех вычислений должно же быть место где некая переменная с результатом уходит в отображение.
Опыт в с++ околонулевой, в универе пробовал с++ builder и там через форму можно было найти объект гуя и отследить связанные с ним переменные. Тут какого-то конструктора гуя не видно вообще, где переменные уходят в printf или что-то подобное тоже не понятно...
Помогите плз их найти.
Цитата Berbraer @
Неожиданно для себя не могу найти место, где переменная из переменной превращается в циферку... После всех вычислений должно же быть место где некая переменная с результатом уходит в отображение.

Попробуй произвести поиск по всем исходникам строки "sprintf".
Код напичкан CString::Format()-ами. Походу именно так переменные и "превращаются в циферки".
Цитата ЫукпШ @
Попробуй произвести поиск по всем исходникам строки "sprintf".

sprintf и т.п. в исходнике отсутствует (кроме пары мест записи в лог), его я первым делом искал, а других способов вывода данных на экран в си я не знаю.


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

Qraizer, за подсказку CString::Format() спасибо, попробую разобраться что это.
Сообщение отредактировано: Berbraer -
Цитата Qraizer @

Вернулся к задаче после небольшого перерыва, нашёл, что вывод происходит через DDX_Control, нашёл ID индикаторов и сам диалог:

ExpandedWrap disabled
    void CDiskMarkDlg::DoDataExchange(CDataExchange* pDX)
    {
        CMainDialogFx::DoDataExchange(pDX);
     
        DDX_Control(pDX, IDC_BUTTON_ALL, m_ButtonAll);
        DDX_Control(pDX, IDC_BUTTON_TEST_0, m_ButtonTest0);
        DDX_Control(pDX, IDC_BUTTON_TEST_1, m_ButtonTest1);
        DDX_Control(pDX, IDC_BUTTON_TEST_2, m_ButtonTest2);
        DDX_Control(pDX, IDC_BUTTON_TEST_3, m_ButtonTest3);
     
        //вот тут
        DDX_Control(pDX, IDC_TEST_READ_0, m_TestRead0);
        DDX_Control(pDX, IDC_TEST_READ_1, m_TestRead1);
        DDX_Control(pDX, IDC_TEST_READ_2, m_TestRead2);
        DDX_Control(pDX, IDC_TEST_READ_3, m_TestRead3);
     
        DDX_Control(pDX, IDC_TEST_WRITE_0, m_TestWrite0);
        DDX_Control(pDX, IDC_TEST_WRITE_1, m_TestWrite1);
        DDX_Control(pDX, IDC_TEST_WRITE_2, m_TestWrite2);
        DDX_Control(pDX, IDC_TEST_WRITE_3, m_TestWrite3);
     
    #ifdef MIX_MODE
        DDX_Control(pDX, IDC_TEST_MIX_0, m_TestMix0);
        DDX_Control(pDX, IDC_TEST_MIX_1, m_TestMix1);
        DDX_Control(pDX, IDC_TEST_MIX_2, m_TestMix2);
        DDX_Control(pDX, IDC_TEST_MIX_3, m_TestMix3);
        DDX_Control(pDX, IDC_COMBO_MIX, m_ComboMix);
    #endif
     
        DDX_Control(pDX, IDC_COMMENT, m_Comment);
     
        DDX_Control(pDX, IDC_COMBO_COUNT, m_ComboCount);
        DDX_Control(pDX, IDC_COMBO_SIZE, m_ComboSize);
        DDX_Control(pDX, IDC_COMBO_DRIVE, m_ComboDrive);
        DDX_Control(pDX, IDC_COMBO_UNIT, m_ComboUnit);
     
        DDX_Control(pDX, IDC_DEMO_SETTING, m_DemoSetting);
        DDX_Control(pDX, IDC_READ_UNIT, m_ReadUnit);
        DDX_Control(pDX, IDC_WRITE_UNIT, m_WriteUnit);
     
    #ifdef MIX_MODE
        DDX_Control(pDX, IDC_MIX_UNIT, m_MixUnit);
    #endif
     
        DDX_Text(pDX, IDC_COMBO_COUNT, m_ValueTestCount);
        DDX_Text(pDX, IDC_COMBO_SIZE, m_ValueTestSize);
        DDX_Text(pDX, IDC_COMBO_DRIVE, m_ValueTestDrive);
        DDX_Text(pDX, IDC_COMBO_UNIT, m_ValueTestUnit);
        DDX_CBIndex(pDX, IDC_COMBO_COUNT, m_IndexTestCount);
        DDX_CBIndex(pDX, IDC_COMBO_SIZE, m_IndexTestSize);
        DDX_CBIndex(pDX, IDC_COMBO_DRIVE, m_IndexTestDrive);
        DDX_CBIndex(pDX, IDC_COMBO_UNIT, m_IndexTestUnit);
    #ifdef MIX_MODE
        DDX_CBIndex(pDX, IDC_COMBO_MIX, m_IndexTestMix);
    #endif
    }


С утра пытаюсь достать значение m_TestRead. Тестирую на флешке, параметры которой известны. Пытаюсь просто умножить m_TestRead на 2-100, чтобы увидеть изменение цифры на экране ну и понять, что я добрался до непосредственно значения, а не указателя и т.п.
И нифига. Либо заворачивает компилятор, либо компилятор пропускает, но на экране вообще ничего не изменяется...
Обычно вижу это:

ExpandedWrap disabled
    DDX_Control(pDX, IDC_TEST_READ_0, (m_TestRead0*100));
     
    1>F:\!!CrystalDiskMark8_0_2Src\CrystalDiskMark\DiskMarkDlg.cpp(193,50): error C2678: бинарный "*": не найден оператор, принимающий левый операнд типа "CStaticFx" (или приемлемое преобразование отсутствует)
    1>C:\Program Files (x86)\Windows Kits\10\Include\10.0.19041.0\um\d2d1helper.h(1003,1): message : может быть "D2D1_MATRIX_3X2_F operator *(const D2D1_MATRIX_3X2_F &,const D2D1_MATRIX_3X2_F &)" (компилируется исходный файл DiskMarkDlg.cpp)
    1>F:\!!CrystalDiskMark8_0_2Src\CrystalDiskMark\DiskMarkDlg.cpp(193,50): message : при попытке сопоставить список аргументов "(CStaticFx, int)"
    1>F:\!!CrystalDiskMark8_0_2Src\CrystalDiskMark\DiskMarkDlg.cpp(193,51): error C2660: DDX_Control: функция не принимает 2 аргументов
    1>C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.28.29910\atlmfc\include\afxdd_.h(71,13): message : см. объявление "DDX_Control" (компилируется исходный файл DiskMarkDlg.cpp)
    1>Сборка проекта "DiskMark.vcxproj" завершена с ошибкой.
     
     
    -------------------
     
     
    m_TestRead0 *= 10;
     
     
    1>F:\!!CrystalDiskMark8_0_2Src\CrystalDiskMark\DiskMarkDlg.cpp(192,14): error C2676: бинарный "*=": "CStaticFx" не определяет этот оператор или преобразование к типу приемлемо к встроенному оператору
    1>Сборка проекта "DiskMark.vcxproj" завершена с ошибкой.


Раскурил код, насколько позволяют мои два с половиной познания Си. m_TestRead определена классом CStaticFx, этот класс написан автором кода. Но в DDX_Control она передаётся в стандартный класс CWnd, причём, через указатель, насколько понимаю значение символа &.
В итоге, совершенно не понятно, появляется ли тут непосредственно результат вычисления скорости диска, или это некая смычка между классами и всё?...
Я в глубокой растерянности. Как записать значение в лог представляю, собственно, у автора лог ведётся стандартным спринтф емнип. Но как достать переменные, содержащие значения выводимые на экран, не могу разобраться, памагити! :wall:

Вот основыные части кода:

ExpandedWrap disabled
        CStaticFx m_TestRead0;
        CStaticFx m_TestRead1;
        CStaticFx m_TestRead2;
        CStaticFx m_TestRead3;
     
        CStaticFx m_TestWrite0;
        CStaticFx m_TestWrite1;
        CStaticFx m_TestWrite2;
        CStaticFx m_TestWrite3;
     
    //-----------------------------------------------------------------------------
     
    void AFXAPI DDX_Control(CDataExchange* pDX, int nIDC, CWnd& rControl);
     
    //-----------------------------------------------------------------------------
     
    void CDiskMarkDlg::DoDataExchange(CDataExchange* pDX)
    {
        CMainDialogFx::DoDataExchange(pDX);
     
        DDX_Control(pDX, IDC_BUTTON_ALL, m_ButtonAll);
        DDX_Control(pDX, IDC_BUTTON_TEST_0, m_ButtonTest0);
        DDX_Control(pDX, IDC_BUTTON_TEST_1, m_ButtonTest1);
        DDX_Control(pDX, IDC_BUTTON_TEST_2, m_ButtonTest2);
        DDX_Control(pDX, IDC_BUTTON_TEST_3, m_ButtonTest3);
        //m_TestRead0 *= 2;
        DDX_Control(pDX, IDC_TEST_READ_0, (m_TestRead0));
        DDX_Control(pDX, IDC_TEST_READ_1, m_TestRead1);
        DDX_Control(pDX, IDC_TEST_READ_2, m_TestRead2);
        DDX_Control(pDX, IDC_TEST_READ_3, m_TestRead3);
     
        DDX_Control(pDX, IDC_TEST_WRITE_0, m_TestWrite0);
        DDX_Control(pDX, IDC_TEST_WRITE_1, m_TestWrite1);
        DDX_Control(pDX, IDC_TEST_WRITE_2, m_TestWrite2);
        DDX_Control(pDX, IDC_TEST_WRITE_3, m_TestWrite3);
     
    #ifdef MIX_MODE
        DDX_Control(pDX, IDC_TEST_MIX_0, m_TestMix0);
        DDX_Control(pDX, IDC_TEST_MIX_1, m_TestMix1);
        DDX_Control(pDX, IDC_TEST_MIX_2, m_TestMix2);
        DDX_Control(pDX, IDC_TEST_MIX_3, m_TestMix3);
        DDX_Control(pDX, IDC_COMBO_MIX, m_ComboMix);
    #endif
     
        DDX_Control(pDX, IDC_COMMENT, m_Comment);
     
        DDX_Control(pDX, IDC_COMBO_COUNT, m_ComboCount);
        DDX_Control(pDX, IDC_COMBO_SIZE, m_ComboSize);
        DDX_Control(pDX, IDC_COMBO_DRIVE, m_ComboDrive);
        DDX_Control(pDX, IDC_COMBO_UNIT, m_ComboUnit);
     
        DDX_Control(pDX, IDC_DEMO_SETTING, m_DemoSetting);
        DDX_Control(pDX, IDC_READ_UNIT, m_ReadUnit);
        DDX_Control(pDX, IDC_WRITE_UNIT, m_WriteUnit);
     
    #ifdef MIX_MODE
        DDX_Control(pDX, IDC_MIX_UNIT, m_MixUnit);
    #endif
     
        DDX_Text(pDX, IDC_COMBO_COUNT, m_ValueTestCount);
        DDX_Text(pDX, IDC_COMBO_SIZE, m_ValueTestSize);
        DDX_Text(pDX, IDC_COMBO_DRIVE, m_ValueTestDrive);
        DDX_Text(pDX, IDC_COMBO_UNIT, m_ValueTestUnit);
        DDX_CBIndex(pDX, IDC_COMBO_COUNT, m_IndexTestCount);
        DDX_CBIndex(pDX, IDC_COMBO_SIZE, m_IndexTestSize);
        DDX_CBIndex(pDX, IDC_COMBO_DRIVE, m_IndexTestDrive);
        DDX_CBIndex(pDX, IDC_COMBO_UNIT, m_IndexTestUnit);
    #ifdef MIX_MODE
        DDX_CBIndex(pDX, IDC_COMBO_MIX, m_IndexTestMix);
    #endif
    }
     
    //------------------------------------------------------------
     
    class CStaticFx : public CStatic
    {
        DECLARE_DYNAMIC(CStaticFx);
     
    public:
        // Constructors
        CStaticFx();
        virtual ~CStaticFx();
     
        // Control
        BOOL InitControl(int x, int y, int width, int height, double zoomRatio, CDC* bkDC,
            LPCWSTR imagePath, int imageCount, DWORD textAlign, int renderMode, BOOL bHighContrast, BOOL bDarkMode);
        void SetMargin(int top, int left, int bottom, int right, double zoomRatio);
        CSize GetSize(void);
        void SetDrawFrame(BOOL bDrawFrame);
        void SetDrawFrameEx(BOOL bDrawFrame, COLORREF frameColor = RGB(128, 128, 128));
        void SetGlassColor(COLORREF glassColor, BYTE glassAlpha);
        void SetMeter(BOOL bMeter, double meterRatio);
        void SetLabelUnit(CString label, CString unit);
     
        // Font
        void SetFontEx(CString face, int size, int sizeToolTip, double zoomRatio, double fontRatio = 1.0,
             COLORREF textColor = RGB(0, 0, 0), LONG fontWeight = FW_NORMAL, BYTE fontRender = CLEARTYPE_NATURAL_QUALITY);
     
        // ToolTip
        void SetToolTipText(LPCTSTR pText);
        void SetToolTipActivate(BOOL bActivate = TRUE);
        void SetToolTipWindowText(LPCTSTR pText);
        CString GetToolTipText();
     
        // Mouse
        void SetHandCursor(BOOL bHandCuror = TRUE);
     
    protected:
        // Draw Control
        virtual void DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct);
        virtual void DrawControl(CDC* drawDC, LPDRAWITEMSTRUCT lpDrawItemStruct, CBitmap& ctrlBitmap, CBitmap& bkBitmap, int no);
        virtual void DrawString(CDC* drawDC, LPDRAWITEMSTRUCT lpDrawItemStruct);
     
        // Image
        BOOL LoadBitmap(LPCTSTR fileName);
        BOOL LoadBitmap(HBITMAP hBitmap);
        void SetBkReload(void);
        BOOL SetBitmap(CBitmap& bitmap);
        void LoadCtrlBk(CDC* drawDC);
     
        // ToolTip
        void InitToolTip();
        virtual BOOL PreTranslateMessage(MSG* pMsg);
     
        // Message Map
        DECLARE_MESSAGE_MAP()
        afx_msg BOOL OnEraseBkgnd(CDC* pDC);
        afx_msg void OnMouseMove(UINT nFlags, CPoint point);
        afx_msg void OnMouseHover(UINT nFlags, CPoint point);
        afx_msg void OnMouseLeave();
        afx_msg void OnKillfocus();
        afx_msg void OnSetfocus();
        afx_msg BOOL OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message);
     
    protected:
        // Control
        int m_X;
        int m_Y;
        CSize m_CtrlSize;
        CRect m_Margin;
        int m_RenderMode;
        BOOL m_bHighContrast;
        BOOL m_bDarkMode;
        BOOL m_bDrawFrame;
        COLORREF m_FrameColor;
     
        CString m_Label;
        CString m_Unit;
     
        // Glass
        COLORREF m_GlassColor;
        BYTE m_GlassAlpha;
     
        // Meter
        BOOL m_bMeter;
        double m_MeterRatio;
     
        // Image
        CString m_ImagePath;
        int m_ImageCount;
        CDC* m_BkDC;
        CBitmap m_BkBitmap;
        BOOL m_bBkBitmapInit;
        BOOL m_bBkLoad;
        CBitmap m_CtrlBitmap;
        CImage m_CtrlImage;
     
        // Font
        DWORD m_TextAlign;
        CFont m_Font;
        CFont m_FontToolTip;
        COLORREF m_TextColor;
     
        // ToolTip
        CToolTipCtrl m_ToolTip;
        CString m_ToolTipText;
     
        // Mouse
        BOOL m_bHover;
        BOOL m_bFocas;
        BOOL m_bTrackingNow;
        BOOL m_bHandCursor;
    };
Цитата Berbraer @
Но как достать переменные, содержащие значения выводимые на экран, не могу разобраться, памагити! :wall:

Надо исследовать подсудимую программу.
я делаю так:
1. Скачаем программу DebugView с сайта Микрософт:
DebugView
2. Запустим прогу, увидим окошко.
3. Добавим модуль с таким текстом в твою программу (или спрячем модуль в библиотеку):
ExpandedWrap disabled
    void Type_Debug_String(const TCHAR* pFmt,...)
    {
     if(!pFmt) return;
     va_list ap;        //Указатель на список параметров
     va_start(ap,pFmt); //Настроились на список параметров
     TCHAR sss[32768];
     _vsntprintf_s(sss,ARRAYSIZE(sss),_TRUNCATE,pFmt,ap);
     ::OutputDebugString(sss);
     va_end(ap); //Завершаем работу с макрокомандами
    }

4. Если в исходниках исследуемой программы захочется подсмотреть,
как менются некие переменные (в разных точках программы в процессе работы)
просто пишем вывод в стиле С:
ExpandedWrap disabled
    // если i - это int i, d - это double d
     Type_Debug_String(_T("i=%d i=0x%X d=%e"),i,i,d);

В окошке DebugView увидим выводимые строчки.
итп итд
-----
Что касается всего исследования - у тебя есть подсказка.
Объекты-строки содержат операцию "Format".
Именно посредством этой операции, возможно, численные значения преобразуются
в строку для последующего вывода в контрол.
Значит, надо искать среди этих объектов-строк -
какой из них содержит интересующую переменную.
Добравшись до этого объекта можно искать дальше всю логику и историю
вычислений/изменений/преобразований конкретной переменной.
Сообщение отредактировано: ЫукпШ -
Ок, поищу форматы. Но m_TestWrite и иже там не встречается точно. Придётся идти шагами...
Но в строке DDX_Control(pDX, IDC_TEST_READ_0, m_TestRead0); переменная m_TestRead0 - строковая?
А можно её из строки прям тут взад в бинарную преобразовать?
Ну, кроме ручного метода вычитания 0x30 из символов, домножения на степень 10 и сложения :D
Цитата Berbraer @
Ок, поищу форматы. Но m_TestWrite и иже там не встречается точно.

Берем TotalCommander.
Начинаем поиск в директории с zip-ом исходников.
Указываем "все файлы", "ищем в архивах",
строка "m_TestWrite".
Обнаруживаем её тут:
user posted image
Смотрим файлы, и видим, что m_TestWrite - это объекты-статики:
ExpandedWrap disabled
        CStaticFx m_TestWrite0;
        CStaticFx m_TestWrite1;
        CStaticFx m_TestWrite2;
        CStaticFx m_TestWrite3;

T.е., по всей вероятности, это "станция конечная" для всех переменных.
Значение как-то добывается, считается. Далее преобразуется в строку,
а потом для отображения выводится в статик.
Переменную надо нежно брать за хобот в момент перед преобразованием
в строку. Именно в этой точке имеется готовое к выводу число.
Сообщение отредактировано: ЫукпШ -
Berbraer, почему бы тебе просто не сказать, какого результата ото всех своих усилий тебе хочется достичь?
M
Тема перенесена из C/C++ => C/C++: Общие вопросы
Сообщение будет удалено через 1 дн.
1 пользователей читают эту тему (1 гостей и 0 скрытых пользователей)
0 пользователей:


Рейтинг@Mail.ru
[ Script execution time: 0,0417 ]   [ 20 queries used ]   [ Generated: 12.06.21, 12:16 GMT ]