Add detailed analysis and documentation for RSNet.dll download functionality
- Introduced a comprehensive markdown document outlining the API surface of RSNet.dll related to downloading video files. - Documented initialization, connection, record querying, and download processes. - Provided insights into the exported functions, their parameters, and expected behaviors. - Included practical implications and recommendations for implementing a downloader script using C# interop. - Highlighted the necessary struct layouts and callback mechanisms for effective integration with the DLL.
This commit is contained in:
parent
0272c5ac3a
commit
de077ca5d5
34 changed files with 2084 additions and 152 deletions
|
|
@ -1,234 +1,389 @@
|
|||
# Surveillance Client DPI Analysis
|
||||
# Surveillance Client Server And Recorded Video Download Analysis
|
||||
|
||||
Date: 2026-03-25
|
||||
Date: 2026-04-17
|
||||
|
||||
Target binary: `Surveillance_client.exe`
|
||||
|
||||
Analysis method: Ghidra MCP against the already-imported and analyzed program database.
|
||||
Analysis method: Ghidra MCP against the already-open executable, with non-destructive analysis only. During this pass, allowed writes were limited to function renames and comments.
|
||||
|
||||
## 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.
|
||||
Determine how the client connects to remote devices and how it searches for and downloads recorded video, with the practical goal of building a small standalone downloader that can fetch an arbitrary duration from an arbitrary camera.
|
||||
|
||||
## 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.
|
||||
- The EXE is mostly UI, orchestration, and request-shaping code.
|
||||
- The real connection, record-query, playback-control, and download logic is implemented in `RSNET.DLL`.
|
||||
- Local playback and file rendering are implemented in `RSPLAY.DLL`.
|
||||
- The EXE contains a clear playback/download workflow that prepares request structures and hands them to `RSNET.DLL` exports.
|
||||
- The current executable analysis is enough to map the high-level flow and the parameter shapes, but not enough to recover the on-the-wire protocol. For that, `RSNet.dll` needs to be loaded into Ghidra next.
|
||||
|
||||
## Confirmed Entry Flow
|
||||
## Installed Module Layout
|
||||
|
||||
The startup chain currently identified is:
|
||||
The installed client directory contains the key vendor modules:
|
||||
|
||||
1. `___tmainCRTStartup` at `0x00708d44`
|
||||
2. `qt_startup_dispatch` at `0x00709b00`
|
||||
3. `qWinMain` thunk at `0x00709c02`
|
||||
4. Application main routine at `0x004c7260`
|
||||
- `RSNet.dll`
|
||||
- `RSPlay.dll`
|
||||
- `QRSosAdapter.dll`
|
||||
- `QtNetwork4.dll`
|
||||
|
||||
Notes:
|
||||
This matches the import thunks present in the EXE.
|
||||
|
||||
- `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.
|
||||
## Confirmed DLL Boundary
|
||||
|
||||
## Evidence This Is An Older Qt Widgets Application
|
||||
The following named functions in the EXE are import thunks, not native implementations:
|
||||
|
||||
The import table and strings include multiple indicators that this is not a modern Qt high-DPI-aware build:
|
||||
- `RSNetQueryParam` at `0x006e96f0`
|
||||
- `RSNetQueryParamEx` at `0x006e9720`
|
||||
- `RSNetAlarmSubscribe` at `0x006e99a0`
|
||||
- `RSPlayGetPlayFileTimeRange` at `0x006ea760`
|
||||
|
||||
- `QApplication`
|
||||
- `QPlastiqueStyle`
|
||||
- `QProxyStyle`
|
||||
- `QStyleOptionViewItemV4`
|
||||
- `desktop`
|
||||
- `screenGeometry`
|
||||
- `availableGeometry`
|
||||
- `primaryScreen`
|
||||
Example:
|
||||
|
||||
Why that matters:
|
||||
- `RSNetQueryParam` is just `JMP dword ptr [0x0076e648]`
|
||||
|
||||
- `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.
|
||||
External symbol resolution in the loaded EXE confirms these libraries and exports:
|
||||
|
||||
## What Was Not Found
|
||||
### `RSNET.DLL`
|
||||
|
||||
The following searches did not produce evidence of a built-in DPI implementation:
|
||||
Relevant exports confirmed in the import table:
|
||||
|
||||
- `SetProcessDPIAware`
|
||||
- `SetProcessDpiAwareness`
|
||||
- `SetThreadDpiAwarenessContext`
|
||||
- `WM_DPICHANGED`
|
||||
- `devicePixelRatio`
|
||||
- `HighDpi`
|
||||
- `QT_AUTO_SCREEN_SCALE_FACTOR`
|
||||
- `AA_EnableHighDpiScaling`
|
||||
- `RSNetConnectionStart`
|
||||
- `RSNetConnectionStartEx`
|
||||
- `RSNetQueryRecordEx`
|
||||
- `RSNetStartRecordPlayEx`
|
||||
- `RSNetReqRecordPlayCtrol`
|
||||
- `RSNetStartDownloadRecord`
|
||||
- `RSNetStartDownloadRecordEx`
|
||||
- `RSNetStopDownloadRecord`
|
||||
- `RSNetReqRecordData`
|
||||
- `RSNetStopRecordPlay`
|
||||
- `RSNetReplayRecordData`
|
||||
- `RSNetReposRecordData`
|
||||
- `RSNetGetDevInfo`
|
||||
- `RSNetSearchDev`
|
||||
|
||||
I also searched program strings for common manifest content such as:
|
||||
### `RSPLAY.DLL`
|
||||
|
||||
- `dpiAware`
|
||||
- `asmv3`
|
||||
- `requestedExecutionLevel`
|
||||
- `trustInfo`
|
||||
Relevant playback exports confirmed in the import table:
|
||||
|
||||
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`
|
||||
- `RSPlayCreatePlayInstance`
|
||||
- `RSPlaySetPlayWnd`
|
||||
- `RSPlayStartPlay`
|
||||
- `RSPlaySetCallbackMessageEx`
|
||||
- `RSPlayImageCallback`
|
||||
- `RSPlayOpenPlayFile`
|
||||
- `RSPlayOpenPlayFileListEx`
|
||||
- `RSPlayGetPlayFileTimeRange`
|
||||
- `RSPlaySetCurPlayedTimeEx`
|
||||
- `RSPlayInputNetFrame`
|
||||
- `RSPlayStartlocalrecord`
|
||||
- `RSPlayStoplocalrecord`
|
||||
|
||||
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.
|
||||
- `RSNET.DLL` is the module that matters for device login, remote record queries, remote playback, and remote download.
|
||||
- `RSPLAY.DLL` is mostly decode/render/local playback support, not the primary network protocol implementation.
|
||||
|
||||
### `load_window_status_from_settings` at `0x005a72b0`
|
||||
## Confirmed EXE-Side Flow
|
||||
|
||||
This function reads a `QSettings` array named `window_status` and loads nested UI state.
|
||||
### UI widgets involved
|
||||
|
||||
Confirmed per-window fields:
|
||||
The strings and handlers in the EXE show a playback and file-download workflow:
|
||||
|
||||
- `windowGeometry`
|
||||
- `isCurWindow`
|
||||
- `isFullScreen`
|
||||
- `isMainWindow`
|
||||
- `maxTabIndex`
|
||||
- `Widget_Playback`
|
||||
- `Widget_Playback_FileDownload`
|
||||
- `Download By Date`
|
||||
- `Download By Files`
|
||||
- `DownLoad Start Time`
|
||||
- `MainStream`
|
||||
- `SubStream`
|
||||
- `playback-download`
|
||||
- `QRSAdapterReqRecordPlayCtrol`
|
||||
|
||||
Confirmed nested view/screen fields:
|
||||
Relevant strings also show signals/slots for:
|
||||
|
||||
- `view_status`
|
||||
- `mainview_status`
|
||||
- `screenIndex`
|
||||
- `screenBeginIndex`
|
||||
- `isScreenEnlarge`
|
||||
- `autoSwitchInterval`
|
||||
- `autoSwitchIndependent`
|
||||
- `autoSwitchIsOn`
|
||||
- `stream_status`
|
||||
- `groupChannelID`
|
||||
- `videoIndex`
|
||||
- `isCurSelected`
|
||||
- `isSoundOn`
|
||||
- `Emap_status`
|
||||
- `emapIDIndex`
|
||||
- `searchRequest(QString)`
|
||||
- `playbackResponse()`
|
||||
- `fileDownload()`
|
||||
- `download()`
|
||||
- `stopdownload()`
|
||||
|
||||
### Functions renamed during analysis
|
||||
|
||||
The following EXE functions were renamed in the Ghidra database:
|
||||
|
||||
- `0x004a9690` -> `PlaybackFileDownloadWidget_connectSignals`
|
||||
- `0x0049f570` -> `RecordPlaybackControl_toggleMode`
|
||||
- `0x004afb30` -> `PlaybackFileDownloadWidget_download`
|
||||
- `0x004b1be0` -> `PlaybackFileDownloadWidget_downloadByTime`
|
||||
|
||||
These names reflect verified behavior from decompilation.
|
||||
|
||||
## What The Download UI Does
|
||||
|
||||
### `PlaybackFileDownloadWidget_connectSignals`
|
||||
|
||||
This function wires the file-download UI:
|
||||
|
||||
- download button -> `download()`
|
||||
- stop button -> `stopdownload()`
|
||||
- cancel button -> `cancel()`
|
||||
- date/time selector changes -> `GetFileNumAndSize(QDateTime)`
|
||||
|
||||
That establishes the UI entrypoint cleanly.
|
||||
|
||||
### `PlaybackFileDownloadWidget_download`
|
||||
|
||||
This is the main dispatcher for the download dialog.
|
||||
|
||||
It has two modes:
|
||||
|
||||
1. File-based download mode
|
||||
2. Time-range download mode
|
||||
|
||||
In file-based mode it:
|
||||
|
||||
- iterates rows in the record table
|
||||
- checks selected rows
|
||||
- tracks row state in a per-row metadata structure
|
||||
- starts a timer to process queued download items
|
||||
|
||||
In time-range mode it:
|
||||
|
||||
- reads the selected start and end `QDateTime` values from the UI
|
||||
- iterates available remote record segments
|
||||
- compares the requested interval against each segment
|
||||
- computes overlap windows
|
||||
- schedules one or more download requests accordingly
|
||||
|
||||
The function logs several debug markers:
|
||||
|
||||
- `DownloadByTime 111111111111111111`
|
||||
- `DownloadByTime 222222222222222222`
|
||||
- `DownloadByTime 33333333333333333333`
|
||||
- `DownloadByTime 444444444444444444444`
|
||||
|
||||
Those correspond to different interval-overlap cases between the selected range and a returned recording segment.
|
||||
|
||||
### `PlaybackFileDownloadWidget_downloadByTime`
|
||||
|
||||
This function handles the actual by-time iteration across remote record segments.
|
||||
|
||||
It reconstructs begin/end timestamps from record metadata, converts them to `QDateTime`, compares them against the user-selected range, then dispatches a lower-level download request for the relevant slice.
|
||||
|
||||
The logic strongly suggests the client does not ask the device for an arbitrary time range in one step unless the selected window aligns with a single record segment. Instead, it walks matching segments and issues one or more segment-bounded download requests.
|
||||
|
||||
Implication for a standalone tool:
|
||||
|
||||
- arbitrary time-range download likely requires:
|
||||
- querying the device for record segments first
|
||||
- intersecting those with the requested interval
|
||||
- issuing one or more download requests
|
||||
- stitching or sequencing the resulting data if needed
|
||||
|
||||
## EXE-Side RSNET Wrapper Layer
|
||||
|
||||
The EXE contains thin wrappers around the `RSNET.DLL` APIs. These wrappers are useful because they reveal request structure shapes and callback wiring even though the real protocol lives in the DLL.
|
||||
|
||||
### Connection wrapper
|
||||
|
||||
`FUN_006eaf70`
|
||||
|
||||
Behavior:
|
||||
|
||||
- copies fields from a caller-supplied struct into a local 0x38-byte request block
|
||||
- stores two callback/context values into the owning object
|
||||
- calls `RSNetConnectionStartEx(&local_38)`
|
||||
|
||||
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.
|
||||
- connection/login is performed through `RSNetConnectionStartEx`
|
||||
- the caller passes a structured login/connect request, not loose scalar parameters
|
||||
- the request likely includes address or P2P information, credentials, and callback context
|
||||
|
||||
### `save_window_status_to_settings` at `0x005a6170`
|
||||
### Remote record query wrapper
|
||||
|
||||
This function writes back the same structures into `QSettings`.
|
||||
`FUN_006eb6f0`
|
||||
|
||||
Behavior:
|
||||
|
||||
- allocates a small 8-byte helper object from fields `param_2[0x12]` and `param_2[0x11]`
|
||||
- copies roughly 0x60 bytes of request data into a local buffer
|
||||
- assigns completion callbacks
|
||||
- calls `RSNetQueryRecordEx(handle, &local_64)`
|
||||
|
||||
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.
|
||||
- remote record search is performed with `RSNetQueryRecordEx`
|
||||
- the query request is non-trivial and includes multiple fields beyond just channel and time
|
||||
- two tail fields are treated specially and likely represent callback target/context or an auxiliary selection object
|
||||
|
||||
### `apply_mainwindow_fullscreen_setting` at `0x0047c1f0`
|
||||
### Remote playback wrapper
|
||||
|
||||
This function compares a key against `mainwindow/fullscreen` and activates the matching `QAction` when the value is true.
|
||||
`FUN_006e9e00`
|
||||
|
||||
Behavior:
|
||||
|
||||
- creates an `RSPlay` instance via `RSPlayCreatePlayInstance(1)`
|
||||
- optionally binds the playback window handle via `RSPlaySetPlayWnd`
|
||||
- starts local rendering via `RSPlayStartPlay`
|
||||
- registers callback handlers with `RSPlaySetCallbackMessageEx` and `RSPlayImageCallback`
|
||||
- fills a request block from the provided playback parameters
|
||||
- calls `RSNetStartRecordPlayEx(connectionHandle, &local_40)`
|
||||
|
||||
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.
|
||||
- remote recorded playback is a network operation through `RSNET.DLL`
|
||||
- incoming data is then fed into an `RSPLAY.DLL` decode/render pipeline
|
||||
- the standalone downloader probably does not need the `RSPLAY` path unless raw playback streaming is required instead of file download
|
||||
|
||||
## Implications For A DPI Fix
|
||||
### Download wrappers
|
||||
|
||||
### Most likely current problem model
|
||||
`FUN_006e9810`
|
||||
|
||||
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:
|
||||
Behavior:
|
||||
|
||||
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.
|
||||
- allocates a 12-byte state object
|
||||
- copies a compact request from the caller
|
||||
- sets a callback function `FUN_006e8690`
|
||||
- calls `RSNetStartDownloadRecord(handle, &local_14)`
|
||||
|
||||
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.
|
||||
`FUN_006e98b0`
|
||||
|
||||
### Why a simple `SetProcessDPIAware` patch is risky
|
||||
Behavior:
|
||||
|
||||
For an older Qt Widgets app:
|
||||
- allocates a 12-byte state object
|
||||
- copies a slightly larger request including an extra byte field
|
||||
- sets callback `FUN_006e8730`
|
||||
- calls `RSNetStartDownloadRecordEx(handle, &local_20)`
|
||||
|
||||
- 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
|
||||
`FUN_006e9980`
|
||||
|
||||
### What a workable solution will probably require
|
||||
Behavior:
|
||||
|
||||
At minimum, a successful patch likely needs one of these paths:
|
||||
- calls `RSNetStopDownloadRecord(downloadHandle)`
|
||||
- frees the associated state object
|
||||
|
||||
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.
|
||||
Interpretation:
|
||||
|
||||
## Ghidra Database Changes Made During Analysis
|
||||
- there are at least two remote download entrypoints: base and extended
|
||||
- the extended form includes one extra byte field that may be stream type, record type, or a mode selector
|
||||
- both return or populate a download handle that is later passed to `RSNetStopDownloadRecord`
|
||||
|
||||
The following functions were renamed in the active program database:
|
||||
### Record data callback path
|
||||
|
||||
- `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`
|
||||
`FUN_006e85b0`
|
||||
|
||||
Decompiler comments were also added at those entrypoints summarizing their purpose.
|
||||
Behavior:
|
||||
|
||||
## Current Confidence Level
|
||||
- if callback state is valid and `param_1 == 1`, it calls `RSNetReqRecordData(*param_2)`
|
||||
- otherwise it posts a Qt event with type `0x3ed` to a target object
|
||||
|
||||
High confidence:
|
||||
Interpretation:
|
||||
|
||||
- Qt-based GUI application
|
||||
- older Qt lineage is likely
|
||||
- no obvious static DPI-awareness implementation exists
|
||||
- window geometry persistence is real and important
|
||||
- remote playback/download is at least partly callback-driven
|
||||
- one callback state value appears to be a target `QObject`
|
||||
- `RSNetReqRecordData` is likely a pull/continue/read-next mechanism for record data transfer
|
||||
|
||||
Medium confidence:
|
||||
### Record playback control
|
||||
|
||||
- the best durable fix will require more than a manifest-only change
|
||||
- geometry migration/reset will likely be necessary for a clean result
|
||||
`RecordPlaybackControl_toggleMode`
|
||||
|
||||
Low confidence without runtime testing:
|
||||
Behavior:
|
||||
|
||||
- whether the best final mode is DPI-unaware with OS scaling, system-DPI-aware, or a custom Qt-side scaling patch
|
||||
- toggles internal playback state based on UI mode values `0x10` through `0x13`
|
||||
- logs `QRSAdapterReqRecordPlayCtrol`
|
||||
- calls a helper that eventually dispatches `RSNetReqRecordPlayCtrol`
|
||||
|
||||
## Recommended Direction
|
||||
Interpretation:
|
||||
|
||||
Treat this as a legacy-Qt DPI retrofit problem, not just a missing API call problem.
|
||||
- pause/resume/seek/speed or similar playback controls go through `RSNetReqRecordPlayCtrol`
|
||||
- this is playback control, not initial search or initial download setup
|
||||
|
||||
The next pass should focus on:
|
||||
## Current Reconstructed Download Pipeline
|
||||
|
||||
- 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
|
||||
From the EXE alone, the likely pipeline is:
|
||||
|
||||
1. Establish device/session connection through `RSNetConnectionStartEx`
|
||||
2. Query available recordings with `RSNetQueryRecordEx`
|
||||
3. In the UI, present file/segment rows to the user
|
||||
4. For time-based download, intersect the requested interval against returned record segments
|
||||
5. For each needed segment or sub-range, call either `RSNetStartDownloadRecord` or `RSNetStartDownloadRecordEx`
|
||||
6. Receive progress/data/completion via callback functions and Qt events
|
||||
7. Stop transfer with `RSNetStopDownloadRecord` when complete or canceled
|
||||
|
||||
## What This Means For A Standalone Downloader
|
||||
|
||||
At a high level, the minimum downloader architecture is likely:
|
||||
|
||||
1. Login/connect request builder
|
||||
2. Record query request builder
|
||||
3. Segment intersection logic for arbitrary user time ranges
|
||||
4. Download request builder
|
||||
5. Callback/event loop or polling layer for transfer progress and completion
|
||||
|
||||
The most important unresolved details are all inside `RSNet.dll`:
|
||||
|
||||
- exact login request structure
|
||||
- whether connection uses direct IP, media port, P2P ID, or multiple modes under one API
|
||||
- exact query-record structure fields
|
||||
- exact download request structure fields
|
||||
- callback message formats and result codes
|
||||
- file format or chunk framing of downloaded data
|
||||
- authentication handshake and any encryption or session-key behavior
|
||||
|
||||
## What Is Known Versus Unknown
|
||||
|
||||
### Known from EXE analysis
|
||||
|
||||
- The EXE does not appear to implement the wire protocol itself.
|
||||
- `RSNET.DLL` is the primary networking and remote-record module.
|
||||
- `RSPLAY.DLL` handles playback/render support.
|
||||
- The UI supports both file-based and time-based record download.
|
||||
- Arbitrary time-range download is implemented as interval intersection over returned recording segments.
|
||||
- The download path uses `RSNetStartDownloadRecord` or `RSNetStartDownloadRecordEx`.
|
||||
- Record search uses `RSNetQueryRecordEx`.
|
||||
- Record playback uses `RSNetStartRecordPlayEx` and `RSNetReqRecordPlayCtrol`.
|
||||
|
||||
### Unknown until `RSNet.dll` is analyzed
|
||||
|
||||
- packet layout and transport protocol
|
||||
- exact authentication mechanism
|
||||
- exact request structure fields
|
||||
- whether the client speaks directly to the device, uses P2P relay logic, or switches transport modes internally
|
||||
- how downloaded bytes are framed and persisted to disk
|
||||
|
||||
## Recommended Next Step
|
||||
|
||||
Load `RSNet.dll` into Ghidra next.
|
||||
|
||||
That is the correct next target if the goal is to build an independent downloader rather than automate the existing EXE.
|
||||
|
||||
After `RSNet.dll` is loaded, the next analysis pass should focus on:
|
||||
|
||||
- `RSNetConnectionStartEx`
|
||||
- `RSNetQueryRecordEx`
|
||||
- `RSNetStartDownloadRecord`
|
||||
- `RSNetStartDownloadRecordEx`
|
||||
- `RSNetReqRecordData`
|
||||
- `RSNetStopDownloadRecord`
|
||||
- any credential, P2P, relay, encryption, or session-management helpers they call
|
||||
|
||||
## Credentials And Live Validation
|
||||
|
||||
Credentials are not required yet for the current static pass.
|
||||
|
||||
They will become useful later for one of these reasons:
|
||||
|
||||
- validating a reconstructed downloader against a real target
|
||||
- comparing dynamic behavior with captured traffic
|
||||
- understanding whether connection mode changes based on device type, P2P ID, or network reachability
|
||||
|
||||
If live testing becomes necessary, credentials should be stored in an untracked local file such as a new `.gitignore`d notes/config file inside the repository or workspace.
|
||||
|
||||
## Analysis State Notes
|
||||
|
||||
- Earlier in the session, a few function definitions were accidentally deleted by using the wrong MCP endpoint on the writable program. Those functions were restored immediately.
|
||||
- A repository instruction file now explicitly forbids destructive Ghidra actions during analysis unless the user explicitly requests them.
|
||||
- Current repository instruction file: `.github/copilot-instructions.md`
|
||||
Loading…
Add table
Add a link
Reference in a new issue