Skip to content

Add forensic modules for Nova AI Chatbot (com.scaleup.chatai) - #696

Merged
abrignoni merged 23 commits into
abrignoni:mainfrom
guilhermegui08:com.scaleup.chatai
Sep 20, 2026
Merged

abrignoni merged 23 commits into
abrignoni:mainfrom
guilhermegui08:com.scaleup.chatai

Conversation

@guilhermegui08

Copy link
Copy Markdown
Contributor

This PR adds 7 modules for the Nova AI Chatbot application. The package ID is com.scaleup.chatai and the main database is located at /data/data/com.scaleup.chatai/databases/chat-ai.db.

Modules Added

Module Description
HistoryDetailImage Extracts all images from the HistoryDetailImage table, correctly identifying AI‑generated images (ASSISTANT role) vs user‑submitted images (USER role). Includes prompt, generation state, pipeline, style ID, and Firebase path.
HistoryDetailDocuments Extracts all user‑submitted documents from the HistoryDetailDocument table with name, MIME type, size, source type, and Firebase path.
Conversations Full conversation reconstruction by joining History, HistoryDetail, and all attachment tables. One row per message with images, documents, and links displayed inline.
Cached Images Extracts all cached images from the Glide disk cache (cache/image_manager_disk_cache/*.0). Generates an HTML gallery with thumbnails, file size, and modification time using direct file paths to the extracted .0 files.

Output Format

All modules produce:

  • HTML report with previews
  • TSV file for further analysis
  • Timeline output

Screenshot

imagem

Acknowledgements

This work was developed with the assistance of AI

@abrignoni

abrignoni commented May 20, 2026 via email

Copy link
Copy Markdown
Owner

@guilhermegui08

Copy link
Copy Markdown
Contributor Author

For the code to be merged it must use the built-in check in media function to handle images. We are also not allowing HTML escaping from the scripts due to code injection security risks. Generally the code needs to be more concise and refrain from the use of deprecated methods that are problematic, like datetime.utcfromtimestamp. The script also needs to be LAVA compatible to be merged. Lastly make sure to follow reporting conventions as seen in other scripts. The artifacts are needed and truly awesome. Looking forward to merging them.

On Tue, May 19, 2026 at 6:59 AM Guilherme Guilherme < @.> wrote: This PR adds 7 modules for the Nova AI Chatbot application. The package ID is com.scaleup.chatai and the main database is located at /data/data/com.scaleup.chatai/databases/chat-ai.db. Modules Added Module Description HistoryDetailImage Extracts all images from the HistoryDetailImage table, correctly identifying AI‑generated images (ASSISTANT role) vs user‑submitted images (USER role). Includes prompt, generation state, pipeline, style ID, and Firebase path. HistoryDetailDocuments Extracts all user‑submitted documents from the HistoryDetailDocument table with name, MIME type, size, source type, and Firebase path. Conversations Full conversation reconstruction by joining History, HistoryDetail, and all attachment tables. One row per message with images, documents, and links displayed inline. Cached Images Extracts all cached images from the Glide disk cache ( cache/image_manager_disk_cache/.0). Generates an HTML gallery with thumbnails, file size, and modification time using direct file paths to the extracted .0 files. Output Format All modules produce: - HTML report with previews - TSV file for further analysis - Timeline output Screenshot imagem.png (view on web) https://github.com/user-attachments/assets/f92230cd-0a39-4557-bbf0-c81c7f2fdd35 Acknowledgements This work was developed with the assistance of AI ------------------------------ You can view, comment on, or merge this pull request online at: #696 Commit Summary - 0aa20d7 <0aa20d7> Add artifact scripts - abac85b <abac85b> Add icons File Changes (8 files https://github.com/abrignoni/ALEAPP/pull/696/files) - A scripts/artifacts/AIChatbotNovaCachedImages.py https://github.com/abrignoni/ALEAPP/pull/696/files#diff-cdd4c2671937a5f97e53fcdf86ae3e751ac775f01ea71eaad0f18bb374f1e81d (172) - A scripts/artifacts/AIChatbotNovaConversations.py https://github.com/abrignoni/ALEAPP/pull/696/files#diff-2c58da10af5c3819ca2f0ec6af3606a01abc7e49a6a13f7f4bc908b26a9143b0 (579) - A scripts/artifacts/AIChatbotNovaHistory.py https://github.com/abrignoni/ALEAPP/pull/696/files#diff-b60625e3d8c63ae89320d2e621bccab746a9816886618d405cf21d5905624688 (276) - A scripts/artifacts/AIChatbotNovaHistoryDetail.py https://github.com/abrignoni/ALEAPP/pull/696/files#diff-c6335c334f1e8cf44ba9d05cbb7a4b88e2e6a5db6b951dd2d681d41f5f22dd50 (329) - A scripts/artifacts/AIChatbotNovaHistoryDetailDocument.py https://github.com/abrignoni/ALEAPP/pull/696/files#diff-c9d28daf3308d18ad25da896cd072b32051496b7f6761082a45e5d18b2e8c7b1 (411) - A scripts/artifacts/AIChatbotNovaHistoryDetailImage.py https://github.com/abrignoni/ALEAPP/pull/696/files#diff-f351bf831e092dc6ffbbc28c4becef1dc1e59e81d75f50352aa5b1f9c86b3068 (395) - A scripts/artifacts/AIChatbotNovaHistoryDetailLink.py https://github.com/abrignoni/ALEAPP/pull/696/files#diff-501240b26c7a0ae9bb95941529cdda85d18508bdea4b88b8cf5ba6f4681de882 (296) - M scripts/report_icons.py https://github.com/abrignoni/ALEAPP/pull/696/files#diff-7aa964d9bb13d7f57672bf4c44bc346a54149de3b837f674dd763423371f01d4 (1) Patch Links: - https://github.com/abrignoni/ALEAPP/pull/696.patch - https://github.com/abrignoni/ALEAPP/pull/696.diff — Reply to this email directly, view it on GitHub <#696>, or unsubscribe https://github.com/notifications/unsubscribe-auth/AG3DPC5ANQVUGM7VYACZQPT43Q47RAVCNFSM6AAAAACZEFVHQOVHI2DSMVQWIX3LMV43ASLTON2WKOZUGQ3TMNZWGI4DIMA . You are receiving this because you are subscribed to this thread.Message ID: @.*>

Thank you for your time. I Will be looking forward the next weeks to fix the modules. Right now I'm very busy with other projects.

@abrignoni

abrignoni commented May 21, 2026

Copy link
Copy Markdown
Owner

The media function you need to use is called check_in_media. Also you need to use the LAVA objects when reporting so the epoch timestamp can then be offset by LAVA as opposed to hard coded UTC in human readable form. Here is a video on how to make LAVA compliant artifacts.

https://www.youtube.com/watch?v=qTgZUh4GPxk

I apologize for not being more clear previously. I need to update the readme.md of the project but time has been at a premium lately.

Be aware that any artifact that currently uses any of the old functions we are slowly updating. If you need an example of a LAVA compliant artifact look at WhatsApp.py in iLEAPP.

guilhermegui08 and others added 10 commits May 29, 2026 17:01
This artifact module extracts metadata from the Nova AI Chatbot database, which exclusively logs remote cloud reference URLs stored as relative paths to Firebase rather than keeping local physical media files or full file paths on the device. Because there are no on-disk assets to index, calling the built-in check_in_media function is bypassed to avoid empty results. Instead, these relative cloud paths are safely kept intact and explicitly typed as standard "text" columns within the headers. This ensures the cloud metadata is accurately preserved in the final forensic reports as pure text strings, completely eliminating HTML injection risks while maintaining strict, native LAVA-compliant formatting.
The Image Manager Cache report already extracts cached images from Nova AI. This module was a duplicate and is unnecessary.
Extracts account info, device identifiers, usage metrics, and Adapty payment data from ChatAI preference files.
Remove Artifact HTML Report
@guilhermegui08

guilhermegui08 commented Jun 4, 2026

Copy link
Copy Markdown
Contributor Author

1. AIChatbotNovaHistory

  • Description: Parses the primary application database (chat-ai.db) to extract critical communication metadata.
  • Output: Generates 5 distinct reports mapping historical data from core tables, covering structured logs, message interactions, and database-backed telemetry.

2. AIChatbotNovaSharedPrefs

  • Description: Targets the application's XML configuration stores within the shared_prefs/ directory (e.g., MOMO_PREF_FILE.xml and AdaptySDKPrefs.xml).
  • Output: Generates 2 distinct reports focused on user account identifiers, decoded Firebase JWT tokens, global usage metrics, and SDK payment profiles.

3. AIChatbotNovaMediaStore

  • Description: Correlates file attachment records from the HistoryDetailDocument table with local storage data found in the application's external media directory (sdcard/Android/media/com.scaleup.chatai/Nova/) and the Android MediaStore index (external.db).
  • Output: Generates 1 comprehensive report that bridges the gap between locally present files and cloud-only assets (Firebase Storage sync residues), providing crucial insight into user interaction history even if physical files were deleted or synced from another device.

4. AIChatbotNovaConversations

  • Description: Aggregates and cross-references multi-table outputs from the history modules to compile an entire thread history. It dynamically maps local physical file storage paths for images and documents when available.
  • Output: Provides 1 consolidated report that fully reconstructs the user's complete chat history.

abrignoni and others added 2 commits August 10, 2026 09:01
- Two modules called check_in_media with the six-argument signature the
  core no longer has, so they would have crashed on any Nova-carrying
  image; converted to the current call and the SimpleNamespace scaffolding
  removed.
- Roughly sixty columns declared a "text" header type and ten declared
  "date time", neither of which any consumer implements; the fake types
  are stripped and the timestamp columns are real datetime columns now,
  converted from the stored epochs (milliseconds, with a magnitude guard
  that reads sub-1e11 values as seconds).
- The model and persona code maps stay, with notes stating they come from
  the author's observation of the app rather than vendor documentation;
  every cell already shows the stored code beside the name, and unmapped
  codes report as stored.
- image/jpeg was hardcoded for images and orphaned files; the MIME column
  now reports the database value where present and stays blank otherwise.
  "Cloud-only" in path columns is now "Not in MediaStore", which is what
  the lookup actually established.
- version/date metadata replaced with the fields the framework reads.

Verified by a synthetic round-trip database exercising all six database
artifacts (rows, column counts, code labels and epoch conversion all
correct) and a clean quiet run across the 12 corpus images, none of which
carry the app.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@abrignoni

Copy link
Copy Markdown
Owner

Thank you for this one, the schema mapping work is substantial. I pushed a rework to your branch to bring it onto the current core: the check_in_media calls used a signature that no longer exists (they would have crashed on real data), about seventy column headers declared types nothing implements, the timestamps were raw epochs and now convert properly, the MIME and path columns now say only what the data shows, and the model and persona maps stay with notes stating they come from your observation of the app, with the stored code shown beside every name. The corpus run also caught and fixed a crash on images without a MediaStore files table. Everything passes a synthetic round-trip of all six database artifacts and runs clean across our 12 test images. One thing holds the merge: none of our images carry Nova, so we want a test extraction with real app data before this lands. If you can generate one (even a small chat with an image, a document and a link) and share it, that closes the gap. Not merging yet, but this is ready the moment we can validate it.

@guilhermegui08

guilhermegui08 commented Aug 10, 2026

Copy link
Copy Markdown
Contributor Author

Thanks for the review of my work. Unfortunately the app was updated and currently, as of my investigation, no longer stores data locally related to chatbot conversations. Shared preferences and other types of data were neither no longer stored. I have deleted the original full system dump that was used to develop these modules and only have the original dump of only private data of the application com.scaleup.chatai. With this dump the majority of the modules work but media store related findings are not present. I can give both my old extraction and new one that made today, as you can see the app no longer stores artifacts of this modules in the private directory. The following link share the compressed file nova_chatbot_extractions.7z protected by password.

@guilhermegui08

Copy link
Copy Markdown
Contributor Author

I forgot to mention that for the extraction of today I have used an old version of the app, the same that I used to develop the modules. Unfortunately, even with an old version, the behavior of the app is different.

https://apkpure.com/nova-ai-chatgpt-powered-chat/com.scaleup.chatai/download/4.3.4

@abrignoni

abrignoni commented Aug 25, 2026

Copy link
Copy Markdown
Owner

Test data is now included for every changed artifact module. Thank you!

@abrignoni abrignoni added the needs-test-data Artifact PR without test data for the changed modules label Aug 25, 2026
@github-actions github-actions Bot removed the needs-test-data Artifact PR without test data for the changed modules label Aug 30, 2026
@guilhermegui08

Copy link
Copy Markdown
Contributor Author

I add a small fixture for each artifact. The compromised data consisted of a JWT token inside a file (data/data/com.scaleup.chatai/shared_prefs/MOMO_PREF_FILE.xml) that I substituted with fake data and encoded it again.

abrignoni and others added 2 commits September 19, 2026 23:40
…baselines

Every artifact key now matches its function name. The loader resolved the old
keys through the "function" entry, but artifact_processor looks the metadata up
by function name, so it found nothing and the LAVA writer stopped the artifact
after the HTML and TSV had already been written. Six of the nine failed that way
on a real run; the two whose keys already matched completed.

All nine take a single context and read every copy of their file through
unique_files, so a second Android user is reported instead of dropped. Measured
on a tree holding user 0 with 14 History rows and user 10 with 10: 14 rows
before, 24 after, with both databases named in the located at line. A duplicate
data/user/0 view leaves the count unchanged.

A stored 0 is a value, so sync state, sync retry count, token count and style id
no longer render blank. History sync state was empty on every row and now reads
the 0 the store holds.

The document size column is reported as stored rather than formatted as bytes.
All three records hold 3, one of them a video, so a byte count is not
established.

User Media Submissions drops three columns that could never hold a value, and it
and Conversations return the databases they read as the source path.

Baselines recorded for all nine artifacts: 14, 52, 3, 11, 0, 52, 14, 138 and 22
rows. run_test_cases passes 9 of 9 and --storage-views passes 16, with the links
artifact skipped as uninformative at zero rows.

Notes and descriptions rewritten against the committed test case, including the
tables the module does not report and the columns the case leaves empty.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@abrignoni
abrignoni merged commit edd112f into abrignoni:main Sep 20, 2026
10 checks passed
@abrignoni

Copy link
Copy Markdown
Owner

Thanks for the fixtures. That is what unblocked this, and the schema mapping was the part that took the real effort.

I pushed a rework to your branch and merged it. The main thing was a defect that only shows on a full run: the artifact keys did not match the function names. The loader resolves that through the "function" entry so the artifacts loaded fine, but artifact_processor looks the metadata up by function name, found nothing, and the LAVA writer stopped the artifact after the HTML and TSV had already been written. Six of the nine failed that way. The keys are now the function names and all nine complete.

The rest:

  • All nine take a single context argument and read every copy of their file through unique_files. Before, get_file_path and files_found[0] took the first match, so on a device with a second Android user that user's chats were dropped. Tested with user 0 holding 14 History rows and user 10 holding 10: 14 rows before, 24 after, both databases named in the located at line.
  • A stored 0 was rendered blank by value or "". That hit sync state, sync retry count, token count and style id. History sync state was empty on every row and now shows the 0 the store holds.
  • The document size column is reported as stored rather than formatted as bytes. All three records hold 3, one of them a video, so a byte count is not established.
  • User Media Submissions had three columns that could never hold a value, so those are gone, and it and Conversations now return the databases they read as the source path.
  • Baselines are recorded for all nine artifacts, so the Test Cases job has something to compare against: 14, 52, 3, 11, 0, 52, 14, 138 and 22 rows.

Notes and descriptions were rewritten against your test case, including the tables the module does not report and the columns your case leaves empty. The links artifact says plainly that it is unexercised, since HistoryDetailLink has no rows in that extraction.

Nothing needed from you. Thanks for sticking with it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants