Reconstructing RDP Screens from Bitmap Cache Tiles
Why an RDP cache collage lines up in places and drifts in others, how to pick the collage width, and how to rebuild a screen tile by tile on a canvas.
TL;DR. RDP cache tiles have no screen coordinates, and identical pieces are cached only once. A collage with the right number of tiles per row makes the parts of a window that were cached row by row line up, but every deduplicated tile shifts everything after it by one, so the edges drift. Use the collage to find the region, then rebuild the screen on a grid by hand: drag the tiles into place, reuse a single tile where it repeats, and export the result as PNG with a layout JSON that documents what you placed where. RDP Bitmap Cache Parser does this in the Reconstruct tab; BSI's RdpCacheStitcher is the desktop alternative.
This article is part of the investigations series. For the format details behind it, see the bcache*.bmc and Cache*.bin file format.
The problem: tiles without coordinates
Each bitmap tile in the cache is stored with a key, a width, a height and pixels. Nothing says where it was on the screen. What you do have:
- Cache order. Tiles are stored in the order the cache holds them. For a region the client received in one go, such as a window being drawn, that order can follow the region's rows.
- Tile sizes. Most tiles are 64×64. Narrower or shorter tiles often come from the right or bottom edge of a region.
- Content. Text that continues from one tile to the next, window borders, title bars and scrollbars are the pieces of the puzzle.
What breaks the order:
- Deduplication. A piece that is already in the cache is not stored again. A plain title bar segment, an empty black console area or a flat desktop background exists once, however many times it appeared on screen.
- Mixed sessions and views. The same file accumulates tiles from different moments, windows and sessions.
- Slot reuse in
.bmcfiles, which can leave slot remnants of older content.
The collage: fast, useful, and slightly wrong
A collage lays all tiles out in one image, N tiles per row, in cache order. bmc-tools produces one with -b, with the number of tiles per row set by -w (default 64). RDP Bitmap Cache Parser has the same view in the Collage tab, with a configurable number of tiles per row and two layouts:
| Layout | Arrangement |
|---|---|
| Cache order | Tile 0 at top-left, then left to right, row by row |
| bmc-tools layout | Reproduces the arrangement of bmc-tools' _collage.bmp, so you can compare images directly |
Choosing the width
If a window was cached row by row and is W tiles wide, a collage with W tiles per row lines up that window's rows vertically. To find W:
- Find a tile with an obvious vertical feature (a window border, a scrollbar, a column of text).
- Change the tiles-per-row value until that feature forms a straight vertical line across several rows.
- Confirm with text: words cut at a tile edge should continue on the next tile to the right.
The default of 64 tiles per row is rarely the width of anything on screen. It is a reasonable overview, not a reconstruction.
Why it drifts: a worked example
The fictional sample shipped with the tool (a synthetic case, not a real incident) makes the effect visible. Its Cache0000.bin holds 47 tiles:
- Tile 0 is the plain desktop background, stored once.
- Tiles 1–25 are a console window, in row order, 7 tiles wide.
A console 7 tiles wide and several rows high covers more than 25 cells. The missing cells are pieces identical to ones already cached: plain title bar segments and empty black console areas. Each time the client skipped storing a repeated piece, every later tile moved one cell to the left relative to its true screen position.
With 7 tiles per row in cache order:
| Collage rows | Tiles | Result |
|---|---|---|
| Middle rows | 7–20 | Line up: the rclone.exe copy C:\Users\Public\data E:\exfil command and its transfer summary read across |
| First and last rows | Before 7, after 20 | Drift: title bar and bottom of the console are shifted, because deduplicated pieces are missing |
The middle rows line up because the console lines there are all different, so nothing in them was deduplicated. The edges are made of repetitive pieces, so they collapse. That is normal behaviour of the cache, not a parsing error, and no single collage width can fix it.
Rebuilding the screen by hand
Manual reconstruction means placing each tile at the cell where it belongs, including reusing one tile for several cells when it was deduplicated.
With RDP Bitmap Cache Parser
The Reconstruct tab is a grid canvas:
- Filter the tiles first. Review first narrows the list to console-like and text-like tiles; Hide blank and duplicate tiles removes clutter.
- Drag a tile onto a cell, or select a tile and then click a cell. A tile can be placed in as many cells as needed, which is how you fill in deduplicated title bars and empty console areas.
- Start from the anchor you found in the collage (for the sample: the rows that contain the command line) and work outward: the row above must continue the borders and text of the row below.
- Leave cells empty when you do not know. An honest gap is better than a guessed tile.
- Export a PNG of the canvas for the report and a layout JSON that records which tile you placed in which cell. The JSON makes the reconstruction reviewable and repeatable.
There is no automatic stitching and no OCR: you read the screen, the tool only helps you place the pieces.
With RdpCacheStitcher
RdpCacheStitcher, published by the German BSI, is a GUI that helps you stitch exported tiles into screens. It works on the tiles exported by bmc-tools. If your team already uses it, the BMP ZIP export of RDP Bitmap Cache Parser names tiles like bmc-tools output (<file>_<NNNN>.bmp), so you can keep that workflow.
Reading what you rebuilt
A reconstructed screen is an interpretation. Write it up that way:
- State the method: "tiles 7–20 of
Cache0000.binline up at 7 tiles per row; rows above and below were placed manually; see layout JSON". - Separate observed from placed: the command line in the sample is visible across adjacent tiles in cache order; the title bar above it was placed by the analyst.
- Do not claim order or time from the image. A clock visible on a rebuilt taskbar (10:52 in the sample) is what the remote screen displayed at that moment, in its own time zone. Tie it to the timeline with other artifacts, as described in RDP lateral movement: source host artifacts.
- Flag remnants: a slot remnant is part of an older tile and may belong to a different moment than the tiles around it.
Practical tips
| Situation | Tip |
|---|---|
| Thousands of tiles | Hide blank and duplicate tiles, then use Review first |
| Text split across tiles | Read tile pairs in the gallery before touching the canvas |
| Narrow edge tiles | They usually close a row on the right or bottom |
| 8-bit tiles | Colours are approximate; match on shapes and text |
| Several cache files | Reconstruct per file; different files can come from different sessions |