Skip to content

Commit

Permalink
feat: write asar integrity resource on windows (#8245)
Browse files Browse the repository at this point in the history
Electron 30-x-y added support for ASAR integrity fuse on Windows. When enabled the app would fetch the ELECTRONASAR resource out of the executable file and use it to verify the integrity of the ASAR when reading the data from it.
  • Loading branch information
indutny-signal authored Jun 8, 2024
1 parent 29f6504 commit 13e0e0d
Show file tree
Hide file tree
Showing 5 changed files with 66 additions and 0 deletions.
5 changes: 5 additions & 0 deletions .changeset/thick-flies-carry.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"app-builder-lib": patch
---

write asar integrity resource on windows
1 change: 1 addition & 0 deletions packages/app-builder-lib/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@
"lazy-val": "^1.0.5",
"minimatch": "^5.1.1",
"read-config-file": "6.4.0",
"resedit": "^1.7.0",
"sanitize-filename": "^1.6.3",
"semver": "^7.3.8",
"tar": "^6.1.12",
Expand Down
4 changes: 4 additions & 0 deletions packages/app-builder-lib/src/electron/ElectronFramework.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import { LinuxPackager } from "../linuxPackager"
import { MacPackager } from "../macPackager"
import { getTemplatePath } from "../util/pathManager"
import { createMacApp } from "./electronMac"
import { addWinAsarIntegrity } from "./electronWin"
import { computeElectronVersion, getElectronVersionFromInstalled } from "./electronVersion"
import * as fs from "fs/promises"
import injectFFMPEG from "./injectFFMPEG"
Expand Down Expand Up @@ -78,6 +79,9 @@ async function beforeCopyExtraFiles(options: BeforeCopyExtraFilesOptions) {
} else if (packager.platform === Platform.WINDOWS) {
const executable = path.join(appOutDir, `${packager.appInfo.productFilename}.exe`)
await rename(path.join(appOutDir, `${electronBranding.projectName}.exe`), executable)
if (options.asarIntegrity) {
await addWinAsarIntegrity(executable, options.asarIntegrity)
}
} else {
await createMacApp(packager as MacPackager, appOutDir, options.asarIntegrity, (options.platformName as ElectronPlatformName) === "mas")
}
Expand Down
41 changes: 41 additions & 0 deletions packages/app-builder-lib/src/electron/electronWin.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import { readFile, writeFile } from "fs/promises"
import { log } from "builder-util"
import { NtExecutable, NtExecutableResource, Resource } from "resedit"
import { AsarIntegrity } from "../asar/integrity"

/** @internal */
export async function addWinAsarIntegrity(executablePath: string, asarIntegrity: AsarIntegrity) {
const buffer = await readFile(executablePath)
const executable = NtExecutable.from(buffer)
const resource = NtExecutableResource.from(executable)

const versionInfo = Resource.VersionInfo.fromEntries(resource.entries)
if (versionInfo.length !== 1) {
throw new Error(`Failed to parse version info in ${executablePath}`)
}

const languages = versionInfo[0].getAllLanguagesForStringValues()
if (languages.length !== 1) {
throw new Error(`Failed to locate languages in ${executablePath}`)
}

// See: https://github.com/electron/packager/blob/00d20b99cf4aa4621103dbbd09ff7de7d2f7f539/src/resedit.ts#L124
const integrityList = Array.from(Object.entries(asarIntegrity)).map(([file, { algorithm: alg, hash: value }]) => ({
file,
alg,
value,
}))

resource.entries.push({
type: "INTEGRITY",
id: "ELECTRONASAR",
bin: Buffer.from(JSON.stringify(integrityList)),
lang: languages[0].lang,
codepage: languages[0].codepage,
})

resource.outputResource(executable)

await writeFile(executablePath, Buffer.from(executable.generate()))
log.info({ executablePath }, "updating asar integrity executable resource")
}
15 changes: 15 additions & 0 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit 13e0e0d

Please sign in to comment.