I had this problem trying to push back a backup of my Samsung Galaxy S2, using ADB with the CWM (clockworkmod) recovery tool. When pushing to a device file, ADB simply deletes the block device file and creates a regular file in its place, and thus no data actually ends up on the mmcblk0 device.
Unfortunately, piping the output of a command into "adb shell" is not implemented either, and the "adb forward" unix sockets feature also doesn't seem to work, so it's difficult to get the backup back into the device.
The solution is to pipe the image file to netcat, and use ADB's TCP port forwarding to direct the stream into your device. However, if your CWM/busybox doesn't have network tools, you'll also need to download the arm-v7 static binary version of busybox with all the applets from http://www.busybox.net/downloads/binaries/latest/ to be able to run netcat on your device.
# wget "http://www.busybox.net/downloads/binaries/latest/busybox-armv7l"
# adb push busybox-armv7l /tmp/busybox
# adb forward tcp:6789 tcp:9876
# adb shell
~ # chmod +x /tmp/busybox
~ # /tmp/busybox nc -l -p 9876 > /dev/block/mmcblk0
Then, in a new shell:
# dd if=your-image-file.img | nc localhost 6789 &
"dd" is better than "cat" because you can check the copy's progress at intervals (replace 5647 with the PID of the DD command):
# kill -USR1 5647
48+0 records in
47+0 records out
49283072 bytes (49 MB) copied, 17.6145 s, 2.8 MB/s
Beware that writing to mmcblk0 (or the equivalent on your Android device) will obliterate even the boot and recovery partitions so is a great way to brick your device. For the record, my restore worked fine ;-)