<?xml version="1.0" encoding="UTF-8" ?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
<channel>
<title>Pengoo&apos;s blog</title>
<description>Pengoo&apos;s blog</description>
<link>https://pengoo.fr/</link>
<language>en-us</language>
<atom:link href="https://pengoo.fr/feed" rel="self" type="application/rss+xml"/>
<item>
<title>No Legs, No Problem: Dumping BGA MCP NAND Flash</title>
<link>https://pengoo.fr/articles/2026-dumping-bga-mcp-nand-flash/</link>
<pubDate>Thu, 15 Jan 2026 00:00:00 +0000</pubDate>
<description><![CDATA[
<!DOCTYPE html>
<html lang="en" class="article.template">
	<head>
		<meta charset="utf-8">
		<meta name="generator" content="pandoc">
		<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes">
		<meta name="color-scheme" content="only light">
		<meta name="darkreader-lock" content="whatever">
		<title>No Legs, No Problem:  Dumping BGA MCP  NAND Flash</title>
				<meta name="description" content="How to dump BGA MCP NAND Flash with
the Xgecu T48 Flash programmer. Dead-bug style (microscope required).">
				<style>code{white-space: pre-wrap;}
span.smallcaps{font-variant: small-caps;}
div.columns{display: flex; gap: min(4vw, 1.5em);}
div.column{flex: auto; overflow-x: auto;}
div.hanging-indent{margin-left: 1.5em; text-indent: -1.5em;}
/* The extra [class] is a hack that increases specificity enough to
   override a similar rule in reveal.js */
ul.task-list[class]{list-style: none;}
ul.task-list li input[type="checkbox"] {
  font-size: inherit;
  width: 0.8em;
  margin: 0 0.8em 0.2em -1.6em;
  vertical-align: middle;
}
.display.math{display: block; text-align: center; margin: 0.5rem auto;}
</style>
		<link rel="stylesheet" href="../../css/style.css">
		<link rel="icon" sizes="any" href="../../img/favicon.ico">
		<link rel="icon" type="image/svg+xml" href="../../img/favicon.svg">
		<link rel="preload" as="font" type="font/woff2" href="../../fonts/DayCare/DayCareRegular-Mod.woff2" crossorigin="anonymous">
		<link rel="preload" as="font" type="font/woff2" href="../../fonts/CrimsonPro/CrimsonPro-Roman-VF.woff2" crossorigin="anonymous">
		<link rel="alternate" type="application/rss+xml" title="Pengoo's blog" href="https://pengoo.fr/feed">
	</head>
	<body>
		<div class="main-layout">
			<div class="content">
				<p>Firmware holds the good stuff: logic, bugs, and the occasional
hard-coded secrets. In this case, the target device had firmware stored
in NAND
flash<label for="h1">&thinsp;*</label><small style="color: #919191;">A type of non-volatile memory, used everywhere (phones, flash drives, SSDs…)</small>
within a <strong>BGA-packaged
MCP</strong><label for="h2">&thinsp;*</label><small style="color: #919191;">Multiple chips (like NAND and RAM) packed together in one unit (Multi Chip Package), mounted to the PCB with tiny solder balls on the underside of the chip (Ball Grid Array)</small>.
The chip wasn’t directly supported by my Flash programmer, so I had to
improvise by:</p>
<ul>
<li>Modding an adapter</li>
<li>Removing the chip with hot air</li>
<li>Wiring the chip dead-bug
style<label for="h3">&thinsp;*</label><small style="color: #919191;">Soldering wires to the underside of a chip. It kind of looks like a dead bug with its legs in the air.</small>
to the programmer</li>
</ul>
<div class="gallery">
<figure>
<div class="gallery-wrapper">
    
    <label for="img-1" class="zoom-item">
        <img src="https://pengoo.fr/articles/2026-dumping-bga-mcp-nand-flash/img/setup.avif" alt="Yeah…">
    </label>
</div>

<figcaption>Yeah…</figcaption>
</figure>
</div>
<h1 id="intro">Intro</h1>
<p><a href="https://www.flashrom.org">Flashrom</a> on an Arduino makes
for a pretty cool Flash programmer. It’s exactly how I got started with
Flash dumping. Recently though, My Arduino died, so I switched to the
XGecu T48™.</p>
<div class="gallery-m">
<figure>
<div class="gallery-wrapper">
    
    <label for="img-2" class="zoom-item">
        <img src="https://pengoo.fr/articles/2026-dumping-bga-mcp-nand-flash/img/old-setup.avif" alt="Old setup">
    </label>
</div>

<figcaption>Old setup</figcaption>
</figure>
<figure>
<div class="gallery-wrapper">
    
    <label for="img-3" class="zoom-item">
        <img src="https://pengoo.fr/articles/2026-dumping-bga-mcp-nand-flash/img/T48.avif" alt="T48">
    </label>
</div>

<figcaption>T48</figcaption>
</figure>
</div>
<p>To put the T48 to the test, I started dumping firmware off whatever I
had lying around: Old routers, BIOS chips… and everything dumped fine!
Then, I tried dumping an old flip phone. <em>Bad idea.</em> It turns
out, the chip is an unsupported <a
href="https://en.wikipedia.org/wiki/Ball_grid_array">BGA</a> <a
href="https://semiconductor.samsung.com/support/tools-resources/dictionary/semiconductor-glossary-mcp/">MCP</a>
which didn’t fit any of my adapters :(</p>
<h1 id="firmware-you-there">Firmware… you there?</h1>
<p>Looking for an easy way to get the phone’s firmware, I checked the
usual suspects:</p>
<ul>
<li>The vendor’s website</li>
<li>Companion apps</li>
<li>OTA updates from the device that could be <a
href="https://en.wikipedia.org/wiki/Man-in-the-middle_attack">MITM’ed</a></li>
<li>Known vulnerabilities</li>
<li>Firmware dumps on forums</li>
</ul>
<p>But no luck. Nobody seemed to care about this phone (and I don’t
blame them). It’s pretty locked down and rocks a Mediatek SoC with a
proprietary OS based on <a
href="https://lpcwiki.miraheze.org/wiki/MediaTek_MAUI">MAUI</a>.</p>
<p>With no firmware in sight, I switched gears and opened up the phone
to inspect the motherboard. I couldn’t see the SoC or any kind of Flash
chip but I figured it had to be hidden somewhere under the PCB
shielding.</p>
<p>Before removing the shielding, I looked at the motherboard again to
check if I had missed any obvious <strong>debug interface</strong>
(JTAG,SWD,UART…). Some manufacturers are nice enough to leave them
labeled and exposed as ports or test pads.</p>
<p>In my case, labels were missing and I didn’t have datasheets, so I
started to poke at random pads to try to find a hidden interface.
<em>Not that fun,</em> especially when you know that the interface may
not even be routed at all in the first place! Also, there’s no guarantee
it’ll even talk back if you manage to find it, as it may be locked
:P</p>
<p>Anyway, after a bit of unsuccessful probing, I decided to take the
PCB shielding off with flush cutters (rotary tool or hot air station
works too). Once it was off, two chips were revealed. A quick google
search of their markings confirmed they were the SoC and the MCP.</p>
<div class="gallery">
<!-- font is dosis bold -->
<p><div class="gallery-wrapper">
    
    <label for="img-4" class="zoom-item">
        <img src="https://pengoo.fr/articles/2026-dumping-bga-mcp-nand-flash/img/mobo.avif" alt="">
    </label>
</div>
</p>
</div>
<p>Because I wasn’t really familiar with MCPs, I took a look at the
datasheet and noticed that it held <strong>both the phone’s Flash and
RAM in a single chip.</strong> <em>Nice!</em> The only problem is, it
came in a BGA package…</p>
<p>Chips come in a lot of different packages (DIP/SOP/BGA…). Here, The
MCP came in a BGA package, meaning it has tiny solder balls on the
bottom surface, instead of legs.</p>
<div class="gallery-xs">
<figure>
<div class="gallery-wrapper">
    
    <label for="img-5" class="zoom-item">
        <img src="https://pengoo.fr/articles/2026-dumping-bga-mcp-nand-flash/img/EMMC.jpg" alt="BGA eMMC chip">
    </label>
</div>

<figcaption>BGA eMMC chip</figcaption>
</figure>
</div>
<p>If the chip has legs, it’s <em>usually</em> easily dumpable. A
soldering iron or hot air station isn’t even needed. Simple clips or
probes can be used instead. Here’s an example:</p>
<div class="gallery-m">
<figure>
<div class="gallery-wrapper">
    
    <label for="img-6" class="zoom-item">
        <img src="https://pengoo.fr/articles/2026-dumping-bga-mcp-nand-flash/img/SOIC_dump2.avif" alt="Dumping firmware with a SOIC clip">
    </label>
</div>

<figcaption>Dumping firmware with a SOIC clip</figcaption>
</figure>
</div>
<p>The clip is great for chips with legs, but useless when it comes to
BGAs which have tiny solder balls on the bottom. Because I couldn’t find
any debug interface or software bugs to take advantage of, I decided to
go chip-off here. Meaning I have to dump the chip by removing it with
hot air and wiring it to a flash programmer.</p>
<p>Dumping the chip is usually pretty straightforward if your flash
programmer supports the chip and you know how to wire it (you have the
datasheet right?)</p>
<p>In my case, I easily found the chip’s datasheet online (W71NW11GC1DW)
and after a quick read:</p>
<ul>
<li>The chip comes in a BGA package</li>
<li>It’s an MCP (Multi Chip Package), containing both NAND and RAM</li>
<li>The MCP’s NAND has a 16-bit bus and supports <a
href="https://en.wikipedia.org/wiki/Open_NAND_Flash_Interface_Working_Group">ONFI</a></li>
<li>The MCP’s NAND needs 1.8V</li>
</ul>
<p>Although the MCP isn’t directly supported by the T48, the NAND inside
it <code>W29N01GW</code> is very similar to another NAND from the same
vendor that’s already supported (<code>W29N01HWSINA@TSOP48</code>).
Here’s a table comparing the two chips based on their datasheets:</p>
<div class="colheader">
<table>
<thead>
<tr>
<th></th>
<th>W29N01GW</th>
<th>W29N01HWSINA@TSOP48</th>
</tr>
</thead>
<tbody>
<tr>
<td>NAND tech</td>
<td>SLC</td>
<td>-</td>
</tr>
<tr>
<td>Density</td>
<td>1GB</td>
<td>-</td>
</tr>
<tr>
<td>Page size</td>
<td>2,112 bytes</td>
<td>-</td>
</tr>
<tr>
<td>Block size</td>
<td>64 pages (128K + 4K bytes)</td>
<td>-</td>
</tr>
<tr>
<td>ONFI</td>
<td>yes</td>
<td>-</td>
</tr>
<tr>
<td>Bus width</td>
<td>16-bit</td>
<td>-</td>
</tr>
<tr>
<td>Vcc</td>
<td>1.8V</td>
<td>-</td>
</tr>
</tbody>
</table>
</div>
<p>As you can see, I found a perfectly matching chip. While a perfect
match is nice, It isn’t strictly required because NAND parameters can be
adjusted in Xgecu’s software (Vcc, block and page size, ONFI bus
width…).</p>
<p>Things looked promising, but I still needed to figure out which balls
to wire on the MCP. So I looked at the datasheet again and found the
MCP’s ball configuration:</p>
<div class="gallery">
<figure>
<div class="gallery-wrapper">
    
    <label for="img-7" class="zoom-item">
        <img src="https://pengoo.fr/articles/2026-dumping-bga-mcp-nand-flash/img/balls-bk.avif" alt="The MCP’s ball configuration: blue = RAM, red = NAND">
    </label>
</div>

<figcaption>The MCP’s ball configuration: blue = RAM, red =
NAND</figcaption>
</figure>
</div>
<p>Because I only care about the NAND, not the RAM, I only need to wire
the red balls to the programmer. My NAND uses a 16-bit bus, meaning I
have 25 balls to wire (including Vss and Vcc). If this NAND used an
8-bit bus, I’d only need to wire 17.</p>
<p>The problem is, the balls are only 0.3mm wide… <em>pretty tiny.</em>
I considered designing a PCB in KiCad for the wiring, but ended up
dead‑bugging the chip instead. Soldering wires under a microscope just
felt more exciting :D</p>
<h1 id="modding-the-adapter">Modding the adapter</h1>
<p>You’d think wiring a NAND to the T48 would be straightforward. Just
plug some wires in the ZIF socket right? <em>Nope,</em> you have to go
through an adapter first.</p>
<div class="gallery-s">
<figure>
<div class="gallery-wrapper">
    
    <label for="img-8" class="zoom-item">
        <img src="https://pengoo.fr/articles/2026-dumping-bga-mcp-nand-flash/img/adapter.avif" alt="ADP_F48_EX-2">
    </label>
</div>

<figcaption>ADP_F48_EX-2</figcaption>
</figure>
</div>
<p>If you’re working with TSOP NANDs, you’ll need to plug the
<code>ADP_F48_EX-2</code> adapter in the T48 ZIF socket. Why? Because
Xgecu’s software only enables NAND support when it’s able to read data
off the chip on the adapter… <em>kinda sucks,</em> but it is what is
is.</p>
<p>The check could probably be bypassed in software, but I opted for
something dumber instead…</p>
<div class="gallery-s">
<p><div class="gallery-wrapper">
    
    <label for="img-9" class="zoom-item">
        <img src="https://pengoo.fr/articles/2026-dumping-bga-mcp-nand-flash/img/guess-ill-try.avif" alt="">
    </label>
</div>
</p>
</div>
<p>This mod expands the adapter’s header pins upwards to two new header
rows, this way:</p>
<ul>
<li>The adapter is plugged in</li>
<li>NAND functions are unlocked</li>
<li>Any NAND can be wired using DuPont connectors, probes, or a <a
href="https://en.wikipedia.org/wiki/Wire_wrap">wire-wrap</a> tool</li>
</ul>
<div class="gallery-s">
<figure>
<div class="gallery-wrapper">
    
    <label for="img-10" class="zoom-item">
        <img src="https://pengoo.fr/articles/2026-dumping-bga-mcp-nand-flash/img/modded-adapter-front2.avif" alt="Modded adapter front">
    </label>
</div>

<figcaption>Modded adapter front</figcaption>
</figure>
<figure>
<div class="gallery-wrapper">
    
    <label for="img-11" class="zoom-item">
        <img src="https://pengoo.fr/articles/2026-dumping-bga-mcp-nand-flash/img/modded-adapter-back2.avif" alt="Modded adapter back">
    </label>
</div>

<figcaption>Modded adapter back</figcaption>
</figure>
</div>
<p><u>Modding steps</u></p>
<ul>
<li>Score and snap a piece of perfboard to a clean 20x17 size using a
cutter and ruler, the edges have to be flush to provide proper clearance
for the T48 ZIF locking pin</li>
<li>Solder <code>ADP_F48_EX-2</code> in the middle</li>
<li>Solder 10 2.54mm headers pins to each side</li>
<li>Solder wrapping wire between each pin, insulation is key for good
signal integrity</li>
</ul>
<h1 id="no-pinout-we-ball-grid-array">No pinout, we ball (grid
array)</h1>
<h2 id="finding-the-adapters-pinout">Finding the adapter’s pinout</h2>
<p>Now that I could wire NANDs to the adapter, I had to know where each
wire should go. The thing is… the adapter’s pinout isn’t publicly
available, so I had to find it by:</p>
<ul>
<li>Leveraging the <code>Pin Detect</code> feature of Xgecu’s
software</li>
<li>Reading the datasheet of the selected (supported) chip</li>
<li>Probing the adapter</li>
</ul>
<p>XGecu’s software will show the pinout for the selected NAND when:</p>
<ul>
<li><code>Pin Detect</code> is checked</li>
<li>The adapter is plugged without a chip in its socket</li>
</ul>
<p>My goal is to dump the unsupported <code>W29N01GW</code> NAND chip,
so I launched Xgecu’s software and selected the closest matching chip in
a TSOP48 package (<code>W29N01HWSINA@TSOP48</code>). Then, I checked
<code>Pin Detect</code> and clicked the <code>READ</code> button:</p>
<div class="gallery-m">
<figure>
<div class="gallery-wrapper">
    
    <label for="img-12" class="zoom-item">
        <img src="https://pengoo.fr/articles/2026-dumping-bga-mcp-nand-flash/img/pin_detect.avif" alt="Pin detect output">
    </label>
</div>

<figcaption>Pin detect output</figcaption>
</figure>
</div>
<p>To make sense of the pinout given by <code>Pin Detect</code>, you’ll
need to read the T48 ZIF socket this way:</p>
<table>
<tbody>
<tr>
<td>ZIF 1</td>
<td>ZIF 40</td>
</tr>
<tr>
<td>ZIF 2</td>
<td>ZIF 39</td>
</tr>
<tr>
<td>…</td>
<td>…</td>
</tr>
<tr>
<td>ZIF 19</td>
<td>ZIF 22</td>
</tr>
<tr>
<td>ZIF 20</td>
<td>ZIF 21</td>
</tr>
<tr>
<td></td>
<td>locking pin</td>
</tr>
</tbody>
</table>
<p>Unfortunately, <code>Pin Detect</code> didn’t show the power rail
pinout (Vss and Vcc). I had to find it in my chip’s datasheet. Here’s
the pinout of the chip I selected:</p>
<div class="gallery-m">
<figure>
<div class="gallery-wrapper">
    
    <label for="img-13" class="zoom-item">
        <img src="https://pengoo.fr/articles/2026-dumping-bga-mcp-nand-flash/img/selected_chip_pinout.avif" alt="W29N01GVSCAA@TSOP48 pinout">
    </label>
</div>

<figcaption>W29N01GVSCAA@TSOP48 pinout</figcaption>
</figure>
</div>
<p>As you can see:</p>
<ul>
<li>Vcc is assigned to IC pins 12 and 37</li>
<li>Vss is assigned to IC pins 13 and 36</li>
</ul>
<p>Next, I needed to figure out the wiring of the adapter’s TSOP socket.
So I simply probed it with a multimeter until I got the full pinout:</p>
<div class="topcaption">
<p>ADP_F48-EX2 pinout</p>
<table>
<thead>
<tr>
<th>Socket pin</th>
<th>ZIF</th>
</tr>
</thead>
<tbody>
<tr>
<td>1</td>
<td>NC</td>
</tr>
<tr>
<td>2</td>
<td>NC</td>
</tr>
<tr>
<td>3</td>
<td>NC</td>
</tr>
<tr>
<td>4</td>
<td>6</td>
</tr>
<tr>
<td>5</td>
<td>7</td>
</tr>
<tr>
<td>6</td>
<td>8</td>
</tr>
<tr>
<td>7</td>
<td>9</td>
</tr>
<tr>
<td>8</td>
<td>40</td>
</tr>
<tr>
<td>9</td>
<td>10</td>
</tr>
<tr>
<td>10</td>
<td>11</td>
</tr>
<tr>
<td>11</td>
<td>NC</td>
</tr>
<tr>
<td>12</td>
<td>5</td>
</tr>
<tr>
<td>13</td>
<td>39,38,30,2,4 (Vss)</td>
</tr>
<tr>
<td>14</td>
<td>12</td>
</tr>
<tr>
<td>15</td>
<td>13</td>
</tr>
<tr>
<td>16</td>
<td>14</td>
</tr>
<tr>
<td>17</td>
<td>15</td>
</tr>
<tr>
<td>18</td>
<td>3</td>
</tr>
<tr>
<td>19</td>
<td>16</td>
</tr>
<tr>
<td>20</td>
<td>NC</td>
</tr>
<tr>
<td>21</td>
<td>NC</td>
</tr>
<tr>
<td>22</td>
<td>NC</td>
</tr>
<tr>
<td>23</td>
<td>NC</td>
</tr>
<tr>
<td>24</td>
<td>NC</td>
</tr>
<tr>
<td>25</td>
<td>39,38,30,2,4 (Vss)</td>
</tr>
<tr>
<td>26</td>
<td>1(70Ohm)</td>
</tr>
<tr>
<td>27</td>
<td>19(70Ohm)</td>
</tr>
<tr>
<td>28</td>
<td>20(70Ohm)</td>
</tr>
<tr>
<td>29</td>
<td>14(70Ohm)</td>
</tr>
<tr>
<td>30</td>
<td>15(70Ohm)</td>
</tr>
<tr>
<td>31</td>
<td>21(70Ohm)</td>
</tr>
<tr>
<td>32</td>
<td>16(70Ohm)</td>
</tr>
<tr>
<td>33</td>
<td>36(70Ohm)</td>
</tr>
<tr>
<td>34</td>
<td>13</td>
</tr>
<tr>
<td>35</td>
<td>NC</td>
</tr>
<tr>
<td>36</td>
<td>39,38,30,2,4 (Vss)</td>
</tr>
<tr>
<td>37</td>
<td>31</td>
</tr>
<tr>
<td>38</td>
<td>NC</td>
</tr>
<tr>
<td>39</td>
<td>2(560Ohm),3(560Ohm),4</td>
</tr>
<tr>
<td>40</td>
<td>35(70Ohm)</td>
</tr>
<tr>
<td>41</td>
<td>17(70Ohm)</td>
</tr>
<tr>
<td>42</td>
<td>18(70Ohm)</td>
</tr>
<tr>
<td>43</td>
<td>19(70Ohm)</td>
</tr>
<tr>
<td>44</td>
<td>20(70Ohm)</td>
</tr>
<tr>
<td>45</td>
<td>34(70Ohm)</td>
</tr>
<tr>
<td>46</td>
<td>33(70Ohm)</td>
</tr>
<tr>
<td>47</td>
<td>32(70Ohm)</td>
</tr>
<tr>
<td>48</td>
<td>39,38,30,2,4 (Vss)</td>
</tr>
</tbody>
</table>
</div>
<ul>
<li>Ground (Vss) seems to be shared across ZIFs [2,4,30,38,39]</li>
<li>NC means “Not Connected” here</li>
</ul>
<p><strong>With the full picture in mind, I got back to the
chip:</strong></p>
<ul>
<li>The chip’s Vcc is mapped to ZIFs [5,31]</li>
<li>The chip’s Vss is mapped to ZIFs [2,4,30,38,39]</li>
<li>The rest of the pinout is given by <code>Pin Detect</code></li>
</ul>
<p>Easy right? But before finalizing the pinout, I decided to build a
little rig to avoid soldering the chip straight to the adapter.</p>
<h2 id="building-a-perfboard-rig">Building a perfboard rig</h2>
<div class="gallery-s">
<figure>
<div class="gallery-wrapper">
    
    <label for="img-14" class="zoom-item">
        <img src="https://pengoo.fr/articles/2026-dumping-bga-mcp-nand-flash/img/perfboard-rig.avif" alt="Perfboard rig (front and back)">
    </label>
</div>

<figcaption>Perfboard rig (front and back)</figcaption>
</figure>
</div>
<p>Not exactly a masterpiece, but it gets the job done…</p>
<p><u>Building steps</u></p>
<ul>
<li>Get a piece of perfboard with enough space for all the header pins,
my chip required 25 so I went with a 28x5 labeled perfboard</li>
<li>Solder your male header pins, keep a space near the pin for a solder
blob (where you’ll solder the wire from your chip)</li>
<li>Solder each male header to the right solder blob from under the
board</li>
<li>Probe the solder blobs with a multimeter in continuity mode to make
sure no blobs are accidentally soldered together</li>
<li>Stick the perfboard to a piece of cardboard using hot glue</li>
</ul>
<h2 id="finalizing-the-pinout">Finalizing the pinout</h2>
<p>To save brainpower while soldering, I made a diagram showing the
right balls to wire to the perfboard. Since I’ll be soldering on a
flipped chip, I mirrored the image:</p>
<div class="gallery-m">
<figure>
<div class="gallery-wrapper">
    
    <label for="img-15" class="zoom-item">
        <img src="https://pengoo.fr/articles/2026-dumping-bga-mcp-nand-flash/img/balls.avif" alt="MCP Ball-to-perfboard pinout">
    </label>
</div>

<figcaption>MCP Ball-to-perfboard pinout</figcaption>
</figure>
</div>
<p>Each soldered row will be separated with Kapton tape so that the
wires stay put and don’t touch each other.</p>
<p>After putting everything together, I got the following pinout:</p>
<div class="topcaption">
<p>Final pinout</p>
<table>
<thead>
<tr>
<th>MCP</th>
<th>Perfboard</th>
<th>T48</th>
</tr>
</thead>
<tbody>
<tr>
<td>IO8</td>
<td>U</td>
<td>ZIF 1 (IO8)</td>
</tr>
<tr>
<td>#WE</td>
<td>J</td>
<td>ZIF 3 (#WE)</td>
</tr>
<tr>
<td>RY/#BY</td>
<td>L</td>
<td>ZIF 9 (RY/#BY)</td>
</tr>
<tr>
<td>#CE</td>
<td>F</td>
<td>ZIF 10 (#CE)</td>
</tr>
<tr>
<td>CLE</td>
<td>H</td>
<td>ZIF 14 (CLE)</td>
</tr>
<tr>
<td>ALE</td>
<td>G</td>
<td>ZIF 15 (ALE)</td>
</tr>
<tr>
<td>#WP</td>
<td>K</td>
<td>ZIF 16 (#WP)</td>
</tr>
<tr>
<td>IO9</td>
<td>V</td>
<td>ZIF 19 (IO9)</td>
</tr>
<tr>
<td>IO10</td>
<td>W</td>
<td>ZIF 20 (IO10)</td>
</tr>
<tr>
<td>IO2</td>
<td>O</td>
<td>ZIF 21 (IO2)</td>
</tr>
<tr>
<td>IO7</td>
<td>T</td>
<td>ZIF 22 (IO7)</td>
</tr>
<tr>
<td>IO6</td>
<td>S</td>
<td>ZIF 23 (IO6)</td>
</tr>
<tr>
<td>IO5</td>
<td>R</td>
<td>ZIF 24 (IO5)</td>
</tr>
<tr>
<td>IO4</td>
<td>Q</td>
<td>ZIF 25 (IO4)</td>
</tr>
<tr>
<td>IO3</td>
<td>P</td>
<td>ZIF 26 (IO3)</td>
</tr>
<tr>
<td>IO1</td>
<td>N</td>
<td>ZIF 27 (IO1)</td>
</tr>
<tr>
<td>IO0</td>
<td>M</td>
<td>ZIF 28 (IO0)</td>
</tr>
<tr>
<td>Vss</td>
<td>A</td>
<td>ZIF 30 (Vss)</td>
</tr>
<tr>
<td>Vccn (The NAND’s Vcc)</td>
<td>C</td>
<td>ZIF 31 (Vcc)</td>
</tr>
<tr>
<td>IO15</td>
<td>X</td>
<td>ZIF 32 (IO15)</td>
</tr>
<tr>
<td>IO14</td>
<td>Y</td>
<td>ZIF 33 (IO14)</td>
</tr>
<tr>
<td>IO13</td>
<td>Z</td>
<td>ZIF 34 (IO13)</td>
</tr>
<tr>
<td>IO12</td>
<td>A2</td>
<td>ZIF 35 (IO12)</td>
</tr>
<tr>
<td>IO11</td>
<td>B2</td>
<td>ZIF 36 (IO11)</td>
</tr>
<tr>
<td>#RE</td>
<td>I</td>
<td>ZIF 40 (#RE)</td>
</tr>
</tbody>
</table>
</div>
<h1 id="wiring-that-nand">Wiring that NAND</h1>
<p><u>Quick PSA</u></p>
<ul>
<li>Don’t breathe the fumes</li>
<li>Ventilate</li>
<li>Wash your hands</li>
</ul>
<h2 id="the-tools">The Tools</h2>
<p>Most things can be ordered through aliexpress. The 45 degree bent
nozzle helps a lot when working under a microscope.</p>
<div class="left">
<ul>
<li>Removing the MCP
<ul>
<li>Hot air station (Atten ST-862D with 45 degree bent nozzles)</li>
<li>Tweezers</li>
<li>Thick no-clean flux</li>
<li>99% IPA, soft toothbrush</li>
<li>Kapton tape</li>
</ul></li>
<li>Dead-bugging the MCP
<ul>
<li>Microscope (optical and trinocular if enough $$$)</li>
<li>0.1mm enameled copper wire</li>
<li>Leaded solder balls (size will depend on your chip)</li>
<li>Kapton tape</li>
<li>Soldering Iron, fine conical tip, solder</li>
<li>Thick no-clean flux</li>
<li>99% IPA, soft toothbrush</li>
</ul></li>
<li>Wiring it all up
<ul>
<li>Short, high quality dupont cables or wrapping wire + tool</li>
</ul></li>
</ul>
</div>
<h2 id="removing-the-mcp">Removing the MCP</h2>
<p>The first step I took, was to calibrate the hot air station with an
oven thermometer. This isn’t strictly necessary but I figured it
wouldn’t hurt. Then, I practiced on a dead motherboard to dial in the
airflow and temperature.</p>
<p>Unfortunately, there’s no magic numbers. YMMV depending on the hot
air station, nozzle, solder, working distance, etc… I had to practice a
bit to find the right settings. Long story short:</p>
<ul>
<li>I started at 300°C</li>
<li>When small chips flew off, I reduced the airflow</li>
<li>If the chip wasn’t moving, couldn’t be nudged or the solder wouldn’t
shine, I upped the temperature or airflow</li>
</ul>
<p>In the end, I settled on 400°C at 40% airflow but, again, YMMV.
Here’s a practice session on a dead motherboard:</p>
<figure>
<div class="gallery-wrapper">
    
    <label for="img-16" class="zoom-item">
        <img src="https://pengoo.fr/articles/2026-dumping-bga-mcp-nand-flash/img/chip_removal.avif" alt="This took about 2 minutes">
    </label>
</div>

<figcaption>This took about 2 minutes</figcaption>
</figure>
<p>Removing chips with hot air wasn’t something I was used to, so I came
up with a checklist to make sure I didn’t mess things up:</p>
<ul>
<li>Remove any plastics (it will burn)</li>
<li>Protect the nearest components (Kapton tape/aluminium/coin…)</li>
<li>Heat the board and the chip by going around the chip multiple times
in a circular motion (may take some time)</li>
<li>Put some flux around the chip (reapply multiple times if
needed)</li>
<li>Lift the chip with tweezers when it starts to slide or responds to a
<strong>gentle</strong> nudge (shiny solder is also a good sign)</li>
<li>Clean the board with 99% isopropyl alcohol and a toothbrush</li>
</ul>
<p>Once I felt confident enough, I went for the real chip and…
everything went according to plan! Most pads had enough residual solder
left so I didn’t bother reballing the whole chip with a stencil. I only
reballed a few pads with flux, solder balls and a soldering iron (thick
flux keeps leaded balls in place).</p>
<p>To wrap things up, I cleaned the board with IPA and a soft
toothbrush. Then, I secured the chip to a piece of cardboard with Kapton
tape, so that it wouldn’t move while dead-bugging.</p>
<div class="gallery-m">
<figure>
<div class="gallery-wrapper">
    
    <label for="img-17" class="zoom-item">
        <img src="https://pengoo.fr/articles/2026-dumping-bga-mcp-nand-flash/img/dead-bug-start.avif" alt="Dead-bugging setup">
    </label>
</div>

<figcaption>Dead-bugging setup</figcaption>
</figure>
</div>
<h2 id="dead-bugging-the-mcp">Dead-bugging the MCP</h2>
<p>To save some time cutting 25 wires, I wrapped the wire around a piece
of cardboard and trimmed both ends to get equal lengths (keeping wires
short and of equal length is important when high-speed data lines are
involved). Then, I burned the wire’s insulating layer:</p>
<div class="gallery-xs">
<figure>
<div class="gallery-wrapper">
    
    <label for="img-18" class="zoom-item">
        <img src="https://pengoo.fr/articles/2026-dumping-bga-mcp-nand-flash/img/enamel_removal.avif" alt="Removing the enamel">
    </label>
</div>

<figcaption>Removing the enamel</figcaption>
</figure>
</div>
<p>Enameled wires are coated with a thin layer of insulation. A quick
way to burn it off is by dipping the tip of each wire into a hot solder
blob (iron at about 400°C). The tip of the wire should shine when the
coating comes off.</p>
<p>Once it was burned off, I followed the ball‑to‑perfboard pinout I
made earlier and started dead‑bugging the real chip. Each wire goes from
a pad on the MCP, to a solder blob on the perfboard rig.</p>
<div class="gallery-m">
<figure>
<div class="gallery-wrapper">
    
    <label for="img-19" class="zoom-item">
        <img src="https://pengoo.fr/articles/2026-dumping-bga-mcp-nand-flash/img/dead-bug.avif" alt="Dead-bugged chip">
    </label>
</div>

<figcaption>Dead-bugged chip</figcaption>
</figure>
</div>
<p>The wires are kept secured and insulated with layers of Kapton tape.
Because this is temporary and my flux is “no-clean” I didn’t wipe the
excess flux with IPA. It’s always best to do it though.</p>
<p>To finish things off, I wired the MCP to the modded adapter using
Dupont cables (make sure they aren’t too loose).</p>
<div class="gallery-m">
<figure>
<div class="gallery-wrapper">
    
    <label for="img-20" class="zoom-item">
        <img src="https://pengoo.fr/articles/2026-dumping-bga-mcp-nand-flash/img/setup.avif" alt="Final setup">
    </label>
</div>

<figcaption>Final setup</figcaption>
</figure>
</div>
<h1 id="dumping-that-nand">Dumping that NAND</h1>
<p>My NAND supports ONFI, if your NAND only supports the legacy
interface, most things are the same except you can’t use the ONFI
autodetect function and need to adjust every parameter manually
(Vcc,NAND id…) according to the datasheet.</p>
<p>Here’s the overall process for ONFI NANDs:</p>
<ul>
<li>Plug Adapter in T48 ZIF socket</li>
<li>Click <code>Select IC(S)</code>, select exact or closest matching
NAND in TSOP48 package.</li>
<li>Check <code>Pin Detect</code> and <code>Check ID</code></li>
<li>Open <code>Config OP.</code> tab</li>
<li>Scroll to <code>3. Customize NAND parameters</code></li>
<li>Check <code>Customize Setting</code></li>
<li>Set Vcc to your chip’s required voltage</li>
<li>Set <code>PIN CONFIGURATION</code> to <code>ONFI STD</code></li>
<li>Set <code>Bus Width</code> to your chip’s bus width</li>
<li>Click <code>View Config Result</code></li>
</ul>
<p>If the generated configuration looks good, click
<code>Auto identi. (ONFI)</code>. The IC name and NAND parameters should
change automatically. It doesn’t hurt to double check with the datasheet
to see if everything has been autodetected correctly.</p>
<div class="gallery-m">
<figure>
<div class="gallery-wrapper">
    
    <label for="img-21" class="zoom-item">
        <img src="https://pengoo.fr/articles/2026-dumping-bga-mcp-nand-flash/img/nand_auto_id.avif" alt="Auto identify ONFI">
    </label>
</div>

<figcaption>Auto identify ONFI</figcaption>
</figure>
</div>
<p>Before dumping the NAND, let’s run a quick sanity check to make sure
we get the right chip ID. Click on <code>Device</code> then
<code>Read ID</code>.</p>
<p>If you get any errors, or chip ID seems off:</p>
<ul>
<li>Check your wiring</li>
<li>Clean/reseat socket</li>
<li>Maybe the circuit can’t keep up with your NAND’s timings (also check
for ringing etc…)</li>
</ul>
<p><code>Read ID</code> worked? Nice. Time to dump the chip with
<code>Read</code>, but let me hit you with a NAND dilemma first:</p>
<h2 id="to-spare-or-not-to-spare">To spare, or not to spare?</h2>
<p>Each page in a NAND’s block holds two regions, <code>main</code> and
<code>spare</code>. <code>Main</code> holds the actual data while
<code>spare</code> holds metadata, like Error Correction Codes
(ECC).</p>
<p>Tools like binwalk can get confused by <code>spare</code> data, which
might get interpreted as garbage. You can choose to exclude
<code>spare</code> data under the <code>Config OP.</code> tab.</p>
<p>If your blocks are error-free, you may remove <code>spare</code> and
analyze the dump. Otherwise, you may need to repair bad blocks with ECC
metadata stored in <code>spare</code>. Error correction (among other
things) may be done by the chip itself (on-Die ECC), a controller or the
CPU/SoC.</p>
<p>Once everything was configured, I claimed my reward by pressing the
big <code>Read</code> button.</p>
<h1 id="hex-sweet-hex">Hex, sweet hex</h1>
<div class="gallery-m">
<figure>
<div class="gallery-wrapper">
    
    <label for="img-22" class="zoom-item">
        <img src="https://pengoo.fr/articles/2026-dumping-bga-mcp-nand-flash/img/flash_custom_nand_sucess.avif" alt="Pressing Read">
    </label>
</div>

<figcaption>Pressing <code>Read</code></figcaption>
</figure>
</div>
<p>Luckily, the firmware wasn’t fully encrypted, so I was able to dig
out some strings from low-entropy regions :)</p>
<div class="gallery-m">
<figure>
<div class="gallery-wrapper">
    
    <label for="img-23" class="zoom-item">
        <img src="https://pengoo.fr/articles/2026-dumping-bga-mcp-nand-flash/img/bootloader-str.avif" alt="Fun bootloader strings">
    </label>
</div>

<figcaption>Fun bootloader strings</figcaption>
</figure>
</div>
<p><strong>CONGRATS!</strong> You’ve just dumped a BGA NAND… now,
depending on your mood, next steps could be:</p>
<ul>
<li>Repairing bad blocks</li>
<li>Firmware analysis</li>
<li>Reflashing the chip</li>
<li>Cleaning, reballing and putting the chip back on the
motherboard</li>
<li>Discarding the chip :(</li>
</ul>
<h1 id="sources">Sources</h1>
<div class="sources">
<p><a
href="https://colinoflynn.com/2024/04/dumping-parallel-nand-with-glasgow"
class="uri">https://colinoflynn.com/2024/04/dumping-parallel-nand-with-glasgow</a>
<a
href="https://www.rapid7.com/blog/post/2022/04/07/lessons-in-iot-hacking-how-to-dead-bug-a-bga-flash-memory-chip"
class="uri">https://www.rapid7.com/blog/post/2022/04/07/lessons-in-iot-hacking-how-to-dead-bug-a-bga-flash-memory-chip</a>
<a
href="https://www.embedded.com/flash-101-the-nand-flash-electrical-interface"
class="uri">https://www.embedded.com/flash-101-the-nand-flash-electrical-interface</a>
<a
href="https://phisonblog.com/nand-flash-101-flash-device-interfaces-2"
class="uri">https://phisonblog.com/nand-flash-101-flash-device-interfaces-2</a>
<a href="https://lpcwiki.miraheze.org/wiki/Main_Page"
class="uri">https://lpcwiki.miraheze.org/wiki/Main_Page</a></p>
<p><span><a
href="https://commons.wikimedia.org/wiki/File:EMMC.jpg">Toniperis</a>,
<a href="https://creativecommons.org/licenses/by-sa/4.0">CC BY-SA
4.0</a>, via Wikimedia Commons</span></p>
</div>
<hr />
<p>Questions, comments? Send me an email :) (email in footer)</p>
			</div>
				</nav>
			</div>
								</div>
	</body>
</html>
]]></description>
</item>
</channel>
</rss>
