docs: map msglib dotnet wrapper path

This commit is contained in:
zhaoyilun
2026-07-10 02:29:36 +08:00
parent 7ced6e45f6
commit 8378935c90
4 changed files with 184 additions and 16 deletions

View File

@@ -0,0 +1,99 @@
# Static .NET DB wrapper analysis for MsgLib.db
Date: 2026-07-10
## Question
Can the copied `MsgLib.db` files be opened through the same .NET wrapper path used by the iSphere/IMPP client, and which tables/fields are likely to unlock contact, group, message, and file metadata?
## Evidence checked
Ignored read-only IL/metadata generated from the copied archive:
- `runs/offline-evidence-intake/zyl-qqfile-20260709/metadata/c25-il/HYHC.IMPP.DAL.dll.il`
- `runs/offline-evidence-intake/zyl-qqfile-20260709/metadata/c25-il/Utilities.Lib.DBBase.dll.il`
- `runs/offline-evidence-intake/zyl-qqfile-20260709/metadata/c25-il/Utilities.Lib.DBModel.dll.il`
- `runs/offline-evidence-intake/zyl-qqfile-20260709/metadata/c25-il/Utilities.Lib.DBSQLite.dll.il`
- `runs/offline-evidence-intake/zyl-qqfile-20260709/metadata/c25-il/Utilities.Lib.SQLiteInteraction.dll.il`
- `runs/offline-evidence-intake/zyl-qqfile-20260709/metadata/c25-il/RepairDatabase.exe.il`
- `runs/offline-evidence-intake/zyl-qqfile-20260709/metadata/c25-il/IMPP.Model.dll.il`
- `runs/offline-evidence-intake/zyl-qqfile-20260709/metadata/c25-wrapper-il-summary.json`
`IMPP.Model.dll`, `Utilities.Lib.DBBase.dll`, and `Utilities.Lib.SQLiteInteractionBase.dll` were added to the C25 static inspection because the original C24 wrapper candidates reference them directly. No client executable was run, no original DB was modified, and no raw DB bytes/decrypted message content are committed.
## Connection/password flow findings
1. `HYHC.IMPP.DAL.IMPPDAL` is the client DAL entry point for `MsgLib.db`. Its private constructor accepts `dbPath` and `userInfoDomain`, creates a `DBConfigElement`, and configures:
- `DBID = 0x1a0a`;
- `DBConInfoType = 1`;
- `DatabaseName = dbPath`;
- `Password = "123"`;
- `ConName = Path.GetFileName(dbPath)`;
- `DBFactory = "Utilities.Lib.DBSQLite.Core.SQLiteDBFactory,Utilities.Lib.DBSQLite"`.
2. The same constructor registers the config through `ConfigManager.AddConfigItem(...)`, obtains `_dbAccess` through `DBAccessManager.GetDBAccessInstance(DBID)`, and checks the DB with `IsDBDamage(dbPath)` when the file exists.
3. `Utilities.Lib.DBBase.Base.DBInteractionBase.GetDBConStr(...)` is the central connection-string switch:
- if `DBConfigElement.Decryption` is empty and `DBConInfoType == 0`, it uses `ConStr` directly;
- if `DBConfigElement.Decryption` is empty and `DBConInfoType != 0`, it calls `GenerateDBConStr(config, visitType)`;
- if `Decryption` is set, it instantiates an `IConStrDecryption` implementation and delegates `GetDBConStr(config, visitType)` to it.
4. `Utilities.Lib.SQLiteInteraction.Interaction.GenerateDBConStr(...)` constructs a `System.Data.SQLite.SQLiteConnectionStringBuilder` and, for the DAL path above, sets:
- `Pooling = true`;
- `DataSource = GetFullPath(DatabaseName)`;
- `Password = DBConfigElement.Password` when non-empty;
- `ReadOnly = true`;
- then returns the builder `ConnectionString`.
5. `Utilities.Lib.SQLiteInteraction.Interaction.GetConnection(...)` creates `System.Data.SQLite.SQLiteConnection(connectionString)`.
6. `Utilities.Lib.DBSQLite.Core.SQLiteInteraction.CreateReadConnection(...)` calls `GetDBConStr(config, DBVisitType)` and then `GetConnection(...)`.
## Candidate table/model findings
The static IL gives enough table and model names to target schema-only DB extraction next.
### Message and conversation tables
- `tblMsgGroupPersonMsg` is the main group/discussion message table. Static SQL references include create/insert/update/select paths for:
- `Id`, `SndPerson`, `SndPersonId`, `MsgType`, `MsgText`, `MsgFont`, `MsgTime`;
- `MsgGroupId`, `MsgGroupName`, `SessionTitle`, `SessionPersonId`, `SessionPersonName`, `GroupType`;
- `MsgReadState`, `MsgRecaptionState`, `IsReceipt`, `MessageBody`, `InterOut`, `MsgContent`, `MsgVersion`, `MsgReadStatus`;
- later-added fields such as `ReadMembers`, `UnreadTotal`, and `MemInfoVersion`.
- `tblPersonMsg` is the main one-to-one message table. Static SQL/model fields include sender, receiver, object person, message text/body/content/version/read state, and receipt state fields.
- `tblRecent` likely stores recent conversation entries; model fields include `PersonId` and `PersonName`.
### Contact and display-name sources
- `TD_Roster` is explicitly queried with `JId`, `Nick`, `Ask`, `Subscription`, `Show`, `Status`, and `GroupName`.
- `tblChatLevel` has `PersonId` and `PersonName` fields.
- `tblRecent` has `PersonId` and `PersonName` fields.
- `CustomEffigyModel` includes `PersonJid`, `PersonName`, `PersonSex`, avatar/local path style fields.
### Group and member-display sources
- `tblMsgGroupPersonMsg` provides `MsgGroupId`, `MsgGroupName`, `SessionPersonId`, `SessionPersonName`, `GroupType`, and read/member summary fields.
- `TD_WorkGroupAuth` has create/update/select evidence and model `WorkGroupAuth` contains `GroupJID`, `GroupName`, `SendPersonJid`, `SendPersonName`, and `ChildGroupJid`.
- `GetDiscussMemberNames(groupJid)` queries distinct `SessionPersonId` from `tblMsgGroupPersonMsg` by `MsgGroupId`.
### File metadata candidates
- `tblRecvFile` and the receive/send file models expose `FileName`, file id/path-like fields, `SndPerson`, `SndPersonId`, and sender/receiver display-name fields.
- Group file-message insert/update paths write file-transfer references through `tblMsgGroupPersonMsg`.
## Decision
C25 recovered the wrapper route. The next safe path is no longer blind DB-format guessing.
High-confidence local hypothesis:
> A copied `MsgLib.db` should be attempted through the exact bundled `System.Data.SQLite.dll` path with a read-only connection string equivalent to `Data Source=<copied MsgLib.db>;Password=123;Read Only=True;Pooling=False` or the wrapper-generated equivalent.
C26 can attempt read-only schema extraction from copied DB files under ignored paths. C26 should only query schema/table/column names and row counts first; it must not dump message bodies, personal values, or write to any DB.
If the direct read-only `System.Data.SQLite` open fails, the next fallback is to record the exact exception and use the DAL/wrapper path as the reference for a wrapper-assisted schema-only probe.
## Next slice
Loop C26 should perform copied-DB read-only schema extraction:
1. Use the bundled `System.Data.SQLite.dll` from the extracted iSphere client files.
2. Open only copied DB files under `runs/offline-evidence-intake/.../extracted/msgdb-*`.
3. Use the recovered password `123` and force read-only mode.
4. Query `sqlite_master` and `PRAGMA table_info(...)` for target tables only.
5. Save schema metadata under ignored `runs/.../metadata/` and commit only docs/matrix/status updates.