WelcomeWelcome | FAQFAQ | DownloadsDownloads | WikiWiki

Author Topic: Counterfeit and fake flash devices - let's fight back!  (Read 2718 times)

Offline CentralWare

  • Retired Admins
  • Hero Member
  • *****
  • Posts: 765
Counterfeit and fake flash devices - let's fight back!
« on: February 10, 2024, 09:41:02 AM »
Hey guys, lend me a hand here if you would?
I'm tinkering with the idea but I'm having a difficult time recalling exactly how DD navigates a block device.  (seek/skip/etc)

NOTE: I'm making everything up as I type -- this is completely untested...

Scenario:
  • Let's pretend we have a 16GB flash based device (SD card, USB flash drive, etc.)
  • I use fdisk and/or parted to get the total drive size, in bytes
  • We have a string STRING="ABCDEFGabcdefg" saved as mystring.txt and STRLEN=${#STRING}
  • We use DD to do a write/read test on the device

Initially we're going to use a generic dummy image as our flash drive for testing purposes
Code: [Select]
[ ! -f testdrive.img ] && dd if=/dev/zero of=testdrive.img bs=1GB count=16Go grab a drink while this propagates...


I want to create a loop (starting with zero) and increment by 256MB
Code: [Select]
ONEMEG=1048576
MULTIPLIER=$(expr $ONEMEG \* 256)
DRIVESIZE=$(fdisk -l $DRIVE | grep Disk | grep bytes | awk '{print $5}')
INDEX=0
while [ true ]
do
     POSITION=$(expr $INDEX \* $MULTIPLIER)
     [ $POSITION -gt $DRIVESIZE ] && break
     dd if=mystring.txt of=$DRIVE bs=$STRLEN count=1 seek=$POSITION iflag=seek_bytes 2>/dev/null || exit 1
     sync; sync
done
(If any of the above is incorrect, please set me straight :) )

Note: the above math for POSITION > DRIVESIZE is wrong as it's more involved since we have to subtract STRLEN from DRIVESIZE and such to ensure the STRING can be written to the drive, but it gets the point across as to the intention.

The next pass we want to read from the same position(s) we just wrote to and compare what we read to mystring.txt
I'm thinking, IF this is correct...
Code: [Select]
dd if=$DRIVE of=dump.txt bs=$STRLEN count=1 seek=$POSITION iflag=seek_bytes 2>/dev/null
[ ! "$(diff mystring.txt dump.txt)" == "" ] && echo "$POSITION mismatch"
(Again, if any of the above is incorrect, please feel free to correct me :) )

Anyhow, theoretically, if we did this on a valid storage device everything should write and read back to us as expected -- assuming my DD concept is viable.  The controller for the block device "should" forward to the POSITION we're after in BYTES without us having to do block/sector math, but again -- in theory.

If we did this on a FAKE storage device, it's my theory that addressing would very likely fail this "test" when we'd go back to read the content as most fakeware works on a buffering concept -- fill the "real" storage one block at a time until we run out, then start over -- and it's the start over part that usually is when you notice your files are being lost.  My theory is that they're not programming the fakeware intelligently enough to have addresses high enough to actually store information -- so our READ test "should" fail.

If you guys wouldn't mind lending a hand and we put together a script to DDify our test subject, I have plenty of "fake flash" devices here we can do real-world testing (and tweaking) with!

Thanks!
« Last Edit: February 10, 2024, 09:42:53 AM by CentralWare »

Offline Rich

  • Administrator
  • Hero Member
  • *****
  • Posts: 11635
Re: Counterfeit and fake flash devices - let's fight back!
« Reply #1 on: February 11, 2024, 02:06:18 PM »
Hi CentralWare
I'm not clear on your exact plan, so here's what I came up with.

For data:
I copied the first Mbyte of data from a  .png  image into a file.
Prior to each write to the device, I rotate first byte of data file
to end of file. That allows for 1 million different data blocks.

First the device gets filled, then verified against the original data.

Using an old 128Mb thumb drive writing took 66 seconds and
verification took 20 seconds.

Code: [Select]
#!/bin/sh

OneMeg=`calc 1024*1024`

Seek=0

# Clear out previous results.
> Results.txt

# Create a 1 Mega byte random data file.
head -c $OneMeg Rand.png > Rand.data

# Start time.
Start=`date +"%s.%N"`

while true
do

# Rotate first byte of data file to end of file.
# Strip first byte from Rand.data and save remainder in tmp.data.
tail -c +2 Rand.data > tmp.data
# Grab first byte from Rand.data and appendit to tmp.data.
head -c 1 Rand.data >> tmp.data

dd if=tmp.data of=/dev/sdg bs=1M seek="$Seek" count=1 >> Results.txt 2>&1
# Exit loop when dd error occurs, probably from write past end of device.
[ $? -ne 0 ] && break
# Advance Seek for next 1 Meg block.
Seek=$(( $Seek + 1 ))

# Move tmp.data to Rand.data for next rotate operation.
mv tmp.data Rand.data
done

# End time.
Finish=`date +"%s.%N"`

echo -e "Elapsed Time=$(echo $Finish - $Start | bc -l)\t Seek=$Seek"

tail -n5 Results.txt
echo

echo -e "\n\n\nReading back data \n\n" >> Results.txt

Seek=0

# Create a 1 Mega byte random data file.
head -c $OneMeg Rand.png > Rand.data

# Start time.
Start=`date +"%s.%N"`

while true
do

# Rotate first byte of data file to end of file.
# Strip first byte from Rand.data and save remainder in tmp.data.
tail -c +2 Rand.data > tmp.data
# Grab first byte from Rand.data and appendit to tmp.data.
head -c 1 Rand.data >> tmp.data

dd if=/dev/sdg of=Flash.data bs=1M skip="$Seek" count=1 >> Results.txt 2>&1
# Exit loop when dd error occurs, probably from read past end of device.
[ $? -ne 0 ] && break

Error="`diff -q tmp.data Flash.data 2>&1 | tr '\n' '\t'`"
# If diff detects an error, include the value of Seek.
[ ! -z "$Error" ] && echo -e "$Error\tSeek=$Seek" >> Results.txt

# Advance Seek for next 1 Meg block.
Seek=$(( $Seek + 1 ))

# Move tmp.data to Rand.data for next rotate operation.
mv tmp.data Rand.data
done

# End time.
Finish=`date +"%s.%N"`

echo -e "Elapsed Time=$(echo $Finish - $Start | bc -l)\t Seek=$Seek"

tail -n5 Results.txt

Offline CentralWare

  • Retired Admins
  • Hero Member
  • *****
  • Posts: 765
Re: Counterfeit and fake flash devices - let's fight back!
« Reply #2 on: February 12, 2024, 04:17:31 AM »
@Rich: The theory behind my concept is not to write every byte, but instead, to write 1MB of content, skip to somewhere else on the device and then write again.  Even 1MB is over-kill (my first concept used 16 bytes, which worked, but requires many more writes to accomplish the same task on a certain type of "fake.") NTFS formats crash due to WHERE they place their tables - which tend not to exist (location = ~3GB Address) on most of these types of fakes.

For some fakes, the hand-shake data has been rewritten (which is either 48 bytes or 132 (I think?) bytes -- haven't read up on SDA in years.)  For these devices, you should be able to dd SKIP=[1GB] of 1GB increments and the test should fail once you've exceeded the "true" physical flash storage amount. These devices are usually FAT/32/exFAT formatted and seem to work perfectly from day one as FAT has a bottom-up data model. These fakes also tend to crash when attempting to format them NTFS.  (Note: for chips in the MB size ranges, obviously testing in X MB increments - though I've never seen a real fake first-hand from that era.)

The next type of fake is a controller rewrite (more complex) where a "cache" is created to remember the last X number of writes, where they were parked/written in DATA and how much content they contained overall. Mind you, an SD card reads/writes in BITS and/or NIBBLES (4 bits) so the controller's addressing scheme works quite differently than "dd" sees it so sometimes this gets seen as multiple locations of "good" memory and multiple bad ones.  This "cache" is usually about 10% or so of the flash drives true storage space, the "data" is the remainder.  DATA will begin to fail once the cache is filled and begins to dispose of the oldest writes (FIFO) --- thus SMALL WRITES will fill the device's write cache and cause it to corrupt data the quickest.  THIS is my goal with this part of the project, but I need to start off with something we can easily trace as to WHEN we exceeded the cache.

There are two other fake "types" that we've come across (there may be others) but the above two are the most popular concepts from an engineering standpoint - or at least from what we've purchased to date (there's a ton more to choose from.) There's also a new kid in town which looks as though it's creating caches "on the fly" but we only have one of these units and it's not stable enough to really get a good read on it.

My "exact plan" is to have DD write to BYTE ADDRESS 1,024 (by seek/skip) and write "ABC" at that location, then jump to another address and write "ABC" again.  I then need to make sure that if I reverse the process, DD should be able to READ from address 1,024 and the first three bytes should be "ABC" and so on.  My Long Winded session above may give insight as to why, but it's 4-something in the morning, so no promises! :)

Note: My setup I'm putting together contains a virtual SD (file image that'll be losetup/loop accessed), an actual/tested SD and a known to be fake SD.  There's also going to be exact duplicates of each as I want to do a little bit shifting to see if there are other tell-tale signs visible from a hardware layer.  (We'll be making our own SD card reader to play middle-man - parts are on order.)

Offline Rich

  • Administrator
  • Hero Member
  • *****
  • Posts: 11635
Re: Counterfeit and fake flash devices - let's fight back!
« Reply #3 on: February 12, 2024, 01:47:17 PM »
Hi CentralWare
OK, I did spot some issues.
Code: [Select]
tc@E310:~$ dd --help
Usage: dd [OPERAND]...
  or:  dd OPTION
Copy a file, converting and formatting according to the operands.

 ----- Snip -----

  seek=N          skip N obs-sized blocks at start of output
  skip=N          skip N ibs-sized blocks at start of input

 ----- Snip -----

Each FLAG symbol may be:

 ----- Snip -----

  skip_bytes  treat 'skip=N' as a byte count (iflag only)
  seek_bytes  treat 'seek=N' as a byte count (oflag only)

 ----- Snip -----

Some of your operands and flags appear to be incorrect.
... I want to create a loop (starting with zero) and increment by 256MB
Code: [Select]

 ----- Snip -----

     dd if=mystring.txt of=$DRIVE bs=$STRLEN count=1 seek=$POSITION iflag=seek_bytes 2>/dev/null || exit 1

 ----- Snip -----

(If any of the above is incorrect, please set me straight :) ) ...
I think you wanted:
Code: [Select]
dd if=mystring.txt of=$DRIVE bs=$STRLEN count=1 seek=$POSITION oflag=seek_bytes 2>/dev/null || exit 1
Quote
... I'm thinking, IF this is correct...
Code: [Select]
dd if=$DRIVE of=dump.txt bs=$STRLEN count=1 seek=$POSITION iflag=seek_bytes 2>/dev/null
 ----- Snip -----
(Again, if any of the above is incorrect, please feel free to correct me :) ) ...
That should probably be:
Code: [Select]
dd if=$DRIVE of=dump.txt bs=$STRLEN count=1 skip=$POSITION iflag=skip_bytes 2>/dev/null

Offline andyj

  • Hero Member
  • *****
  • Posts: 1036
Re: Counterfeit and fake flash devices - let's fight back!
« Reply #4 on: February 12, 2024, 04:42:17 PM »
One of the easiest ways I've found to check/debug situations like this is to write the address of a location into that location. This helps find off-by-one in comms, but here you can just write the block number as a string into the block. I wouldn't write the same or random values to each location because you wouldn't have a way to differentiate which location it came from. Also, save some time and start from the end as this is where the fakes will likely fail first.

Code: [Select]
TEST=sdx
LAST=$(($(fdisk -l /dev/$TEST | grep sectors$ | cut -d\  -f7) - 1))
INSTR="This should be sector $LAST"
echo $INSTR | dd of=/dev/$TEST count=1 seek=$LAST
OUTSTR=$(dd if=/dev/$TEST count=1 skip=$LAST)
test "$INSTR" == "$OUTSTR" && echo pass || echo fail

Unless you have a way to have many devices connected at once, automating doesn't seem worthwhile if you are manually swapping devices each time. You can get fancy and divide the number of sectors by some prime number like 13 and write / read back in a loop just to be sure. If caching is a concern then you can pick a larger number or just brute force write a value to every sector and see what you get back if you have the time. It's probably safe to say that any error would indicate a fake so just exit the loop on any fault.

Offline CentralWare

  • Retired Admins
  • Hero Member
  • *****
  • Posts: 765
Re: Counterfeit and fake flash devices - let's fight back!
« Reply #5 on: February 12, 2024, 08:32:59 PM »
@andyj:
Quote
Unless you have a way to have many devices connected at once
Seven 7-Port USB3 hubs all plugged into an eighth hub (49 simultaneous ports)
Granted, we've never run four dozen SD/USB devices for "fake" testing in a single session.

Prime number: reasonable consideration -- probably not overly important (I'll explain)
Random values: also not likely necessary for phase 1 read/write tests (again, will explain)
Start from last SECTOR: Due to the math necessary to calculate bytes per sector, physical versus logical sectors, etc. I figured it may be more prudent to use BYTE addressing since it was available in dd and can be easier to visualize.  From the END and work backward might be an option, but I'd still need to create written blocks near the beginning (see below) and it MAY be necessary to ignore the VERY LAST sector if it errors out DD as it may not be a "whole" sector even in valid (albeit, cheap) media.

Explanation: If we can reasonably ensure that the number of writes we're putting onto the flash device will exceed what is (calculated) larger than an assumed/estimated cache, WHAT we actually write is not horribly important -- so writing the same string over and over again (I used a 16 Byte example as it was easy to depict on paper here) is easy to accomplish, to read-verify and it's the same string over and over again, so there's no "logic" necessary to run the comparison.  This "should" be the fastest method to push tiny little byte packets onto flash media.  Since there's no file system involved, we shouldn't have block sizes to deal with, either - so 16 BYTES should in theory be...  16 BYTES, not 16KILObytes if that's the current format.  As such, Phase 1's read/write test "should" be very quick.

Secondly, more times than not DD will crash (exit with error) while writing to the bogus address to where a read verification won't be an option anyway, so in my mind, random seeds, primes, etc. should not be necessary as they're just CPU cycles spent on trying to fool-proof the system early on.  PHASE 1 just writes to an arbitrary location near the beginning of the flash, jumps in larger increments (say, 1/32 of the entire "reported" flash size) and checks to see if writing to each of these 32 areas comes back without error and with verifying the basic string of text.  Additionally, reading from ZERO and working upward here can show us where the cliff exists (the end of the "true" flash storage area) but if it's a fake, not too many consumers are going to care how big it was supposed to be.

PHASE 2 is all about filling up a fake flash cache.  The amount of DATA we're writing is now less important than the number of TIMES we write to it.  This is where your suggestion of writing the ADDRESS as the STRING would likely work out well by prefixing the number with zeros or some other padding we can rely on.

NOTE: Most fakes will fail during these first two phases, both of which should be reasonably quick and painless.

If the device passes PHASE 1 and PHASE 2, we may then want to move into more of a "byte for byte" mentality; my original post mentions creating 1MB blocks and staggering them across the flash drive at every so many MB in between.  We randomly pick one of the first dozen or so write zones as our corruption test.  Every X number of writes we then read the written data to make sure it's properly making it to the flash.  Every Y number of writes we re-read our corruption test area.  Once we make it to the end, we increment our offset and repeat the staggered approach all the while re-reading the same test zone(s) to make sure the first writes we made remain stable.  PHASE 3 is more of a reliability test as well as a method to catch overly elaborate fakes - it also takes the most amount of time, of course, since we're potentially writing an entire ###GB flash drive.

@Rich: Your attention to detail is always appreciated! :)  Yes, I knew seek/skip would both come into play -- at four or so in the morning I'm guessing "who's on first" is a stretch.

Thank you gentlemen; I'm going to let all of this soak in and get an earlier than usual rest tonight - long day tomorrow!

@andyj: I'll get an update your way by roughly the end of the weekend; I haven't finished mod testing and "free time" tends to come and go.

Offline jazzbiker

  • Hero Member
  • *****
  • Posts: 934
Re: Counterfeit and fake flash devices - let's fight back!
« Reply #6 on: February 13, 2024, 04:04:29 AM »
If I'd face the necessity to regularly test many potential fake devices, I'd engage the small fleet of low-power Raspberries (You better know which ones), compile f3 package essentials for ARM and keep them ready to fight at 24/7/365 shedule recruiting new staff on demand.

Offline CentralWare

  • Retired Admins
  • Hero Member
  • *****
  • Posts: 765
Re: Counterfeit and fake flash devices - let's fight back!
« Reply #7 on: February 13, 2024, 04:54:36 AM »
@jazzbiker: No clue what you're referring to! :)
Though there's a slight issue...  I'd have to ARM them with card readers and/or USB!

...though I could use Picos...

Offline jazzbiker

  • Hero Member
  • *****
  • Posts: 934
Re: Counterfeit and fake flash devices - let's fight back!
« Reply #8 on: February 13, 2024, 05:46:56 AM »
@jazzbiker: No clue what you're referring to! :)
Though there's a slight issue...  I'd have to ARM them with card readers and/or USB!

...though I could use Picos...

Picos not Linux-capable, as far as I know. I saw Model A Raspberries, they are less consuming. For Pi1 Model A they say about less of 1 W consumption. USB socket is present.

In x86 TinyCore one can load everything into memory using copy2fs.flg, then unmount the boot device (losing ability to backup) and disconnect it. Does piCore allows the same trick, freeing the card reader for spare usage? Still it is microSD, not full-size ...

Edit. In theory an adapter for connecting full-size SD card to microSD socket is not impossible.
« Last Edit: February 13, 2024, 05:50:17 AM by jazzbiker »

Offline CentralWare

  • Retired Admins
  • Hero Member
  • *****
  • Posts: 765
Re: Counterfeit and fake flash devices - let's fight back!
« Reply #9 on: February 13, 2024, 05:48:29 AM »
Preliminary tests are in!

Virtual drive (16GB sparse) was the guinea-pig and passed with flying colors.
Working/tested Cheap China MicroSD card of 400GB - again, passed with Aces.
Fake Cheap China 512GB MicroSD wolf in a mis-cut 64GB sheep's clothing with the "New Kid In Town" caching system -- DETECTED as a failure in a matter of SECONDS.
(See screen shot)

Here are the results:
1) By starting at the END of the card's storage (Test 1B) testing does not instantly detect and cause it to abort.
    Type 1 fakes WOULD fail this method and the Test 1A method.

2) By starting at the beginning and incrementing by 1/128th of the drive's reported size takes too long as the DATA is actually being written to the true SD storage and read back at ~15-25MB/s
    This was improved upon by skipping more space in between writes in Test 1A, thus causing longer address records the cache has to record and retain and allowing us to "spend" the cache area more quickly.

3) Once the caches were full, all further tests failed as there was simply not enough time allowed for the SD internal controller to clear out previously written sectors in order to write the new ones over them.  File systems usually have a much slower approach to this; writing directly to the flash controller puts the controller's programming to the test!


FAKE MEDIA thus far fails different testing zones and as such, completes in record time.

REAL MEDIA takes a good deal longer as the tests are mildly thorough without an "every byte" approach, though a "complete" byte for byte test will be added to the system (as an option) once it's more robustly tested.

NOTE: PICO doesn't have to be LINUX in order to accomplish the task.  Just being able to READ and WRITE to an I2C or SPI connected card reader or USB port is all we need.

Offline vinceASPECT

  • Hero Member
  • *****
  • Posts: 801
Re: Counterfeit and fake flash devices - let's fight back!
« Reply #10 on: February 13, 2024, 11:30:00 AM »
i Have been reading this.  Fakes    will   paint  tech in a bad light.

......warranty   &    "returns"  &  refund  or  replace  ......within  the  remit  of  retail  statute  &  Rights.........
( .....for  citizens  solution  )  
C.

Offline CentralWare

  • Retired Admins
  • Hero Member
  • *****
  • Posts: 765
Re: Counterfeit and fake flash devices - let's fight back!
« Reply #11 on: February 14, 2024, 09:25:42 AM »
The enclosed script should be used with extreme care!
This is a DESTRUCTIVE TEST - be sure to back up your media before running this script.
Additionally, DOUBLE CHECK to ensure the drive you enter as
VDISK=/dev/sd## on line 5 is in fact the device you want to scan.

Fakes will paint tech in a bad light.
Fake PEOPLE is what put things in a bad light -- people too lazy or too corrupt to make an honest living.  This is why we do what we do.

Offline CentralWare

  • Retired Admins
  • Hero Member
  • *****
  • Posts: 765
Re: Counterfeit and fake flash devices - let's fight back!
« Reply #12 on: February 14, 2024, 09:28:53 AM »
NOTE: It's not just the corrupt people who hack these devices that are to blame.
The manufacturers who are willing to sell their rejects are equally to blame.
(It's not like those rejects could serve any other purpose!!!)

Offline andyj

  • Hero Member
  • *****
  • Posts: 1036
Re: Counterfeit and fake flash devices - let's fight back!
« Reply #13 on: February 14, 2024, 06:13:33 PM »
If I was to guess I'd say the manufacturers intend to destroy their rejects to protect their name, but the person at that manufacturer in charge of destroying them is instead selling them to whoever will pay anything for them. A combination of poorly paid people and easy money.

Offline gadget42

  • Hero Member
  • *****
  • Posts: 793
Re: Counterfeit and fake flash devices - let's fight back!
« Reply #14 on: March 07, 2024, 09:46:53 AM »
after reviewing:
https://forum.tinycorelinux.net/index.php/topic,26897.0.html

and visiting the referenced register dot com links, naturally went poking and found this:

https://www.theregister.com/2024/02/07/failed_usb_sticks
The fluctuation theorem has long been known for a sudden switch of the Hamiltonian of a classical system Z54 . For a quantum system with a Hamiltonian changing from... https://forum.tinycorelinux.net/index.php/topic,25972.msg166580.html#msg166580