24

From what I've read, an Appimage file is a compressed application along with all of its resources, and when run it is auto-mounted and then executed.

I want to inspect the resources and files inside an Appimage file I've downloaded, without actually running the Appimage.

How can I do this?

2
  • I searched for this question before posting and was surprised to find no version of the question at all already posted. So I've kept this one as simple as possible.
    – Wildcard
    Commented Apr 26, 2020 at 19:58
  • 1
    It appears there isn't currently a reliable way to do this without executing the binary :( The documentation suggests using mount, but even that requires you to extract the image offset from the file. Creating an external command that can do the mounting automatically is filed as bug #830 in their bug tracker.
    – IMSoP
    Commented Apr 27, 2020 at 15:25

3 Answers 3

23

Without changing their extension:

As such, an appimage can be mounted or extracted. That is:

To mount them: (which amounts to executing them, something the OP wants to avoid - and for that very reason needs to be aware of - as stated in a comment by @Jasen)

my.AppImage --appimage-mount

The AppImage is unmounted when the application called in the example is interrupted (e.g., by pressing Ctrl+C, closing the terminal etc.).

Note: This is only available for type 2 AppImages. Type 1 AppImages do not provide any self-mounting mechanism. To mount type 1 AppImages, use

mount -o loop

To extract them:

An alternative to mounting the AppImages is to extract their contents. This allows for modifying the contents. The resulting directory is a valid AppDir, and users can create AppImages from them again using appimagetool.

Analog to mounting AppImages, there is a simple commandline switch to extract the contents of type 2 AppImages without external tools. Just call the AppImage with the parameter --appimage-extract. This will cause the runtime to create a new directory called squashfs-root, containing the contents of the AppImage’s AppDir specification.

Type 1 AppImages require the deprecated tool AppImageExtract to extract the contents of an AppImage. It’s very limited functionality wise, and requires a GUI to run. It creates a new directory in the user’s desktop directory.

There is an answer on superuser on how to extract files from an AppImage.

Looking at my appimages I see that only some of them can be mounted with gnome-disk-image-mounter. Also here.


Changing their extension:

Not all appimages have exactly the same structure, but all are archives. Wikipedia says: "An AppImage of version 1.0 is an ISO 9660 Rock Ridge file (which can be optionally zisofs compressed) containing a minimal AppDir and a tiny runtime. (Version 2 may use other file system image formats like SquashFS)".

So, it can be extracted. In this way you can examine the files.

Simply changing the extension from AppImage to an archive extension that my file-roller archive manager can read (I tested with zip, 7z, etc) and double-clicking the file reveals the contents in file-roller:

enter image description here

They can also be extracted, of course. The "extract" file manager context menu action works too in order to extract the archive. (As said in comment, the unzip command reports an error with a file renamed with a zip extension, so renaming to zip is not the proper choice in itself, but it works with archive managers like file-roller.)

4
  • I tried copying an AppImage to test.zip and running unzip test.zip and I got the message: End-of-central-directory signature not found. Either this file is not a zipfile, or it constitutes one disk of a multi-part archive. In the latter case the central directory and zipfile comment will be found on the last disk(s) of this archive. note: test.zip may be a plain executable, not an archive
    – Wildcard
    Commented Apr 26, 2020 at 23:43
  • 2
    @Wildcard - it seems that some archive managers like file-roller do not care about the proper archive extension as long as the file IS an archive with an archive extension (no matter what that is), and are able to extract it, while unzip tool is extension-oriented and looks for more extension-specific properties in order to operate. So, instead of unzip, use the file manager extract action or file-roller -f. See file-roller --help for details.
    – cipricus
    Commented Apr 27, 2020 at 7:37
  • 1
    I would like to point out that the first method does actually exec the appimage binary, so its not a suitable method to examine untrusted files.
    – Jasen
    Commented Jan 20, 2022 at 0:09
  • @Jasen - I have added a note on that.
    – cipricus
    Commented May 23, 2023 at 8:28
11

According to AppImage documentation the --appimage-mount option allows you to mount and inspect the contents.

For example:

./Joplin.AppImage --appimage-mount /tmp/mount_myXXXX

The application's help can usually be shown with ./whatever.AppImage --help like any other application, but to see the AppImage specific options, you can run:

./whatever.AppImage --appimage-help

Here is the relevant portion of the output:

AppImage options:
...
  --appimage-mount                Mount embedded filesystem image and print
                                  mount point and wait for kill with Ctrl-C

You don't have to create a mountpoint for it or delete the directory afterwards; the AppImage will take care of all of that.

3
  • 1
    also, --appimage-extract to extract it.
    – cipricus
    Commented Apr 27, 2020 at 7:45
  • 8
    A file you're trying to examine should NOT be executed. This is a dangerous answer Commented Apr 27, 2020 at 10:47
  • 2
    @SyferPolski Particularly as the OP specified, "without actually running the Appimage". Commented Apr 27, 2020 at 13:10
1
  1. use binwalk -e app to extract all the parts of the appimage to the current directory.
  2. locate the .squashfs file in the output
  3. extract the .squashfs image to the current directory with unsquashfs -li <file.squashfs>

This could be made into a script

#!/bin/bash
appimage="$1"
temp=$(mktemp -d)
cd "$temp"
binwalk -e "$1"
find . -name "*.squashfs" -exec unsquashfs -li {} \;
echo "extracted $appimage files to $temp"

Here's an example execution

~/TMP/MAGICK2 $ ~/SCRIPTS/archive.appimage.extract ~/DOWNLOADS/APPS/magick

DECIMAL         HEX             DESCRIPTION
-------------------------------------------------------------------------------------------------------
0               0x0             ELF 64-bit LSB executable, AMD x86-64, version 1
30683           0x77DB          LZMA compressed data, properties: 0x09, dictionary size: 131072 bytes, uncompressed size: 4105 bytes
157144          0x265D8         xz compressed data
204032          0x31D00         LZMA compressed data, properties: 0x0B, dictionary size: 16777216 bytes, uncompressed size: 33554432 bytes
204736          0x31FC0         LZMA compressed data, properties: 0x7E, dictionary size: 16777216 bytes, uncompressed size: 100663296 bytes
204928          0x32080         LZMA compressed data, properties: 0x8A, dictionary size: 16777216 bytes, uncompressed size: 100663296 bytes
204992          0x320C0         LZMA compressed data, properties: 0x90, dictionary size: 16777216 bytes, uncompressed size: 33554432 bytes
205312          0x32200         LZMA compressed data, properties: 0xC8, dictionary size: 16777216 bytes, uncompressed size: 50331648 bytes
WARNING: Extractor.execute failed to run '/opt/firmware-mod-kit/trunk/unsquashfs_all.sh '324C0.squashfs'': [Errno 2] No such file or directory
206016          0x324C0         Squashfs filesystem, little endian, version 4.0, compression: gzip, size: 29028995 bytes,  591 inodes, blocksize: 131072 bytes, created: Thu Jan  1 00:00:00 1970 

Parallel unsquashfs: Using 4 processors
557 inodes (1101 blocks) to write

drwxr-xr-x root/root               118 2023-12-25 20:45 squashfs-root
-rw-r--r-- root/root              7993 2023-12-25 20:45 squashfs-root/.DirIcon
-rwxr-xr-x root/root              1237 2023-12-25 20:45 squashfs-root/AppRun
-rw-r--r-- root/root               194 2023-12-25 20:45 squashfs-root/imagemagick.desktop
[...]
-rw-r--r-- root/root             18826 2023-12-25 20:45 squashfs-root/usr/share/man/man1/mogrify.1
-rw-r--r-- root/root              8148 2023-12-25 20:45 squashfs-root/usr/share/man/man1/montage.1
-rw-r--r-- root/root              3390 2023-12-25 20:45 squashfs-root/usr/share/man/man1/stream.1

created 541 files
created 34 directories
created 16 symlinks
created 0 devices
created 0 fifos
extracted /home/ychaouche/DOWNLOADS/APPS/magick files to /tmp/tmp.6J1v63xax2
~/TMP/MAGICK2 $ cd /tmp/tmp.6J1v63xax2/
/tmp/tmp.6J1v63xax2 $ ls
total 195M
-rw-r--r-- 1 ychaouche ychaouche    0 Jan  7 15:23 31D00
-rw-r--r-- 1 ychaouche ychaouche  28M Jan  7 15:23 31D00.7z
-rw-r--r-- 1 ychaouche ychaouche    0 Jan  7 15:23 31FC0
-rw-r--r-- 1 ychaouche ychaouche  28M Jan  7 15:23 31FC0.7z
-rw-r--r-- 1 ychaouche ychaouche    0 Jan  7 15:23 32080
-rw-r--r-- 1 ychaouche ychaouche  28M Jan  7 15:23 32080.7z
-rw-r--r-- 1 ychaouche ychaouche    0 Jan  7 15:23 320C0
-rw-r--r-- 1 ychaouche ychaouche  28M Jan  7 15:23 320C0.7z
-rw-r--r-- 1 ychaouche ychaouche    0 Jan  7 15:23 32200
-rw-r--r-- 1 ychaouche ychaouche  28M Jan  7 15:23 32200.7z
-rw-r--r-- 1 ychaouche ychaouche  28M Jan  7 15:23 324C0.squashfs
-rw-r--r-- 1 ychaouche ychaouche  28M Jan  7 15:23 77DB.7z
drwxr-xr-x 3 ychaouche ychaouche 4.0K Dec 25 20:45 squashfs-root
/tmp/tmp.6J1v63xax2 -1- $ cd squashfs-root/
/tmp/tmp.6J1v63xax2/squashfs-root $ ls
total 20K
-rwxr-xr-x 1 ychaouche ychaouche 1.3K Dec 25 20:45 AppRun
-rw-r--r-- 1 ychaouche ychaouche  194 Dec 25 20:45 imagemagick.desktop
-rw-r--r-- 1 ychaouche ychaouche 7.9K Dec 25 20:45 imagemagick.png
drwxr-xr-x 7 ychaouche ychaouche 4.0K Dec 25 20:45 usr
/tmp/tmp.6J1v63xax2/squashfs-root $

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .