How do I extract a file from a .dmg image on Linux?

I’m trying to get this single .bin file, MAFTZ0110.bin which the clowns at Nikon decided needed to be wrapped in a .dmg disk image, instead of, you know, zipped like every other file on the planet.

The .dmg is here (choose mac):
https://downloadcenter.nikonimglib.com/en/download/fw/360.html

I’ve tried everything I could find on the internet.

  1. dmg2img file.dmg imagefile.img -> extracts, but bad super block errors, can’t mount, not a block device, etc.

  2. 7z x your_file.dmg -> extracts a bunch of crap, but none will mount:

    ‘0 - Protective Master Boot Record(MBR: 0)’
    ‘3 - (Apple_Free: 3)’
    ‘6 - GPT Partition Data(Backup GPT Table: 6)’
    ‘1 - GPT Header(Primary GPT Header: 1)’
    ‘4 - disk image(Apple_APFS: 4)’
    ‘7 - GPT Header(Backup GPT Header: 7)’
    ‘2 - GPT Partition Data(Primary GPT Table: 2)’
    ‘5 - (Apple_Free: 5)’

Yes, ls includes those single quotes!

  1. USB image writer -> wrote to drive, but inserting the thumb drive doesn’t auto-mount and I can’t mount it manually. bad superblock, etc. Doesn’t seem to have partitions either, just /dev/sdj.

  2. Tried everything here: https://askubuntu.com/questions/38112/how-can-i-open-a-dmg-file

hfsprogs is installed. Currently trying on Mint 19.3.

Any ideas?

Here is an example I’ve done with a raspbian image…

Using fdisk, check the file for its partitions and locations:

fdisk -l 2020-12-02-raspios-buster-armhf-lite.img

Disk 2020-12-02-raspios-buster-armhf-lite.img: 1.75 GiB, 1858076672 bytes, 3629056 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: dos
Disk identifier: 0x067e19d7

Device                                    Boot  Start     End Sectors  Size Id Type
2020-12-02-raspios-buster-armhf-lite.img1        8192  532479  524288  256M  c W95 FAT32 (LBA)
2020-12-02-raspios-buster-armhf-lite.img2      532480 3629055 3096576  1.5G 83 Linux

My raspbian image file shows 2 partitions. Lets say the Linux partition (number 2) is the one we want to mount. First calculate the offset. This is done by multiplying the sector size by the start sector for the partition we want to mount. In this case we will be multiplying 512 * 532480 = 272629760. Now we can mount the partition on top of a directory of our choice.

mkdir mnt
mount -o loop,offset=272629760 2020-12-02-raspios-buster-armhf-lite.img mnt
ls mnt
bin  boot  dev  etc  home  lib  lost+found  media  mnt  opt  proc  root  run  sbin  srv  sys  tmp  usr  var

For your image you might need to include the mount option ‘-t’ and specify the partition type your mounting.

I hope this helps.

4 Likes

The easiest way I know of is to go into a BestBuy with a flash drive and unwrap your dmg file with one of the demo mac’s available.

Personally, never got any of those Linux tools to work. But the comment above me is so thorough that it will probably work.

All else fails you could try mine.

Good luck!

Dependencies:
apfs-fuse-git https://github.com/sgan81/apfs-fuse
gzip

  1. Extract the .dmg into its own directory: ‘7z e F-FTZ-V0110M.dmg -oF-FTZ-V0110M’
  2. Rename the APFS image to something manageable: ‘mv 4\ -\ disk\ image(Apple_APFS:\ 4) apfs-image.img’
  3. Make a mount point in your working directory: ‘mkdir mount’
  4. Mount using: ‘apfs-fuse apfs-image.img ./mount’
  5. MAFTZ0110.bin is in mount/root/FTZUpdate

‘file’ output:
MAFTZ0110.bin: Hitachi SH big-endian COFF object file, not stripped, 3 sections, symbol offset=0x4c454e53, 1178992640 symbols

if you’re not able to get apfs-fuse-git to work on your distro then here’s a link to MAFTZ0110.bin: https://mega.nz/file/8hF3naIR#4soxYKo9yP4X8JCX50KZ45OcjvyZrw4jgoSzBf6S3dA
Don’t take my word for it though, run ‘file’ on it and make sure it’s not a virus.

1 Like

Thank you! I think this is the solution, but I’m having a bit of trouble with the compiling of APFS Fuse. I’m trying it on a fresh install of Debian 11 with the zip downloaded from GitHub.

The issue seems to be with lzfse, possibly a missing dependency. The output of ccmake (per the included README.md) is:

-- The C compiler identification is GNU 10.2.1
-- The CXX compiler identification is GNU 10.2.1
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working C compiler: /usr/bin/cc - skipped
-- Detecting C compile features
-- Detecting C compile features - done
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Check for working CXX compiler: /usr/bin/c++ - skipped
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Configuring done
CMake Error at CMakeLists.txt:22 (add_library):
  Cannot find source file:

    3rdparty/lzfse/src/lzfse.h

  Tried extensions .c .C .c++ .cc .cpp .cxx .cu .m .M .mm .h .hh .h++ .hm
  .hpp .hxx .in .txx


CMake Error at CMakeLists.txt:22 (add_library):
  No SOURCES given to target: lzfse


CMake Generate step failed.  Build files cannot be regenerated correctly.

When I look in apfs-fuse-master/3rdparty/lzfse, this folder is empty. Which is probably the problem. Do I need to download headers or something here first?

The lzfuse directory is empty because it points to another repository. https://github.com/lzfse/lzfse/tree/e634ca58b4821d9f3d560cdc6df5dec02ffc93fd
You’ll need to follow the build instructions for lzfuse first to be able to use it as a dependency. Because I’m on Arch, the pkgbuild took care of this step for me. Sorry it wasn’t obvious :stuck_out_tongue:

You need to set the --recurse-submodules flag when cloning so it automatically pulls the lzfse repository in so:
git clone --recurse-submodules https://github.com/sgan81/apfs-fuse.git

Looks like Darling may have an implementation of a DMG mounter:

https://docs.darlinghq.org/what-to-try.html#attach-disk-images

Attach disk images

Darling ships with an implementation of hdiutil , a tool that allows you to attach and detach DMG disk images:

Darling [~]$ hdiutil attach Downloads/SomeApp.dmg
....