No Legs, No Problem:
Dumping BGA MCP
NAND
Flash
Firmware holds the good stuff: logic, bugs, and the occasional hard-coded secrets. In this case, the target device had firmware stored in NAND flashA type of non-volatile memory, used everywhere (phones, flash drives, SSDs…) within a BGA-packaged MCPMultiple 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). The chip wasn’t directly supported by my Flash programmer, so I had to improvise by:
- Modding an adapter
- Removing the chip with hot air
- Wiring the chip dead-bug styleSoldering wires to the underside of a chip. It kind of looks like a dead bug with its legs in the air. to the programmer
Intro
Flashrom 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™.
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. Bad idea. It turns out, the chip is an unsupported BGA MCP which didn’t fit any of my adapters :(
Firmware… you there?
Looking for an easy way to get the phone’s firmware, I checked the usual suspects:
- The vendor’s website
- Companion apps
- OTA updates from the device that could be MITM’ed
- Known vulnerabilities
- Firmware dumps on forums
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 MAUI.
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.
Before removing the shielding, I looked at the motherboard again to check if I had missed any obvious debug interface (JTAG,SWD,UART…). Some manufacturers are nice enough to leave them labeled and exposed as ports or test pads.
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. Not that fun, 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
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.
Because I wasn’t really familiar with MCPs, I took a look at the datasheet and noticed that it held both the phone’s Flash and RAM in a single chip. Nice! The only problem is, it came in a BGA package…
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.
If the chip has legs, it’s usually 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:
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.
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?)
In my case, I easily found the chip’s datasheet online (W71NW11GC1DW) and after a quick read:
- The chip comes in a BGA package
- It’s an MCP (Multi Chip Package), containing both NAND and RAM
- The MCP’s NAND has a 16-bit bus and supports ONFI
- The MCP’s NAND needs 1.8V
Although the MCP isn’t directly supported by the T48, the NAND inside
it W29N01GW is very similar to another NAND from the same
vendor that’s already supported (W29N01HWSINA@TSOP48).
Here’s a table comparing the two chips based on their datasheets:
| W29N01GW | W29N01HWSINA@TSOP48 | |
|---|---|---|
| NAND tech | SLC | - |
| Density | 1GB | - |
| Page size | 2,112 bytes | - |
| Block size | 64 pages (128K + 4K bytes) | - |
| ONFI | yes | - |
| Bus width | 16-bit | - |
| Vcc | 1.8V | - |
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…).
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:
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.
The problem is, the balls are only 0.3mm wide… pretty tiny. 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
Modding the adapter
You’d think wiring a NAND to the T48 would be straightforward. Just plug some wires in the ZIF socket right? Nope, you have to go through an adapter first.
If you’re working with TSOP NANDs, you’ll need to plug the
ADP_F48_EX-2 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… kinda sucks, but it is what is
is.
The check could probably be bypassed in software, but I opted for something dumber instead…
This mod expands the adapter’s header pins upwards to two new header rows, this way:
- The adapter is plugged in
- NAND functions are unlocked
- Any NAND can be wired using DuPont connectors, probes, or a wire-wrap tool
Modding steps
- 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
- Solder
ADP_F48_EX-2in the middle - Solder 10 2.54mm headers pins to each side
- Solder wrapping wire between each pin, insulation is key for good signal integrity
No pinout, we ball (grid array)
Finding the adapter’s pinout
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:
- Leveraging the
Pin Detectfeature of Xgecu’s software - Reading the datasheet of the selected (supported) chip
- Probing the adapter
XGecu’s software will show the pinout for the selected NAND when:
Pin Detectis checked- The adapter is plugged without a chip in its socket
My goal is to dump the unsupported W29N01GW NAND chip,
so I launched Xgecu’s software and selected the closest matching chip in
a TSOP48 package (W29N01HWSINA@TSOP48). Then, I checked
Pin Detect and clicked the READ button:
To make sense of the pinout given by Pin Detect, you’ll
need to read the T48 ZIF socket this way:
| ZIF 1 | ZIF 40 |
| ZIF 2 | ZIF 39 |
| … | … |
| ZIF 19 | ZIF 22 |
| ZIF 20 | ZIF 21 |
| locking pin |
Unfortunately, Pin Detect 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:
As you can see:
- Vcc is assigned to IC pins 12 and 37
- Vss is assigned to IC pins 13 and 36
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:
ADP_F48-EX2 pinout
| Socket pin | ZIF |
|---|---|
| 1 | NC |
| 2 | NC |
| 3 | NC |
| 4 | 6 |
| 5 | 7 |
| 6 | 8 |
| 7 | 9 |
| 8 | 40 |
| 9 | 10 |
| 10 | 11 |
| 11 | NC |
| 12 | 5 |
| 13 | 39,38,30,2,4 (Vss) |
| 14 | 12 |
| 15 | 13 |
| 16 | 14 |
| 17 | 15 |
| 18 | 3 |
| 19 | 16 |
| 20 | NC |
| 21 | NC |
| 22 | NC |
| 23 | NC |
| 24 | NC |
| 25 | 39,38,30,2,4 (Vss) |
| 26 | 1(70Ohm) |
| 27 | 19(70Ohm) |
| 28 | 20(70Ohm) |
| 29 | 14(70Ohm) |
| 30 | 15(70Ohm) |
| 31 | 21(70Ohm) |
| 32 | 16(70Ohm) |
| 33 | 36(70Ohm) |
| 34 | 13 |
| 35 | NC |
| 36 | 39,38,30,2,4 (Vss) |
| 37 | 31 |
| 38 | NC |
| 39 | 2(560Ohm),3(560Ohm),4 |
| 40 | 35(70Ohm) |
| 41 | 17(70Ohm) |
| 42 | 18(70Ohm) |
| 43 | 19(70Ohm) |
| 44 | 20(70Ohm) |
| 45 | 34(70Ohm) |
| 46 | 33(70Ohm) |
| 47 | 32(70Ohm) |
| 48 | 39,38,30,2,4 (Vss) |
- Ground (Vss) seems to be shared across ZIFs [2,4,30,38,39]
- NC means “Not Connected” here
With the full picture in mind, I got back to the chip:
- The chip’s Vcc is mapped to ZIFs [5,31]
- The chip’s Vss is mapped to ZIFs [2,4,30,38,39]
- The rest of the pinout is given by
Pin Detect
Easy right? But before finalizing the pinout, I decided to build a little rig to avoid soldering the chip straight to the adapter.
Building a perfboard rig
Not exactly a masterpiece, but it gets the job done…
Building steps
- 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
- Solder your male header pins, keep a space near the pin for a solder blob (where you’ll solder the wire from your chip)
- Solder each male header to the right solder blob from under the board
- Probe the solder blobs with a multimeter in continuity mode to make sure no blobs are accidentally soldered together
- Stick the perfboard to a piece of cardboard using hot glue
Finalizing the pinout
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:
Each soldered row will be separated with Kapton tape so that the wires stay put and don’t touch each other.
After putting everything together, I got the following pinout:
Final pinout
| MCP | Perfboard | T48 |
|---|---|---|
| IO8 | U | ZIF 1 (IO8) |
| #WE | J | ZIF 3 (#WE) |
| RY/#BY | L | ZIF 9 (RY/#BY) |
| #CE | F | ZIF 10 (#CE) |
| CLE | H | ZIF 14 (CLE) |
| ALE | G | ZIF 15 (ALE) |
| #WP | K | ZIF 16 (#WP) |
| IO9 | V | ZIF 19 (IO9) |
| IO10 | W | ZIF 20 (IO10) |
| IO2 | O | ZIF 21 (IO2) |
| IO7 | T | ZIF 22 (IO7) |
| IO6 | S | ZIF 23 (IO6) |
| IO5 | R | ZIF 24 (IO5) |
| IO4 | Q | ZIF 25 (IO4) |
| IO3 | P | ZIF 26 (IO3) |
| IO1 | N | ZIF 27 (IO1) |
| IO0 | M | ZIF 28 (IO0) |
| Vss | A | ZIF 30 (Vss) |
| Vccn (The NAND’s Vcc) | C | ZIF 31 (Vcc) |
| IO15 | X | ZIF 32 (IO15) |
| IO14 | Y | ZIF 33 (IO14) |
| IO13 | Z | ZIF 34 (IO13) |
| IO12 | A2 | ZIF 35 (IO12) |
| IO11 | B2 | ZIF 36 (IO11) |
| #RE | I | ZIF 40 (#RE) |
Wiring that NAND
Quick PSA
- Don’t breathe the fumes
- Ventilate
- Wash your hands
The Tools
Most things can be ordered through aliexpress. The 45 degree bent nozzle helps a lot when working under a microscope.
- Removing the MCP
- Hot air station (Atten ST-862D with 45 degree bent nozzles)
- Tweezers
- Thick no-clean flux
- 99% IPA, soft toothbrush
- Kapton tape
- Dead-bugging the MCP
- Microscope (optical and trinocular if enough $$$)
- 0.1mm enameled copper wire
- Leaded solder balls (size will depend on your chip)
- Kapton tape
- Soldering Iron, fine conical tip, solder
- Thick no-clean flux
- 99% IPA, soft toothbrush
- Wiring it all up
- Short, high quality dupont cables or wrapping wire + tool
Removing the MCP
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.
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:
- I started at 300°C
- When small chips flew off, I reduced the airflow
- If the chip wasn’t moving, couldn’t be nudged or the solder wouldn’t shine, I upped the temperature or airflow
In the end, I settled on 400°C at 40% airflow but, again, YMMV. Here’s a practice session on a dead motherboard:
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:
- Remove any plastics (it will burn)
- Protect the nearest components (Kapton tape/aluminium/coin…)
- Heat the board and the chip by going around the chip multiple times in a circular motion (may take some time)
- Put some flux around the chip (reapply multiple times if needed)
- Lift the chip with tweezers when it starts to slide or responds to a gentle nudge (shiny solder is also a good sign)
- Clean the board with 99% isopropyl alcohol and a toothbrush
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).
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.
Dead-bugging the MCP
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:
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.
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.
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.
To finish things off, I wired the MCP to the modded adapter using Dupont cables (make sure they aren’t too loose).
Dumping that NAND
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.
Here’s the overall process for ONFI NANDs:
- Plug Adapter in T48 ZIF socket
- Click
Select IC(S), select exact or closest matching NAND in TSOP48 package. - Check
Pin DetectandCheck ID - Open
Config OP.tab - Scroll to
3. Customize NAND parameters - Check
Customize Setting - Set Vcc to your chip’s required voltage
- Set
PIN CONFIGURATIONtoONFI STD - Set
Bus Widthto your chip’s bus width - Click
View Config Result
If the generated configuration looks good, click
Auto identi. (ONFI). 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.
Before dumping the NAND, let’s run a quick sanity check to make sure
we get the right chip ID. Click on Device then
Read ID.
If you get any errors, or chip ID seems off:
- Check your wiring
- Clean/reseat socket
- Maybe the circuit can’t keep up with your NAND’s timings (also check for ringing etc…)
Read ID worked? Nice. Time to dump the chip with
Read, but let me hit you with a NAND dilemma first:
To spare, or not to spare?
Each page in a NAND’s block holds two regions, main and
spare. Main holds the actual data while
spare holds metadata, like Error Correction Codes
(ECC).
Tools like binwalk can get confused by spare data, which
might get interpreted as garbage. You can choose to exclude
spare data under the Config OP. tab.
If your blocks are error-free, you may remove spare and
analyze the dump. Otherwise, you may need to repair bad blocks with ECC
metadata stored in spare. Error correction (among other
things) may be done by the chip itself (on-Die ECC), a controller or the
CPU/SoC.
Once everything was configured, I claimed my reward by pressing the
big Read button.
Hex, sweet hex
ReadCONGRATS! You’ve just dumped a BGA NAND… now, depending on your mood, next steps could be:
- Repairing bad blocks
- Firmware analysis
- Reflashing the chip
- Cleaning, reballing and putting the chip back on the motherboard
- Discarding the chip :(
Sources
https://colinoflynn.com/2024/04/dumping-parallel-nand-with-glasgow https://www.rapid7.com/blog/post/2022/04/07/lessons-in-iot-hacking-how-to-dead-bug-a-bga-flash-memory-chip https://www.embedded.com/flash-101-the-nand-flash-electrical-interface https://phisonblog.com/nand-flash-101-flash-device-interfaces-2 https://lpcwiki.miraheze.org/wiki/Main_Page
Toniperis, CC BY-SA 4.0, via Wikimedia Commons
Questions, comments? Send me an email :) (email in footer)