first decomp and analysis

This commit is contained in:
Marco 2026-03-25 16:41:55 +01:00
commit 7ac5c0320d
17 changed files with 454 additions and 0 deletions

View file

@ -0,0 +1,234 @@
# Surveillance Client DPI Analysis
Date: 2026-03-25
Target binary: `Surveillance_client.exe`
Analysis method: Ghidra MCP against the already-imported and analyzed program database.
## Objective
Determine how the client initializes its UI, whether it already contains any DPI-awareness logic, and what practical patch points exist for making the application usable on high-resolution displays.
## Executive Summary
- The binary is a Qt Widgets desktop application, and the available imports strongly suggest an older Qt 4-era codebase.
- No direct static use of Windows DPI-awareness APIs was found.
- No obvious embedded DPI manifest strings were found in the loaded program strings.
- The application persists window geometry and display layout state through `QSettings`, including explicit `QRect` geometry records.
- That persistence layer is likely to matter for any DPI patch, because old pixel-based geometry can become incorrect or visually tiny once DPI behavior changes.
## Confirmed Entry Flow
The startup chain currently identified is:
1. `___tmainCRTStartup` at `0x00708d44`
2. `qt_startup_dispatch` at `0x00709b00`
3. `qWinMain` thunk at `0x00709c02`
4. Application main routine at `0x004c7260`
Notes:
- `qt_startup_dispatch` converts `GetCommandLineW()` output into a local 8-bit argv-style buffer and forwards execution into Qt startup.
- This is a useful early patch region if a future binary modification needs to happen before the first top-level window is created.
## Evidence This Is An Older Qt Widgets Application
The import table and strings include multiple indicators that this is not a modern Qt high-DPI-aware build:
- `QApplication`
- `QPlastiqueStyle`
- `QProxyStyle`
- `QStyleOptionViewItemV4`
- `desktop`
- `screenGeometry`
- `availableGeometry`
- `primaryScreen`
Why that matters:
- `QPlastiqueStyle` and `QStyleOptionViewItemV4` are strong Qt 4-era signals.
- A Qt 4-era app is much less likely to support automatic per-monitor DPI scaling cleanly.
- If DPI awareness is turned on without additional UI scaling work, the usual failure mode is a crisp but very small interface.
## What Was Not Found
The following searches did not produce evidence of a built-in DPI implementation:
- `SetProcessDPIAware`
- `SetProcessDpiAwareness`
- `SetThreadDpiAwarenessContext`
- `WM_DPICHANGED`
- `devicePixelRatio`
- `HighDpi`
- `QT_AUTO_SCREEN_SCALE_FACTOR`
- `AA_EnableHighDpiScaling`
I also searched program strings for common manifest content such as:
- `dpiAware`
- `asmv3`
- `requestedExecutionLevel`
- `trustInfo`
None of those were found in the loaded strings.
## Resource Layout
The PE section layout includes a resource section:
- `.rsrc: 0x00dd7000 - 0x00df05ff`
Even with a resource section present, no obvious manifest or DPI-related XML strings surfaced through the Ghidra string search during this pass.
## Settings And Geometry Findings
Several settings-related functions were isolated and renamed in the Ghidra database for future work.
### `init_app_settings_defaults` at `0x0059ca30`
This function initializes many application settings keys and default values.
Relevant confirmed keys:
- `mainwindow/fullscreen`
- `mainwindow/size`
- `window_status`
- `gen/liveviewstatus`
- `gen/autolive`
- `screenAutoSwitch/interval`
- `screenAutoSwitch/forceSync`
- `screenAutoSwitch/isOn`
Relevant confirmed defaults:
- `mainwindow/size = 0x400 x 0x300` which is `1024 x 768`
- `mainwindow/fullscreen = false`
Interpretation:
- The main window has a fixed persisted default size in pixels.
- That is a strong warning sign for DPI patching, because a legacy saved size can remain visually small after changing DPI behavior.
### `load_window_status_from_settings` at `0x005a72b0`
This function reads a `QSettings` array named `window_status` and loads nested UI state.
Confirmed per-window fields:
- `windowGeometry`
- `isCurWindow`
- `isFullScreen`
- `isMainWindow`
- `maxTabIndex`
Confirmed nested view/screen fields:
- `view_status`
- `mainview_status`
- `screenIndex`
- `screenBeginIndex`
- `isScreenEnlarge`
- `autoSwitchInterval`
- `autoSwitchIndependent`
- `autoSwitchIsOn`
- `stream_status`
- `groupChannelID`
- `videoIndex`
- `isCurSelected`
- `isSoundOn`
- `Emap_status`
- `emapIDIndex`
Interpretation:
- The application stores a substantial amount of layout state in settings.
- `windowGeometry` is especially important because it appears to be persisted as a `QRect`.
- If the process DPI mode changes, previously stored geometry may need migration, scaling, deletion, or selective reset.
### `save_window_status_to_settings` at `0x005a6170`
This function writes back the same structures into `QSettings`.
Interpretation:
- Even if a DPI hack works visually at first launch, the application can overwrite the new layout with old pixel-based assumptions on exit.
- Any durable solution should consider both the load and save side of geometry persistence.
### `apply_mainwindow_fullscreen_setting` at `0x0047c1f0`
This function compares a key against `mainwindow/fullscreen` and activates the matching `QAction` when the value is true.
Interpretation:
- The UI state is driven through Qt actions, not direct Win32 window management.
- That reinforces the view that DPI fixes will likely need to be applied at Qt startup or Qt widget/layout level rather than through a narrow Win32 patch alone.
## Implications For A DPI Fix
### Most likely current problem model
Based on the evidence, the binary looks like a legacy Qt Widgets application with no obvious modern DPI-awareness implementation. That creates two realistic scenarios:
1. The process is effectively DPI-unaware and Windows bitmap scaling is not being applied in the way the user wants.
2. The process is being made DPI-aware somewhere outside the obvious static import path, causing the UI to render at legacy pixel sizes and appear tiny.
This analysis did not prove which of those two runtime cases is active on the target system. It did establish that the executable itself does not appear to contain a straightforward built-in high-DPI implementation.
### Why a simple `SetProcessDPIAware` patch is risky
For an older Qt Widgets app:
- enabling DPI awareness alone often produces a sharp but tiny UI
- stored `QRect` geometry may restore undersized windows
- icon sizes, style metrics, and custom-painted controls may remain pixel-based
- there is no evidence yet of `WM_DPICHANGED` handling for per-monitor updates
### What a workable solution will probably require
At minimum, a successful patch likely needs one of these paths:
1. A compatibility-style solution that lets Windows scale the app acceptably.
2. An early startup patch plus application-wide Qt scaling adjustments before top-level widgets are shown.
3. A deeper patch that also normalizes saved geometry and possibly icon/font/style metrics.
## Ghidra Database Changes Made During Analysis
The following functions were renamed in the active program database:
- `0x00709b00` -> `qt_startup_dispatch`
- `0x0059ca30` -> `init_app_settings_defaults`
- `0x005a72b0` -> `load_window_status_from_settings`
- `0x005a6170` -> `save_window_status_to_settings`
- `0x0047c1f0` -> `apply_mainwindow_fullscreen_setting`
Decompiler comments were also added at those entrypoints summarizing their purpose.
## Current Confidence Level
High confidence:
- Qt-based GUI application
- older Qt lineage is likely
- no obvious static DPI-awareness implementation exists
- window geometry persistence is real and important
Medium confidence:
- the best durable fix will require more than a manifest-only change
- geometry migration/reset will likely be necessary for a clean result
Low confidence without runtime testing:
- whether the best final mode is DPI-unaware with OS scaling, system-DPI-aware, or a custom Qt-side scaling patch
## Recommended Direction
Treat this as a legacy-Qt DPI retrofit problem, not just a missing API call problem.
The next pass should focus on:
- locating the `QApplication` construction site inside `0x004c7260`
- locating first top-level window creation/show
- tracing where `windowGeometry` is applied to the main window
- deciding whether to pursue an OS-scaling strategy or a real application-side scaling patch

View file

@ -0,0 +1,152 @@
# Surveillance Client DPI Next Steps
Date: 2026-03-25
## Goal
Find the lowest-risk path to make the legacy client usable on high-resolution monitors without breaking multi-window video layout behavior.
## Recommended Work Plan
### Phase 1: Establish Runtime Baseline
1. Test the current executable under Windows with no compatibility overrides.
2. Test with external manifest variants or compatibility settings that force:
- DPI unaware
- System DPI aware
- Per-monitor aware
3. Capture screenshots and note:
- overall UI size
- text crispness
- icon scaling
- video view scaling
- behavior when moving between monitors with different DPI
Reason:
- This determines whether the practical answer is an OS-scaling solution or a true binary patch.
- For a Qt 4-era application, this experiment can save a lot of unnecessary reverse engineering.
### Phase 2: Finish Startup Mapping In Ghidra
1. Trace `0x004c7260` in more detail until the `QApplication` constructor call is isolated.
2. Identify the first top-level widget or main window constructor.
3. Identify where `show`, `showNormal`, or `showFullScreen` is first invoked for the main UI.
4. Identify where `window_status` data is applied back onto live windows after `load_window_status_from_settings`.
Reason:
- If a binary patch is needed, the ideal injection point is after `QApplication` exists but before the first user-visible window is shown.
### Phase 3: Decide On Patch Strategy
#### Option A: Keep The App DPI-Unaware And Let Windows Scale It
Use this if:
- the UI becomes acceptably sized
- video rendering remains correct
- visual blur is acceptable
Advantages:
- lowest engineering risk
- no need to understand all custom Qt painting and layout code
- least likely to break camera preview surfaces
Risks:
- text and controls may remain blurry
- behavior may vary by Windows version
#### Option B: System-DPI-Aware Patch Plus Geometry Reset/Migration
Use this if:
- the app looks tiny now because it is already treated as DPI aware in some configuration
- Qt scales fonts and base metrics acceptably at startup when system DPI is exposed
Required work:
1. Add or patch early DPI-awareness setup before UI creation.
2. Clear or rescale persisted `windowGeometry` and related layout state.
3. Verify icons, toolbars, tab metrics, and preview panes at 125%, 150%, and 200%.
Risks:
- still no clean per-monitor behavior
- custom pixel-sized controls may remain too small
#### Option C: Application-Side Qt Scaling Retrofit
Use this if:
- Windows scaling is visually unacceptable
- a crisp interface is required
Required work:
1. Patch after `QApplication` creation.
2. Scale fonts globally.
3. Scale icon sizes and style metrics.
4. Scale or invalidate stored `QRect` window geometry.
5. Verify custom widgets and video panes.
Likely implementation ideas:
- patching application font defaults
- patching style pixel metrics through an existing proxy style path
- scaling saved geometry before it is applied
- forcing a first-run reset of `window_status`
Risks:
- highest reverse-engineering effort
- most likely to require multiple iteration cycles
## Specific Reverse-Engineering Targets
The next Ghidra pass should answer these exact questions:
1. Where is `QApplication` constructed?
2. What function creates the main window?
3. Where does the program apply `windowGeometry` from `QSettings`?
4. Are there custom widgets using hardcoded pixel sizes?
5. Are video preview surfaces tied to raw pixel assumptions that could regress under scaling?
## Settings To Watch Closely
These keys are likely to interfere with a DPI patch and should be considered for migration or reset:
- `mainwindow/size`
- `mainwindow/fullscreen`
- `window_status`
- `view_status`
- `mainview_status`
- `screenIndex`
- `screenBeginIndex`
- `isScreenEnlarge`
## Practical Recommendation
Start with a runtime experiment matrix before editing the binary.
If Windows-side scaling already produces acceptable results, stop there.
If it does not, the next best path is:
1. isolate `QApplication` creation
2. isolate main-window show
3. patch startup before show
4. neutralize or migrate persisted geometry
5. validate video panes and multi-monitor layout behavior
## Exit Criteria For A Successful Fix
The fix should only be considered successful if all of the following hold:
1. Main UI is readable at common desktop scales such as 125%, 150%, and 200%.
2. Camera preview panes are not clipped or distorted.
3. Multi-window layouts still restore correctly.
4. Moving the app between monitors does not make it unusably small.
5. Saved geometry does not trap the app in an old tiny layout after restart.