Skip to content

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.

Published on 9 min read

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 .bmc files, 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:

LayoutArrangement
Cache orderTile 0 at top-left, then left to right, row by row
bmc-tools layoutReproduces 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:

  1. Find a tile with an obvious vertical feature (a window border, a scrollbar, a column of text).
  2. Change the tiles-per-row value until that feature forms a straight vertical line across several rows.
  3. 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 rowsTilesResult
Middle rows7–20Line up: the rclone.exe copy C:\Users\Public\data E:\exfil command and its transfer summary read across
First and last rowsBefore 7, after 20Drift: 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:

  1. Filter the tiles first. Review first narrows the list to console-like and text-like tiles; Hide blank and duplicate tiles removes clutter.
  2. 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.
  3. 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.
  4. Leave cells empty when you do not know. An honest gap is better than a guessed tile.
  5. 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.

Automatic first pass

The Auto-reconstruct tab proposes fragments for you. It compares the edge pixels of every tile with the edges of the others (colour continuity, and gradients that carry on across the seam), joins the most confident pairs, then grows each fragment one cell at a time, scoring every candidate against all the neighbours already placed. Single-colour tiles are left out of the matching, because they fit next to anything, and are only used to fill gaps enclosed by edges of the same colour. Fragments are listed largest first, each joint carries a confidence, weak joints are outlined, and Edit in Reconstruct copies a fragment to the grid so you can correct it.

Treat the output as a lead, not a result. Flat areas and sparse text are ambiguous, and when a tile is missing from the cache a look-alike can take its place with a convincing seam. Check each fragment against the original tiles before it goes into a report. There is no OCR: you still read the screen yourself.

Guided reconstruction: pin what you are sure of

The Guided view of the same tab turns the first pass around. You pin the tiles you are sure of on one shared canvas: drag a tile, or a whole fragment, onto a cell (or select it, then click the cell; on a phone, tap then tap). Pins never move. The solver grows the canvas outward from them, scoring every candidate against all the neighbours already placed. When two placed neighbours independently choose the same tile, it accepts a rougher seam than it would from one neighbour alone, and it brings in an automatic fragment whole when it fits the canvas without a collision or an implausible seam. Click an empty cell next to the canvas to see the best candidates with their fit, then accept one or reject it: a rejected tile is never proposed for that cell again. Conflicting pins, such as two tiles on one cell or a narrow edge tile with a neighbour after it, are listed so you can fix them, not silently dropped. Undo and redo cover every step, and the layout JSON carries the pins and rejections, so importing it later resumes the session.

Pins help less than you might hope on screens made of flat panels and bitmap text: each one extends the canvas only as far as the edges around it carry information. On our synthetic desktops, three pins per screen place about a tenth of each screen on their own; accepting suggestions cell by cell is what gets you further. Grown and merged tiles are still guesses. Only what you pinned or accepted is your call, and the export says which is which.

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.bin line 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

SituationTip
Thousands of tilesHide blank and duplicate tiles, then use Review first
Text split across tilesRead tile pairs in the gallery before touching the canvas
Narrow edge tilesThey usually close a row on the right or bottom
8-bit tilesColours are approximate; match on shapes and text
Several cache filesReconstruct per file; different files can come from different sessions

Related articles

Step-by-step: load bcache*.bmc and Cache*.bin files into a free in-browser parser, triage tiles, build a collage, rebuild a screen and export the evidence.
Which artifacts on the RDP source host show where a user connected and when, and how to use them to date and attribute what the bitmap cache shows.
bmc-tools, RdpCacheStitcher and RDP Bitmap Cache Parser side by side: what each does, where each fits in a case, and the honest limits of the browser tool.