<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Zobaid Islam Santo</title>
    <description>The latest articles on DEV Community by Zobaid Islam Santo (@pikadexofc).</description>
    <link>https://dev.to/pikadexofc</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4160756%2F5b0da777-1803-4423-8d73-dc361c4d1abe.jpg</url>
      <title>DEV Community: Zobaid Islam Santo</title>
      <link>https://dev.to/pikadexofc</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/pikadexofc"/>
    <language>en</language>
    <item>
      <title>Reverse Engineering CapCut's Encrypted Video Cache (BDVE Type 1) and Building an Open-Source Solver</title>
      <dc:creator>Zobaid Islam Santo</dc:creator>
      <pubDate>Sun, 04 Oct 2026 02:51:52 +0000</pubDate>
      <link>https://dev.to/pikadexofc/reverse-engineering-capcuts-encrypted-video-cache-bdve-type-1-and-building-an-open-source-solver-108j</link>
      <guid>https://dev.to/pikadexofc/reverse-engineering-capcuts-encrypted-video-cache-bdve-type-1-and-building-an-open-source-solver-108j</guid>
      <description>&lt;p&gt;If you've ever inspected the local draft directory of CapCut or JianYing (ByteDance's video editors), you might have noticed video cache files taking up hundreds of megabytes in folders like &lt;code&gt;Resources/combination&lt;/code&gt; or &lt;code&gt;Resources/videoAlg&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Naturally, you might try opening one with VLC, QuickTime, or running:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ffmpeg &lt;span class="nt"&gt;-i&lt;/span&gt; 48C34141-8F08-4483-A597-073963B3DB0A_video.mp4 output.mp4
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Only to be greeted by this demuxer error:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[mov,mp4-m4a-3gp-3g2-mj2 @ 0x7fa2b00] moov atom not found
Invalid data found when processing input
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The file size on disk is complete (e.g. 50 MB, 1 GB), yet neither VLC nor FFmpeg can parse even a single valid packet.&lt;/p&gt;

&lt;p&gt;Here is the technical story of how I reverse-engineered ByteDance's proprietary &lt;strong&gt;BDVE Type 1&lt;/strong&gt; obfuscation scheme and created &lt;strong&gt;&lt;a href="https://github.com/pikadexofc/export-capcut-pro-video-free" rel="noopener noreferrer"&gt;CapCut Cache Recover&lt;/a&gt;*-‛a 100% pure Python forensic stream recovery engine and graphical suite that restores original bitstreams with **0% re-encoding quality loss&lt;/strong&gt; in under 0.3 seconds.&lt;/p&gt;




&lt;h3&gt;
  
  
  The Investigation: Dissecting the ByteStream
&lt;/h3&gt;

&lt;p&gt;When inspecting the hex headers of an ISO Base Media File Format (MP4/MOV) container, you normally expect to see an initial &lt;code&gt;ftyp&lt;/code&gt; box:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Offset 0x00:  00 00 00 20 66 74 79 70 69 73 6f 6d ...
              [Size: 32 ] [ 'ftyp'    ] [ 'isom'     ]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;However, examining a CapCut combination clip revealed unexpected bytes at offset 0:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Offset 0x00:  3B 3B 3B 1B 5D 4F 42 4B ...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Notice the pattern: &lt;code&gt;3B 3B 3B&lt;/code&gt;. If we compute a bitwise XOR with &lt;code&gt;0x3B&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;3B ^ 3B = 0x00
3B ^ 3B = 0x00
3B ^ 3B = 0x00
1B ^ 3B = 0x20  (32 in decimal!)
5D ^ 3B = 0x66  ('f')
4F ^ 3B = 0x74  ('t')
42 ^ 3B = 0x79  ('y')
4B ^ 3B = 0x70  ('p')
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The XOR mask is clearly &lt;code&gt;0x3B&lt;/code&gt;! Decrypting the first 8 bytes reveals the standard &lt;code&gt;ftyp&lt;/code&gt; header.&lt;/p&gt;

&lt;p&gt;But ByteDance didn't just XOR the entire file with &lt;code&gt;0x3B&lt;/code&gt;. Attempting a naive full-file XOR corrupted the file worse.&lt;/p&gt;




&lt;h3&gt;
  
  
  Understanding BDVE Cryptor Type 1
&lt;/h3&gt;

&lt;p&gt;ByteDance applies &lt;strong&gt;periodic XOR slicing&lt;/strong&gt;:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Periodic Cadence&lt;/strong&gt;: Every &lt;code&gt;step&lt;/code&gt; bytes along the media payload (&lt;code&gt;mdat&lt;/code&gt;), a slice of &lt;code&gt;length&lt;/code&gt; bytes is scrambled with a single-byte &lt;code&gt;key&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Plaintext Gaps&lt;/strong&gt;: The bytes between slices remain unencrypted plaintext.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The Proprietary Trailer&lt;/strong&gt;: At the very end of the file, ByteDance appends a 68-byte custom container containing a &lt;code&gt;bdve&lt;/code&gt; box and a child &lt;code&gt;crpt&lt;/code&gt; box:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;+-----------------------+--------+------------------------------------+
| Field                 | Size   | Value / Description                |
+-----------------------+--------+------------------------------------+
| Box Size              | 4B     | 0x00000044 (68 bytes)              |
| Box Type              | 4B     | 'bdve'                             |
| Sub-box Size          | 4B     | 0x0000003C (60 bytes)              |
| Sub-box Type          | 4B     | 'crpt'                             |
| Version               | 4B     | 0x00000001 (Type 1 Cryptor)        |
| Algorithm ID          | 4B     | 0x00000001 (Periodic XOR)          |
| Reserved / Salt       | 16B    | Implementation parameters          |
| Verification SHA-256  | 32B    | SHA-256(step || length || key)     |
+-----------------------+--------+------------------------------------+
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The trailer stores a 32-byte cryptographic digest:&lt;/p&gt;

&lt;p&gt;$$\text{digest} = \text{SHA-256}(\text{BigEndian32}(\text{step}) \parallel \text{BigEndian32}(\text{length}) \parallel \text{Uint8}(\text{key}))$$&lt;/p&gt;




&lt;h3&gt;
  
  
  Solving the Modulo Constraints
&lt;/h3&gt;

&lt;p&gt;The search space for arbitrary 32-bit &lt;code&gt;step&lt;/code&gt; and &lt;code&gt;length&lt;/code&gt; integers is too large for brute force ($2^{64}$). However, we can use the structure of H.264 video streams to solve for &lt;code&gt;step&lt;/code&gt; and &lt;code&gt;length&lt;/code&gt; mathematically in milliseconds:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Locate the &lt;code&gt;moov&lt;/code&gt; atom&lt;/strong&gt;: By scanning backward from the &lt;code&gt;bdve&lt;/code&gt; trailer, we identify the plaintext sample table boxes (&lt;code&gt;stsz&lt;/code&gt;, &lt;code&gt;stsc&lt;/code&gt;, &lt;code&gt;stco&lt;/code&gt;/&lt;code&gt;co64&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Extract Sample Chunk Offsets&lt;/strong&gt;: The sample table gives us the exact byte offsets where H.264 NAL units (Network Abstraction Layer) are located in the file.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;NAL Unit Scoring&lt;/strong&gt;: A valid H.264 NAL header begins with a 4-byte start code (&lt;code&gt;0x00000001&lt;/code&gt;) followed by a NAL type byte (e.g., SPS=7, PPS=8, IDR Slice=5). If a sample offset is in an encrypted block, its bytes will only match NAL signatures when XOR'd with the key.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Modulo Arithmetic&lt;/strong&gt;: Slices are encrypted at offsets:
$$\text{offset} \pmod{\text{step}} &amp;lt; \text{length}$$
Every verified encrypted offset imposes:
$$\text{length} &amp;gt; (\text{offset} \pmod{\text{step}})$$
Every verified plaintext offset imposes:
$$\text{length} \le (\text{offset} \pmod{\text{step}})$$&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Testing candidate step intervals (derived from common chunk boundaries like 49,435 or 65,536) rapidly narrows the candidate set to a single integer pair &lt;code&gt;(step, length)&lt;/code&gt;. We then verify against the 32-byte trailer SHA-256 digest.&lt;/p&gt;

&lt;p&gt;When the digest matches, we have mathematical certainty of the exact cryptographic parameters.&lt;/p&gt;




&lt;h3&gt;
  
  
  Pure Bitstream Inversion (Zero Re-Encoding Loss)
&lt;/h3&gt;

&lt;p&gt;Once &lt;code&gt;(step, length, key)&lt;/code&gt; are known:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;We read the source file in chunks.&lt;/li&gt;
&lt;li&gt;For each byte range where &lt;code&gt;pos % step &amp;lt; length&lt;/code&gt;, we XOR the slice with &lt;code&gt;key&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;We truncate the 68-byte proprietary &lt;code&gt;bdve&lt;/code&gt; trailer.&lt;/li&gt;
&lt;li&gt;We write out the clean MP4 file.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Throughput&lt;/strong&gt;: Because this is purely bitwise inversion with zero transcoding, throughput exceeds &lt;strong&gt;100 MB/s&lt;/strong&gt; on standard hardware. A 500 MB video decrypts in ~4 seconds.&lt;/p&gt;

&lt;p&gt;Most importantly, the original AVC/H.264 NAL units and AAC LC audio packets are bit-for-bit identical to CapCut's rendered output. There is &lt;strong&gt;zero generational compression loss&lt;/strong&gt;, zero color space shift, and zero dropped frames.&lt;/p&gt;




&lt;h3&gt;
  
  
  Building the Tool: Ergonomics &amp;amp; Polish
&lt;/h3&gt;

&lt;p&gt;I packaged the engine into an open-source tool: &lt;strong&gt;&lt;a href="https://github.com/pikadexofc/export-capcut-pro-video-free" rel="noopener noreferrer"&gt;CapCut Cache Recover&lt;/a&gt;&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Key features include:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Interactive Terminal Selector&lt;/strong&gt;: Auto-indexes recent CapCut drafts and lets you navigate with arrow keys (&lt;code&gt;↑ / ↓&lt;/code&gt;) in PowerShell or Command Prompt.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Native Windows Explorer "Save As" (Ctrl+S style)&lt;/strong&gt;: Lets you pick the exact output folder and filename via a standard file dialog.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;CapCut Project Metadata Resolution&lt;/strong&gt;: Parses &lt;code&gt;draft_meta_info.json&lt;/code&gt; and &lt;code&gt;draft_content.json&lt;/code&gt; to extract your real project and clip names (&lt;code&gt;shining motion u - Compound clip16.mp4&lt;/code&gt;) instead of cryptic GUIDs (&lt;code&gt;48C34141-8F08-4483...mp4&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Desktop GUI&lt;/strong&gt;: Native 4-tab dark obsidian visual suite (&lt;code&gt;#0B0F14&lt;/code&gt;) with Drag &amp;amp; Drop and keyboard accelerators.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Standalone Windows Executable&lt;/strong&gt;: A 12 MB portable binary requiring zero Python installation.&lt;/li&gt;
&lt;/ol&gt;




&lt;h3&gt;
  
  
  Getting Started
&lt;/h3&gt;

&lt;p&gt;You can install it via PowerShell in 5 seconds:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight powershell"&gt;&lt;code&gt;&lt;span class="n"&gt;irm&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;https://raw.githubusercontent.com/pikadexofc/export-capcut-pro-video-free/main/install.ps1&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;iex&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Or clone the source code on GitHub:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git clone https://github.com/pikadexofc/export-capcut-pro-video-free.git
&lt;span class="nb"&gt;cd &lt;/span&gt;export-capcut-pro-video-free
python &lt;span class="nt"&gt;-m&lt;/span&gt; pip &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="nb"&gt;.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;GitHub Repository&lt;/strong&gt;: &lt;a href="https://github.com/pikadexofc/export-capcut-pro-video-free" rel="noopener noreferrer"&gt;pikadexofc/export-capcut-pro-video-free&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Latest Binary Release&lt;/strong&gt;: &lt;a href="https://github.com/pikadexofc/export-capcut-pro-video-free/releases/tag/v1.0.1" rel="noopener noreferrer"&gt;v1.0.1 on GitHub Releases&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;&lt;em&gt;Engineered by **Md. Zobaed Islam Shanto&lt;/em&gt;* • Founded under &lt;strong&gt;PixelPie Media&lt;/strong&gt;.*&lt;br&gt;&lt;br&gt;
&lt;em&gt;If this utility saved your project, consider supporting development: &lt;a href="https://mdzobaedislamshanto.supportkori.shop/" rel="noopener noreferrer"&gt;⚡ Fund the Production&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>opensource</category>
    </item>
  </channel>
</rss>
