diff --git a/node_modules/app-builder-lib/out/asar/asarUtil.js b/node_modules/app-builder-lib/out/asar/asarUtil.js
index 7f37444..1a85145 100644
--- a/node_modules/app-builder-lib/out/asar/asarUtil.js
+++ b/node_modules/app-builder-lib/out/asar/asarUtil.js
@@ -31,10 +31,16 @@ class AsarPackager {
         }
         await (0, promises_1.mkdir)(path.dirname(this.outFile), { recursive: true });
         const unpackedFileIndexMap = new Map();
-        for (const fileSet of fileSets) {
+        const orderedFileSets = [
+            // Write dependencies first to minimize offset changes to asar header
+            ...fileSets.slice(1),
+            // Finish with the app files that change most often
+            fileSets[0]
+        ].map(orderFileSet);
+        for (const fileSet of orderedFileSets) {
             unpackedFileIndexMap.set(fileSet, await this.createPackageFromFiles(fileSet, packager.info));
         }
-        await this.writeAsarFile(fileSets, unpackedFileIndexMap);
+        await this.writeAsarFile(orderedFileSets, unpackedFileIndexMap);
     }
     async createPackageFromFiles(fileSet, packager) {
         const metadata = fileSet.metadata;
@@ -238,4 +244,47 @@ function copyFileOrData(fileCopier, data, source, destination, stats) {
         return (0, promises_1.writeFile)(destination, data);
     }
 }
+function orderFileSet(fileSet) {
+    const filesAndIndices = Array.from(fileSet.files.entries());
+    filesAndIndices.sort(([, a], [, b]) => {
+        if (a === b) {
+            return 0;
+        }
+        // Place addons last because their signature change
+        const isAAddon = a.endsWith('.node');
+        const isBAddon = b.endsWith('.node');
+        if (isAAddon && !isBAddon) {
+            return 1;
+        }
+        if (isBAddon && !isAAddon) {
+            return -1;
+        }
+        // Otherwise order by name
+        return a < b ? -1 : 1;
+    });
+    let transformedFiles;
+    if (fileSet.transformedFiles) {
+        transformedFiles = new Map();
+        const indexMap = new Map();
+        for (const [newIndex, [oldIndex,]] of filesAndIndices.entries()) {
+            indexMap.set(oldIndex, newIndex);
+        }
+        for (const [oldIndex, value] of fileSet.transformedFiles) {
+            const newIndex = indexMap.get(oldIndex);
+            if (newIndex === undefined) {
+                const file = fileSet.files[oldIndex];
+                throw new Error(`Internal error: ${file} was lost while ordering asar`);
+            }
+            transformedFiles.set(newIndex, value);
+        }
+    }
+    const { src, destination, metadata, } = fileSet;
+    return {
+        src,
+        destination,
+        metadata,
+        files: filesAndIndices.map(([, file]) => file),
+        transformedFiles,
+    };
+}
 //# sourceMappingURL=asarUtil.js.map
\ No newline at end of file
diff --git a/node_modules/app-builder-lib/out/macPackager.js b/node_modules/app-builder-lib/out/macPackager.js
index 9df12c4..465ffa3 100644
--- a/node_modules/app-builder-lib/out/macPackager.js
+++ b/node_modules/app-builder-lib/out/macPackager.js
@@ -194,7 +194,8 @@ class MacPackager extends platformPackager_1.PlatformPackager {
                     builder_util_1.log.warn("Mac Developer is used to sign app — it is only for development and testing, not for production");
                 }
             }
-            if (identity == null) {
+            const customSign = await (0, platformPackager_1.resolveFunction)(options.sign, "sign");
+            if (!customSign && identity == null) {
                 await (0, macCodeSign_1.reportError)(isMas, certificateTypes, qualifier, keychainFile, this.forceCodeSigning);
                 return false;
             }
@@ -261,11 +262,11 @@ class MacPackager extends platformPackager_1.PlatformPackager {
         };
         builder_util_1.log.info({
             file: builder_util_1.log.filePath(appPath),
-            identityName: identity.name,
-            identityHash: identity.hash,
+            identityName: identity ? identity.name : undefined,
+            identityHash: identity ? identity.hash : undefined,
             provisioningProfile: signOptions.provisioningProfile || "none",
         }, "signing");
-        await this.doSign(signOptions);
+        await this.doSign(signOptions, masOptions);
         // https://github.com/electron-userland/electron-builder/issues/1196#issuecomment-312310209
         if (masOptions != null && !isDevelopment) {
             const certType = isDevelopment ? "Mac Developer" : "3rd Party Mac Developer Installer";
@@ -332,7 +333,14 @@ class MacPackager extends platformPackager_1.PlatformPackager {
         return optionsForFile;
     }
     //noinspection JSMethodCanBeStatic
-    doSign(opts) {
+    doSign(opts, masOptions) {
+        const options = masOptions == null ? this.platformSpecificBuildOptions : masOptions;
+
+        const customSign = (0, platformPackager_1.resolveFunction)(options.sign, "sign");
+        if (customSign) {
+            return Promise.resolve(customSign(opts));
+        }
+
         return (0, osx_sign_1.signAsync)(opts);
     }
     //noinspection JSMethodCanBeStatic
diff --git a/node_modules/app-builder-lib/out/targets/LinuxTargetHelper.js b/node_modules/app-builder-lib/out/targets/LinuxTargetHelper.js
index fcb7f54..3f27bf3 100644
--- a/node_modules/app-builder-lib/out/targets/LinuxTargetHelper.js
+++ b/node_modules/app-builder-lib/out/targets/LinuxTargetHelper.js
@@ -99,7 +99,7 @@ class LinuxTargetHelper {
             // https://specifications.freedesktop.org/desktop-entry-spec/desktop-entry-spec-latest.html#exec-variables
             const execCodes = ["%f", "%u", "%F", "%U"];
             if (executableArgs == null || executableArgs.findIndex(arg => execCodes.includes(arg)) === -1) {
-                exec += " %U";
+                exec += " --no-sandbox %U";
             }
         }
         const desktopMeta = {
diff --git a/node_modules/app-builder-lib/scheme.json b/node_modules/app-builder-lib/scheme.json
index 1d45055..0d0cb9c 100644
--- a/node_modules/app-builder-lib/scheme.json
+++ b/node_modules/app-builder-lib/scheme.json
@@ -2784,6 +2784,17 @@
             "string"
           ]
         },
+        "sign": {
+          "anyOf": [
+            {
+              "type": [
+                "null",
+                "string"
+              ]
+            }
+          ],
+          "description": "The custom function (or path to file or module id) to sign macOS files."
+        },
         "signIgnore": {
           "anyOf": [
             {
diff --git a/node_modules/app-builder-lib/templates/linux/after-install.tpl b/node_modules/app-builder-lib/templates/linux/after-install.tpl
index 0f541f9..d1e77a0 100644
--- a/node_modules/app-builder-lib/templates/linux/after-install.tpl
+++ b/node_modules/app-builder-lib/templates/linux/after-install.tpl
@@ -10,8 +10,5 @@ else
     ln -sf '/opt/${sanitizedProductName}/${executable}' '/usr/bin/${executable}'
 fi
 
-# SUID chrome-sandbox for Electron 5+
-chmod 4755 '/opt/${sanitizedProductName}/chrome-sandbox' || true
-
 update-mime-database /usr/share/mime || true
 update-desktop-database /usr/share/applications || true
diff --git a/node_modules/app-builder-lib/templates/nsis/installSection.nsh b/node_modules/app-builder-lib/templates/nsis/installSection.nsh
index 053772f..7981a4e 100644
--- a/node_modules/app-builder-lib/templates/nsis/installSection.nsh
+++ b/node_modules/app-builder-lib/templates/nsis/installSection.nsh
@@ -22,11 +22,38 @@ StrCpy $appExe "$INSTDIR\${APP_EXECUTABLE_FILENAME}"
       SpiderBanner::Show /MODERN
     !endif
 
+    # Set text (1000 is the id of text element of SpiderBanner)
     FindWindow $0 "#32770" "" $hwndparent
     FindWindow $0 "#32770" "" $hwndparent $0
-    GetDlgItem $0 $0 1000
-    SendMessage $0 ${WM_SETTEXT} 0 "STR:$(installing)"
 
+    GetDlgItem $1 $0 1000
+    SendMessage $1 ${WM_SETTEXT} 0 "STR:$(installing)"
+
+    # Set header image compatible with "ManifestDPIAware" mode.
+    !ifdef HEADER_ICO
+      # Convert 24 Dialog Units to pixels:
+      # See https://github.com/mozilla/gecko-dev/blob/8de0e699002872d969aebf1bc8407e5c839a4472/toolkit/mozapps/installer/windows/nsis/common.nsh#L8801
+
+      # rect = LPRect { .left = 0, .top = 0, .right = 24, .bottom = 0 }
+      # See https://nsis.sourceforge.io/Docs/System/System.html#faq
+      System::Call "*(i 0, i 0, i 24, i 0) p.r1"
+
+      # Call `MapDialogRect(window, &rect)`
+      System::Call `user32::MapDialogRect(p $0, p r1)`
+
+      # rect.right now contains the converted value (24du => ?px).
+      # Place `rect.right` into `r2`
+      System::Call "*$1(i, i, i.r2, i)"
+      System::Free $1
+
+      # Load image and pass `r2` as both width and height, get the image handle
+      # back to `r2` register.
+      System::Call `user32::LoadImage(i 0, t "$PLUGINSDIR\installerHeaderico.ico", i ${IMAGE_ICON}, i r2, i r2, i ${LR_LOADFROMFILE}) i.r2`
+
+      # 1025 is the id of the icon of SpiderBanner.
+      GetDlgItem $1 $0 1025
+      SendMessage $1 ${STM_SETIMAGE} ${IMAGE_ICON} $2
+    !endif
     StrCpy $1 $hwndparent
 		System::Call 'user32::ShutdownBlockReasonCreate(${SYSTYPE_PTR}r1, w "$(installing)")'
   ${endif}
