Skip to content

Commit 13e0e0d

Browse files
authoredJun 8, 2024··
feat: write asar integrity resource on windows (#8245)
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.
1 parent 29f6504 commit 13e0e0d

File tree

5 files changed

+66
-0
lines changed

5 files changed

+66
-0
lines changed
 

‎.changeset/thick-flies-carry.md

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"app-builder-lib": patch
3+
---
4+
5+
write asar integrity resource on windows

‎packages/app-builder-lib/package.json

+1
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@
7070
"lazy-val": "^1.0.5",
7171
"minimatch": "^5.1.1",
7272
"read-config-file": "6.4.0",
73+
"resedit": "^1.7.0",
7374
"sanitize-filename": "^1.6.3",
7475
"semver": "^7.3.8",
7576
"tar": "^6.1.12",

‎packages/app-builder-lib/src/electron/ElectronFramework.ts

+4
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import { LinuxPackager } from "../linuxPackager"
1010
import { MacPackager } from "../macPackager"
1111
import { getTemplatePath } from "../util/pathManager"
1212
import { createMacApp } from "./electronMac"
13+
import { addWinAsarIntegrity } from "./electronWin"
1314
import { computeElectronVersion, getElectronVersionFromInstalled } from "./electronVersion"
1415
import * as fs from "fs/promises"
1516
import injectFFMPEG from "./injectFFMPEG"
@@ -78,6 +79,9 @@ async function beforeCopyExtraFiles(options: BeforeCopyExtraFilesOptions) {
7879
} else if (packager.platform === Platform.WINDOWS) {
7980
const executable = path.join(appOutDir, `${packager.appInfo.productFilename}.exe`)
8081
await rename(path.join(appOutDir, `${electronBranding.projectName}.exe`), executable)
82+
if (options.asarIntegrity) {
83+
await addWinAsarIntegrity(executable, options.asarIntegrity)
84+
}
8185
} else {
8286
await createMacApp(packager as MacPackager, appOutDir, options.asarIntegrity, (options.platformName as ElectronPlatformName) === "mas")
8387
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
import { readFile, writeFile } from "fs/promises"
2+
import { log } from "builder-util"
3+
import { NtExecutable, NtExecutableResource, Resource } from "resedit"
4+
import { AsarIntegrity } from "../asar/integrity"
5+
6+
/** @internal */
7+
export async function addWinAsarIntegrity(executablePath: string, asarIntegrity: AsarIntegrity) {
8+
const buffer = await readFile(executablePath)
9+
const executable = NtExecutable.from(buffer)
10+
const resource = NtExecutableResource.from(executable)
11+
12+
const versionInfo = Resource.VersionInfo.fromEntries(resource.entries)
13+
if (versionInfo.length !== 1) {
14+
throw new Error(`Failed to parse version info in ${executablePath}`)
15+
}
16+
17+
const languages = versionInfo[0].getAllLanguagesForStringValues()
18+
if (languages.length !== 1) {
19+
throw new Error(`Failed to locate languages in ${executablePath}`)
20+
}
21+
22+
// See: https://github.com/electron/packager/blob/00d20b99cf4aa4621103dbbd09ff7de7d2f7f539/src/resedit.ts#L124
23+
const integrityList = Array.from(Object.entries(asarIntegrity)).map(([file, { algorithm: alg, hash: value }]) => ({
24+
file,
25+
alg,
26+
value,
27+
}))
28+
29+
resource.entries.push({
30+
type: "INTEGRITY",
31+
id: "ELECTRONASAR",
32+
bin: Buffer.from(JSON.stringify(integrityList)),
33+
lang: languages[0].lang,
34+
codepage: languages[0].codepage,
35+
})
36+
37+
resource.outputResource(executable)
38+
39+
await writeFile(executablePath, Buffer.from(executable.generate()))
40+
log.info({ executablePath }, "updating asar integrity executable resource")
41+
}

‎pnpm-lock.yaml

+15
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)
Please sign in to comment.