From 865d4bcf57d12ca5c4336ec0637b55fa2dc67ea7 Mon Sep 17 00:00:00 2001 From: Joyee Cheung Date: Thu, 1 Jan 2026 15:37:58 +0100 Subject: [PATCH 1/6] test: use fixture directories for sea tests Instead of copying and writing files on the fly for SEA tests, put the fixtures into a directory and copy them into tmpdir for testing. This allows easier reproduction and debugging when they do fail - we can just copy the entire fixture directory and test directly from there. --- test/common/sea.js | 53 ++++++-- test/fixtures/sea/addon/sea-config.json | 8 ++ test/fixtures/sea/addon/sea.js | 9 ++ .../sea/asset-keys-empty/sea-config.json | 4 + .../sea.js} | 0 test/fixtures/sea/asset-keys/asset-1.txt | 1 + test/fixtures/sea/asset-keys/asset-2.txt | 1 + test/fixtures/sea/asset-keys/asset-3.txt | 1 + test/fixtures/sea/asset-keys/sea-config.json | 9 ++ test/fixtures/sea/asset-keys/sea.js | 9 ++ .../sea/assets-invalid-type/sea-config.json | 5 + test/fixtures/sea/assets-invalid-type/sea.js | 3 + .../assets-nonexistent-file/sea-config.json | 7 + .../sea/assets-nonexistent-file/sea.js | 3 + test/fixtures/sea/assets-raw/person.jpg | Bin 0 -> 45658 bytes test/fixtures/sea/assets-raw/sea-config.json | 7 + .../{get-asset-raw.js => assets-raw/sea.js} | 0 test/fixtures/sea/assets/person.jpg | Bin 0 -> 45658 bytes test/fixtures/sea/assets/sea-config.json | 8 ++ .../sea/{get-asset.js => assets/sea.js} | 0 test/fixtures/sea/assets/utf8_test_text.txt | 1 + .../requirable.js | 3 + .../sea-config.json | 5 + .../sea/disable-experimental-warning/sea.js | 64 +++++++++ test/fixtures/sea/empty/empty.js | 0 test/fixtures/sea/empty/sea-config.json | 4 + .../sea/exec-argv-empty/sea-config.json | 6 + test/fixtures/sea/exec-argv-empty/sea.js | 6 + .../exec-argv-extension-cli/sea-config.json | 7 + .../sea/exec-argv-extension-cli/sea.js | 14 ++ .../exec-argv-extension-env/sea-config.json | 7 + .../sea/exec-argv-extension-env/sea.js | 19 +++ .../exec-argv-extension-none/sea-config.json | 7 + .../sea/exec-argv-extension-none/sea.js | 14 ++ test/fixtures/sea/exec-argv/sea-config.json | 6 + test/fixtures/sea/exec-argv/sea.js | 18 +++ .../sea/inspect-in-sea-flags/sea-config.json | 4 + test/fixtures/sea/inspect-in-sea-flags/sea.js | 1 + test/fixtures/sea/inspect/hello.js | 1 + test/fixtures/sea/inspect/sea-config.json | 4 + test/fixtures/sea/simple/requirable.js | 3 + test/fixtures/sea/simple/sea-config.json | 6 + test/fixtures/sea/simple/sea.js | 64 +++++++++ .../snapshot-and-code-cache/sea-config.json | 6 + .../sea/snapshot-and-code-cache/snapshot.js | 7 + .../sea/snapshot-worker/sea-config.json | 5 + test/fixtures/sea/snapshot-worker/snapshot.js | 8 ++ test/fixtures/sea/snapshot/sea-config.json | 5 + test/fixtures/sea/snapshot/snapshot.js | 7 + .../fixtures/sea/use-code-cache/requirable.js | 3 + .../sea/use-code-cache/sea-config.json | 5 + test/fixtures/sea/use-code-cache/sea.js | 64 +++++++++ test/node-api/test_sea_addon/test.js | 49 ++----- ...executable-application-asset-keys-empty.js | 33 +---- ...ingle-executable-application-asset-keys.js | 42 +----- ...cutable-application-assets-invalid-type.js | 35 +++++ ...ble-application-assets-nonexistent-file.js | 35 +++++ ...ingle-executable-application-assets-raw.js | 62 ++------- ...st-single-executable-application-assets.js | 126 +++--------------- ...cation-disable-experimental-sea-warning.js | 40 +----- ...est-single-executable-application-empty.js | 45 ++----- ...-executable-application-exec-argv-empty.js | 34 +---- ...ble-application-exec-argv-extension-cli.js | 35 +---- ...ble-application-exec-argv-extension-env.js | 34 +---- ...le-application-exec-argv-extension-none.js | 35 +---- ...single-executable-application-exec-argv.js | 33 +---- ...utable-application-inspect-in-sea-flags.js | 30 +---- ...t-single-executable-application-inspect.js | 31 +---- ...ble-application-snapshot-and-code-cache.js | 47 +------ ...-executable-application-snapshot-worker.js | 51 +------ ...-single-executable-application-snapshot.js | 48 +------ ...e-executable-application-use-code-cache.js | 46 +------ .../sea/test-single-executable-application.js | 40 +----- 73 files changed, 695 insertions(+), 738 deletions(-) create mode 100644 test/fixtures/sea/addon/sea-config.json create mode 100644 test/fixtures/sea/addon/sea.js create mode 100644 test/fixtures/sea/asset-keys-empty/sea-config.json rename test/fixtures/sea/{get-asset-keys.js => asset-keys-empty/sea.js} (100%) create mode 100644 test/fixtures/sea/asset-keys/asset-1.txt create mode 100644 test/fixtures/sea/asset-keys/asset-2.txt create mode 100644 test/fixtures/sea/asset-keys/asset-3.txt create mode 100644 test/fixtures/sea/asset-keys/sea-config.json create mode 100644 test/fixtures/sea/asset-keys/sea.js create mode 100644 test/fixtures/sea/assets-invalid-type/sea-config.json create mode 100644 test/fixtures/sea/assets-invalid-type/sea.js create mode 100644 test/fixtures/sea/assets-nonexistent-file/sea-config.json create mode 100644 test/fixtures/sea/assets-nonexistent-file/sea.js create mode 100644 test/fixtures/sea/assets-raw/person.jpg create mode 100644 test/fixtures/sea/assets-raw/sea-config.json rename test/fixtures/sea/{get-asset-raw.js => assets-raw/sea.js} (100%) create mode 100644 test/fixtures/sea/assets/person.jpg create mode 100644 test/fixtures/sea/assets/sea-config.json rename test/fixtures/sea/{get-asset.js => assets/sea.js} (100%) create mode 100644 test/fixtures/sea/assets/utf8_test_text.txt create mode 100644 test/fixtures/sea/disable-experimental-warning/requirable.js create mode 100644 test/fixtures/sea/disable-experimental-warning/sea-config.json create mode 100644 test/fixtures/sea/disable-experimental-warning/sea.js create mode 100644 test/fixtures/sea/empty/empty.js create mode 100644 test/fixtures/sea/empty/sea-config.json create mode 100644 test/fixtures/sea/exec-argv-empty/sea-config.json create mode 100644 test/fixtures/sea/exec-argv-empty/sea.js create mode 100644 test/fixtures/sea/exec-argv-extension-cli/sea-config.json create mode 100644 test/fixtures/sea/exec-argv-extension-cli/sea.js create mode 100644 test/fixtures/sea/exec-argv-extension-env/sea-config.json create mode 100644 test/fixtures/sea/exec-argv-extension-env/sea.js create mode 100644 test/fixtures/sea/exec-argv-extension-none/sea-config.json create mode 100644 test/fixtures/sea/exec-argv-extension-none/sea.js create mode 100644 test/fixtures/sea/exec-argv/sea-config.json create mode 100644 test/fixtures/sea/exec-argv/sea.js create mode 100644 test/fixtures/sea/inspect-in-sea-flags/sea-config.json create mode 100644 test/fixtures/sea/inspect-in-sea-flags/sea.js create mode 100644 test/fixtures/sea/inspect/hello.js create mode 100644 test/fixtures/sea/inspect/sea-config.json create mode 100644 test/fixtures/sea/simple/requirable.js create mode 100644 test/fixtures/sea/simple/sea-config.json create mode 100644 test/fixtures/sea/simple/sea.js create mode 100644 test/fixtures/sea/snapshot-and-code-cache/sea-config.json create mode 100644 test/fixtures/sea/snapshot-and-code-cache/snapshot.js create mode 100644 test/fixtures/sea/snapshot-worker/sea-config.json create mode 100644 test/fixtures/sea/snapshot-worker/snapshot.js create mode 100644 test/fixtures/sea/snapshot/sea-config.json create mode 100644 test/fixtures/sea/snapshot/snapshot.js create mode 100644 test/fixtures/sea/use-code-cache/requirable.js create mode 100644 test/fixtures/sea/use-code-cache/sea-config.json create mode 100644 test/fixtures/sea/use-code-cache/sea.js create mode 100644 test/sea/test-single-executable-application-assets-invalid-type.js create mode 100644 test/sea/test-single-executable-application-assets-nonexistent-file.js diff --git a/test/common/sea.js b/test/common/sea.js index 53bfd93d927842..92a2f04f1a1bcf 100644 --- a/test/common/sea.js +++ b/test/common/sea.js @@ -4,6 +4,9 @@ const common = require('../common'); const fixtures = require('../common/fixtures'); const tmpdir = require('../common/tmpdir'); const { inspect } = require('util'); +const fs = require('fs'); +const path = require('path'); +const assert = require('assert'); const { readFileSync, copyFileSync, statSync } = require('fs'); const { @@ -70,37 +73,71 @@ function skipIfSingleExecutableIsNotSupported() { } } -function generateSEA(targetExecutable, sourceExecutable, seaBlob, verifyWorkflow = false) { +function generateSEA(fixtureDir, workingDir = tmpdir.path, configPath = 'sea-config.json', verifyWorkflow = false) { + // Copy fixture files to working directory if they are different. + if (fixtureDir !== workingDir) { + fs.cpSync(fixtureDir, workingDir, { recursive: true }); + } + + // Determine the output executable path. + const outputFile = path.resolve(workingDir, process.platform === 'win32' ? 'sea.exe' : 'sea'); + try { - copyFileSync(sourceExecutable, targetExecutable); + // Copy the executable. + copyFileSync(process.execPath, outputFile); + console.log(`Copied ${process.execPath} to ${outputFile}`); } catch (e) { - const message = `Cannot copy ${sourceExecutable} to ${targetExecutable}: ${inspect(e)}`; + const message = `Cannot copy ${process.execPath} to ${outputFile}: ${inspect(e)}`; if (verifyWorkflow) { throw new Error(message); } common.skip(message); } - console.log(`Copied ${sourceExecutable} to ${targetExecutable}`); + // Generate the blob using --experimental-sea-config. + spawnSyncAndExitWithoutError( + process.execPath, + ['--experimental-sea-config', configPath], + { + cwd: workingDir, + env: { + NODE_DEBUG_NATIVE: 'SEA', + ...process.env, + }, + }, + ); + + // Parse the config to get the output file path. + const config = JSON.parse(fs.readFileSync(path.resolve(workingDir, configPath))); + assert.strictEqual(typeof config.output, 'string'); + const seaPrepBlob = path.resolve(workingDir, config.output); + assert(fs.existsSync(seaPrepBlob), `Expected SEA blob ${seaPrepBlob} to exist`); + + // Use postject to inject the blob. const postjectFile = fixtures.path('postject-copy', 'node_modules', 'postject', 'dist', 'cli.js'); try { spawnSyncAndExitWithoutError(process.execPath, [ postjectFile, - targetExecutable, + outputFile, 'NODE_SEA_BLOB', - seaBlob, + seaPrepBlob, '--sentinel-fuse', 'NODE_SEA_FUSE_fce680ab2cc467b6e072b8b5df1996b2', ...process.platform === 'darwin' ? [ '--macho-segment-name', 'NODE_SEA' ] : [], ]); } catch (e) { - const message = `Cannot inject ${seaBlob} into ${targetExecutable}: ${inspect(e)}`; + const message = `Cannot inject ${seaPrepBlob} into ${outputFile}: ${inspect(e)}`; if (verifyWorkflow) { throw new Error(message); } common.skip(message); } - console.log(`Injected ${seaBlob} into ${targetExecutable}`); + console.log(`Injected ${seaPrepBlob} into ${outputFile}`); + + signSEA(outputFile, verifyWorkflow); + return outputFile; +} +function signSEA(targetExecutable, verifyWorkflow = false) { if (process.platform === 'darwin') { try { spawnSyncAndExitWithoutError('codesign', [ '--sign', '-', targetExecutable ]); diff --git a/test/fixtures/sea/addon/sea-config.json b/test/fixtures/sea/addon/sea-config.json new file mode 100644 index 00000000000000..8e9f7d86f7a4bd --- /dev/null +++ b/test/fixtures/sea/addon/sea-config.json @@ -0,0 +1,8 @@ +{ + "main": "sea.js", + "output": "sea-prep.blob", + "disableExperimentalSEAWarning": true, + "assets": { + "hello.node": "binding.node" + } +} diff --git a/test/fixtures/sea/addon/sea.js b/test/fixtures/sea/addon/sea.js new file mode 100644 index 00000000000000..c7e62a733c3ca8 --- /dev/null +++ b/test/fixtures/sea/addon/sea.js @@ -0,0 +1,9 @@ +const sea = require('node:sea'); +const fs = require('fs'); +const path = require('path'); + +const addonPath = path.join(process.cwd(), 'hello.node'); +fs.writeFileSync(addonPath, new Uint8Array(sea.getRawAsset('hello.node'))); +const mod = {exports: {}}; +process.dlopen(mod, addonPath); +console.log('hello,', mod.exports.hello()); diff --git a/test/fixtures/sea/asset-keys-empty/sea-config.json b/test/fixtures/sea/asset-keys-empty/sea-config.json new file mode 100644 index 00000000000000..8acf995f9ae7ab --- /dev/null +++ b/test/fixtures/sea/asset-keys-empty/sea-config.json @@ -0,0 +1,4 @@ +{ + "main": "sea.js", + "output": "sea-prep.blob" +} diff --git a/test/fixtures/sea/get-asset-keys.js b/test/fixtures/sea/asset-keys-empty/sea.js similarity index 100% rename from test/fixtures/sea/get-asset-keys.js rename to test/fixtures/sea/asset-keys-empty/sea.js diff --git a/test/fixtures/sea/asset-keys/asset-1.txt b/test/fixtures/sea/asset-keys/asset-1.txt new file mode 100644 index 00000000000000..4034524332e074 --- /dev/null +++ b/test/fixtures/sea/asset-keys/asset-1.txt @@ -0,0 +1 @@ +This is asset 1 diff --git a/test/fixtures/sea/asset-keys/asset-2.txt b/test/fixtures/sea/asset-keys/asset-2.txt new file mode 100644 index 00000000000000..d61c042511d6e0 --- /dev/null +++ b/test/fixtures/sea/asset-keys/asset-2.txt @@ -0,0 +1 @@ +This is asset 2 diff --git a/test/fixtures/sea/asset-keys/asset-3.txt b/test/fixtures/sea/asset-keys/asset-3.txt new file mode 100644 index 00000000000000..cc9f44832dac0e --- /dev/null +++ b/test/fixtures/sea/asset-keys/asset-3.txt @@ -0,0 +1 @@ +This is asset 3 diff --git a/test/fixtures/sea/asset-keys/sea-config.json b/test/fixtures/sea/asset-keys/sea-config.json new file mode 100644 index 00000000000000..250fef01e98b69 --- /dev/null +++ b/test/fixtures/sea/asset-keys/sea-config.json @@ -0,0 +1,9 @@ +{ + "main": "sea.js", + "output": "sea-prep.blob", + "assets": { + "asset-1.txt": "asset-1.txt", + "asset-2.txt": "asset-2.txt", + "asset-3.txt": "asset-3.txt" + } +} diff --git a/test/fixtures/sea/asset-keys/sea.js b/test/fixtures/sea/asset-keys/sea.js new file mode 100644 index 00000000000000..2330b8fa3d9549 --- /dev/null +++ b/test/fixtures/sea/asset-keys/sea.js @@ -0,0 +1,9 @@ +'use strict'; + +const { isSea, getAssetKeys } = require('node:sea'); +const assert = require('node:assert'); + +assert(isSea()); + +const keys = getAssetKeys(); +console.log('Asset keys:', JSON.stringify(keys.sort())); diff --git a/test/fixtures/sea/assets-invalid-type/sea-config.json b/test/fixtures/sea/assets-invalid-type/sea-config.json new file mode 100644 index 00000000000000..418df8cf78f7cf --- /dev/null +++ b/test/fixtures/sea/assets-invalid-type/sea-config.json @@ -0,0 +1,5 @@ +{ + "main": "sea.js", + "output": "sea-prep.blob", + "assets": "invalid" +} diff --git a/test/fixtures/sea/assets-invalid-type/sea.js b/test/fixtures/sea/assets-invalid-type/sea.js new file mode 100644 index 00000000000000..71e4a5e1aac763 --- /dev/null +++ b/test/fixtures/sea/assets-invalid-type/sea.js @@ -0,0 +1,3 @@ +'use strict'; +// This file is used for testing invalid "assets" configuration. +// It should not be executed because the configuration should fail. diff --git a/test/fixtures/sea/assets-nonexistent-file/sea-config.json b/test/fixtures/sea/assets-nonexistent-file/sea-config.json new file mode 100644 index 00000000000000..f4549fe63770f4 --- /dev/null +++ b/test/fixtures/sea/assets-nonexistent-file/sea-config.json @@ -0,0 +1,7 @@ +{ + "main": "sea.js", + "output": "sea-prep.blob", + "assets": { + "nonexistent": "nonexistent.txt" + } +} diff --git a/test/fixtures/sea/assets-nonexistent-file/sea.js b/test/fixtures/sea/assets-nonexistent-file/sea.js new file mode 100644 index 00000000000000..340e8ecac75251 --- /dev/null +++ b/test/fixtures/sea/assets-nonexistent-file/sea.js @@ -0,0 +1,3 @@ +'use strict'; +// This file is used for testing nonexistent asset file. +// It should not be executed because the configuration should fail. diff --git a/test/fixtures/sea/assets-raw/person.jpg b/test/fixtures/sea/assets-raw/person.jpg new file mode 100644 index 0000000000000000000000000000000000000000..96d46888d76c19a976eaed55fb1987183b69bbc7 GIT binary patch literal 45658 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%0D*%BK~3)9Ck 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%0D*%BK~3)9Ck z-Ca^?DuWMKlp8A;Q|UgP#DaTchcYx%Xd9}RnIvEeAnBJyg*dYf2V7JCV=h2>Qc*Fe5eY>XD% z=nq_UCm%ist#*(MD`~hj(n6Vduhlns^*oj;>ykz$jv^mV`Qzhm|&33r3lyyjz-z zT5F97x0a=nF(XMMRk;OOl&~SjPh5{~IvRPIL7+Byb>g||g^sM}Inl$9lB}G|x7(>M z^iWemmfCU}qNbLa8_T3=B*={m^(V^+a8E*U$3IkuIF^VDprix_ZO*ozWINDp}D?5YibKCOm`EkjB0D!vUON^A5o}IXK%RSzO!RiMI zB(kG2*=Xb)Oj64U1K1s|zuNx*rwJvtjCr9~%U0S4QV&iNNoo-p?o@sqKVBeIfmBE;_zR>5S*)!Y+2ngIgC?ZjqeRM$$#(u|+KzV0N(?Do?&TjQu#U zsuGCnj0##Xz-}Ejp1-FMg(+Lj*Ltu5QV&v$xXI@O0E}dOzMMp~6=rKf zWVI!3wyhMk7W(OA3RlX4f=POG@3d|MAa(xk8OJ5l28V91k0QAt$tp`Vx~1&(wRbvd zfVGz$X=SXakT$@@k_gDARrL@el^?JzyF60<(eCWl$1*+sRf7QPrd;rO2S>kDYv*S$ z^q!98y+_%)_W1^?EStc=z^C$7E!h|afxtU@r~p;}0MdO&v@yh=KgE^b{I2bV z#f<}~{?!1j$9f(DZ{K;cvk0EsxKMhVf7{D4V1CWu~-sLR8vqP{mWX3sobu(%}0CVsVlE zTyUTz)l8`sLaOA2>3~N={vEhvl9Ys*MsR*Z1n`ndAh$m7a&}{&$RqqXX_S+l1aW}k zTxGoj%x;+?J=YH3^B+_1!BV)sI%?frlF;RKUq&c`K0va})6Twth70oZ;W5AxyX zbr?}9%PmbTvZ0Atv+HF8A3}b7F)2c1tfZaQ$%!$XWSnR4IrieGDV6P3vKQ;%cY98&fN2r0q5tIuWqpxQQ~kF}gK~Z7+}OXZi5# zH2{Njpm9K6ba=$pI`Ro1w#d42iGk@tN1jKvWdkGr9C0j##!b@~0bmtUs}kQX@GV_y zdDT;edYRdn9F#9=Jd`gZ4{Ig6!i?Nv!FMFrKCHxi`Lx+O}M8<%o1 z!DE0(%U~V|rSUhYQL7=2o(Jfqwb#01TTmh_$gV&;e?RZzr6seX<)HCYe))* z4~K*teD)4G3SR>4u|MTL_EAD|IJFA44#04dUj}6LDJskAQay<3I7ufP!lGU)PByDb z%mDV!U+p|3l68|Wk<;tKNjOv9swuVzaT!j`JN`dI#9=(AiVOA5<52}a#>peQ02SEd z<=5msxZ#qOadaJ)TTYU;(LKd0rB%z+)8}qW79mONft(D1_zdxDLqlZjeYVdV=A4*EIDPhFV&RYr01@JG(Q-h8+gtdu{92-`sJ1D9+xYS6Ker fqk&VJo8+{zVmM=c<9RJE(n require('test'), { + code: 'ERR_UNKNOWN_BUILTIN_MODULE', +}); + +deepStrictEqual(process.argv, [process.execPath, process.execPath, '-a', '--b=c', 'd']); + +strictEqual(require.cache, undefined); +strictEqual(require.extensions, undefined); +strictEqual(require.main, module); +strictEqual(require.resolve, undefined); + +strictEqual(__filename, process.execPath); +strictEqual(__dirname, dirname(process.execPath)); +strictEqual(module.exports, exports); + +throws(() => require('./requirable.js'), { + code: 'ERR_UNKNOWN_BUILTIN_MODULE', +}); + +const requirable = createdRequire('./requirable.js'); +deepStrictEqual(requirable, { + hello: 'world', +}); + +console.log('Hello, world! 😊'); diff --git a/test/fixtures/sea/empty/empty.js b/test/fixtures/sea/empty/empty.js new file mode 100644 index 00000000000000..e69de29bb2d1d6 diff --git a/test/fixtures/sea/empty/sea-config.json b/test/fixtures/sea/empty/sea-config.json new file mode 100644 index 00000000000000..cd76437e265d90 --- /dev/null +++ b/test/fixtures/sea/empty/sea-config.json @@ -0,0 +1,4 @@ +{ + "main": "empty.js", + "output": "sea-prep.blob" +} diff --git a/test/fixtures/sea/exec-argv-empty/sea-config.json b/test/fixtures/sea/exec-argv-empty/sea-config.json new file mode 100644 index 00000000000000..11b06a6c764f2d --- /dev/null +++ b/test/fixtures/sea/exec-argv-empty/sea-config.json @@ -0,0 +1,6 @@ +{ + "main": "sea.js", + "output": "sea-prep.blob", + "disableExperimentalSEAWarning": true, + "execArgv": [] +} diff --git a/test/fixtures/sea/exec-argv-empty/sea.js b/test/fixtures/sea/exec-argv-empty/sea.js new file mode 100644 index 00000000000000..1c98860ba34495 --- /dev/null +++ b/test/fixtures/sea/exec-argv-empty/sea.js @@ -0,0 +1,6 @@ +const assert = require('assert'); + +console.log('process.argv:', JSON.stringify(process.argv)); +assert.strictEqual(process.argv[2], 'user-arg'); +assert.deepStrictEqual(process.execArgv, []); +console.log('empty execArgv test passed'); diff --git a/test/fixtures/sea/exec-argv-extension-cli/sea-config.json b/test/fixtures/sea/exec-argv-extension-cli/sea-config.json new file mode 100644 index 00000000000000..0ec0d706b384ab --- /dev/null +++ b/test/fixtures/sea/exec-argv-extension-cli/sea-config.json @@ -0,0 +1,7 @@ +{ + "main": "sea.js", + "output": "sea-prep.blob", + "disableExperimentalSEAWarning": true, + "execArgv": ["--no-warnings"], + "execArgvExtension": "cli" +} diff --git a/test/fixtures/sea/exec-argv-extension-cli/sea.js b/test/fixtures/sea/exec-argv-extension-cli/sea.js new file mode 100644 index 00000000000000..e9585483fcc21d --- /dev/null +++ b/test/fixtures/sea/exec-argv-extension-cli/sea.js @@ -0,0 +1,14 @@ +const assert = require('assert'); + +console.log('process.argv:', JSON.stringify(process.argv)); +console.log('process.execArgv:', JSON.stringify(process.execArgv)); + +// Should have execArgv from SEA config + CLI --node-options +assert.deepStrictEqual(process.execArgv, ['--no-warnings', '--max-old-space-size=1024']); + +assert.deepStrictEqual(process.argv.slice(2), [ + 'user-arg1', + 'user-arg2' +]); + +console.log('execArgvExtension cli test passed'); diff --git a/test/fixtures/sea/exec-argv-extension-env/sea-config.json b/test/fixtures/sea/exec-argv-extension-env/sea-config.json new file mode 100644 index 00000000000000..f0d098bdb1d3d1 --- /dev/null +++ b/test/fixtures/sea/exec-argv-extension-env/sea-config.json @@ -0,0 +1,7 @@ +{ + "main": "sea.js", + "output": "sea-prep.blob", + "disableExperimentalSEAWarning": true, + "execArgv": ["--no-warnings"], + "execArgvExtension": "env" +} diff --git a/test/fixtures/sea/exec-argv-extension-env/sea.js b/test/fixtures/sea/exec-argv-extension-env/sea.js new file mode 100644 index 00000000000000..1d706dfe7cfe11 --- /dev/null +++ b/test/fixtures/sea/exec-argv-extension-env/sea.js @@ -0,0 +1,19 @@ +const assert = require('assert'); + +process.emitWarning('This warning should not be shown in the output', 'TestWarning'); + +console.log('process.argv:', JSON.stringify(process.argv)); +console.log('process.execArgv:', JSON.stringify(process.execArgv)); + +// Should have execArgv from SEA config. +// Note that flags from NODE_OPTIONS are not included in process.execArgv no matter it's +// an SEA or not, but we can test whether it works by checking that the warning emitted +// above was silenced. +assert.deepStrictEqual(process.execArgv, ['--no-warnings']); + +assert.deepStrictEqual(process.argv.slice(2), [ + 'user-arg1', + 'user-arg2' +]); + +console.log('execArgvExtension env test passed'); diff --git a/test/fixtures/sea/exec-argv-extension-none/sea-config.json b/test/fixtures/sea/exec-argv-extension-none/sea-config.json new file mode 100644 index 00000000000000..15c7447abcf6c2 --- /dev/null +++ b/test/fixtures/sea/exec-argv-extension-none/sea-config.json @@ -0,0 +1,7 @@ +{ + "main": "sea.js", + "output": "sea-prep.blob", + "disableExperimentalSEAWarning": true, + "execArgv": ["--no-warnings"], + "execArgvExtension": "none" +} diff --git a/test/fixtures/sea/exec-argv-extension-none/sea.js b/test/fixtures/sea/exec-argv-extension-none/sea.js new file mode 100644 index 00000000000000..c089b065677091 --- /dev/null +++ b/test/fixtures/sea/exec-argv-extension-none/sea.js @@ -0,0 +1,14 @@ +const assert = require('assert'); + +console.log('process.argv:', JSON.stringify(process.argv)); +console.log('process.execArgv:', JSON.stringify(process.execArgv)); + +// Should only have execArgv from SEA config, no NODE_OPTIONS +assert.deepStrictEqual(process.execArgv, ['--no-warnings']); + +assert.deepStrictEqual(process.argv.slice(2), [ + 'user-arg1', + 'user-arg2' +]); + +console.log('execArgvExtension none test passed'); diff --git a/test/fixtures/sea/exec-argv/sea-config.json b/test/fixtures/sea/exec-argv/sea-config.json new file mode 100644 index 00000000000000..d32cbd22e325f5 --- /dev/null +++ b/test/fixtures/sea/exec-argv/sea-config.json @@ -0,0 +1,6 @@ +{ + "main": "sea.js", + "output": "sea-prep.blob", + "disableExperimentalSEAWarning": true, + "execArgv": ["--no-warnings", "--max-old-space-size=2048"] +} diff --git a/test/fixtures/sea/exec-argv/sea.js b/test/fixtures/sea/exec-argv/sea.js new file mode 100644 index 00000000000000..7f0f8ece575138 --- /dev/null +++ b/test/fixtures/sea/exec-argv/sea.js @@ -0,0 +1,18 @@ +const assert = require('assert'); + +process.emitWarning('This warning should not be shown in the output', 'TestWarning'); + +console.log('process.argv:', JSON.stringify(process.argv)); +console.log('process.execArgv:', JSON.stringify(process.execArgv)); + +assert.deepStrictEqual(process.execArgv, [ '--no-warnings', '--max-old-space-size=2048' ]); + +// We start from 2, because in SEA, the index 1 would be the same as the execPath +// to accommodate the general expectation that index 1 is the path to script for +// applications. +assert.deepStrictEqual(process.argv.slice(2), [ + 'user-arg1', + 'user-arg2' +]); + +console.log('multiple execArgv test passed'); diff --git a/test/fixtures/sea/inspect-in-sea-flags/sea-config.json b/test/fixtures/sea/inspect-in-sea-flags/sea-config.json new file mode 100644 index 00000000000000..8acf995f9ae7ab --- /dev/null +++ b/test/fixtures/sea/inspect-in-sea-flags/sea-config.json @@ -0,0 +1,4 @@ +{ + "main": "sea.js", + "output": "sea-prep.blob" +} diff --git a/test/fixtures/sea/inspect-in-sea-flags/sea.js b/test/fixtures/sea/inspect-in-sea-flags/sea.js new file mode 100644 index 00000000000000..ab74fd7b79969d --- /dev/null +++ b/test/fixtures/sea/inspect-in-sea-flags/sea.js @@ -0,0 +1 @@ +console.log(process.argv); diff --git a/test/fixtures/sea/inspect/hello.js b/test/fixtures/sea/inspect/hello.js new file mode 100644 index 00000000000000..e9fe0090d63813 --- /dev/null +++ b/test/fixtures/sea/inspect/hello.js @@ -0,0 +1 @@ +console.log('Hello, world!'); diff --git a/test/fixtures/sea/inspect/sea-config.json b/test/fixtures/sea/inspect/sea-config.json new file mode 100644 index 00000000000000..96c7d51e65d381 --- /dev/null +++ b/test/fixtures/sea/inspect/sea-config.json @@ -0,0 +1,4 @@ +{ + "main": "hello.js", + "output": "sea-prep.blob" +} diff --git a/test/fixtures/sea/simple/requirable.js b/test/fixtures/sea/simple/requirable.js new file mode 100644 index 00000000000000..69f1fd8c3776c1 --- /dev/null +++ b/test/fixtures/sea/simple/requirable.js @@ -0,0 +1,3 @@ +module.exports = { + hello: 'world', +}; diff --git a/test/fixtures/sea/simple/sea-config.json b/test/fixtures/sea/simple/sea-config.json new file mode 100644 index 00000000000000..c1dec576ecc5c4 --- /dev/null +++ b/test/fixtures/sea/simple/sea-config.json @@ -0,0 +1,6 @@ + +{ + "main": "sea.js", + "output": "snapshot.blob", + "disableExperimentalSEAWarning": true +} diff --git a/test/fixtures/sea/simple/sea.js b/test/fixtures/sea/simple/sea.js new file mode 100644 index 00000000000000..65bb8d37e019a2 --- /dev/null +++ b/test/fixtures/sea/simple/sea.js @@ -0,0 +1,64 @@ +const { Module: { createRequire } } = require('module'); +const createdRequire = createRequire(__filename); + +// Although, require('../common') works locally, that couldn't be used here +// because we set NODE_TEST_DIR=/Users/iojs/node-tmp on Jenkins CI. +const { expectWarning, mustNotCall } = createdRequire(process.env.COMMON_DIRECTORY); + +const builtinWarning = +`Currently the require() provided to the main script embedded into single-executable applications only supports loading built-in modules. +To load a module from disk after the single executable application is launched, use require("module").createRequire(). +Support for bundled module loading or virtual file systems are under discussions in https://github.com/nodejs/single-executable`; + +// This additionally makes sure that no unexpected warnings are emitted. +if (!createdRequire('./sea-config.json').disableExperimentalSEAWarning) { + expectWarning('Warning', builtinWarning); // Triggered by require() calls below. + expectWarning('ExperimentalWarning', + 'Single executable application is an experimental feature and ' + + 'might change at any time'); + // Any unexpected warning would throw this error: + // https://github.com/nodejs/node/blob/c301404105a7256b79a0b8c4522ce47af96dfa17/test/common/index.js#L697-L700. +} + +// Should be possible to require core modules that optionally require the +// "node:" scheme. +const { deepStrictEqual, strictEqual, throws } = require('assert'); +const { dirname } = require('node:path'); + +// Checks that the source filename is used in the error stack trace. +strictEqual(new Error('lol').stack.split('\n')[1], ' at sea.js:29:13'); + +// Should be possible to require a core module that requires using the "node:" +// scheme. +{ + const { test } = require('node:test'); + strictEqual(typeof test, 'function'); +} + +// Should not be possible to require a core module without the "node:" scheme if +// it requires using the "node:" scheme. +throws(() => require('test'), { + code: 'ERR_UNKNOWN_BUILTIN_MODULE', +}); + +deepStrictEqual(process.argv, [process.execPath, process.execPath, '-a', '--b=c', 'd']); + +strictEqual(require.cache, undefined); +strictEqual(require.extensions, undefined); +strictEqual(require.main, module); +strictEqual(require.resolve, undefined); + +strictEqual(__filename, process.execPath); +strictEqual(__dirname, dirname(process.execPath)); +strictEqual(module.exports, exports); + +throws(() => require('./requirable.js'), { + code: 'ERR_UNKNOWN_BUILTIN_MODULE', +}); + +const requirable = createdRequire('./requirable.js'); +deepStrictEqual(requirable, { + hello: 'world', +}); + +console.log('Hello, world! 😊'); diff --git a/test/fixtures/sea/snapshot-and-code-cache/sea-config.json b/test/fixtures/sea/snapshot-and-code-cache/sea-config.json new file mode 100644 index 00000000000000..9913b1a4e9460d --- /dev/null +++ b/test/fixtures/sea/snapshot-and-code-cache/sea-config.json @@ -0,0 +1,6 @@ +{ + "main": "snapshot.js", + "output": "sea-prep.blob", + "useSnapshot": true, + "useCodeCache": true +} diff --git a/test/fixtures/sea/snapshot-and-code-cache/snapshot.js b/test/fixtures/sea/snapshot-and-code-cache/snapshot.js new file mode 100644 index 00000000000000..39b51a0324fced --- /dev/null +++ b/test/fixtures/sea/snapshot-and-code-cache/snapshot.js @@ -0,0 +1,7 @@ +const { + setDeserializeMainFunction, +} = require('v8').startupSnapshot; + +setDeserializeMainFunction(() => { + console.log('Hello from snapshot'); +}); diff --git a/test/fixtures/sea/snapshot-worker/sea-config.json b/test/fixtures/sea/snapshot-worker/sea-config.json new file mode 100644 index 00000000000000..d4d3f30853cc1f --- /dev/null +++ b/test/fixtures/sea/snapshot-worker/sea-config.json @@ -0,0 +1,5 @@ +{ + "main": "snapshot.js", + "output": "sea-prep.blob", + "useSnapshot": true +} diff --git a/test/fixtures/sea/snapshot-worker/snapshot.js b/test/fixtures/sea/snapshot-worker/snapshot.js new file mode 100644 index 00000000000000..438090b3b764c1 --- /dev/null +++ b/test/fixtures/sea/snapshot-worker/snapshot.js @@ -0,0 +1,8 @@ +const { + setDeserializeMainFunction, +} = require('v8').startupSnapshot; + +setDeserializeMainFunction(() => { + const { Worker } = require('worker_threads'); + new Worker("console.log('Hello from Worker')", { eval: true }); +}); diff --git a/test/fixtures/sea/snapshot/sea-config.json b/test/fixtures/sea/snapshot/sea-config.json new file mode 100644 index 00000000000000..d4d3f30853cc1f --- /dev/null +++ b/test/fixtures/sea/snapshot/sea-config.json @@ -0,0 +1,5 @@ +{ + "main": "snapshot.js", + "output": "sea-prep.blob", + "useSnapshot": true +} diff --git a/test/fixtures/sea/snapshot/snapshot.js b/test/fixtures/sea/snapshot/snapshot.js new file mode 100644 index 00000000000000..39b51a0324fced --- /dev/null +++ b/test/fixtures/sea/snapshot/snapshot.js @@ -0,0 +1,7 @@ +const { + setDeserializeMainFunction, +} = require('v8').startupSnapshot; + +setDeserializeMainFunction(() => { + console.log('Hello from snapshot'); +}); diff --git a/test/fixtures/sea/use-code-cache/requirable.js b/test/fixtures/sea/use-code-cache/requirable.js new file mode 100644 index 00000000000000..69f1fd8c3776c1 --- /dev/null +++ b/test/fixtures/sea/use-code-cache/requirable.js @@ -0,0 +1,3 @@ +module.exports = { + hello: 'world', +}; diff --git a/test/fixtures/sea/use-code-cache/sea-config.json b/test/fixtures/sea/use-code-cache/sea-config.json new file mode 100644 index 00000000000000..a69bd831f91287 --- /dev/null +++ b/test/fixtures/sea/use-code-cache/sea-config.json @@ -0,0 +1,5 @@ +{ + "main": "sea.js", + "output": "sea-prep.blob", + "useCodeCache": true +} diff --git a/test/fixtures/sea/use-code-cache/sea.js b/test/fixtures/sea/use-code-cache/sea.js new file mode 100644 index 00000000000000..65bb8d37e019a2 --- /dev/null +++ b/test/fixtures/sea/use-code-cache/sea.js @@ -0,0 +1,64 @@ +const { Module: { createRequire } } = require('module'); +const createdRequire = createRequire(__filename); + +// Although, require('../common') works locally, that couldn't be used here +// because we set NODE_TEST_DIR=/Users/iojs/node-tmp on Jenkins CI. +const { expectWarning, mustNotCall } = createdRequire(process.env.COMMON_DIRECTORY); + +const builtinWarning = +`Currently the require() provided to the main script embedded into single-executable applications only supports loading built-in modules. +To load a module from disk after the single executable application is launched, use require("module").createRequire(). +Support for bundled module loading or virtual file systems are under discussions in https://github.com/nodejs/single-executable`; + +// This additionally makes sure that no unexpected warnings are emitted. +if (!createdRequire('./sea-config.json').disableExperimentalSEAWarning) { + expectWarning('Warning', builtinWarning); // Triggered by require() calls below. + expectWarning('ExperimentalWarning', + 'Single executable application is an experimental feature and ' + + 'might change at any time'); + // Any unexpected warning would throw this error: + // https://github.com/nodejs/node/blob/c301404105a7256b79a0b8c4522ce47af96dfa17/test/common/index.js#L697-L700. +} + +// Should be possible to require core modules that optionally require the +// "node:" scheme. +const { deepStrictEqual, strictEqual, throws } = require('assert'); +const { dirname } = require('node:path'); + +// Checks that the source filename is used in the error stack trace. +strictEqual(new Error('lol').stack.split('\n')[1], ' at sea.js:29:13'); + +// Should be possible to require a core module that requires using the "node:" +// scheme. +{ + const { test } = require('node:test'); + strictEqual(typeof test, 'function'); +} + +// Should not be possible to require a core module without the "node:" scheme if +// it requires using the "node:" scheme. +throws(() => require('test'), { + code: 'ERR_UNKNOWN_BUILTIN_MODULE', +}); + +deepStrictEqual(process.argv, [process.execPath, process.execPath, '-a', '--b=c', 'd']); + +strictEqual(require.cache, undefined); +strictEqual(require.extensions, undefined); +strictEqual(require.main, module); +strictEqual(require.resolve, undefined); + +strictEqual(__filename, process.execPath); +strictEqual(__dirname, dirname(process.execPath)); +strictEqual(module.exports, exports); + +throws(() => require('./requirable.js'), { + code: 'ERR_UNKNOWN_BUILTIN_MODULE', +}); + +const requirable = createdRequire('./requirable.js'); +deepStrictEqual(requirable, { + hello: 'world', +}); + +console.log('Hello, world! 😊'); diff --git a/test/node-api/test_sea_addon/test.js b/test/node-api/test_sea_addon/test.js index 386ece80955c9d..ef5fa118a0a45a 100644 --- a/test/node-api/test_sea_addon/test.js +++ b/test/node-api/test_sea_addon/test.js @@ -6,57 +6,30 @@ const { generateSEA, skipIfSingleExecutableIsNotSupported } = require('../../com skipIfSingleExecutableIsNotSupported(); -const assert = require('assert'); - const tmpdir = require('../../common/tmpdir'); -const { copyFileSync, writeFileSync, existsSync, rmSync } = require('fs'); +const { copyFileSync, rmSync, cpSync } = require('fs'); const { - spawnSyncAndExitWithoutError, spawnSyncAndAssert, } = require('../../common/child_process'); const { join } = require('path'); -const configFile = tmpdir.resolve('sea-config.json'); -const seaPrepBlob = tmpdir.resolve('sea-prep.blob'); -const outputFile = tmpdir.resolve(process.platform === 'win32' ? 'sea.exe' : 'sea'); -tmpdir.refresh(); +const fixtures = require('../../common/fixtures'); -// Copy test fixture to working directory const addonPath = join(__dirname, 'build', common.buildType, 'binding.node'); const copiedAddonPath = tmpdir.resolve('binding.node'); -copyFileSync(addonPath, copiedAddonPath); -writeFileSync(tmpdir.resolve('sea.js'), ` -const sea = require('node:sea'); -const fs = require('fs'); -const path = require('path'); -const addonPath = path.join(${JSON.stringify(tmpdir.path)}, 'hello.node'); -fs.writeFileSync(addonPath, new Uint8Array(sea.getRawAsset('hello.node'))); -const mod = {exports: {}} -process.dlopen(mod, addonPath); -console.log('hello,', mod.exports.hello()); -`, 'utf-8'); +tmpdir.refresh(); -writeFileSync(configFile, ` -{ - "main": "sea.js", - "output": "sea-prep.blob", - "disableExperimentalSEAWarning": true, - "assets": { - "hello.node": "binding.node" - } -} -`, 'utf8'); +// Copy fixture files to working directory. +const fixtureDir = fixtures.path('sea', 'addon'); +cpSync(fixtureDir, tmpdir.path, { recursive: true }); -spawnSyncAndExitWithoutError( - process.execPath, - ['--experimental-sea-config', 'sea-config.json'], - { cwd: tmpdir.path }, -); -assert(existsSync(seaPrepBlob)); +// Copy the built addon to working directory. +copyFileSync(addonPath, copiedAddonPath); -generateSEA(outputFile, process.execPath, seaPrepBlob); +// Generate the SEA using the working directory directly (skip copy). +const outputFile = generateSEA(tmpdir.path, tmpdir.path); -// Remove the copied addon after it's been packaged into the SEA blob +// Remove the copied addon after it's been packaged into the SEA blob. rmSync(copiedAddonPath, { force: true }); spawnSyncAndAssert( diff --git a/test/sea/test-single-executable-application-asset-keys-empty.js b/test/sea/test-single-executable-application-asset-keys-empty.js index 9168f2b27235be..c12bcd690a40ef 100644 --- a/test/sea/test-single-executable-application-asset-keys-empty.js +++ b/test/sea/test-single-executable-application-asset-keys-empty.js @@ -14,42 +14,17 @@ skipIfSingleExecutableIsNotSupported(); const tmpdir = require('../common/tmpdir'); -const { copyFileSync, writeFileSync, existsSync } = require('fs'); const { - spawnSyncAndExitWithoutError, spawnSyncAndAssert, } = require('../common/child_process'); -const assert = require('assert'); const fixtures = require('../common/fixtures'); -const seaPrepBlob = tmpdir.resolve('sea-prep.blob'); -const outputFile = tmpdir.resolve(process.platform === 'win32' ? 'sea.exe' : 'sea'); - tmpdir.refresh(); -copyFileSync(fixtures.path('sea', 'get-asset-keys.js'), tmpdir.resolve('sea.js')); - -writeFileSync(tmpdir.resolve('sea-config.json'), ` -{ - "main": "sea.js", - "output": "sea-prep.blob" -} -`, 'utf8'); -spawnSyncAndExitWithoutError( - process.execPath, - ['--experimental-sea-config', 'sea-config.json'], - { - env: { - NODE_DEBUG_NATIVE: 'SEA', - ...process.env, - }, - cwd: tmpdir.path, - }, - {}); - -assert(existsSync(seaPrepBlob)); - -generateSEA(outputFile, process.execPath, seaPrepBlob); +const outputFile = generateSEA( + fixtures.path('sea', 'asset-keys-empty'), + tmpdir.path, +); spawnSyncAndAssert( outputFile, diff --git a/test/sea/test-single-executable-application-asset-keys.js b/test/sea/test-single-executable-application-asset-keys.js index a2d1dce487e356..a4728eb681e617 100644 --- a/test/sea/test-single-executable-application-asset-keys.js +++ b/test/sea/test-single-executable-application-asset-keys.js @@ -14,51 +14,17 @@ skipIfSingleExecutableIsNotSupported(); const tmpdir = require('../common/tmpdir'); -const { copyFileSync, writeFileSync, existsSync } = require('fs'); const { - spawnSyncAndExitWithoutError, spawnSyncAndAssert, } = require('../common/child_process'); -const assert = require('assert'); const fixtures = require('../common/fixtures'); -const configFile = tmpdir.resolve('sea-config.json'); -const seaPrepBlob = tmpdir.resolve('sea-prep.blob'); -const outputFile = tmpdir.resolve(process.platform === 'win32' ? 'sea.exe' : 'sea'); - tmpdir.refresh(); -copyFileSync(fixtures.path('sea', 'get-asset-keys.js'), tmpdir.resolve('sea.js')); -writeFileSync(tmpdir.resolve('asset-1.txt'), 'This is asset 1'); -writeFileSync(tmpdir.resolve('asset-2.txt'), 'This is asset 2'); -writeFileSync(tmpdir.resolve('asset-3.txt'), 'This is asset 3'); - -writeFileSync(configFile, ` -{ - "main": "sea.js", - "output": "sea-prep.blob", - "assets": { - "asset-1.txt": "asset-1.txt", - "asset-2.txt": "asset-2.txt", - "asset-3.txt": "asset-3.txt" - } -} -`, 'utf8'); -spawnSyncAndExitWithoutError( - process.execPath, - ['--experimental-sea-config', 'sea-config.json'], - { - env: { - NODE_DEBUG_NATIVE: 'SEA', - ...process.env, - }, - cwd: tmpdir.path, - }, - {}); - -assert(existsSync(seaPrepBlob)); - -generateSEA(outputFile, process.execPath, seaPrepBlob); +const outputFile = generateSEA( + fixtures.path('sea', 'asset-keys'), + tmpdir.path, +); spawnSyncAndAssert( outputFile, diff --git a/test/sea/test-single-executable-application-assets-invalid-type.js b/test/sea/test-single-executable-application-assets-invalid-type.js new file mode 100644 index 00000000000000..927acd8ac647d4 --- /dev/null +++ b/test/sea/test-single-executable-application-assets-invalid-type.js @@ -0,0 +1,35 @@ +'use strict'; + +// Test that invalid "assets" field (not a map) is rejected. + +require('../common'); +const { + spawnSyncAndExit, +} = require('../common/child_process'); +const fixtures = require('../common/fixtures'); +const tmpdir = require('../common/tmpdir'); +const { copyFileSync } = require('fs'); + +tmpdir.refresh(); + +// Copy the fixture files to tmpdir +copyFileSync( + fixtures.path('sea', 'assets-invalid-type', 'sea-config.json'), + tmpdir.resolve('sea-config.json'), +); +copyFileSync( + fixtures.path('sea', 'assets-invalid-type', 'sea.js'), + tmpdir.resolve('sea.js'), +); + +spawnSyncAndExit( + process.execPath, + ['--experimental-sea-config', 'sea-config.json'], + { + cwd: tmpdir.path, + }, + { + status: 1, + signal: null, + stderr: /"assets" field of .*sea-config\.json is not a map of strings/, + }); diff --git a/test/sea/test-single-executable-application-assets-nonexistent-file.js b/test/sea/test-single-executable-application-assets-nonexistent-file.js new file mode 100644 index 00000000000000..260eb798fb8150 --- /dev/null +++ b/test/sea/test-single-executable-application-assets-nonexistent-file.js @@ -0,0 +1,35 @@ +'use strict'; + +// Test that nonexistent asset file is rejected. + +const common = require('../common'); // eslint-disable-line no-unused-vars +const { + spawnSyncAndExit, +} = require('../common/child_process'); +const fixtures = require('../common/fixtures'); +const tmpdir = require('../common/tmpdir'); +const { copyFileSync } = require('fs'); + +tmpdir.refresh(); + +// Copy the fixture files to tmpdir +copyFileSync( + fixtures.path('sea', 'assets-nonexistent-file', 'sea-config.json'), + tmpdir.resolve('sea-config.json'), +); +copyFileSync( + fixtures.path('sea', 'assets-nonexistent-file', 'sea.js'), + tmpdir.resolve('sea.js'), +); + +spawnSyncAndExit( + process.execPath, + ['--experimental-sea-config', 'sea-config.json'], + { + cwd: tmpdir.path, + }, + { + status: 1, + signal: null, + stderr: /Cannot read asset nonexistent\.txt: no such file or directory/, + }); diff --git a/test/sea/test-single-executable-application-assets-raw.js b/test/sea/test-single-executable-application-assets-raw.js index ff0fb3ecacddb3..e45a76b5b1272a 100644 --- a/test/sea/test-single-executable-application-assets-raw.js +++ b/test/sea/test-single-executable-application-assets-raw.js @@ -1,7 +1,6 @@ 'use strict'; -const common = require('../common'); - +require('../common'); const { generateSEA, skipIfSingleExecutableIsNotSupported, @@ -12,59 +11,24 @@ skipIfSingleExecutableIsNotSupported(); // This tests the snapshot support in single executable applications. const tmpdir = require('../common/tmpdir'); -const { copyFileSync, writeFileSync, existsSync } = require('fs'); const { spawnSyncAndExitWithoutError, } = require('../common/child_process'); -const assert = require('assert'); const fixtures = require('../common/fixtures'); tmpdir.refresh(); -if (!tmpdir.hasEnoughSpace(120 * 1024 * 1024)) { - common.skip('Not enough disk space'); -} - -const configFile = tmpdir.resolve('sea-config.json'); -const seaPrepBlob = tmpdir.resolve('sea-prep.blob'); -const outputFile = tmpdir.resolve(process.platform === 'win32' ? 'sea.exe' : 'sea'); +const outputFile = generateSEA( + fixtures.path('sea', 'assets-raw'), + tmpdir.path, +); -{ - tmpdir.refresh(); - copyFileSync(fixtures.path('sea', 'get-asset-raw.js'), tmpdir.resolve('sea.js')); - copyFileSync(fixtures.path('person.jpg'), tmpdir.resolve('person.jpg')); - writeFileSync(configFile, ` +spawnSyncAndExitWithoutError( + outputFile, { - "main": "sea.js", - "output": "sea-prep.blob", - "assets": { - "person.jpg": "person.jpg" - } - } - `, 'utf8'); - - spawnSyncAndExitWithoutError( - process.execPath, - ['--experimental-sea-config', 'sea-config.json'], - { - env: { - NODE_DEBUG_NATIVE: 'SEA', - ...process.env, - }, - cwd: tmpdir.path, - }); - - assert(existsSync(seaPrepBlob)); - - generateSEA(outputFile, process.execPath, seaPrepBlob); - - spawnSyncAndExitWithoutError( - outputFile, - { - env: { - ...process.env, - NODE_DEBUG_NATIVE: 'SEA', - __TEST_PERSON_JPG: fixtures.path('person.jpg'), - }, + env: { + ...process.env, + NODE_DEBUG_NATIVE: 'SEA', + __TEST_PERSON_JPG: fixtures.path('person.jpg'), }, - ); -} + }, +); diff --git a/test/sea/test-single-executable-application-assets.js b/test/sea/test-single-executable-application-assets.js index dd285021cd714b..c327f1fe6a2e0c 100644 --- a/test/sea/test-single-executable-application-assets.js +++ b/test/sea/test-single-executable-application-assets.js @@ -1,7 +1,8 @@ 'use strict'; -const common = require('../common'); +// This tests the assets support in single executable applications. +require('../common'); const { generateSEA, skipIfSingleExecutableIsNotSupported, @@ -9,121 +10,30 @@ const { skipIfSingleExecutableIsNotSupported(); -// This tests the snapshot support in single executable applications. const tmpdir = require('../common/tmpdir'); - -const { copyFileSync, writeFileSync, existsSync } = require('fs'); const { spawnSyncAndAssert, - spawnSyncAndExit, - spawnSyncAndExitWithoutError, } = require('../common/child_process'); -const assert = require('assert'); const fixtures = require('../common/fixtures'); tmpdir.refresh(); -if (!tmpdir.hasEnoughSpace(120 * 1024 * 1024)) { - common.skip('Not enough disk space'); -} - -const configFile = tmpdir.resolve('sea-config.json'); -const seaPrepBlob = tmpdir.resolve('sea-prep.blob'); -const outputFile = tmpdir.resolve(process.platform === 'win32' ? 'sea.exe' : 'sea'); +const outputFile = generateSEA( + fixtures.path('sea', 'assets'), + tmpdir.path, +); -{ - tmpdir.refresh(); - copyFileSync(fixtures.path('sea', 'get-asset.js'), tmpdir.resolve('sea.js')); - writeFileSync(configFile, ` +spawnSyncAndAssert( + outputFile, { - "main": "sea.js", - "output": "sea-prep.blob", - "assets": "invalid" - } - `); - - spawnSyncAndExit( - process.execPath, - ['--experimental-sea-config', 'sea-config.json'], - { - cwd: tmpdir.path, - }, - { - status: 1, - signal: null, - stderr: /"assets" field of sea-config\.json is not a map of strings/, - }); -} - -{ - tmpdir.refresh(); - copyFileSync(fixtures.path('sea', 'get-asset.js'), tmpdir.resolve('sea.js')); - writeFileSync(configFile, ` - { - "main": "sea.js", - "output": "sea-prep.blob", - "assets": { - "nonexistent": "nonexistent.txt" - } - } - `); - - spawnSyncAndExit( - process.execPath, - ['--experimental-sea-config', 'sea-config.json'], - { - cwd: tmpdir.path, + env: { + ...process.env, + NODE_DEBUG_NATIVE: 'SEA', + __TEST_PERSON_JPG: fixtures.path('person.jpg'), + __TEST_UTF8_TEXT_PATH: fixtures.path('utf8_test_text.txt'), }, - { - status: 1, - signal: null, - stderr: /Cannot read asset nonexistent\.txt: no such file or directory/, - }); -} - -{ - tmpdir.refresh(); - copyFileSync(fixtures.path('sea', 'get-asset.js'), tmpdir.resolve('sea.js')); - copyFileSync(fixtures.utf8TestTextPath, tmpdir.resolve('utf8_test_text.txt')); - copyFileSync(fixtures.path('person.jpg'), tmpdir.resolve('person.jpg')); - writeFileSync(configFile, ` + }, { - "main": "sea.js", - "output": "sea-prep.blob", - "assets": { - "utf8_test_text.txt": "utf8_test_text.txt", - "person.jpg": "person.jpg" - } - } - `, 'utf8'); - - spawnSyncAndExitWithoutError( - process.execPath, - ['--experimental-sea-config', 'sea-config.json'], - { - env: { - NODE_DEBUG_NATIVE: 'SEA', - ...process.env, - }, - cwd: tmpdir.path, - }); - - assert(existsSync(seaPrepBlob)); - - generateSEA(outputFile, process.execPath, seaPrepBlob); - - spawnSyncAndAssert( - outputFile, - { - env: { - ...process.env, - NODE_DEBUG_NATIVE: 'SEA', - __TEST_PERSON_JPG: fixtures.path('person.jpg'), - __TEST_UTF8_TEXT_PATH: fixtures.path('utf8_test_text.txt'), - }, - }, - { - trim: true, - stdout: fixtures.utf8TestText, - }, - ); -} + trim: true, + stdout: fixtures.utf8TestText, + }, +); diff --git a/test/sea/test-single-executable-application-disable-experimental-sea-warning.js b/test/sea/test-single-executable-application-disable-experimental-sea-warning.js index b85a2f2e09f05e..efe1882bc46fdc 100644 --- a/test/sea/test-single-executable-application-disable-experimental-sea-warning.js +++ b/test/sea/test-single-executable-application-disable-experimental-sea-warning.js @@ -12,45 +12,17 @@ skipIfSingleExecutableIsNotSupported(); // This tests the creation of a single executable application which has the // experimental SEA warning disabled. -const fixtures = require('../common/fixtures'); const tmpdir = require('../common/tmpdir'); -const { copyFileSync, writeFileSync, existsSync } = require('fs'); -const { spawnSyncAndAssert, spawnSyncAndExitWithoutError } = require('../common/child_process'); +const { spawnSyncAndAssert } = require('../common/child_process'); const { join } = require('path'); -const assert = require('assert'); - -const inputFile = fixtures.path('sea.js'); -const requirableFile = tmpdir.resolve('requirable.js'); -const configFile = tmpdir.resolve('sea-config.json'); -const seaPrepBlob = tmpdir.resolve('sea-prep.blob'); -const outputFile = tmpdir.resolve(process.platform === 'win32' ? 'sea.exe' : 'sea'); +const fixtures = require('../common/fixtures'); tmpdir.refresh(); -writeFileSync(requirableFile, ` -module.exports = { - hello: 'world', -}; -`); - -writeFileSync(configFile, ` -{ - "main": "sea.js", - "output": "sea-prep.blob", - "disableExperimentalSEAWarning": true -} -`); - -// Copy input to working directory -copyFileSync(inputFile, tmpdir.resolve('sea.js')); -spawnSyncAndExitWithoutError( - process.execPath, - ['--experimental-sea-config', 'sea-config.json'], - { cwd: tmpdir.path }); - -assert(existsSync(seaPrepBlob)); - -generateSEA(outputFile, process.execPath, seaPrepBlob); +const outputFile = generateSEA( + fixtures.path('sea', 'disable-experimental-warning'), + tmpdir.path, +); spawnSyncAndAssert( outputFile, diff --git a/test/sea/test-single-executable-application-empty.js b/test/sea/test-single-executable-application-empty.js index 6bffc94dbefeb1..ae3d9a6caa2ffd 100644 --- a/test/sea/test-single-executable-application-empty.js +++ b/test/sea/test-single-executable-application-empty.js @@ -1,7 +1,6 @@ 'use strict'; -const common = require('../common'); - +require('../common'); const { generateSEA, skipIfSingleExecutableIsNotSupported, @@ -13,45 +12,17 @@ skipIfSingleExecutableIsNotSupported(); // script. const tmpdir = require('../common/tmpdir'); -const { writeFileSync, existsSync } = require('fs'); +const fixtures = require('../common/fixtures'); const { spawnSyncAndExitWithoutError } = require('../common/child_process'); -const assert = require('assert'); - -const configFile = tmpdir.resolve('sea-config.json'); -const seaPrepBlob = tmpdir.resolve('sea-prep.blob'); -const outputFile = tmpdir.resolve(process.platform === 'win32' ? 'sea.exe' : 'sea'); tmpdir.refresh(); -writeFileSync(tmpdir.resolve('empty.js'), '', 'utf-8'); -writeFileSync(configFile, ` -{ - "main": "empty.js", - "output": "sea-prep.blob" -} -`); - -spawnSyncAndExitWithoutError( - process.execPath, - ['--experimental-sea-config', 'sea-config.json'], - { cwd: tmpdir.path }); - -assert(existsSync(seaPrepBlob)); - -// Verify the workflow. -try { - generateSEA(outputFile, process.execPath, seaPrepBlob, true); -} catch (e) { - if (/Cannot copy/.test(e.message)) { - common.skip(e.message); - } else if (common.isWindows) { - if (/Cannot sign/.test(e.message) || /Cannot find signtool/.test(e.message)) { - common.skip(e.message); - } - } - - throw e; -} +const outputFile = generateSEA( + fixtures.path('sea', 'empty'), + tmpdir.path, + 'sea-config.json', + true, +); spawnSyncAndExitWithoutError( outputFile, diff --git a/test/sea/test-single-executable-application-exec-argv-empty.js b/test/sea/test-single-executable-application-exec-argv-empty.js index acae5e8eb50b37..a8c1feacfb16e2 100644 --- a/test/sea/test-single-executable-application-exec-argv-empty.js +++ b/test/sea/test-single-executable-application-exec-argv-empty.js @@ -11,39 +11,17 @@ skipIfSingleExecutableIsNotSupported(); // This tests the execArgv functionality with empty array in single executable applications. -const fixtures = require('../common/fixtures'); const tmpdir = require('../common/tmpdir'); -const { copyFileSync, writeFileSync, existsSync } = require('fs'); -const { spawnSyncAndAssert, spawnSyncAndExitWithoutError } = require('../common/child_process'); +const { spawnSyncAndAssert } = require('../common/child_process'); const { join } = require('path'); -const assert = require('assert'); - -const configFile = tmpdir.resolve('sea-config.json'); -const seaPrepBlob = tmpdir.resolve('sea-prep.blob'); -const outputFile = tmpdir.resolve(process.platform === 'win32' ? 'sea.exe' : 'sea'); +const fixtures = require('../common/fixtures'); tmpdir.refresh(); -// Copy test fixture to working directory -copyFileSync(fixtures.path('sea-exec-argv-empty.js'), tmpdir.resolve('sea.js')); - -writeFileSync(configFile, ` -{ - "main": "sea.js", - "output": "sea-prep.blob", - "disableExperimentalSEAWarning": true, - "execArgv": [] -} -`); - -spawnSyncAndExitWithoutError( - process.execPath, - ['--experimental-sea-config', 'sea-config.json'], - { cwd: tmpdir.path }); - -assert(existsSync(seaPrepBlob)); - -generateSEA(outputFile, process.execPath, seaPrepBlob); +const outputFile = generateSEA( + fixtures.path('sea', 'exec-argv-empty'), + tmpdir.path, +); // Test that empty execArgv work correctly spawnSyncAndAssert( diff --git a/test/sea/test-single-executable-application-exec-argv-extension-cli.js b/test/sea/test-single-executable-application-exec-argv-extension-cli.js index fcd8602fc763f4..7747fd3733e4e7 100644 --- a/test/sea/test-single-executable-application-exec-argv-extension-cli.js +++ b/test/sea/test-single-executable-application-exec-argv-extension-cli.js @@ -11,40 +11,17 @@ skipIfSingleExecutableIsNotSupported(); // This tests the execArgvExtension "cli" mode in single executable applications. -const fixtures = require('../common/fixtures'); const tmpdir = require('../common/tmpdir'); -const { copyFileSync, writeFileSync, existsSync } = require('fs'); -const { spawnSyncAndAssert, spawnSyncAndExitWithoutError } = require('../common/child_process'); +const { spawnSyncAndAssert } = require('../common/child_process'); const { join } = require('path'); -const assert = require('assert'); - -const configFile = tmpdir.resolve('sea-config.json'); -const seaPrepBlob = tmpdir.resolve('sea-prep.blob'); -const outputFile = tmpdir.resolve(process.platform === 'win32' ? 'sea.exe' : 'sea'); +const fixtures = require('../common/fixtures'); tmpdir.refresh(); -// Copy test fixture to working directory -copyFileSync(fixtures.path('sea-exec-argv-extension-cli.js'), tmpdir.resolve('sea.js')); - -writeFileSync(configFile, ` -{ - "main": "sea.js", - "output": "sea-prep.blob", - "disableExperimentalSEAWarning": true, - "execArgv": ["--no-warnings"], - "execArgvExtension": "cli" -} -`); - -spawnSyncAndExitWithoutError( - process.execPath, - ['--experimental-sea-config', 'sea-config.json'], - { cwd: tmpdir.path }); - -assert(existsSync(seaPrepBlob)); - -generateSEA(outputFile, process.execPath, seaPrepBlob); +const outputFile = generateSEA( + fixtures.path('sea', 'exec-argv-extension-cli'), + tmpdir.path, +); // Test that --node-options works with execArgvExtension: "cli" spawnSyncAndAssert( diff --git a/test/sea/test-single-executable-application-exec-argv-extension-env.js b/test/sea/test-single-executable-application-exec-argv-extension-env.js index 1bacba1fb0a34c..9604cb5d2882de 100644 --- a/test/sea/test-single-executable-application-exec-argv-extension-env.js +++ b/test/sea/test-single-executable-application-exec-argv-extension-env.js @@ -11,40 +11,18 @@ skipIfSingleExecutableIsNotSupported(); // This tests the execArgvExtension "env" mode (default) in single executable applications. -const fixtures = require('../common/fixtures'); const tmpdir = require('../common/tmpdir'); -const { copyFileSync, writeFileSync, existsSync } = require('fs'); -const { spawnSyncAndAssert, spawnSyncAndExitWithoutError } = require('../common/child_process'); +const { spawnSyncAndAssert } = require('../common/child_process'); const { join } = require('path'); const assert = require('assert'); - -const configFile = tmpdir.resolve('sea-config.json'); -const seaPrepBlob = tmpdir.resolve('sea-prep.blob'); -const outputFile = tmpdir.resolve(process.platform === 'win32' ? 'sea.exe' : 'sea'); +const fixtures = require('../common/fixtures'); tmpdir.refresh(); -// Copy test fixture to working directory -copyFileSync(fixtures.path('sea-exec-argv-extension-env.js'), tmpdir.resolve('sea.js')); - -writeFileSync(configFile, ` -{ - "main": "sea.js", - "output": "sea-prep.blob", - "disableExperimentalSEAWarning": true, - "execArgv": ["--no-warnings"], - "execArgvExtension": "env" -} -`); - -spawnSyncAndExitWithoutError( - process.execPath, - ['--experimental-sea-config', 'sea-config.json'], - { cwd: tmpdir.path }); - -assert(existsSync(seaPrepBlob)); - -generateSEA(outputFile, process.execPath, seaPrepBlob); +const outputFile = generateSEA( + fixtures.path('sea', 'exec-argv-extension-env'), + tmpdir.path, +); // Test that NODE_OPTIONS works with execArgvExtension: "env" (default behavior) spawnSyncAndAssert( diff --git a/test/sea/test-single-executable-application-exec-argv-extension-none.js b/test/sea/test-single-executable-application-exec-argv-extension-none.js index c4036bc503382c..5fe3369fe8f23e 100644 --- a/test/sea/test-single-executable-application-exec-argv-extension-none.js +++ b/test/sea/test-single-executable-application-exec-argv-extension-none.js @@ -11,40 +11,17 @@ skipIfSingleExecutableIsNotSupported(); // This tests the execArgvExtension "none" mode in single executable applications. -const fixtures = require('../common/fixtures'); const tmpdir = require('../common/tmpdir'); -const { copyFileSync, writeFileSync, existsSync } = require('fs'); -const { spawnSyncAndAssert, spawnSyncAndExitWithoutError } = require('../common/child_process'); +const { spawnSyncAndAssert } = require('../common/child_process'); const { join } = require('path'); -const assert = require('assert'); - -const configFile = tmpdir.resolve('sea-config.json'); -const seaPrepBlob = tmpdir.resolve('sea-prep.blob'); -const outputFile = tmpdir.resolve(process.platform === 'win32' ? 'sea.exe' : 'sea'); +const fixtures = require('../common/fixtures'); tmpdir.refresh(); -// Copy test fixture to working directory -copyFileSync(fixtures.path('sea-exec-argv-extension-none.js'), tmpdir.resolve('sea.js')); - -writeFileSync(configFile, ` -{ - "main": "sea.js", - "output": "sea-prep.blob", - "disableExperimentalSEAWarning": true, - "execArgv": ["--no-warnings"], - "execArgvExtension": "none" -} -`); - -spawnSyncAndExitWithoutError( - process.execPath, - ['--experimental-sea-config', 'sea-config.json'], - { cwd: tmpdir.path }); - -assert(existsSync(seaPrepBlob)); - -generateSEA(outputFile, process.execPath, seaPrepBlob); +const outputFile = generateSEA( + fixtures.path('sea', 'exec-argv-extension-none'), + tmpdir.path, +); // Test that NODE_OPTIONS is ignored with execArgvExtension: "none" spawnSyncAndAssert( diff --git a/test/sea/test-single-executable-application-exec-argv.js b/test/sea/test-single-executable-application-exec-argv.js index a60dbe1cab5eaf..6273c4cc605f88 100644 --- a/test/sea/test-single-executable-application-exec-argv.js +++ b/test/sea/test-single-executable-application-exec-argv.js @@ -11,39 +11,18 @@ skipIfSingleExecutableIsNotSupported(); // This tests the execArgv functionality with multiple arguments in single executable applications. -const fixtures = require('../common/fixtures'); const tmpdir = require('../common/tmpdir'); -const { copyFileSync, writeFileSync, existsSync } = require('fs'); -const { spawnSyncAndAssert, spawnSyncAndExitWithoutError } = require('../common/child_process'); +const { spawnSyncAndAssert } = require('../common/child_process'); const { join } = require('path'); +const fixtures = require('../common/fixtures'); const assert = require('assert'); -const configFile = tmpdir.resolve('sea-config.json'); -const seaPrepBlob = tmpdir.resolve('sea-prep.blob'); -const outputFile = tmpdir.resolve(process.platform === 'win32' ? 'sea.exe' : 'sea'); - tmpdir.refresh(); -// Copy test fixture to working directory -copyFileSync(fixtures.path('sea-exec-argv.js'), tmpdir.resolve('sea.js')); - -writeFileSync(configFile, ` -{ - "main": "sea.js", - "output": "sea-prep.blob", - "disableExperimentalSEAWarning": true, - "execArgv": ["--no-warnings", "--max-old-space-size=2048"] -} -`); - -spawnSyncAndExitWithoutError( - process.execPath, - ['--experimental-sea-config', 'sea-config.json'], - { cwd: tmpdir.path }); - -assert(existsSync(seaPrepBlob)); - -generateSEA(outputFile, process.execPath, seaPrepBlob); +const outputFile = generateSEA( + fixtures.path('sea', 'exec-argv'), + tmpdir.path, +); // Test that multiple execArgv are properly applied spawnSyncAndAssert( diff --git a/test/sea/test-single-executable-application-inspect-in-sea-flags.js b/test/sea/test-single-executable-application-inspect-in-sea-flags.js index 66faed4812dba2..cbba700b497fab 100644 --- a/test/sea/test-single-executable-application-inspect-in-sea-flags.js +++ b/test/sea/test-single-executable-application-inspect-in-sea-flags.js @@ -6,10 +6,9 @@ require('../common'); const assert = require('assert'); -const { writeFileSync, existsSync } = require('fs'); const { spawnSyncAndAssert } = require('../common/child_process'); const tmpdir = require('../common/tmpdir'); -const { spawnSyncAndExitWithoutError } = require('../common/child_process'); +const fixtures = require('../common/fixtures'); const { generateSEA, @@ -18,34 +17,13 @@ const { skipIfSingleExecutableIsNotSupported(); -const configFile = tmpdir.resolve('sea-config.json'); -const seaPrepBlob = tmpdir.resolve('sea-prep.blob'); -const outputFile = tmpdir.resolve(process.platform === 'win32' ? 'sea.exe' : 'sea'); - tmpdir.refresh(); -writeFileSync(tmpdir.resolve('sea.js'), `console.log(process.argv);`, 'utf-8'); - -// Create SEA configuration -writeFileSync(configFile, ` -{ - "main": "sea.js", - "output": "sea-prep.blob" -} -`); - -// Generate the SEA prep blob -spawnSyncAndExitWithoutError( - process.execPath, - ['--experimental-sea-config', 'sea-config.json'], - { cwd: tmpdir.path }, +const outputFile = generateSEA( + fixtures.path('sea', 'inspect-in-sea-flags'), + tmpdir.path, ); -assert(existsSync(seaPrepBlob)); - -// Generate the SEA executable -generateSEA(outputFile, process.execPath, seaPrepBlob); - // Spawn the SEA with inspect option spawnSyncAndAssert( outputFile, diff --git a/test/sea/test-single-executable-application-inspect.js b/test/sea/test-single-executable-application-inspect.js index 5422159fbf3a88..d1b5a55f5f0ff1 100644 --- a/test/sea/test-single-executable-application-inspect.js +++ b/test/sea/test-single-executable-application-inspect.js @@ -5,10 +5,9 @@ const common = require('../common'); const assert = require('assert'); -const { writeFileSync, existsSync } = require('fs'); const { spawn } = require('child_process'); const tmpdir = require('../common/tmpdir'); -const { spawnSyncAndExitWithoutError } = require('../common/child_process'); +const fixtures = require('../common/fixtures'); const { generateSEA, @@ -18,35 +17,13 @@ const { skipIfSingleExecutableIsNotSupported(); common.skipIfInspectorDisabled(); -const configFile = tmpdir.resolve('sea-config.json'); -const seaPrepBlob = tmpdir.resolve('sea-prep.blob'); -const outputFile = tmpdir.resolve(process.platform === 'win32' ? 'sea.exe' : 'sea'); - tmpdir.refresh(); -// Create a simple hello world script -writeFileSync(tmpdir.resolve('hello.js'), `console.log('Hello, world!');`, 'utf-8'); - -// Create SEA configuration -writeFileSync(configFile, ` -{ - "main": "hello.js", - "output": "sea-prep.blob" -} -`); - -// Generate the SEA prep blob -spawnSyncAndExitWithoutError( - process.execPath, - ['--experimental-sea-config', 'sea-config.json'], - { cwd: tmpdir.path }, +const outputFile = generateSEA( + fixtures.path('sea', 'inspect'), + tmpdir.path, ); -assert(existsSync(seaPrepBlob)); - -// Generate the SEA executable -generateSEA(outputFile, process.execPath, seaPrepBlob); - // Spawn the SEA with inspect option const seaProcess = spawn(outputFile, [], { env: { diff --git a/test/sea/test-single-executable-application-snapshot-and-code-cache.js b/test/sea/test-single-executable-application-snapshot-and-code-cache.js index 24e10a1c12d6be..cfd6ad8cc60a83 100644 --- a/test/sea/test-single-executable-application-snapshot-and-code-cache.js +++ b/test/sea/test-single-executable-application-snapshot-and-code-cache.js @@ -12,58 +12,19 @@ skipIfSingleExecutableIsNotSupported(); // This tests "useCodeCache" is ignored when "useSnapshot" is true. const tmpdir = require('../common/tmpdir'); -const { writeFileSync, existsSync } = require('fs'); const { spawnSyncAndAssert, } = require('../common/child_process'); -const { join } = require('path'); -const assert = require('assert'); - -const configFile = join(tmpdir.path, 'sea-config.json'); -const seaPrepBlob = join(tmpdir.path, 'sea-prep.blob'); -const outputFile = join(tmpdir.path, process.platform === 'win32' ? 'sea.exe' : 'sea'); +const fixtures = require('../common/fixtures'); { tmpdir.refresh(); - const code = ` - const { - setDeserializeMainFunction, - } = require('v8').startupSnapshot; - - setDeserializeMainFunction(() => { - console.log('Hello from snapshot'); - }); - `; - - writeFileSync(join(tmpdir.path, 'snapshot.js'), code, 'utf-8'); - writeFileSync(configFile, ` - { - "main": "snapshot.js", - "output": "sea-prep.blob", - "useSnapshot": true, - "useCodeCache": true - } - `); - spawnSyncAndAssert( - process.execPath, - ['--experimental-sea-config', 'sea-config.json'], - { - cwd: tmpdir.path, - env: { - NODE_DEBUG_NATIVE: 'SEA', - ...process.env, - }, - }, - { - stderr: /"useCodeCache" is redundant when "useSnapshot" is true/, - }, + const outputFile = generateSEA( + fixtures.path('sea', 'snapshot-and-code-cache'), + tmpdir.path, ); - assert(existsSync(seaPrepBlob)); - - generateSEA(outputFile, process.execPath, seaPrepBlob); - spawnSyncAndAssert( outputFile, { diff --git a/test/sea/test-single-executable-application-snapshot-worker.js b/test/sea/test-single-executable-application-snapshot-worker.js index 75ae6a27098798..81b48dd8beeda7 100644 --- a/test/sea/test-single-executable-application-snapshot-worker.js +++ b/test/sea/test-single-executable-application-snapshot-worker.js @@ -12,57 +12,18 @@ skipIfSingleExecutableIsNotSupported(); // This tests the snapshot support in single executable applications. const tmpdir = require('../common/tmpdir'); -const { writeFileSync, existsSync } = require('fs'); const { - spawnSyncAndAssert, spawnSyncAndExitWithoutError, + spawnSyncAndAssert, } = require('../common/child_process'); -const assert = require('assert'); - -const configFile = tmpdir.resolve('sea-config.json'); -const seaPrepBlob = tmpdir.resolve('sea-prep.blob'); -const outputFile = tmpdir.resolve(process.platform === 'win32' ? 'sea.exe' : 'sea'); +const fixtures = require('../common/fixtures'); { tmpdir.refresh(); - // FIXME(joyeecheung): currently `worker_threads` cannot be loaded during the - // snapshot building process because internal/worker.js is accessing isMainThread at - // the top level (and there are maybe more code that access these at the top-level), - // and have to be loaded in the deserialized snapshot main function. - // Change these states to be accessed on-demand. - const code = ` - const { - setDeserializeMainFunction, - } = require('v8').startupSnapshot; - setDeserializeMainFunction(() => { - const { Worker } = require('worker_threads'); - new Worker("console.log('Hello from Worker')", { eval: true }); - }); - `; - - writeFileSync(tmpdir.resolve('snapshot.js'), code, 'utf-8'); - writeFileSync(configFile, ` - { - "main": "snapshot.js", - "output": "sea-prep.blob", - "useSnapshot": true - } - `); - - spawnSyncAndExitWithoutError( - process.execPath, - ['--experimental-sea-config', 'sea-config.json'], - { - cwd: tmpdir.path, - env: { - NODE_DEBUG_NATIVE: 'SEA', - ...process.env, - }, - }); - - assert(existsSync(seaPrepBlob)); - - generateSEA(outputFile, process.execPath, seaPrepBlob); + const outputFile = generateSEA( + fixtures.path('sea', 'snapshot-worker'), + tmpdir.path, + ); spawnSyncAndAssert( outputFile, diff --git a/test/sea/test-single-executable-application-snapshot.js b/test/sea/test-single-executable-application-snapshot.js index 15adcdb9b814bf..284cf183fc4273 100644 --- a/test/sea/test-single-executable-application-snapshot.js +++ b/test/sea/test-single-executable-application-snapshot.js @@ -12,22 +12,19 @@ skipIfSingleExecutableIsNotSupported(); // This tests the snapshot support in single executable applications. const tmpdir = require('../common/tmpdir'); -const { writeFileSync, existsSync } = require('fs'); +const { writeFileSync } = require('fs'); const { spawnSyncAndAssert, spawnSyncAndExit, } = require('../common/child_process'); +const fixtures = require('../common/fixtures'); const assert = require('assert'); -const configFile = tmpdir.resolve('sea-config.json'); -const seaPrepBlob = tmpdir.resolve('sea-prep.blob'); -const outputFile = tmpdir.resolve(process.platform === 'win32' ? 'sea.exe' : 'sea'); - { tmpdir.refresh(); writeFileSync(tmpdir.resolve('snapshot.js'), '', 'utf-8'); - writeFileSync(configFile, ` + writeFileSync(tmpdir.resolve('sea-config.json'), ` { "main": "snapshot.js", "output": "sea-prep.blob", @@ -50,42 +47,11 @@ const outputFile = tmpdir.resolve(process.platform === 'win32' ? 'sea.exe' : 'se { tmpdir.refresh(); - const code = ` - const { - setDeserializeMainFunction, - } = require('v8').startupSnapshot; - - setDeserializeMainFunction(() => { - console.log('Hello from snapshot'); - }); - `; - - writeFileSync(tmpdir.resolve('snapshot.js'), code, 'utf-8'); - writeFileSync(configFile, ` - { - "main": "snapshot.js", - "output": "sea-prep.blob", - "useSnapshot": true - } - `); - - spawnSyncAndAssert( - process.execPath, - ['--experimental-sea-config', 'sea-config.json'], - { - cwd: tmpdir.path, - env: { - NODE_DEBUG_NATIVE: 'SEA', - ...process.env, - }, - }, - { - stderr: /Single executable application is an experimental feature/, - }); - assert(existsSync(seaPrepBlob)); - - generateSEA(outputFile, process.execPath, seaPrepBlob); + const outputFile = generateSEA( + fixtures.path('sea', 'snapshot'), + tmpdir.path, + ); spawnSyncAndAssert( outputFile, diff --git a/test/sea/test-single-executable-application-use-code-cache.js b/test/sea/test-single-executable-application-use-code-cache.js index a66930f610ea1f..a81dd960592564 100644 --- a/test/sea/test-single-executable-application-use-code-cache.js +++ b/test/sea/test-single-executable-application-use-code-cache.js @@ -12,51 +12,17 @@ skipIfSingleExecutableIsNotSupported(); // This tests the creation of a single executable application which uses the // V8 code cache. -const fixtures = require('../common/fixtures'); const tmpdir = require('../common/tmpdir'); -const { copyFileSync, writeFileSync, existsSync } = require('fs'); -const { spawnSyncAndAssert, spawnSyncAndExitWithoutError } = require('../common/child_process'); +const { spawnSyncAndAssert } = require('../common/child_process'); const { join } = require('path'); -const assert = require('assert'); - -const inputFile = fixtures.path('sea.js'); -const requirableFile = tmpdir.resolve('requirable.js'); -const configFile = tmpdir.resolve('sea-config.json'); -const seaPrepBlob = tmpdir.resolve('sea-prep.blob'); -const outputFile = tmpdir.resolve(process.platform === 'win32' ? 'sea.exe' : 'sea'); +const fixtures = require('../common/fixtures'); tmpdir.refresh(); -writeFileSync(requirableFile, ` -module.exports = { - hello: 'world', -}; -`); - -writeFileSync(configFile, ` -{ - "main": "sea.js", - "output": "sea-prep.blob", - "useCodeCache": true -} -`); - -// Copy input to working directory -copyFileSync(inputFile, tmpdir.resolve('sea.js')); -spawnSyncAndExitWithoutError( - process.execPath, - ['--experimental-sea-config', 'sea-config.json'], - { - cwd: tmpdir.path, - env: { - NODE_DEBUG_NATIVE: 'SEA', - ...process.env, - }, - }); - -assert(existsSync(seaPrepBlob)); - -generateSEA(outputFile, process.execPath, seaPrepBlob); +const outputFile = generateSEA( + fixtures.path('sea', 'use-code-cache'), + tmpdir.path, +); spawnSyncAndAssert( outputFile, diff --git a/test/sea/test-single-executable-application.js b/test/sea/test-single-executable-application.js index 036589c1cb269a..f3b2cbdf4b38ed 100644 --- a/test/sea/test-single-executable-application.js +++ b/test/sea/test-single-executable-application.js @@ -11,45 +11,17 @@ skipIfSingleExecutableIsNotSupported(); // This tests the creation of a single executable application. -const fixtures = require('../common/fixtures'); const tmpdir = require('../common/tmpdir'); -const { copyFileSync, writeFileSync, existsSync } = require('fs'); -const { spawnSyncAndAssert, spawnSyncAndExitWithoutError } = require('../common/child_process'); +const { spawnSyncAndAssert } = require('../common/child_process'); const { join } = require('path'); -const assert = require('assert'); - -const inputFile = fixtures.path('sea.js'); -const requirableFile = tmpdir.resolve('requirable.js'); -const configFile = tmpdir.resolve('sea-config.json'); -const seaPrepBlob = tmpdir.resolve('sea-prep.blob'); -const outputFile = tmpdir.resolve(process.platform === 'win32' ? 'sea.exe' : 'sea'); +const fixtures = require('../common/fixtures'); tmpdir.refresh(); -writeFileSync(requirableFile, ` -module.exports = { - hello: 'world', -}; -`); - -writeFileSync(configFile, ` -{ - "main": "sea.js", - "output": "sea-prep.blob", - "disableExperimentalSEAWarning": false -} -`); - -// Copy input to working directory -copyFileSync(inputFile, tmpdir.resolve('sea.js')); -spawnSyncAndExitWithoutError( - process.execPath, - ['--experimental-sea-config', 'sea-config.json'], - { cwd: tmpdir.path }); - -assert(existsSync(seaPrepBlob)); - -generateSEA(outputFile, process.execPath, seaPrepBlob); +const outputFile = generateSEA( + fixtures.path('sea', 'simple'), + tmpdir.path, +); spawnSyncAndAssert( outputFile, From 9a814147cfe138b71c4609fb31c6d233cc53bddd Mon Sep 17 00:00:00 2001 From: Joyee Cheung Date: Tue, 23 Dec 2025 00:59:47 +0100 Subject: [PATCH 2/6] deps: add tools and scripts to pull LIEF as a dependency --- .gitignore | 1 + LICENSE | 206 ++++++++++++++++++++ deps/LIEF/LICENSE | 202 +++++++++++++++++++ deps/LIEF/README.md | 237 +++++++++++++++++++++++ tools/dep_updaters/update-lief.sh | 68 +++++++ tools/prepare_lief.py | 310 ++++++++++++++++++++++++++++++ 6 files changed, 1024 insertions(+) create mode 100644 deps/LIEF/LICENSE create mode 100644 deps/LIEF/README.md create mode 100644 tools/dep_updaters/update-lief.sh create mode 100644 tools/prepare_lief.py diff --git a/.gitignore b/.gitignore index bf839aa91c86e1..221e4f4062486a 100644 --- a/.gitignore +++ b/.gitignore @@ -144,6 +144,7 @@ tools/*/*.i.tmp /deps/**/.github/ # Ignore dependencies fetched by tools/v8/fetch_deps.py /deps/.cipd +!deps/LIEF/** # === Rules for Windows vcbuild.bat === /temp-vcbuild diff --git a/LICENSE b/LICENSE index 8090eacac19436..4b94162d3f4e66 100644 --- a/LICENSE +++ b/LICENSE @@ -960,6 +960,212 @@ The externally maintained libraries used by Node.js are: license. """ +- LIEF, located at deps/LIEF, is licensed as follows: + """ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "{}" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright 2017 - 2025 R. Thomas + Copyright 2017 - 2025 Quarkslab + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + """ + - llhttp, located at deps/llhttp, is licensed as follows: """ This software is licensed under the MIT License. diff --git a/deps/LIEF/LICENSE b/deps/LIEF/LICENSE new file mode 100644 index 00000000000000..0c225d7eeb8036 --- /dev/null +++ b/deps/LIEF/LICENSE @@ -0,0 +1,202 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "{}" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright 2017 - 2025 R. Thomas + Copyright 2017 - 2025 Quarkslab + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/deps/LIEF/README.md b/deps/LIEF/README.md new file mode 100644 index 00000000000000..0276c436d973d3 --- /dev/null +++ b/deps/LIEF/README.md @@ -0,0 +1,237 @@ +

+
+

+
+ +

+ Blog • + Documentation • + About +

+
+ +# About + +The purpose of this project is to provide a cross-platform library to parse, +modify and abstract ELF, PE and MachO formats. + +**Main features**: + + * **Parsing**: LIEF can parse [ELF](https://lief.re/doc/latest/formats/elf/index.html), [PE](https://lief.re/doc/latest/formats/pe/index.html), [MachO](https://lief.re/doc/latest/formats/macho/index.html), [COFF](https://lief.re/doc/latest/formats/coff/index.html), OAT, DEX, VDEX, ART and provides an user-friendly API to access to internals. + * **Modify**: LIEF can use to modify some parts of these formats (adding a section, changing a symbol's name, ...) + * **Abstract**: Three formats have common features like sections, symbols, entry point... LIEF factors them. + * **API**: LIEF can be used in [C++](https://lief.re/doc/latest/doxygen/), Python, [Rust](https://lief-rs.s3.fr-par.scw.cloud/doc/latest/lief/index.html) and C + +**Extended features**: + + * [**DWARF/PDB** Support](https://lief.re/doc/latest/extended/debug_info/index.html) + * [**Objective-C** Metadata](https://lief.re/doc/latest/extended/objc/index.html) + * [**Dyld Shared Cache**](https://lief.re/doc/latest/extended/dsc/index.html) with support for extracting Dylib + * [**Disassembler**](https://lief.re/doc/latest/extended/disassembler/index.html): AArch64, x86/x86-64, ARM, RISC-V, Mips, PowerPC, eBPF + * [**Assembler**](https://lief.re/doc/latest/extended/assembler/index.html): AArch64, x86/x86-64 + +**Plugins**: + + * [**Ghidra**](https://lief.re/doc/latest/plugins/ghidra/index.html) + * [**BinaryNinja**](https://lief.re/doc/latest/plugins/binaryninja/index.html) + +# Content + +- [About](#about) +- [Download / Install](#downloads--install) +- [Getting started](#getting-started) +- [Blog](https://lief.re/blog/) +- [Documentation](#documentation) + - [Rust](https://lief.re/doc/stable/rust/lief/) + - [Sphinx](https://lief.re/doc/latest/index.html) + - [Doxygen](https://lief.re/doc/latest/doxygen/index.html) + - Tutorials: + - [Parse and manipulate formats](https://lief.re/doc/latest/tutorials/01_play_with_formats.html) + - [Play with ELF symbols](https://lief.re/doc/latest/tutorials/03_elf_change_symbols.html) + - [PE Resources](https://lief.re/doc/latest/tutorials/07_pe_resource.html) + - [Transforming an ELF executable into a library](https://lief.re/doc/latest/tutorials/08_elf_bin2lib.html) + - [How to use frida on a non-rooted device](https://lief.re/doc/latest/tutorials/09_frida_lief.html) + - [Android formats](https://lief.re/doc/latest/tutorials/10_android_formats.html) + - [Mach-O modification](https://lief.re/doc/latest/tutorials/11_macho_modification.html) + - [ELF Coredump](https://lief.re/doc/latest/tutorials/12_elf_coredump.html) + - [PE Authenticode](https://lief.re/doc/latest/tutorials/13_pe_authenticode.html) +- [Contact](#contact) +- [About](#about) + - [Authors](#authors) + - [License](#license) + - [Bibtex](#bibtex) + +## Downloads / Install + +## C++ + +```cmake +find_package(LIEF REQUIRED) +target_link_libraries(my-project LIEF::LIEF) +``` + +## Rust + +```toml +[package] +name = "my-awesome-project" +version = "0.0.1" +edition = "2021" + +[dependencies] +lief = "0.17.1" +``` + +## Python + +To install the latest **version** (release): + +```console +pip install lief +``` + +To install nightly build: + +```console +pip install [--user] --force-reinstall --index-url https://lief.s3-website.fr-par.scw.cloud/latest lief==1.0.0.dev0 +``` + +### Packages + +- LIEF Extended: https://extended.lief.re (GitHub OAuth) +- **Nightly**: + * SDK: https://lief.s3-website.fr-par.scw.cloud/latest/sdk + * Python Wheels: https://lief.s3-website.fr-par.scw.cloud/latest/lief +- **v0.17.1**: https://github.com/lief-project/LIEF/releases/tag/0.17.1 + +Here are guides to install or integrate LIEF: + + * [Python](https://lief.re/doc/latest/installation.html#python) + * [Visual Studio](https://lief.re/doc/latest/installation.html#visual-studio-integration) + * [XCode](https://lief.re/doc/latest/installation.html#xcode-integration) + * [CMake](https://lief.re/doc/latest/installation.html#cmake-integration) + +## Getting started + +### Python + +```python +import lief + +# ELF +binary = lief.parse("/usr/bin/ls") +for section in binary.sections: + print(section.name, section.virtual_address) + +# PE +binary = lief.parse("C:\\Windows\\explorer.exe") + +if rheader := pe.rich_header: + print(rheader.key) + +# Mach-O +binary = lief.parse("/usr/bin/ls") +for fixup in binary.dyld_chained_fixups: + print(fixup) +``` + +### Rust + +```rust +use lief::Binary; +use lief::pe::debug::Entries::CodeViewPDB; + +if let Some(Binary::PE(pe)) = Binary::parse(path.as_str()) { + for entry in pe.debug() { + if let CodeViewPDB(pdb_view) = entry { + println!("{}", pdb_view.filename()); + } + } +} +``` + +### C++ + +```cpp +#include + +int main(int argc, char** argv) { + // ELF + if (std::unique_ptr elf = LIEF::ELF::Parser::parse("/bin/ls")) { + for (const LIEF::ELF::Section& section : elf->sections()) { + std::cout << section->name() << ' ' << section->virtual_address() << '\n'; + } + } + + // PE + if (std::unique_ptr pe = LIEF::PE::Parser::parse("C:\\Windows\\explorer.exe")) { + if (const LIEF::PE::RichHeader* rheader : pe->rich_header()) { + std::cout << rheader->key() << '\n'; + } + } + + // Mach-O + if (std::unique_ptr macho = LIEF::MachO::Parser::parse("/bin/ls")) { + for (const LIEF::MachO::DyldChainedFixups& fixup : macho->dyld_chained_fixups()) { + std::cout << fixup << '\n'; + } + } + + return 0; +} + +``` + +### C (Limited API) + +```cpp +#include + +int main(int argc, char** argv) { + Elf_Binary_t* elf = elf_parse("/usr/bin/ls"); + + Elf_Section_t** sections = elf->sections; + + for (size_t i = 0; sections[i] != NULL; ++i) { + printf("%s\n", sections[i]->name); + } + + elf_binary_destroy(elf); + return 0; +} +``` + +## Documentation + +* [Main documentation](https://lief.re/doc/latest/index.html) +* [Doxygen](https://lief.re/doc/latest/doxygen/index.html) +* [Rust](https://lief.re/doc/stable/rust/lief/) + +## Contact + +* **Mail**: contact at lief re +* **Discord**: [LIEF](https://discord.gg/7hRFGWYedu) + +## About + +### Authors + +Romain Thomas ([@rh0main](https://www.romainthomas.fr/)) - Formerly at [Quarkslab](https://www.quarkslab.com) + +### License + +LIEF is provided under the [Apache 2.0 license](https://github.com/lief-project/LIEF/blob/0.17.1/LICENSE). + +### Bibtex + +```bibtex +@MISC {LIEF, + author = "Romain Thomas", + title = "LIEF - Library to Instrument Executable Formats", + howpublished = "https://lief.quarkslab.com/", + month = "apr", + year = "2017" +} +``` + + diff --git a/tools/dep_updaters/update-lief.sh b/tools/dep_updaters/update-lief.sh new file mode 100644 index 00000000000000..39d16caf9eae7e --- /dev/null +++ b/tools/dep_updaters/update-lief.sh @@ -0,0 +1,68 @@ +#!/bin/sh +set -e +# Shell script to update lief in the source tree to a specific version + +BASE_DIR=$(cd "$(dirname "$0")/../.." && pwd) +DEPS_DIR="$BASE_DIR/deps" +[ -z "$NODE" ] && NODE="$BASE_DIR/out/Release/node" +[ -x "$NODE" ] || NODE=$(command -v node) + +# shellcheck disable=SC1091 +. "$BASE_DIR/tools/dep_updaters/utils.sh" + +NEW_VERSION="$("$NODE" --input-type=module <<'EOF' +const res = await fetch('https://api.github.com/repos/lief-project/LIEF/releases/latest', + process.env.GITHUB_TOKEN && { + headers: { + "Authorization": `Bearer ${process.env.GITHUB_TOKEN}` + }, + }); +if (!res.ok) throw new Error(`FetchError: ${res.status} ${res.statusText}`, { cause: res }); +const { tag_name } = await res.json(); +console.log(tag_name.replace('v', '')); +EOF +)" + +CURRENT_VERSION=$(grep "#define LIEF_VERSION" "$DEPS_DIR/LIEF/include/LIEF/version.h" | sed -n "s/^.*VERSION \"\(.*\)-\"/\1/p") + +# This function exit with 0 if new version and current version are the same +compare_dependency_version "lief" "$NEW_VERSION" "$CURRENT_VERSION" + +echo "Making temporary workspace..." + +WORKSPACE=$(mktemp -d 2> /dev/null || mktemp -d -t 'tmp') + +cleanup () { + EXIT_CODE=$? + [ -d "$WORKSPACE" ] && rm -rf "$WORKSPACE" + exit $EXIT_CODE +} + +trap cleanup INT TERM EXIT + +LIEF_ZIP="lief-$NEW_VERSION.zip" + +cd "$WORKSPACE" + +echo "Fetching lief source archive..." +curl -sL -o "$LIEF_ZIP" "https://github.com/lief-project/LIEF/archive/refs/tags/$NEW_VERSION.zip" +# log_and_verify_sha256sum "lief" "$LIEF_ZIP" +unzip "$LIEF_ZIP" +rm "$LIEF_ZIP" + +# Prepare third-party and configured headers in-place so build files don't need generation steps +python3 "$BASE_DIR/tools/prepare_lief.py" --source-dir "$WORKSPACE/LIEF-$NEW_VERSION" --lief-dir "$WORKSPACE/LIEF" --version "$NEW_VERSION" || { + echo "Failed to prepare LIEF third-party and headers" >&2 + exit 1 +} + +echo "Replacing existing LIEF (except GYP and GN build files)" +cp "$DEPS_DIR/LIEF/"*.gyp "$DEPS_DIR/LIEF/"*.gypi "$DEPS_DIR/LIEF/"*.gn "$DEPS_DIR/LIEF/"*.gni "$DEPS_DIR/LIEF/README.md" "$WORKSPACE/LIEF/" >> /dev/null 2>&1 + +rm -rf "$DEPS_DIR/LIEF" +mv "$WORKSPACE/LIEF" "$DEPS_DIR/LIEF" + +# Update the version number on maintaining-dependencies.md +# and print the new version as the last line of the script as we need +# to add it to $GITHUB_ENV variable +finalize_version_update "lief" "$NEW_VERSION" diff --git a/tools/prepare_lief.py b/tools/prepare_lief.py new file mode 100644 index 00000000000000..3da0d8f3df46ae --- /dev/null +++ b/tools/prepare_lief.py @@ -0,0 +1,310 @@ +#!/usr/bin/env python3 +import argparse +import re +import shutil +import sys +import tempfile +import zipfile +from pathlib import Path + +def ensure_dir(p: Path): + p.mkdir(parents=True, exist_ok=True) + + +def extract_zip(prefix: str, zip_path: Path, dst_third_party: Path): + """Extract a third-party archive into dst_third_party/prefix. + + Typical structure inside the archive is a single top-level directory like + "mbedtls-/". We extract under dst_third_party, then rename that + directory to a stable name dst_third_party/prefix. + """ + ensure_dir(dst_third_party) + with zipfile.ZipFile(zip_path, 'r') as zf: + # Determine the top-level directory inside the archive + names = zf.namelist() + top_candidates = {n.split('/', 1)[0] for n in names if '/' in n} + top_dir = next((n for n in sorted(top_candidates) if n.startswith(f"{prefix}-")), None) + if top_dir is None: # There is no versioned top-level dir, create one + top_dir = prefix + extract_parent_dir = dst_third_party / prefix + if not extract_parent_dir.exists(): + extract_parent_dir.mkdir() + else: + extract_parent_dir = dst_third_party + print(f"Extracting {zip_path} -> {extract_parent_dir} (top_dir: {top_dir})") + zf.extractall(extract_parent_dir) + + extracted_dir = dst_third_party / top_dir + target_dir = dst_third_party / prefix + if extracted_dir.exists() and extracted_dir != target_dir: + if target_dir.exists(): + shutil.rmtree(target_dir) + extracted_dir.rename(target_dir) + +def find_single_subdir(root: Path) -> Path: + entries = [p for p in root.iterdir() if p.is_dir()] + if len(entries) == 1: + return entries[0] + # Try to pick the most likely one by name length (zip usually extracts into a single dir) + if entries: + return sorted(entries, key=lambda p: len(p.name))[0] + return root + + +def cmake_configure_in(template: str, values: dict) -> str: + # Handle @VAR@ replacement and #cmakedefine VAR @VAR@ + def repl_at(m): + var = m.group(1) + return str(values.get(var, "")) + + # Replace @VAR@ + s = re.sub(r"@([A-Za-z0-9_]+)@", repl_at, template) + + # Process #cmakedefine lines + out_lines = [] + for line in s.splitlines(): + m = re.match(r"\s*#cmakedefine\s+([A-Za-z0-9_]+)\s+(\S+)", line) + if m: + name = m.group(1) + var_token = m.group(2) + # var_token was already replaced above (may still be a token if not found) + # try to look it up from values if it's still in @VAR@ format + val = 0 + if var_token.startswith("@") and var_token.endswith("@"): + key = var_token.strip("@") + val = int(values.get(key, 0) or 0) + else: + try: + val = int(var_token) + except Exception: + val = 0 + if val: + out_lines.append(f"#define {name} {val}") + else: + out_lines.append(f"/* #undef {name} */") + else: + out_lines.append(line) + return "\n".join(out_lines) + "\n" + + +def write_file(path: Path, content: str): + ensure_dir(path.parent) + with open(path, 'w', encoding='utf-8') as f: + f.write(content) + + +def parse_version_tuple(version: str): + m = re.match(r"^(\d+)\.(\d+)\.(\d+)$", version) + if not m: + return (0, 0, 0) + return tuple(int(x) for x in m.groups()) + + +def main(): + ap = argparse.ArgumentParser(description='Prepare LIEF third-party and configured headers for checked-in sources') + ap.add_argument('--source-dir', required=True, help='Path to the unzipped LIEF source directory (e.g. /tmp/LIEF-/)') + ap.add_argument('--lief-dir', required=True, help='Target path to deps/LIEF (the vendored destination in this repo)') + ap.add_argument('--version', help='LIEF version (X.Y.Z). If omitted, try to infer a fallback (0.17.0).') + ap.add_argument('--commit', default='', help='Commit hash to embed into version.h (optional)') + ap.add_argument('--tag', default='', help='Git tag to embed into version.h (optional)') + args = ap.parse_args() + + source_dir = Path(args.source_dir).resolve() + lief_dir = Path(args.lief_dir).resolve() + if not source_dir.exists(): + print(f"source-dir does not exist: {source_dir}", file=sys.stderr) + return 1 + if not lief_dir.exists(): + ensure_dir(lief_dir) + + # 1) Copy only the relevant files from source_dir to lief_dir + included_dirs = ['src', 'include', 'config', 'README.md', 'LICENSE'] + for item in included_dirs: + src = source_dir / item + dst = lief_dir / item + if not src.exists(): + print(f"Warning: expected item missing: {src}", file=sys.stderr) + continue + print(f"Copying {src} -> {dst}") + if src.is_dir(): + if dst.exists(): + shutil.rmtree(dst) + shutil.copytree(src, dst) + else: + shutil.copy2(src, dst) + + # 2) Extract selected third-party zips into third-party/ + # Keep this generic via a small allowlist so we can extend later if needed. + # For now, we only extract 'mbedtls'. + src_third_party = source_dir / 'third-party' + dst_third_party = lief_dir / 'third-party' + ensure_dir(dst_third_party) + + # Use a temporary third party directory, then move needed files to lief_dir + tmp_third_party = Path(tempfile.mkdtemp()) + # For example, src_third_party/mbedtls-.zip contains mbedtls-/, + # we extract that to tmp_third_party/mbedtls, and in the extracted directory, we + # only want to copy the 'library' folder, so tmp_third_party/mbedtls/library -> + # dst_third_party/mbedtls/library. Any other files under the extracted mbedtls + # directory will be ignored. + libs_to_extract = { + 'mbedtls': ['library', 'include', 'README.md', 'LICENSE'], # #include "mbedtls/private_access.h" + 'spdlog': ['include', 'src', 'LICENSE', 'README.md'], # #include "spdlog/fmt/..." + 'frozen': ['include', 'LICENSE', 'README.rst'], # #include + 'expected': ['include', 'README.md', 'COPYING'], # #include + 'utfcpp': ['source', 'README.md', 'LICENSE'], # #include | #include "utf8/unchecked.h" + 'tcb-span': ['span.hpp'], # #include + } + extracted_libs = [] + with tempfile.TemporaryDirectory() as _tmp_dir: + tmp_third_party = Path(_tmp_dir) + zip_files = sorted(src_third_party.glob('*.zip')) + for lib, included in libs_to_extract.items(): + # Find the matching zip file that starts with lib name + zip_path = next((z for z in zip_files if z.name.startswith(f"{lib}-")), None) + if zip_path is None: + print(f"Warning: No archive found for '{lib}' in {src_third_party}", file=sys.stderr) + continue + + # Extract archive into a tmp location under tmp_third_party/{lib} + extract_zip(lib, zip_path, tmp_third_party) + extracted_libs.append(lib) + + # Move the allow-listed directories from each lib in tmp_third_party to dst_third_party + src = tmp_third_party / lib + dst = dst_third_party / lib + for subpath in included: + src_item = src / subpath + dst_item = dst / subpath + if not src_item.exists(): + print(f"Warning: expected item missing: {src_item}", file=sys.stderr) + continue + ensure_dir(dst_item.parent) + if dst_item.exists(): + if dst_item.is_dir(): + shutil.rmtree(dst_item) + else: + dst_item.unlink() + print(f"Moving {src_item} -> {dst_item}") + shutil.move(str(src_item), str(dst_item)) + + # 2) Place internal headers expected by the project layout under src/ + # - third-party/expected/include/tl/expected.hpp + # -> include/LIEF/third-party/internal/expected.hpp + # - third-party/tcb-span/span.hpp + # -> include/LIEF/third-party/internal/span.hpp + # - third-party/utfcpp/source/utf8 + # -> include/LIEF/third-party/internal/utfcpp/utf8 + internal_mappings = [ + ['third-party/expected/include/tl/expected.hpp', 'include/LIEF/third-party/internal/expected.hpp'], + ['third-party/tcb-span/span.hpp', 'include/LIEF/third-party/internal/span.hpp'], + ['third-party/utfcpp/source/utf8', 'include/LIEF/third-party/internal/utfcpp/utf8'], + ] + for src_rel, dst_rel in internal_mappings: + src_path = lief_dir / src_rel + dst_path = lief_dir / dst_rel + if not src_path.exists(): + print(f"Warning: expected internal header missing: {src_path}", file=sys.stderr) + continue + print(f"Copying internal header {src_path} -> {dst_path}") + ensure_dir(dst_path.parent) + if dst_path.exists(): + if dst_path.is_dir(): + shutil.rmtree(dst_path) + else: + dst_path.unlink() + if src_path.is_dir(): + shutil.copytree(src_path, dst_path) + else: + shutil.copy2(src_path, dst_path) + + # 3) Generate configured headers into src/LIEF/ + # Prefer templates from target include/, fall back to source include/ if missing. + configs = [ + ['include/LIEF/config.h.in', 'include/LIEF/config.h'], + ['include/LIEF/version.h.in', 'include/LIEF/version.h'], + ['src/compiler_support.h.in', 'src/compiler_support.h'], + ] + + # The CMakeLists.txt usually contains the default version values like this. Parse them. + # set(LIEF_VERSION_MAJOR 0) + # set(LIEF_VERSION_MINOR 17) + # set(LIEF_VERSION_PATCH 0) + cmakelists_path = source_dir / 'CMakeLists.txt' + major_ver = minor_ver = patch_ver = 0 + if cmakelists_path.exists(): + with open(cmakelists_path, 'r', encoding='utf-8') as f: + cmake_contents = f.read() + m_major = re.search(r'set\s*\(\s*LIEF_VERSION_MAJOR\s+(\d+)\s*\)', cmake_contents) + m_minor = re.search(r'set\s*\(\s*LIEF_VERSION_MINOR\s+(\d+)\s*\)', cmake_contents) + m_patch = re.search(r'set\s*\(\s*LIEF_VERSION_PATCH\s+(\d+)\s*\)', cmake_contents) + if m_major: + major_ver = int(m_major.group(1)) + if m_minor: + minor_ver = int(m_minor.group(1)) + if m_patch: + patch_ver = int(m_patch.group(1)) + + vals = { + 'PROJECT_NAME': 'LIEF', + 'LIEF_VERSION_MAJOR': major_ver, + 'LIEF_VERSION_MINOR': minor_ver, + 'LIEF_VERSION_PATCH': patch_ver, + 'LIEF_COMMIT_HASH': args.commit, + 'LIEF_IS_TAGGED': 0 if not args.tag else 1, + 'LIEF_GIT_TAG': args.tag or '', + + 'LIEF_PE_SUPPORT': 1, + 'LIEF_ELF_SUPPORT': 1, + 'LIEF_MACHO_SUPPORT': 1, + 'LIEF_COFF_SUPPORT': 1, + + 'LIEF_OAT_SUPPORT': 0, + 'LIEF_DEX_SUPPORT': 0, + 'LIEF_VDEX_SUPPORT': 0, + 'LIEF_ART_SUPPORT': 0, + + 'LIEF_DEBUG_INFO_SUPPORT': 0, + 'LIEF_OBJC_SUPPORT': 0, + 'LIEF_DYLD_SHARED_CACHE_SUPPORT': 0, + 'LIEF_ASM_SUPPORT': 0, + 'LIEF_EXTENDED': 0, + + 'ENABLE_JSON_SUPPORT': 0, + 'LIEF_JSON_SUPPORT': 0, + 'LIEF_LOGGING_SUPPORT': 0, + 'LIEF_LOGGING_DEBUG_SUPPORT': 0, + 'LIEF_FROZEN_ENABLED': 1, + + 'LIEF_EXTERNAL_EXPECTED': 0, + 'LIEF_EXTERNAL_UTF8CPP': 0, + 'LIEF_EXTERNAL_MBEDTLS': 0, + 'LIEF_EXTERNAL_FROZEN': 0, + 'LIEF_EXTERNAL_SPAN': 0, + + 'LIEF_NLOHMANN_JSON_EXTERNAL': 0, + + 'LIEF_SUPPORT_CXX11': 1, + 'LIEF_SUPPORT_CXX14': 1, + 'LIEF_SUPPORT_CXX17': 1, + } + + for cfg_in_rel, cfg_out_rel in configs: + cfg_in_path = lief_dir / cfg_in_rel + cfg_out_path = lief_dir / cfg_out_rel + if not cfg_in_path.exists(): + print(f"Warning: config template missing: {cfg_in_path}", file=sys.stderr) + continue + with open(cfg_in_path, 'r', encoding='utf-8') as f: + template = f.read() + configured = cmake_configure_in(template, vals) + ensure_dir(cfg_out_path.parent) + write_file(cfg_out_path, configured) + + extracted_summary = ', '.join(sorted(set(extracted_libs))) if extracted_libs else 'none' + print(f'LIEF preparation complete: third-party extracted from {source_dir} into {lief_dir} [{extracted_summary}] and headers configured into src/') + return 0 + + +if __name__ == '__main__': + sys.exit(main()) From 7f943bbae60b21ad0e58dc6b73d614f5f1b8c128 Mon Sep 17 00:00:00 2001 From: Joyee Cheung Date: Tue, 23 Dec 2025 00:59:48 +0100 Subject: [PATCH 3/6] deps: add LIEF as a dependency --- deps/LIEF/config/mbedtls/config.h | 5 + deps/LIEF/include/LIEF/ART.hpp | 28 + deps/LIEF/include/LIEF/ART/EnumToString.hpp | 40 + deps/LIEF/include/LIEF/ART/File.hpp | 55 + deps/LIEF/include/LIEF/ART/Header.hpp | 130 + deps/LIEF/include/LIEF/ART/Parser.hpp | 107 + deps/LIEF/include/LIEF/ART/enums.hpp | 133 + deps/LIEF/include/LIEF/ART/hash.hpp | 47 + .../LIEF/include/LIEF/ART/java_structures.hpp | 397 + deps/LIEF/include/LIEF/ART/json.hpp | 31 + deps/LIEF/include/LIEF/ART/types.hpp | 31 + deps/LIEF/include/LIEF/ART/utils.hpp | 51 + deps/LIEF/include/LIEF/ASM.hpp | 28 + deps/LIEF/include/LIEF/Abstract.hpp | 26 + deps/LIEF/include/LIEF/Abstract/Binary.hpp | 441 + deps/LIEF/include/LIEF/Abstract/DebugInfo.hpp | 79 + deps/LIEF/include/LIEF/Abstract/Function.hpp | 121 + deps/LIEF/include/LIEF/Abstract/Header.hpp | 147 + deps/LIEF/include/LIEF/Abstract/Parser.hpp | 60 + .../LIEF/include/LIEF/Abstract/Relocation.hpp | 98 + deps/LIEF/include/LIEF/Abstract/Section.hpp | 131 + deps/LIEF/include/LIEF/Abstract/Symbol.hpp | 97 + deps/LIEF/include/LIEF/Abstract/hash.hpp | 49 + deps/LIEF/include/LIEF/Abstract/json.hpp | 30 + .../include/LIEF/BinaryStream/ASN1Reader.hpp | 72 + .../LIEF/BinaryStream/BinaryStream.hpp | 476 + .../include/LIEF/BinaryStream/FileStream.hpp | 80 + .../LIEF/BinaryStream/MemoryStream.hpp | 89 + .../include/LIEF/BinaryStream/SpanStream.hpp | 129 + .../LIEF/BinaryStream/VectorStream.hpp | 97 + deps/LIEF/include/LIEF/COFF.hpp | 42 + .../include/LIEF/COFF/AuxiliarySymbol.hpp | 125 + .../AuxiliarySymbols/AuxiliaryCLRToken.hpp | 106 + .../COFF/AuxiliarySymbols/AuxiliaryFile.hpp | 85 + .../AuxiliaryFunctionDefinition.hpp | 110 + .../AuxiliarySectionDefinition.hpp | 166 + .../AuxiliaryWeakExternal.hpp | 113 + .../AuxiliarybfAndefSymbol.hpp | 60 + deps/LIEF/include/LIEF/COFF/BigObjHeader.hpp | 123 + deps/LIEF/include/LIEF/COFF/Binary.hpp | 252 + deps/LIEF/include/LIEF/COFF/Header.hpp | 155 + deps/LIEF/include/LIEF/COFF/Parser.hpp | 109 + deps/LIEF/include/LIEF/COFF/ParserConfig.hpp | 38 + deps/LIEF/include/LIEF/COFF/RegularHeader.hpp | 78 + deps/LIEF/include/LIEF/COFF/Relocation.hpp | 218 + deps/LIEF/include/LIEF/COFF/Section.hpp | 250 + deps/LIEF/include/LIEF/COFF/String.hpp | 83 + deps/LIEF/include/LIEF/COFF/Symbol.hpp | 286 + deps/LIEF/include/LIEF/COFF/utils.hpp | 63 + deps/LIEF/include/LIEF/DEX.hpp | 32 + deps/LIEF/include/LIEF/DEX/Class.hpp | 138 + deps/LIEF/include/LIEF/DEX/CodeInfo.hpp | 60 + deps/LIEF/include/LIEF/DEX/EnumToString.hpp | 35 + deps/LIEF/include/LIEF/DEX/Field.hpp | 94 + deps/LIEF/include/LIEF/DEX/File.hpp | 176 + deps/LIEF/include/LIEF/DEX/Header.hpp | 136 + deps/LIEF/include/LIEF/DEX/MapItem.hpp | 96 + deps/LIEF/include/LIEF/DEX/MapList.hpp | 84 + deps/LIEF/include/LIEF/DEX/Method.hpp | 118 + deps/LIEF/include/LIEF/DEX/Parser.hpp | 124 + deps/LIEF/include/LIEF/DEX/Prototype.hpp | 64 + deps/LIEF/include/LIEF/DEX/Type.hpp | 113 + deps/LIEF/include/LIEF/DEX/deopt.hpp | 34 + deps/LIEF/include/LIEF/DEX/enums.hpp | 82 + deps/LIEF/include/LIEF/DEX/hash.hpp | 66 + deps/LIEF/include/LIEF/DEX/instructions.hpp | 356 + deps/LIEF/include/LIEF/DEX/json.hpp | 33 + deps/LIEF/include/LIEF/DEX/types.hpp | 28 + deps/LIEF/include/LIEF/DEX/utils.hpp | 49 + deps/LIEF/include/LIEF/DWARF.hpp | 42 + .../include/LIEF/DWARF/CompilationUnit.hpp | 282 + deps/LIEF/include/LIEF/DWARF/DebugInfo.hpp | 96 + deps/LIEF/include/LIEF/DWARF/Editor.hpp | 58 + deps/LIEF/include/LIEF/DWARF/Function.hpp | 180 + deps/LIEF/include/LIEF/DWARF/Parameter.hpp | 146 + deps/LIEF/include/LIEF/DWARF/Scope.hpp | 66 + deps/LIEF/include/LIEF/DWARF/Type.hpp | 198 + deps/LIEF/include/LIEF/DWARF/Variable.hpp | 141 + .../include/LIEF/DWARF/editor/ArrayType.hpp | 38 + .../include/LIEF/DWARF/editor/BaseType.hpp | 50 + .../LIEF/DWARF/editor/CompilationUnit.hpp | 100 + .../include/LIEF/DWARF/editor/EnumType.hpp | 62 + .../include/LIEF/DWARF/editor/Function.hpp | 129 + .../LIEF/DWARF/editor/FunctionType.hpp | 58 + .../include/LIEF/DWARF/editor/PointerType.hpp | 38 + .../include/LIEF/DWARF/editor/StructType.hpp | 76 + deps/LIEF/include/LIEF/DWARF/editor/Type.hpp | 67 + .../include/LIEF/DWARF/editor/TypeDef.hpp | 38 + .../include/LIEF/DWARF/editor/Variable.hpp | 65 + deps/LIEF/include/LIEF/DWARF/enums.hpp | 46 + deps/LIEF/include/LIEF/DWARF/types.hpp | 42 + deps/LIEF/include/LIEF/DWARF/types/Array.hpp | 78 + deps/LIEF/include/LIEF/DWARF/types/Atomic.hpp | 54 + deps/LIEF/include/LIEF/DWARF/types/Base.hpp | 71 + .../include/LIEF/DWARF/types/ClassLike.hpp | 154 + .../LIEF/include/LIEF/DWARF/types/Coarray.hpp | 40 + deps/LIEF/include/LIEF/DWARF/types/Const.hpp | 56 + .../LIEF/include/LIEF/DWARF/types/Dynamic.hpp | 40 + deps/LIEF/include/LIEF/DWARF/types/Enum.hpp | 40 + deps/LIEF/include/LIEF/DWARF/types/File.hpp | 40 + .../include/LIEF/DWARF/types/Immutable.hpp | 54 + .../include/LIEF/DWARF/types/Interface.hpp | 40 + .../LIEF/include/LIEF/DWARF/types/Pointer.hpp | 56 + .../LIEF/DWARF/types/PointerToMember.hpp | 57 + .../include/LIEF/DWARF/types/RValueRef.hpp | 54 + .../include/LIEF/DWARF/types/Reference.hpp | 54 + .../include/LIEF/DWARF/types/Restrict.hpp | 54 + deps/LIEF/include/LIEF/DWARF/types/SetTy.hpp | 54 + deps/LIEF/include/LIEF/DWARF/types/Shared.hpp | 54 + .../include/LIEF/DWARF/types/StringTy.hpp | 40 + .../include/LIEF/DWARF/types/Subroutine.hpp | 47 + .../LIEF/DWARF/types/TemplateAlias.hpp | 60 + deps/LIEF/include/LIEF/DWARF/types/Thrown.hpp | 56 + .../LIEF/include/LIEF/DWARF/types/Typedef.hpp | 57 + .../include/LIEF/DWARF/types/Volatile.hpp | 56 + deps/LIEF/include/LIEF/DyldSharedCache.hpp | 24 + .../LIEF/DyldSharedCache/DyldSharedCache.hpp | 307 + .../include/LIEF/DyldSharedCache/Dylib.hpp | 158 + .../LIEF/DyldSharedCache/MappingInfo.hpp | 103 + .../include/LIEF/DyldSharedCache/SubCache.hpp | 103 + .../include/LIEF/DyldSharedCache/caching.hpp | 55 + .../include/LIEF/DyldSharedCache/utils.hpp | 54 + .../include/LIEF/DyldSharedCache/uuid.hpp | 29 + deps/LIEF/include/LIEF/ELF.hpp | 53 + deps/LIEF/include/LIEF/ELF/Binary.hpp | 1183 + deps/LIEF/include/LIEF/ELF/Builder.hpp | 205 + deps/LIEF/include/LIEF/ELF/DynamicEntry.hpp | 299 + .../include/LIEF/ELF/DynamicEntryArray.hpp | 112 + .../include/LIEF/ELF/DynamicEntryFlags.hpp | 145 + .../include/LIEF/ELF/DynamicEntryLibrary.hpp | 73 + .../include/LIEF/ELF/DynamicEntryRpath.hpp | 103 + .../include/LIEF/ELF/DynamicEntryRunPath.hpp | 105 + .../include/LIEF/ELF/DynamicSharedObject.hpp | 75 + deps/LIEF/include/LIEF/ELF/EnumToString.hpp | 28 + deps/LIEF/include/LIEF/ELF/GnuHash.hpp | 155 + deps/LIEF/include/LIEF/ELF/Header.hpp | 334 + deps/LIEF/include/LIEF/ELF/Note.hpp | 285 + deps/LIEF/include/LIEF/ELF/NoteDetails.hpp | 25 + .../LIEF/ELF/NoteDetails/AndroidIdent.hpp | 82 + .../include/LIEF/ELF/NoteDetails/Core.hpp | 25 + .../include/LIEF/ELF/NoteDetails/NoteAbi.hpp | 94 + .../LIEF/ELF/NoteDetails/NoteGnuProperty.hpp | 119 + .../LIEF/ELF/NoteDetails/Properties.hpp | 28 + .../include/LIEF/ELF/NoteDetails/QNXStack.hpp | 71 + .../LIEF/ELF/NoteDetails/core/CoreAuxv.hpp | 120 + .../LIEF/ELF/NoteDetails/core/CoreFile.hpp | 115 + .../ELF/NoteDetails/core/CorePrPsInfo.hpp | 94 + .../ELF/NoteDetails/core/CorePrStatus.hpp | 201 + .../LIEF/ELF/NoteDetails/core/CoreSigInfo.hpp | 68 + .../NoteDetails/properties/AArch64Feature.hpp | 70 + .../NoteDetails/properties/AArch64PAuth.hpp | 76 + .../ELF/NoteDetails/properties/Generic.hpp | 54 + .../ELF/NoteDetails/properties/Needed.hpp | 39 + .../properties/NoteNoCopyOnProtected.hpp | 47 + .../ELF/NoteDetails/properties/StackSize.hpp | 56 + .../ELF/NoteDetails/properties/X86Feature.hpp | 103 + .../ELF/NoteDetails/properties/X86ISA.hpp | 114 + deps/LIEF/include/LIEF/ELF/Parser.hpp | 283 + deps/LIEF/include/LIEF/ELF/ParserConfig.hpp | 60 + deps/LIEF/include/LIEF/ELF/ProcessorFlags.hpp | 126 + deps/LIEF/include/LIEF/ELF/Relocation.hpp | 361 + .../include/LIEF/ELF/Relocations/AArch64.def | 147 + .../LIEF/include/LIEF/ELF/Relocations/ARM.def | 145 + .../LIEF/include/LIEF/ELF/Relocations/BPF.def | 11 + .../include/LIEF/ELF/Relocations/Hexagon.def | 100 + .../LIEF/ELF/Relocations/LoongArch.def | 151 + .../include/LIEF/ELF/Relocations/Mips.def | 117 + .../include/LIEF/ELF/Relocations/PowerPC.def | 62 + .../LIEF/ELF/Relocations/PowerPC64.def | 89 + .../include/LIEF/ELF/Relocations/RISCV.def | 63 + .../LIEF/include/LIEF/ELF/Relocations/SH4.def | 115 + .../include/LIEF/ELF/Relocations/Sparc.def | 89 + .../include/LIEF/ELF/Relocations/SystemZ.def | 71 + .../include/LIEF/ELF/Relocations/i386.def | 46 + .../include/LIEF/ELF/Relocations/x86_64.def | 50 + deps/LIEF/include/LIEF/ELF/Section.hpp | 393 + deps/LIEF/include/LIEF/ELF/Segment.hpp | 337 + deps/LIEF/include/LIEF/ELF/Symbol.hpp | 276 + deps/LIEF/include/LIEF/ELF/SymbolVersion.hpp | 131 + .../include/LIEF/ELF/SymbolVersionAux.hpp | 65 + .../LIEF/ELF/SymbolVersionAuxRequirement.hpp | 93 + .../LIEF/ELF/SymbolVersionDefinition.hpp | 114 + .../LIEF/ELF/SymbolVersionRequirement.hpp | 142 + deps/LIEF/include/LIEF/ELF/SysvHash.hpp | 90 + deps/LIEF/include/LIEF/ELF/enums.hpp | 217 + deps/LIEF/include/LIEF/ELF/enums.inc | 1 + deps/LIEF/include/LIEF/ELF/hash.hpp | 104 + deps/LIEF/include/LIEF/ELF/json.hpp | 31 + deps/LIEF/include/LIEF/ELF/utils.hpp | 46 + deps/LIEF/include/LIEF/LIEF.hpp | 40 + deps/LIEF/include/LIEF/MachO.hpp | 91 + deps/LIEF/include/LIEF/MachO/AtomInfo.hpp | 93 + deps/LIEF/include/LIEF/MachO/Binary.hpp | 1123 + deps/LIEF/include/LIEF/MachO/BinaryParser.hpp | 302 + deps/LIEF/include/LIEF/MachO/BindingInfo.hpp | 174 + .../LIEF/MachO/BindingInfoIterator.hpp | 109 + .../include/LIEF/MachO/BuildToolVersion.hpp | 86 + deps/LIEF/include/LIEF/MachO/BuildVersion.hpp | 136 + deps/LIEF/include/LIEF/MachO/Builder.hpp | 228 + .../include/LIEF/MachO/ChainedBindingInfo.hpp | 154 + .../LIEF/MachO/ChainedPointerAnalysis.hpp | 478 + .../LIEF/include/LIEF/MachO/CodeSignature.hpp | 97 + .../include/LIEF/MachO/CodeSignatureDir.hpp | 97 + .../LIEF/include/LIEF/MachO/DataCodeEntry.hpp | 98 + deps/LIEF/include/LIEF/MachO/DataInCode.hpp | 121 + .../include/LIEF/MachO/DyldBindingInfo.hpp | 126 + .../include/LIEF/MachO/DyldChainedFixups.hpp | 240 + .../LIEF/MachO/DyldChainedFixupsCreator.hpp | 170 + .../include/LIEF/MachO/DyldChainedFormat.hpp | 53 + .../include/LIEF/MachO/DyldEnvironment.hpp | 71 + .../include/LIEF/MachO/DyldExportsTrie.hpp | 128 + deps/LIEF/include/LIEF/MachO/DyldInfo.hpp | 460 + deps/LIEF/include/LIEF/MachO/DylibCommand.hpp | 170 + .../include/LIEF/MachO/DylinkerCommand.hpp | 74 + .../LIEF/MachO/DynamicSymbolCommand.hpp | 300 + .../include/LIEF/MachO/EncryptionInfo.hpp | 93 + deps/LIEF/include/LIEF/MachO/EnumToString.hpp | 36 + deps/LIEF/include/LIEF/MachO/ExportInfo.hpp | 165 + deps/LIEF/include/LIEF/MachO/FatBinary.hpp | 134 + .../include/LIEF/MachO/FilesetCommand.hpp | 108 + .../include/LIEF/MachO/FunctionStarts.hpp | 119 + .../LIEF/MachO/FunctionVariantFixups.hpp | 92 + .../include/LIEF/MachO/FunctionVariants.hpp | 326 + .../LIEF/MachO/FunctionVariants/Arm64.def | 56 + .../MachO/FunctionVariants/PerProcess.def | 8 + .../MachO/FunctionVariants/SystemWide.def | 9 + .../LIEF/MachO/FunctionVariants/X86_64.def | 17 + deps/LIEF/include/LIEF/MachO/Header.hpp | 261 + .../LIEF/MachO/IndirectBindingInfo.hpp | 68 + deps/LIEF/include/LIEF/MachO/LinkEdit.hpp | 97 + .../LIEF/include/LIEF/MachO/LinkerOptHint.hpp | 98 + deps/LIEF/include/LIEF/MachO/LoadCommand.hpp | 201 + deps/LIEF/include/LIEF/MachO/MainCommand.hpp | 81 + deps/LIEF/include/LIEF/MachO/NoteCommand.hpp | 97 + deps/LIEF/include/LIEF/MachO/Parser.hpp | 101 + deps/LIEF/include/LIEF/MachO/ParserConfig.hpp | 57 + deps/LIEF/include/LIEF/MachO/RPathCommand.hpp | 85 + deps/LIEF/include/LIEF/MachO/Relocation.hpp | 176 + .../include/LIEF/MachO/RelocationDyld.hpp | 92 + .../include/LIEF/MachO/RelocationFixup.hpp | 167 + .../include/LIEF/MachO/RelocationObject.hpp | 116 + deps/LIEF/include/LIEF/MachO/Routine.hpp | 142 + deps/LIEF/include/LIEF/MachO/Section.hpp | 303 + .../include/LIEF/MachO/SegmentCommand.hpp | 299 + .../include/LIEF/MachO/SegmentSplitInfo.hpp | 90 + .../LIEF/include/LIEF/MachO/SourceVersion.hpp | 75 + deps/LIEF/include/LIEF/MachO/Stub.hpp | 168 + deps/LIEF/include/LIEF/MachO/SubClient.hpp | 81 + deps/LIEF/include/LIEF/MachO/SubFramework.hpp | 83 + deps/LIEF/include/LIEF/MachO/Symbol.hpp | 243 + .../LIEF/include/LIEF/MachO/SymbolCommand.hpp | 132 + .../LIEF/include/LIEF/MachO/ThreadCommand.hpp | 131 + .../LIEF/include/LIEF/MachO/TwoLevelHints.hpp | 95 + deps/LIEF/include/LIEF/MachO/UUIDCommand.hpp | 71 + .../include/LIEF/MachO/UnknownCommand.hpp | 71 + deps/LIEF/include/LIEF/MachO/VersionMin.hpp | 86 + deps/LIEF/include/LIEF/MachO/enums.hpp | 108 + deps/LIEF/include/LIEF/MachO/enums.inc | 607 + deps/LIEF/include/LIEF/MachO/hash.hpp | 128 + deps/LIEF/include/LIEF/MachO/json.hpp | 31 + deps/LIEF/include/LIEF/MachO/type_traits.hpp | 29 + deps/LIEF/include/LIEF/MachO/utils.hpp | 68 + deps/LIEF/include/LIEF/OAT.hpp | 32 + deps/LIEF/include/LIEF/OAT/Binary.hpp | 141 + deps/LIEF/include/LIEF/OAT/Class.hpp | 100 + deps/LIEF/include/LIEF/OAT/DexFile.hpp | 95 + deps/LIEF/include/LIEF/OAT/EnumToString.hpp | 33 + deps/LIEF/include/LIEF/OAT/Header.hpp | 156 + deps/LIEF/include/LIEF/OAT/Method.hpp | 91 + deps/LIEF/include/LIEF/OAT/Parser.hpp | 98 + deps/LIEF/include/LIEF/OAT/enums.hpp | 90 + deps/LIEF/include/LIEF/OAT/hash.hpp | 53 + deps/LIEF/include/LIEF/OAT/json.hpp | 30 + deps/LIEF/include/LIEF/OAT/type_traits.hpp | 26 + deps/LIEF/include/LIEF/OAT/utils.hpp | 63 + deps/LIEF/include/LIEF/ObjC.hpp | 25 + deps/LIEF/include/LIEF/ObjC/Class.hpp | 148 + deps/LIEF/include/LIEF/ObjC/DeclOpt.hpp | 29 + deps/LIEF/include/LIEF/ObjC/IVar.hpp | 110 + deps/LIEF/include/LIEF/ObjC/Metadata.hpp | 68 + deps/LIEF/include/LIEF/ObjC/Method.hpp | 114 + deps/LIEF/include/LIEF/ObjC/Property.hpp | 107 + deps/LIEF/include/LIEF/ObjC/Protocol.hpp | 126 + deps/LIEF/include/LIEF/Object.hpp | 67 + deps/LIEF/include/LIEF/PDB.hpp | 26 + deps/LIEF/include/LIEF/PDB/BuildMetadata.hpp | 208 + .../LIEF/include/LIEF/PDB/CompilationUnit.hpp | 142 + deps/LIEF/include/LIEF/PDB/DebugInfo.hpp | 117 + deps/LIEF/include/LIEF/PDB/Function.hpp | 117 + deps/LIEF/include/LIEF/PDB/PublicSymbol.hpp | 129 + deps/LIEF/include/LIEF/PDB/Type.hpp | 120 + deps/LIEF/include/LIEF/PDB/types.hpp | 29 + deps/LIEF/include/LIEF/PDB/types/Array.hpp | 42 + .../LIEF/include/LIEF/PDB/types/Attribute.hpp | 108 + deps/LIEF/include/LIEF/PDB/types/BitField.hpp | 42 + .../LIEF/include/LIEF/PDB/types/ClassLike.hpp | 110 + deps/LIEF/include/LIEF/PDB/types/Enum.hpp | 42 + deps/LIEF/include/LIEF/PDB/types/Function.hpp | 42 + deps/LIEF/include/LIEF/PDB/types/Method.hpp | 102 + deps/LIEF/include/LIEF/PDB/types/Modifier.hpp | 45 + deps/LIEF/include/LIEF/PDB/types/Pointer.hpp | 45 + deps/LIEF/include/LIEF/PDB/types/Simple.hpp | 43 + deps/LIEF/include/LIEF/PDB/types/Union.hpp | 42 + deps/LIEF/include/LIEF/PDB/utils.hpp | 31 + deps/LIEF/include/LIEF/PE.hpp | 92 + deps/LIEF/include/LIEF/PE/Binary.hpp | 950 + deps/LIEF/include/LIEF/PE/Builder.hpp | 209 + deps/LIEF/include/LIEF/PE/CodeIntegrity.hpp | 97 + deps/LIEF/include/LIEF/PE/CodePage.hpp | 172 + deps/LIEF/include/LIEF/PE/DataDirectory.hpp | 153 + deps/LIEF/include/LIEF/PE/Debug.hpp | 27 + deps/LIEF/include/LIEF/PE/DelayImport.hpp | 171 + .../LIEF/include/LIEF/PE/DelayImportEntry.hpp | 110 + deps/LIEF/include/LIEF/PE/DosHeader.hpp | 242 + deps/LIEF/include/LIEF/PE/EnumToString.hpp | 37 + deps/LIEF/include/LIEF/PE/ExceptionInfo.hpp | 120 + deps/LIEF/include/LIEF/PE/Export.hpp | 237 + deps/LIEF/include/LIEF/PE/ExportEntry.hpp | 159 + deps/LIEF/include/LIEF/PE/Factory.hpp | 96 + deps/LIEF/include/LIEF/PE/Header.hpp | 306 + deps/LIEF/include/LIEF/PE/Import.hpp | 205 + deps/LIEF/include/LIEF/PE/ImportEntry.hpp | 126 + .../include/LIEF/PE/LoadConfigurations.hpp | 25 + .../PE/LoadConfigurations/CHPEMetadata.hpp | 21 + .../CHPEMetadata/Metadata.hpp | 103 + .../CHPEMetadata/MetadataARM64.hpp | 398 + .../CHPEMetadata/MetadataX86.hpp | 173 + .../LoadConfigurations/DynamicRelocation.hpp | 28 + .../DynamicRelocation/DynamicFixup.hpp | 114 + .../DynamicFixupARM64Kernel.hpp | 113 + .../DynamicRelocation/DynamicFixupARM64X.hpp | 110 + .../DynamicFixupControlTransfer.hpp | 101 + .../DynamicRelocation/DynamicFixupGeneric.hpp | 75 + .../DynamicRelocation/DynamicFixupUnknown.hpp | 72 + .../DynamicRelocationBase.hpp | 140 + .../DynamicRelocation/DynamicRelocationV1.hpp | 65 + .../DynamicRelocation/DynamicRelocationV2.hpp | 66 + .../DynamicRelocation/FunctionOverride.hpp | 138 + .../FunctionOverrideInfo.hpp | 127 + .../EnclaveConfiguration.hpp | 249 + .../PE/LoadConfigurations/EnclaveImport.hpp | 185 + .../LoadConfigurations/LoadConfiguration.hpp | 885 + .../LoadConfigurations/VolatileMetadata.hpp | 157 + deps/LIEF/include/LIEF/PE/OptionalHeader.hpp | 461 + deps/LIEF/include/LIEF/PE/Parser.hpp | 220 + deps/LIEF/include/LIEF/PE/ParserConfig.hpp | 78 + deps/LIEF/include/LIEF/PE/Relocation.hpp | 118 + deps/LIEF/include/LIEF/PE/RelocationEntry.hpp | 232 + deps/LIEF/include/LIEF/PE/ResourceData.hpp | 140 + .../include/LIEF/PE/ResourceDirectory.hpp | 133 + deps/LIEF/include/LIEF/PE/ResourceNode.hpp | 256 + .../LIEF/include/LIEF/PE/ResourcesManager.hpp | 231 + deps/LIEF/include/LIEF/PE/RichEntry.hpp | 82 + deps/LIEF/include/LIEF/PE/RichHeader.hpp | 117 + deps/LIEF/include/LIEF/PE/Section.hpp | 289 + deps/LIEF/include/LIEF/PE/TLS.hpp | 193 + deps/LIEF/include/LIEF/PE/debug/CodeView.hpp | 88 + .../include/LIEF/PE/debug/CodeViewPDB.hpp | 123 + deps/LIEF/include/LIEF/PE/debug/Debug.hpp | 255 + .../LIEF/PE/debug/ExDllCharacteristics.hpp | 94 + deps/LIEF/include/LIEF/PE/debug/FPO.hpp | 128 + .../include/LIEF/PE/debug/PDBChecksum.hpp | 101 + deps/LIEF/include/LIEF/PE/debug/Pogo.hpp | 111 + deps/LIEF/include/LIEF/PE/debug/PogoEntry.hpp | 89 + deps/LIEF/include/LIEF/PE/debug/Repro.hpp | 100 + deps/LIEF/include/LIEF/PE/debug/VCFeature.hpp | 121 + deps/LIEF/include/LIEF/PE/enums.hpp | 57 + deps/LIEF/include/LIEF/PE/enums.inc | 0 .../AArch64/PackedFunction.hpp | 129 + .../AArch64/UnpackedFunction.hpp | 235 + .../RuntimeFunctionAArch64.hpp | 99 + .../PE/exceptions_info/RuntimeFunctionX64.hpp | 269 + .../PE/exceptions_info/UnwindCodeAArch64.hpp | 61 + .../LIEF/PE/exceptions_info/UnwindCodeX64.hpp | 306 + .../PE/exceptions_info/internal_arm64.hpp | 112 + .../LIEF/PE/exceptions_info/internal_x64.hpp | 39 + deps/LIEF/include/LIEF/PE/hash.hpp | 157 + deps/LIEF/include/LIEF/PE/json.hpp | 31 + .../LIEF/PE/resources/AcceleratorCodes.hpp | 203 + .../LIEF/PE/resources/ResourceAccelerator.hpp | 140 + .../LIEF/PE/resources/ResourceDialog.hpp | 511 + .../PE/resources/ResourceDialogExtended.hpp | 215 + .../PE/resources/ResourceDialogRegular.hpp | 152 + .../LIEF/PE/resources/ResourceIcon.hpp | 187 + .../PE/resources/ResourceStringFileInfo.hpp | 114 + .../LIEF/PE/resources/ResourceStringTable.hpp | 168 + .../include/LIEF/PE/resources/ResourceVar.hpp | 104 + .../LIEF/PE/resources/ResourceVarFileInfo.hpp | 109 + .../LIEF/PE/resources/ResourceVersion.hpp | 389 + deps/LIEF/include/LIEF/PE/resources/langs.hpp | 143 + .../include/LIEF/PE/signature/Attribute.hpp | 106 + .../include/LIEF/PE/signature/ContentInfo.hpp | 161 + .../LIEF/PE/signature/GenericContent.hpp | 69 + .../include/LIEF/PE/signature/OIDToString.hpp | 30 + .../LIEF/PE/signature/PKCS9TSTInfo.hpp | 91 + .../include/LIEF/PE/signature/RsaInfo.hpp | 80 + .../include/LIEF/PE/signature/Signature.hpp | 210 + .../LIEF/PE/signature/SignatureParser.hpp | 105 + .../include/LIEF/PE/signature/SignerInfo.hpp | 190 + .../LIEF/PE/signature/SpcIndirectData.hpp | 92 + .../include/LIEF/PE/signature/attributes.hpp | 32 + .../PE/signature/attributes/ContentType.hpp | 79 + .../PE/signature/attributes/GenericType.hpp | 80 + .../PE/signature/attributes/MsCounterSign.hpp | 107 + .../attributes/MsManifestBinaryID.hpp | 83 + .../attributes/MsSpcNestedSignature.hpp | 77 + .../attributes/MsSpcStatementType.hpp | 78 + .../attributes/PKCS9AtSequenceNumber.hpp | 86 + .../attributes/PKCS9CounterSignature.hpp | 80 + .../attributes/PKCS9MessageDigest.hpp | 88 + .../signature/attributes/PKCS9SigningTime.hpp | 87 + .../attributes/SigningCertificateV2.hpp | 73 + .../attributes/SpcRelaxedPeMarkerCheck.hpp | 74 + .../PE/signature/attributes/SpcSpOpusInfo.hpp | 91 + deps/LIEF/include/LIEF/PE/signature/types.hpp | 29 + deps/LIEF/include/LIEF/PE/signature/x509.hpp | 199 + deps/LIEF/include/LIEF/PE/utils.hpp | 94 + deps/LIEF/include/LIEF/VDEX.hpp | 31 + deps/LIEF/include/LIEF/VDEX/File.hpp | 83 + deps/LIEF/include/LIEF/VDEX/Header.hpp | 82 + deps/LIEF/include/LIEF/VDEX/Parser.hpp | 73 + deps/LIEF/include/LIEF/VDEX/hash.hpp | 45 + deps/LIEF/include/LIEF/VDEX/json.hpp | 32 + deps/LIEF/include/LIEF/VDEX/type_traits.hpp | 34 + deps/LIEF/include/LIEF/VDEX/utils.hpp | 51 + deps/LIEF/include/LIEF/Visitor.hpp | 674 + .../LIEF/include/LIEF/asm/AssemblerConfig.hpp | 91 + deps/LIEF/include/LIEF/asm/Engine.hpp | 92 + deps/LIEF/include/LIEF/asm/Instruction.hpp | 216 + deps/LIEF/include/LIEF/asm/aarch64.hpp | 22 + .../include/LIEF/asm/aarch64/Instruction.hpp | 50 + .../LIEF/include/LIEF/asm/aarch64/Operand.hpp | 125 + .../LIEF/include/LIEF/asm/aarch64/opcodes.hpp | 9029 +++++++ .../include/LIEF/asm/aarch64/operands.hpp | 22 + .../LIEF/asm/aarch64/operands/Immediate.hpp | 49 + .../LIEF/asm/aarch64/operands/Memory.hpp | 103 + .../LIEF/asm/aarch64/operands/PCRelative.hpp | 47 + .../LIEF/asm/aarch64/operands/Register.hpp | 67 + .../include/LIEF/asm/aarch64/registers.hpp | 2184 ++ deps/LIEF/include/LIEF/asm/arm.hpp | 21 + .../LIEF/include/LIEF/asm/arm/Instruction.hpp | 43 + deps/LIEF/include/LIEF/asm/arm/opcodes.hpp | 4540 ++++ deps/LIEF/include/LIEF/asm/arm/registers.hpp | 326 + deps/LIEF/include/LIEF/asm/ebpf.hpp | 21 + .../include/LIEF/asm/ebpf/Instruction.hpp | 44 + deps/LIEF/include/LIEF/asm/ebpf/opcodes.hpp | 542 + deps/LIEF/include/LIEF/asm/ebpf/registers.hpp | 55 + deps/LIEF/include/LIEF/asm/mips.hpp | 21 + .../include/LIEF/asm/mips/Instruction.hpp | 44 + deps/LIEF/include/LIEF/asm/mips/opcodes.hpp | 2941 ++ deps/LIEF/include/LIEF/asm/mips/registers.hpp | 472 + deps/LIEF/include/LIEF/asm/powerpc.hpp | 21 + .../include/LIEF/asm/powerpc/Instruction.hpp | 43 + .../LIEF/include/LIEF/asm/powerpc/opcodes.hpp | 2952 ++ .../include/LIEF/asm/powerpc/registers.hpp | 642 + deps/LIEF/include/LIEF/asm/riscv.hpp | 21 + .../include/LIEF/asm/riscv/Instruction.hpp | 44 + deps/LIEF/include/LIEF/asm/riscv/opcodes.hpp | 14341 ++++++++++ .../LIEF/include/LIEF/asm/riscv/registers.hpp | 603 + deps/LIEF/include/LIEF/asm/x86.hpp | 22 + .../LIEF/include/LIEF/asm/x86/Instruction.hpp | 50 + deps/LIEF/include/LIEF/asm/x86/Operand.hpp | 125 + deps/LIEF/include/LIEF/asm/x86/opcodes.hpp | 22364 ++++++++++++++++ deps/LIEF/include/LIEF/asm/x86/operands.hpp | 22 + .../LIEF/asm/x86/operands/Immediate.hpp | 49 + .../include/LIEF/asm/x86/operands/Memory.hpp | 77 + .../LIEF/asm/x86/operands/PCRelative.hpp | 48 + .../LIEF/asm/x86/operands/Register.hpp | 51 + deps/LIEF/include/LIEF/asm/x86/registers.hpp | 422 + deps/LIEF/include/LIEF/canbe_unique.hpp | 120 + .../LIEF/include/LIEF/compiler_attributes.hpp | 54 + deps/LIEF/include/LIEF/config.h | 77 + deps/LIEF/include/LIEF/config.h.in | 77 + deps/LIEF/include/LIEF/debug_loc.hpp | 29 + deps/LIEF/include/LIEF/endianness_support.hpp | 226 + deps/LIEF/include/LIEF/enums.hpp | 92 + deps/LIEF/include/LIEF/errors.hpp | 131 + deps/LIEF/include/LIEF/hash.hpp | 136 + deps/LIEF/include/LIEF/iostream.hpp | 354 + deps/LIEF/include/LIEF/iterators.hpp | 888 + deps/LIEF/include/LIEF/json.hpp | 26 + deps/LIEF/include/LIEF/logging.hpp | 256 + deps/LIEF/include/LIEF/optional.hpp | 42 + deps/LIEF/include/LIEF/platforms.hpp | 57 + deps/LIEF/include/LIEF/platforms/android.hpp | 19 + .../LIEF/platforms/android/version.hpp | 44 + deps/LIEF/include/LIEF/range.hpp | 51 + deps/LIEF/include/LIEF/span.hpp | 25 + .../include/LIEF/third-party/expected.hpp | 27 + .../LIEF/third-party/internal/expected.hpp | 2483 ++ .../LIEF/third-party/internal/span.hpp | 620 + .../internal/utfcpp/utf8/checked.h | 359 + .../third-party/internal/utfcpp/utf8/core.h | 492 + .../third-party/internal/utfcpp/utf8/cpp11.h | 70 + .../third-party/internal/utfcpp/utf8/cpp17.h | 96 + .../third-party/internal/utfcpp/utf8/cpp20.h | 124 + .../internal/utfcpp/utf8/unchecked.h | 287 + deps/LIEF/include/LIEF/third-party/span.hpp | 25 + deps/LIEF/include/LIEF/to_json.hpp | 40 + deps/LIEF/include/LIEF/types.hpp | 29 + deps/LIEF/include/LIEF/utils.hpp | 157 + deps/LIEF/include/LIEF/version.h | 37 + deps/LIEF/include/LIEF/version.h.in | 37 + deps/LIEF/include/LIEF/visibility.h | 45 + deps/LIEF/include/LIEF/visitor_macros.hpp | 133 + deps/LIEF/src/ART/CMakeLists.txt | 16 + deps/LIEF/src/ART/EnumToString.cpp | 128 + deps/LIEF/src/ART/File.cpp | 49 + deps/LIEF/src/ART/Header.cpp | 166 + deps/LIEF/src/ART/Header.tcc | 112 + deps/LIEF/src/ART/Parser.cpp | 108 + deps/LIEF/src/ART/Parser.tcc | 336 + deps/LIEF/src/ART/Structures.cpp | 36 + deps/LIEF/src/ART/Structures.hpp | 637 + deps/LIEF/src/ART/hash.cpp | 63 + deps/LIEF/src/ART/json.cpp | 56 + deps/LIEF/src/ART/json_api.cpp | 41 + deps/LIEF/src/ART/json_internal.hpp | 36 + deps/LIEF/src/ART/utils.cpp | 102 + deps/LIEF/src/Abstract/Binary.cpp | 121 + deps/LIEF/src/Abstract/CMakeLists.txt | 20 + deps/LIEF/src/Abstract/Function.cpp | 75 + deps/LIEF/src/Abstract/Header.cpp | 382 + deps/LIEF/src/Abstract/Parser.cpp | 172 + deps/LIEF/src/Abstract/Relocation.cpp | 31 + deps/LIEF/src/Abstract/Section.cpp | 155 + deps/LIEF/src/Abstract/Section.tcc | 39 + deps/LIEF/src/Abstract/Symbol.cpp | 49 + deps/LIEF/src/Abstract/debug_info.cpp | 49 + deps/LIEF/src/Abstract/hash.cpp | 71 + deps/LIEF/src/Abstract/json.cpp | 128 + deps/LIEF/src/Abstract/json_api.cpp | 37 + deps/LIEF/src/Abstract/json_internal.hpp | 43 + deps/LIEF/src/BinaryStream/ASN1Reader.cpp | 494 + deps/LIEF/src/BinaryStream/BinaryStream.cpp | 299 + deps/LIEF/src/BinaryStream/CMakeLists.txt | 8 + deps/LIEF/src/BinaryStream/FileStream.cpp | 47 + deps/LIEF/src/BinaryStream/MemoryStream.cpp | 44 + deps/LIEF/src/BinaryStream/SpanStream.cpp | 25 + deps/LIEF/src/BinaryStream/VectorStream.cpp | 57 + deps/LIEF/src/CMakeLists.txt | 73 + deps/LIEF/src/COFF/AuxiliarySymbol.cpp | 109 + .../AuxiliarySymbols/AuxiliaryCLRToken.cpp | 80 + .../COFF/AuxiliarySymbols/AuxiliaryFile.cpp | 34 + .../AuxiliaryFunctionDefinition.cpp | 73 + .../AuxiliarySectionDefinition.cpp | 124 + .../AuxiliaryWeakExternal.cpp | 77 + .../AuxiliarybfAndefSymbol.cpp | 24 + .../src/COFF/AuxiliarySymbols/CMakeLists.txt | 8 + deps/LIEF/src/COFF/BigObjHeader.cpp | 67 + deps/LIEF/src/COFF/Binary.cpp | 101 + deps/LIEF/src/COFF/CMakeLists.txt | 14 + deps/LIEF/src/COFF/Header.cpp | 63 + deps/LIEF/src/COFF/Parser.cpp | 316 + deps/LIEF/src/COFF/RegularHeader.cpp | 60 + deps/LIEF/src/COFF/Relocation.cpp | 155 + deps/LIEF/src/COFF/Section.cpp | 143 + deps/LIEF/src/COFF/Symbol.cpp | 253 + deps/LIEF/src/COFF/structures.hpp | 84 + deps/LIEF/src/COFF/utils.cpp | 55 + deps/LIEF/src/DEX/CMakeLists.txt | 25 + deps/LIEF/src/DEX/Class.cpp | 215 + deps/LIEF/src/DEX/CodeInfo.cpp | 53 + deps/LIEF/src/DEX/EnumToString.cpp | 104 + deps/LIEF/src/DEX/Field.cpp | 130 + deps/LIEF/src/DEX/File.cpp | 562 + deps/LIEF/src/DEX/Header.cpp | 168 + deps/LIEF/src/DEX/Header.tcc | 65 + deps/LIEF/src/DEX/MapItem.cpp | 68 + deps/LIEF/src/DEX/MapList.cpp | 92 + deps/LIEF/src/DEX/Method.cpp | 171 + deps/LIEF/src/DEX/Parser.cpp | 175 + deps/LIEF/src/DEX/Parser.tcc | 682 + deps/LIEF/src/DEX/Prototype.cpp | 71 + deps/LIEF/src/DEX/Structures.hpp | 250 + deps/LIEF/src/DEX/Type.cpp | 325 + deps/LIEF/src/DEX/hash.cpp | 147 + deps/LIEF/src/DEX/instructions.cpp | 413 + deps/LIEF/src/DEX/json.cpp | 213 + deps/LIEF/src/DEX/json_api.cpp | 40 + deps/LIEF/src/DEX/json_internal.hpp | 49 + deps/LIEF/src/DEX/utils.cpp | 88 + deps/LIEF/src/DWARF/CMakeLists.txt | 3 + deps/LIEF/src/DWARF/dwarf.cpp | 1096 + deps/LIEF/src/ELF/Binary.cpp | 3418 +++ deps/LIEF/src/ELF/Binary.tcc | 858 + deps/LIEF/src/ELF/Builder.cpp | 242 + deps/LIEF/src/ELF/Builder.tcc | 1939 ++ deps/LIEF/src/ELF/CMakeLists.txt | 45 + deps/LIEF/src/ELF/DataHandler/CMakeLists.txt | 3 + deps/LIEF/src/ELF/DataHandler/Handler.cpp | 182 + deps/LIEF/src/ELF/DataHandler/Handler.hpp | 87 + deps/LIEF/src/ELF/DataHandler/Node.cpp | 49 + deps/LIEF/src/ELF/DataHandler/Node.hpp | 86 + deps/LIEF/src/ELF/DynamicEntry.cpp | 355 + deps/LIEF/src/ELF/DynamicEntryArray.cpp | 75 + deps/LIEF/src/ELF/DynamicEntryFlags.cpp | 216 + deps/LIEF/src/ELF/DynamicEntryLibrary.cpp | 38 + deps/LIEF/src/ELF/DynamicEntryRpath.cpp | 97 + deps/LIEF/src/ELF/DynamicEntryRunPath.cpp | 93 + deps/LIEF/src/ELF/DynamicSharedObject.cpp | 38 + deps/LIEF/src/ELF/EnumToString.cpp | 213 + deps/LIEF/src/ELF/ExeLayout.hpp | 1748 ++ deps/LIEF/src/ELF/GnuHash.cpp | 279 + deps/LIEF/src/ELF/Header.cpp | 370 + deps/LIEF/src/ELF/Layout.cpp | 141 + deps/LIEF/src/ELF/Layout.hpp | 87 + deps/LIEF/src/ELF/Note.cpp | 768 + .../LIEF/src/ELF/NoteDetails/AndroidIdent.cpp | 81 + deps/LIEF/src/ELF/NoteDetails/CMakeLists.txt | 9 + deps/LIEF/src/ELF/NoteDetails/NoteAbi.cpp | 95 + .../src/ELF/NoteDetails/NoteGnuProperty.cpp | 212 + deps/LIEF/src/ELF/NoteDetails/QNXStack.cpp | 64 + .../src/ELF/NoteDetails/core/CMakeLists.txt | 7 + .../src/ELF/NoteDetails/core/CoreAuxv.cpp | 192 + .../src/ELF/NoteDetails/core/CoreFile.cpp | 137 + .../src/ELF/NoteDetails/core/CorePrPsInfo.cpp | 134 + .../src/ELF/NoteDetails/core/CorePrStatus.cpp | 571 + .../src/ELF/NoteDetails/core/CoreSigInfo.cpp | 68 + .../NoteDetails/properties/AArch64Feature.cpp | 68 + .../NoteDetails/properties/AArch64PAuth.cpp | 39 + .../ELF/NoteDetails/properties/CMakeLists.txt | 7 + .../ELF/NoteDetails/properties/StackSize.cpp | 26 + .../ELF/NoteDetails/properties/X86Feature.cpp | 137 + .../src/ELF/NoteDetails/properties/X86ISA.cpp | 201 + .../src/ELF/NoteDetails/properties/common.hpp | 130 + deps/LIEF/src/ELF/ObjectFileLayout.hpp | 135 + deps/LIEF/src/ELF/Parser.cpp | 757 + deps/LIEF/src/ELF/Parser.tcc | 1795 ++ deps/LIEF/src/ELF/ProcessorFlags.cpp | 102 + deps/LIEF/src/ELF/Relocation.cpp | 440 + deps/LIEF/src/ELF/RelocationSizes.cpp | 943 + deps/LIEF/src/ELF/RelocationStrings.cpp | 269 + deps/LIEF/src/ELF/Section.cpp | 543 + deps/LIEF/src/ELF/Segment.cpp | 466 + deps/LIEF/src/ELF/SizingInfo.hpp | 46 + deps/LIEF/src/ELF/Structures.hpp | 144 + deps/LIEF/src/ELF/Symbol.cpp | 244 + deps/LIEF/src/ELF/SymbolVersion.cpp | 52 + deps/LIEF/src/ELF/SymbolVersionAux.cpp | 30 + .../src/ELF/SymbolVersionAuxRequirement.cpp | 43 + deps/LIEF/src/ELF/SymbolVersionDefinition.cpp | 86 + .../LIEF/src/ELF/SymbolVersionRequirement.cpp | 99 + deps/LIEF/src/ELF/SysvHash.cpp | 75 + deps/LIEF/src/ELF/endianness_support.cpp | 279 + deps/LIEF/src/ELF/hash.cpp | 298 + deps/LIEF/src/ELF/json.cpp | 559 + deps/LIEF/src/ELF/json_api.cpp | 41 + deps/LIEF/src/ELF/json_internal.hpp | 98 + deps/LIEF/src/ELF/structures.inc | 343 + deps/LIEF/src/ELF/utils.cpp | 92 + deps/LIEF/src/MachO/AtomInfo.cpp | 48 + deps/LIEF/src/MachO/Binary.cpp | 2626 ++ deps/LIEF/src/MachO/Binary.tcc | 115 + deps/LIEF/src/MachO/BinaryParser.cpp | 468 + deps/LIEF/src/MachO/BinaryParser.tcc | 4042 +++ deps/LIEF/src/MachO/BindingInfo.cpp | 78 + deps/LIEF/src/MachO/BindingInfoIterator.cpp | 42 + deps/LIEF/src/MachO/BuildToolVersion.cpp | 78 + deps/LIEF/src/MachO/BuildVersion.cpp | 111 + deps/LIEF/src/MachO/Builder.cpp | 428 + deps/LIEF/src/MachO/Builder.tcc | 1865 ++ deps/LIEF/src/MachO/CMakeLists.txt | 80 + deps/LIEF/src/MachO/ChainedBindingInfo.cpp | 137 + .../LIEF/src/MachO/ChainedBindingInfoList.cpp | 46 + .../LIEF/src/MachO/ChainedBindingInfoList.hpp | 64 + deps/LIEF/src/MachO/ChainedFixup.cpp | 127 + deps/LIEF/src/MachO/ChainedFixup.hpp | 309 + .../LIEF/src/MachO/ChainedPointerAnalysis.cpp | 577 + deps/LIEF/src/MachO/CodeSignature.cpp | 43 + deps/LIEF/src/MachO/CodeSignatureDir.cpp | 45 + deps/LIEF/src/MachO/DataCodeEntry.cpp | 62 + deps/LIEF/src/MachO/DataInCode.cpp | 44 + deps/LIEF/src/MachO/DyldBindingInfo.cpp | 79 + deps/LIEF/src/MachO/DyldChainedFixups.cpp | 161 + .../src/MachO/DyldChainedFixupsCreator.cpp | 417 + deps/LIEF/src/MachO/DyldChainedFormat.cpp | 66 + deps/LIEF/src/MachO/DyldEnvironment.cpp | 38 + deps/LIEF/src/MachO/DyldExportsTrie.cpp | 86 + deps/LIEF/src/MachO/DyldInfo.cpp | 2226 ++ deps/LIEF/src/MachO/DylibCommand.cpp | 138 + deps/LIEF/src/MachO/DylinkerCommand.cpp | 49 + deps/LIEF/src/MachO/DynamicSymbolCommand.cpp | 92 + deps/LIEF/src/MachO/EncryptionInfo.cpp | 45 + deps/LIEF/src/MachO/EnumToString.cpp | 130 + deps/LIEF/src/MachO/ExportInfo.cpp | 133 + deps/LIEF/src/MachO/FatBinary.cpp | 126 + deps/LIEF/src/MachO/FilesetCommand.cpp | 59 + deps/LIEF/src/MachO/FunctionStarts.cpp | 48 + deps/LIEF/src/MachO/FunctionVariantFixups.cpp | 38 + deps/LIEF/src/MachO/FunctionVariants.cpp | 250 + deps/LIEF/src/MachO/Header.cpp | 214 + deps/LIEF/src/MachO/IndirectBindingInfo.cpp | 0 deps/LIEF/src/MachO/LinkEdit.cpp | 328 + deps/LIEF/src/MachO/LinkerOptHint.cpp | 44 + deps/LIEF/src/MachO/LoadCommand.cpp | 150 + deps/LIEF/src/MachO/MainCommand.cpp | 51 + deps/LIEF/src/MachO/NoteCommand.cpp | 46 + deps/LIEF/src/MachO/Parser.cpp | 248 + deps/LIEF/src/MachO/ParserConfig.cpp | 55 + deps/LIEF/src/MachO/RPathCommand.cpp | 50 + deps/LIEF/src/MachO/Relocation.cpp | 167 + deps/LIEF/src/MachO/RelocationDyld.cpp | 63 + deps/LIEF/src/MachO/RelocationFixup.cpp | 286 + deps/LIEF/src/MachO/RelocationObject.cpp | 99 + deps/LIEF/src/MachO/Routine.cpp | 55 + deps/LIEF/src/MachO/Section.cpp | 316 + deps/LIEF/src/MachO/SegmentCommand.cpp | 278 + deps/LIEF/src/MachO/SegmentSplitInfo.cpp | 44 + deps/LIEF/src/MachO/SourceVersion.cpp | 50 + deps/LIEF/src/MachO/Structures.hpp | 749 + deps/LIEF/src/MachO/Stub.cpp | 109 + deps/LIEF/src/MachO/SubClient.cpp | 40 + deps/LIEF/src/MachO/SubFramework.cpp | 41 + deps/LIEF/src/MachO/Symbol.cpp | 183 + deps/LIEF/src/MachO/SymbolCommand.cpp | 48 + deps/LIEF/src/MachO/ThreadCommand.cpp | 122 + deps/LIEF/src/MachO/TrieNode.cpp | 231 + deps/LIEF/src/MachO/TrieNode.hpp | 89 + deps/LIEF/src/MachO/TwoLevelHints.cpp | 41 + deps/LIEF/src/MachO/UUIDCommand.cpp | 47 + deps/LIEF/src/MachO/UnknownCommand.cpp | 32 + deps/LIEF/src/MachO/VersionMin.cpp | 54 + deps/LIEF/src/MachO/endianness_support.cpp | 554 + deps/LIEF/src/MachO/exports_trie.cpp | 203 + deps/LIEF/src/MachO/exports_trie.hpp | 34 + deps/LIEF/src/MachO/hash.cpp | 375 + deps/LIEF/src/MachO/json.cpp | 497 + deps/LIEF/src/MachO/json_api.cpp | 39 + deps/LIEF/src/MachO/json_internal.hpp | 123 + deps/LIEF/src/MachO/layout_check.cpp | 1576 ++ deps/LIEF/src/MachO/structures.inc | 2 + deps/LIEF/src/MachO/utils.cpp | 169 + deps/LIEF/src/OAT/Binary.cpp | 188 + deps/LIEF/src/OAT/CMakeLists.txt | 23 + deps/LIEF/src/OAT/Class.cpp | 260 + deps/LIEF/src/OAT/DexFile.cpp | 97 + deps/LIEF/src/OAT/EnumToString.cpp | 101 + deps/LIEF/src/OAT/Header.cpp | 265 + deps/LIEF/src/OAT/Header.tcc | 101 + deps/LIEF/src/OAT/Method.cpp | 115 + deps/LIEF/src/OAT/Parser.cpp | 143 + deps/LIEF/src/OAT/Parser.tcc | 546 + deps/LIEF/src/OAT/Structures.hpp | 320 + deps/LIEF/src/OAT/hash.cpp | 113 + deps/LIEF/src/OAT/json.cpp | 109 + deps/LIEF/src/OAT/json_api.cpp | 42 + deps/LIEF/src/OAT/json_internal.hpp | 41 + deps/LIEF/src/OAT/oat_124.tcc | 127 + deps/LIEF/src/OAT/oat_131.tcc | 131 + deps/LIEF/src/OAT/oat_64.tcc | 141 + deps/LIEF/src/OAT/oat_79.tcc | 153 + deps/LIEF/src/OAT/utils.cpp | 115 + deps/LIEF/src/ObjC/CMakeLists.txt | 3 + deps/LIEF/src/ObjC/objc.cpp | 377 + deps/LIEF/src/Object.cpp | 33 + deps/LIEF/src/Object.tcc | 33 + deps/LIEF/src/PDB/CMakeLists.txt | 3 + deps/LIEF/src/PDB/pdb.cpp | 572 + deps/LIEF/src/PE/Binary.cpp | 1500 ++ deps/LIEF/src/PE/Builder.cpp | 1266 + deps/LIEF/src/PE/Builder.tcc | 863 + deps/LIEF/src/PE/CMakeLists.txt | 49 + deps/LIEF/src/PE/CodeIntegrity.cpp | 70 + deps/LIEF/src/PE/CodePage.cpp | 172 + deps/LIEF/src/PE/DataDirectory.cpp | 128 + deps/LIEF/src/PE/DelayImport.cpp | 94 + deps/LIEF/src/PE/DelayImportEntry.cpp | 66 + deps/LIEF/src/PE/DosHeader.cpp | 95 + deps/LIEF/src/PE/EnumToString.cpp | 68 + deps/LIEF/src/PE/ExceptionInfo.cpp | 59 + deps/LIEF/src/PE/Export.cpp | 190 + deps/LIEF/src/PE/ExportEntry.cpp | 53 + deps/LIEF/src/PE/Factory.cpp | 132 + deps/LIEF/src/PE/Header.cpp | 198 + deps/LIEF/src/PE/Import.cpp | 171 + deps/LIEF/src/PE/ImportEntry.cpp | 64 + .../CHPEMetadata/CMakeLists.txt | 5 + .../CHPEMetadata/Metadata.cpp | 53 + .../CHPEMetadata/MetadataARM64.cpp | 421 + .../CHPEMetadata/MetadataX86.cpp | 175 + .../src/PE/LoadConfigurations/CMakeLists.txt | 9 + .../DynamicRelocation/CMakeLists.txt | 12 + .../DynamicRelocation/DynamicFixup.cpp | 95 + .../DynamicFixupARM64Kernel.cpp | 115 + .../DynamicRelocation/DynamicFixupARM64X.cpp | 183 + .../DynamicFixupControlTransfer.cpp | 102 + .../DynamicRelocation/DynamicFixupGeneric.cpp | 90 + .../DynamicRelocationBase.cpp | 79 + .../DynamicRelocation/DynamicRelocationV1.cpp | 100 + .../DynamicRelocation/DynamicRelocationV2.cpp | 90 + .../DynamicRelocation/FunctionOverride.cpp | 223 + .../FunctionOverrideInfo.cpp | 170 + .../EnclaveConfiguration.cpp | 197 + .../PE/LoadConfigurations/EnclaveImport.cpp | 115 + .../LoadConfigurations/LoadConfiguration.cpp | 1145 + .../LoadConfigurations/VolatileMetadata.cpp | 154 + deps/LIEF/src/PE/OptionalHeader.cpp | 222 + deps/LIEF/src/PE/Parser.cpp | 1413 + deps/LIEF/src/PE/Parser.tcc | 803 + deps/LIEF/src/PE/ParserConfig.cpp | 36 + deps/LIEF/src/PE/Relocation.cpp | 148 + deps/LIEF/src/PE/RelocationEntry.cpp | 170 + deps/LIEF/src/PE/ResourceData.cpp | 39 + deps/LIEF/src/PE/ResourceDirectory.cpp | 49 + deps/LIEF/src/PE/ResourceNode.cpp | 461 + deps/LIEF/src/PE/ResourcesManager.cpp | 733 + deps/LIEF/src/PE/RichEntry.cpp | 37 + deps/LIEF/src/PE/RichHeader.cpp | 94 + deps/LIEF/src/PE/Section.cpp | 211 + deps/LIEF/src/PE/Structures.hpp | 255 + deps/LIEF/src/PE/TLS.cpp | 77 + deps/LIEF/src/PE/checksum.cpp | 82 + deps/LIEF/src/PE/checksum.hpp | 84 + deps/LIEF/src/PE/debug/CMakeLists.txt | 13 + deps/LIEF/src/PE/debug/CodeView.cpp | 55 + deps/LIEF/src/PE/debug/CodeViewPDB.cpp | 84 + deps/LIEF/src/PE/debug/Debug.cpp | 127 + .../src/PE/debug/ExDllCharacteristics.cpp | 91 + deps/LIEF/src/PE/debug/FPO.cpp | 104 + deps/LIEF/src/PE/debug/PDBChecksum.cpp | 78 + deps/LIEF/src/PE/debug/Pogo.cpp | 63 + deps/LIEF/src/PE/debug/PogoEntry.cpp | 36 + deps/LIEF/src/PE/debug/Repro.cpp | 44 + deps/LIEF/src/PE/debug/VCFeature.cpp | 46 + deps/LIEF/src/PE/endianness_support.cpp | 16 + .../PE/exceptions_info/AArch64/CMakeLists.txt | 4 + .../AArch64/PackedFunction.cpp | 60 + .../AArch64/UnpackedFunction.cpp | 207 + .../src/PE/exceptions_info/CMakeLists.txt | 8 + .../RuntimeFunctionAArch64.cpp | 74 + .../PE/exceptions_info/RuntimeFunctionX64.cpp | 319 + .../exceptions_info/UnwindAArch64Decoder.cpp | 535 + .../exceptions_info/UnwindAArch64Decoder.hpp | 114 + .../src/PE/exceptions_info/UnwindCodeX64.cpp | 175 + deps/LIEF/src/PE/hash.cpp | 652 + deps/LIEF/src/PE/json.cpp | 975 + deps/LIEF/src/PE/json_api.cpp | 43 + deps/LIEF/src/PE/json_internal.hpp | 157 + deps/LIEF/src/PE/layout_check.cpp | 666 + .../src/PE/resources/AcceleratorCodes.cpp | 203 + deps/LIEF/src/PE/resources/CMakeLists.txt | 14 + .../src/PE/resources/ResourceAccelerator.cpp | 86 + deps/LIEF/src/PE/resources/ResourceDialog.cpp | 413 + .../PE/resources/ResourceDialogExtended.cpp | 333 + .../PE/resources/ResourceDialogRegular.cpp | 279 + deps/LIEF/src/PE/resources/ResourceIcon.cpp | 156 + .../PE/resources/ResourceStringFileInfo.cpp | 114 + .../src/PE/resources/ResourceStringTable.cpp | 163 + deps/LIEF/src/PE/resources/ResourceVar.cpp | 105 + .../src/PE/resources/ResourceVarFileInfo.cpp | 93 + .../LIEF/src/PE/resources/ResourceVersion.cpp | 514 + deps/LIEF/src/PE/resources/styles_array.hpp | 95 + deps/LIEF/src/PE/signature/Attribute.cpp | 59 + deps/LIEF/src/PE/signature/CMakeLists.txt | 15 + deps/LIEF/src/PE/signature/ContentInfo.cpp | 73 + deps/LIEF/src/PE/signature/GenericContent.cpp | 51 + deps/LIEF/src/PE/signature/OIDToString.cpp | 2253 ++ deps/LIEF/src/PE/signature/PKCS9TSTInfo.cpp | 26 + deps/LIEF/src/PE/signature/RsaInfo.cpp | 144 + deps/LIEF/src/PE/signature/Signature.cpp | 587 + .../LIEF/src/PE/signature/SignatureParser.cpp | 1735 ++ deps/LIEF/src/PE/signature/SignerInfo.cpp | 133 + .../LIEF/src/PE/signature/SpcIndirectData.cpp | 41 + .../PE/signature/attributes/CMakeLists.txt | 15 + .../PE/signature/attributes/ContentType.cpp | 33 + .../PE/signature/attributes/GenericType.cpp | 31 + .../PE/signature/attributes/MsCounterSign.cpp | 36 + .../attributes/MsManifestBinaryID.cpp | 26 + .../attributes/MsSpcNestedSignature.cpp | 37 + .../attributes/MsSpcStatementType.cpp | 30 + .../attributes/PKCS9AtSequenceNumber.cpp | 31 + .../attributes/PKCS9CounterSignature.cpp | 35 + .../attributes/PKCS9MessageDigest.cpp | 31 + .../signature/attributes/PKCS9SigningTime.cpp | 33 + .../attributes/SigningCertificateV2.cpp | 32 + .../attributes/SpcRelaxedPeMarkerCheck.cpp | 27 + .../PE/signature/attributes/SpcSpOpusInfo.cpp | 41 + deps/LIEF/src/PE/signature/pkcs7.h | 45 + deps/LIEF/src/PE/signature/x509.cpp | 780 + deps/LIEF/src/PE/structures.inc | 495 + deps/LIEF/src/PE/utils.cpp | 392 + .../advapi32_dll_lookup.hpp | 709 + .../comctl32_dll_lookup.hpp | 182 + .../gdi32_dll_lookup.hpp | 643 + .../kernel32_dll_lookup.hpp | 983 + .../libraries_table.hpp | 42 + .../mfc42u_dll_lookup.hpp | 40 + .../msvcp110_dll_lookup.hpp | 1625 ++ .../msvcp120_dll_lookup.hpp | 1603 ++ .../msvcr100_dll_lookup.hpp | 1655 ++ .../msvcr110_dll_lookup.hpp | 1744 ++ .../msvcr120_dll_lookup.hpp | 2000 ++ .../msvcrt_dll_lookup.hpp | 864 + .../ntdll_dll_lookup.hpp | 1349 + .../ole32_dll_lookup.hpp | 374 + .../oleaut32_dll_lookup.hpp | 432 + .../shcore_dll_lookup.hpp | 122 + .../shell32_dll_lookup.hpp | 383 + .../shlwapi_dll_lookup.hpp | 401 + .../user32_dll_lookup.hpp | 766 + .../ws2_32_dll_lookup.hpp | 151 + .../ordinals_lookup_tables_std/README.md | 1 + .../libraries_table.hpp | 22 + .../oleauth32_dll_lookup.hpp | 435 + .../ws2_32_dll_lookup.hpp | 154 + deps/LIEF/src/VDEX/CMakeLists.txt | 14 + deps/LIEF/src/VDEX/File.cpp | 100 + deps/LIEF/src/VDEX/Header.cpp | 109 + deps/LIEF/src/VDEX/Header.tcc | 44 + deps/LIEF/src/VDEX/Parser.cpp | 100 + deps/LIEF/src/VDEX/Parser.tcc | 406 + deps/LIEF/src/VDEX/Structures.hpp | 90 + deps/LIEF/src/VDEX/hash.cpp | 52 + deps/LIEF/src/VDEX/json.cpp | 49 + deps/LIEF/src/VDEX/json_api.cpp | 42 + deps/LIEF/src/VDEX/json_internal.hpp | 38 + deps/LIEF/src/VDEX/utils.cpp | 97 + deps/LIEF/src/Visitor.cpp | 33 + deps/LIEF/src/asm/CMakeLists.txt | 3 + deps/LIEF/src/asm/asm.cpp | 598 + deps/LIEF/src/compiler_support.h | 23 + deps/LIEF/src/compiler_support.h.in | 23 + .../LIEF/src/dyld-shared-cache/CMakeLists.txt | 3 + deps/LIEF/src/dyld-shared-cache/dyldsc.cpp | 384 + deps/LIEF/src/endianness_support.cpp | 56 + deps/LIEF/src/errors.cpp | 38 + deps/LIEF/src/fmt_formatter.hpp | 37 + deps/LIEF/src/frozen.hpp | 37 + deps/LIEF/src/hash_stream.cpp | 110 + deps/LIEF/src/hash_stream.hpp | 101 + deps/LIEF/src/internal_utils.cpp | 99 + deps/LIEF/src/internal_utils.hpp | 267 + deps/LIEF/src/intmem.h | 223 + deps/LIEF/src/iostream.cpp | 137 + deps/LIEF/src/json_api.cpp | 131 + deps/LIEF/src/logging.cpp | 336 + deps/LIEF/src/logging.hpp | 242 + deps/LIEF/src/messages.hpp | 59 + deps/LIEF/src/overflow_check.hpp | 35 + deps/LIEF/src/overload_cast.hpp | 43 + deps/LIEF/src/paging.cpp | 154 + deps/LIEF/src/paging.hpp | 22 + deps/LIEF/src/platforms/CMakeLists.txt | 1 + .../LIEF/src/platforms/android/CMakeLists.txt | 1 + deps/LIEF/src/platforms/android/version.cpp | 70 + deps/LIEF/src/profiling.hpp | 42 + deps/LIEF/src/range.cpp | 24 + deps/LIEF/src/third-party/utfcpp.hpp | 25 + deps/LIEF/src/utils.cpp | 192 + deps/LIEF/src/visitors/hash.cpp | 156 + deps/LIEF/src/visitors/json.cpp | 34 + deps/LIEF/src/visitors/json.hpp | 47 + deps/LIEF/third-party/expected/COPYING | 121 + deps/LIEF/third-party/expected/README.md | 76 + .../expected/include/tl/expected.hpp | 2483 ++ deps/LIEF/third-party/frozen/LICENSE | 202 + deps/LIEF/third-party/frozen/README.rst | 245 + .../frozen/include/frozen/CMakeLists.txt | 12 + .../frozen/include/frozen/algorithm.h | 202 + .../frozen/include/frozen/bits/algorithms.h | 229 + .../frozen/include/frozen/bits/basic_types.h | 207 + .../include/frozen/bits/constexpr_assert.h | 40 + .../frozen/include/frozen/bits/defines.h | 66 + .../frozen/include/frozen/bits/elsa.h | 57 + .../frozen/include/frozen/bits/elsa_std.h | 40 + .../frozen/include/frozen/bits/exceptions.h | 39 + .../frozen/include/frozen/bits/hash_string.h | 28 + .../frozen/include/frozen/bits/pmh.h | 245 + .../frozen/include/frozen/bits/version.h | 30 + .../third-party/frozen/include/frozen/map.h | 355 + .../frozen/include/frozen/random.h | 97 + .../third-party/frozen/include/frozen/set.h | 261 + .../frozen/include/frozen/string.h | 147 + .../frozen/include/frozen/unordered_map.h | 260 + .../frozen/include/frozen/unordered_set.h | 192 + deps/LIEF/third-party/mbedtls/LICENSE | 553 + deps/LIEF/third-party/mbedtls/README.md | 333 + .../third-party/mbedtls/include/.gitignore | 4 + .../mbedtls/include/CMakeLists.txt | 22 + .../third-party/mbedtls/include/mbedtls/aes.h | 631 + .../mbedtls/include/mbedtls/aria.h | 343 + .../mbedtls/include/mbedtls/asn1.h | 642 + .../mbedtls/include/mbedtls/asn1write.h | 390 + .../mbedtls/include/mbedtls/base64.h | 82 + .../mbedtls/include/mbedtls/bignum.h | 1085 + .../mbedtls/include/mbedtls/block_cipher.h | 76 + .../mbedtls/include/mbedtls/build_info.h | 194 + .../mbedtls/include/mbedtls/camellia.h | 305 + .../third-party/mbedtls/include/mbedtls/ccm.h | 526 + .../mbedtls/include/mbedtls/chacha20.h | 202 + .../mbedtls/include/mbedtls/chachapoly.h | 342 + .../mbedtls/include/mbedtls/check_config.h | 1149 + .../mbedtls/include/mbedtls/cipher.h | 1173 + .../mbedtls/include/mbedtls/cmac.h | 246 + .../mbedtls/include/mbedtls/compat-2.x.h | 46 + .../mbedtls/config_adjust_legacy_crypto.h | 535 + .../mbedtls/config_adjust_legacy_from_psa.h | 873 + .../mbedtls/config_adjust_psa_from_legacy.h | 359 + .../config_adjust_psa_superset_legacy.h | 145 + .../include/mbedtls/config_adjust_ssl.h | 91 + .../include/mbedtls/config_adjust_x509.h | 35 + .../mbedtls/include/mbedtls/config_psa.h | 61 + .../mbedtls/include/mbedtls/constant_time.h | 36 + .../mbedtls/include/mbedtls/ctr_drbg.h | 597 + .../mbedtls/include/mbedtls/debug.h | 156 + .../third-party/mbedtls/include/mbedtls/des.h | 385 + .../third-party/mbedtls/include/mbedtls/dhm.h | 972 + .../mbedtls/include/mbedtls/ecdh.h | 454 + .../mbedtls/include/mbedtls/ecdsa.h | 674 + .../mbedtls/include/mbedtls/ecjpake.h | 298 + .../third-party/mbedtls/include/mbedtls/ecp.h | 1528 ++ .../mbedtls/include/mbedtls/entropy.h | 274 + .../mbedtls/include/mbedtls/error.h | 201 + .../third-party/mbedtls/include/mbedtls/gcm.h | 387 + .../mbedtls/include/mbedtls/hkdf.h | 124 + .../mbedtls/include/mbedtls/hmac_drbg.h | 434 + .../third-party/mbedtls/include/mbedtls/lms.h | 440 + .../mbedtls/include/mbedtls/mbedtls_config.h | 4380 +++ .../third-party/mbedtls/include/mbedtls/md.h | 526 + .../third-party/mbedtls/include/mbedtls/md5.h | 190 + .../include/mbedtls/memory_buffer_alloc.h | 142 + .../mbedtls/include/mbedtls/net_sockets.h | 299 + .../mbedtls/include/mbedtls/nist_kw.h | 166 + .../third-party/mbedtls/include/mbedtls/oid.h | 727 + .../third-party/mbedtls/include/mbedtls/pem.h | 160 + .../third-party/mbedtls/include/mbedtls/pk.h | 1296 + .../mbedtls/include/mbedtls/pkcs12.h | 186 + .../mbedtls/include/mbedtls/pkcs5.h | 198 + .../mbedtls/include/mbedtls/pkcs7.h | 240 + .../mbedtls/include/mbedtls/platform.h | 485 + .../mbedtls/include/mbedtls/platform_time.h | 79 + .../mbedtls/include/mbedtls/platform_util.h | 247 + .../mbedtls/include/mbedtls/poly1305.h | 168 + .../mbedtls/include/mbedtls/private_access.h | 20 + .../mbedtls/include/mbedtls/psa_util.h | 207 + .../mbedtls/include/mbedtls/ripemd160.h | 136 + .../third-party/mbedtls/include/mbedtls/rsa.h | 1164 + .../mbedtls/include/mbedtls/sha1.h | 219 + .../mbedtls/include/mbedtls/sha256.h | 200 + .../mbedtls/include/mbedtls/sha3.h | 172 + .../mbedtls/include/mbedtls/sha512.h | 208 + .../third-party/mbedtls/include/mbedtls/ssl.h | 5821 ++++ .../mbedtls/include/mbedtls/ssl_cache.h | 187 + .../include/mbedtls/ssl_ciphersuites.h | 482 + .../mbedtls/include/mbedtls/ssl_cookie.h | 106 + .../mbedtls/include/mbedtls/ssl_ticket.h | 199 + .../mbedtls/include/mbedtls/threading.h | 137 + .../mbedtls/include/mbedtls/timing.h | 94 + .../mbedtls/include/mbedtls/version.h | 78 + .../mbedtls/include/mbedtls/x509.h | 500 + .../mbedtls/include/mbedtls/x509_crl.h | 184 + .../mbedtls/include/mbedtls/x509_crt.h | 1208 + .../mbedtls/include/mbedtls/x509_csr.h | 382 + .../mbedtls/include/psa/build_info.h | 20 + .../third-party/mbedtls/include/psa/crypto.h | 4977 ++++ .../include/psa/crypto_adjust_auto_enabled.h | 31 + .../psa/crypto_adjust_config_dependencies.h | 51 + .../psa/crypto_adjust_config_key_pair_types.h | 101 + .../psa/crypto_adjust_config_synonyms.h | 49 + .../include/psa/crypto_builtin_composites.h | 214 + .../psa/crypto_builtin_key_derivation.h | 118 + .../include/psa/crypto_builtin_primitives.h | 114 + .../mbedtls/include/psa/crypto_compat.h | 230 + .../mbedtls/include/psa/crypto_config.h | 145 + .../include/psa/crypto_driver_common.h | 44 + .../psa/crypto_driver_contexts_composites.h | 151 + .../crypto_driver_contexts_key_derivation.h | 52 + .../psa/crypto_driver_contexts_primitives.h | 105 + .../mbedtls/include/psa/crypto_extra.h | 1936 ++ .../mbedtls/include/psa/crypto_legacy.h | 88 + .../mbedtls/include/psa/crypto_platform.h | 102 + .../mbedtls/include/psa/crypto_se_driver.h | 1383 + .../mbedtls/include/psa/crypto_sizes.h | 1317 + .../mbedtls/include/psa/crypto_struct.h | 527 + .../mbedtls/include/psa/crypto_types.h | 508 + .../mbedtls/include/psa/crypto_values.h | 2783 ++ .../third-party/mbedtls/library/.gitignore | 11 + .../mbedtls/library/CMakeLists.txt | 359 + .../LIEF/third-party/mbedtls/library/Makefile | 408 + deps/LIEF/third-party/mbedtls/library/aes.c | 2294 ++ deps/LIEF/third-party/mbedtls/library/aesce.c | 618 + deps/LIEF/third-party/mbedtls/library/aesce.h | 136 + deps/LIEF/third-party/mbedtls/library/aesni.c | 846 + deps/LIEF/third-party/mbedtls/library/aesni.h | 162 + .../third-party/mbedtls/library/alignment.h | 684 + deps/LIEF/third-party/mbedtls/library/aria.c | 969 + .../third-party/mbedtls/library/asn1parse.c | 468 + .../third-party/mbedtls/library/asn1write.c | 440 + .../LIEF/third-party/mbedtls/library/base64.c | 323 + .../mbedtls/library/base64_internal.h | 45 + .../LIEF/third-party/mbedtls/library/bignum.c | 2487 ++ .../third-party/mbedtls/library/bignum_core.c | 1022 + .../third-party/mbedtls/library/bignum_core.h | 825 + .../mbedtls/library/bignum_core_invasive.h | 23 + .../mbedtls/library/bignum_internal.h | 50 + .../third-party/mbedtls/library/bignum_mod.c | 394 + .../third-party/mbedtls/library/bignum_mod.h | 452 + .../mbedtls/library/bignum_mod_raw.c | 276 + .../mbedtls/library/bignum_mod_raw.h | 416 + .../mbedtls/library/bignum_mod_raw_invasive.h | 34 + .../mbedtls/library/block_cipher.c | 207 + .../mbedtls/library/block_cipher_internal.h | 99 + .../LIEF/third-party/mbedtls/library/bn_mul.h | 1094 + .../third-party/mbedtls/library/camellia.c | 1058 + deps/LIEF/third-party/mbedtls/library/ccm.c | 764 + .../third-party/mbedtls/library/chacha20.c | 497 + .../third-party/mbedtls/library/chachapoly.c | 478 + .../mbedtls/library/check_crypto_config.h | 141 + .../LIEF/third-party/mbedtls/library/cipher.c | 1689 ++ .../mbedtls/library/cipher_invasive.h | 27 + .../third-party/mbedtls/library/cipher_wrap.c | 2482 ++ .../third-party/mbedtls/library/cipher_wrap.h | 178 + deps/LIEF/third-party/mbedtls/library/cmac.c | 1067 + .../LIEF/third-party/mbedtls/library/common.h | 453 + .../mbedtls/library/constant_time.c | 248 + .../mbedtls/library/constant_time_impl.h | 541 + .../mbedtls/library/constant_time_internal.h | 579 + deps/LIEF/third-party/mbedtls/library/ctr.h | 35 + .../third-party/mbedtls/library/ctr_drbg.c | 1016 + deps/LIEF/third-party/mbedtls/library/debug.c | 465 + .../mbedtls/library/debug_internal.h | 172 + deps/LIEF/third-party/mbedtls/library/des.c | 1042 + deps/LIEF/third-party/mbedtls/library/dhm.c | 712 + deps/LIEF/third-party/mbedtls/library/ecdh.c | 694 + deps/LIEF/third-party/mbedtls/library/ecdsa.c | 867 + .../third-party/mbedtls/library/ecjpake.c | 1216 + deps/LIEF/third-party/mbedtls/library/ecp.c | 3703 +++ .../third-party/mbedtls/library/ecp_curves.c | 5460 ++++ .../mbedtls/library/ecp_curves_new.c | 6036 +++++ .../mbedtls/library/ecp_internal_alt.h | 287 + .../mbedtls/library/ecp_invasive.h | 325 + .../third-party/mbedtls/library/entropy.c | 680 + .../mbedtls/library/entropy_poll.c | 231 + .../mbedtls/library/entropy_poll.h | 64 + deps/LIEF/third-party/mbedtls/library/error.c | 878 + deps/LIEF/third-party/mbedtls/library/gcm.c | 1330 + deps/LIEF/third-party/mbedtls/library/hkdf.c | 161 + .../third-party/mbedtls/library/hmac_drbg.c | 633 + deps/LIEF/third-party/mbedtls/library/lmots.c | 789 + deps/LIEF/third-party/mbedtls/library/lmots.h | 288 + deps/LIEF/third-party/mbedtls/library/lms.c | 778 + deps/LIEF/third-party/mbedtls/library/md.c | 1108 + deps/LIEF/third-party/mbedtls/library/md5.c | 426 + .../LIEF/third-party/mbedtls/library/md_psa.h | 26 + .../third-party/mbedtls/library/md_wrap.h | 46 + .../mbedtls/library/memory_buffer_alloc.c | 745 + .../third-party/mbedtls/library/mps_common.h | 181 + .../third-party/mbedtls/library/mps_error.h | 89 + .../third-party/mbedtls/library/mps_reader.c | 538 + .../third-party/mbedtls/library/mps_reader.h | 366 + .../third-party/mbedtls/library/mps_trace.c | 112 + .../third-party/mbedtls/library/mps_trace.h | 154 + .../third-party/mbedtls/library/net_sockets.c | 696 + .../third-party/mbedtls/library/nist_kw.c | 729 + deps/LIEF/third-party/mbedtls/library/oid.c | 1166 + .../third-party/mbedtls/library/padlock.c | 157 + .../third-party/mbedtls/library/padlock.h | 111 + deps/LIEF/third-party/mbedtls/library/pem.c | 554 + deps/LIEF/third-party/mbedtls/library/pk.c | 1503 ++ .../LIEF/third-party/mbedtls/library/pk_ecc.c | 255 + .../third-party/mbedtls/library/pk_internal.h | 207 + .../third-party/mbedtls/library/pk_wrap.c | 1584 ++ .../third-party/mbedtls/library/pk_wrap.h | 138 + .../LIEF/third-party/mbedtls/library/pkcs12.c | 437 + deps/LIEF/third-party/mbedtls/library/pkcs5.c | 500 + deps/LIEF/third-party/mbedtls/library/pkcs7.c | 773 + .../third-party/mbedtls/library/pkparse.c | 1392 + .../third-party/mbedtls/library/pkwrite.c | 629 + .../third-party/mbedtls/library/pkwrite.h | 121 + .../third-party/mbedtls/library/platform.c | 402 + .../mbedtls/library/platform_util.c | 263 + .../third-party/mbedtls/library/poly1305.c | 492 + .../third-party/mbedtls/library/psa_crypto.c | 9459 +++++++ .../mbedtls/library/psa_crypto_aead.c | 649 + .../mbedtls/library/psa_crypto_aead.h | 499 + .../mbedtls/library/psa_crypto_cipher.c | 721 + .../mbedtls/library/psa_crypto_cipher.h | 316 + .../mbedtls/library/psa_crypto_client.c | 22 + .../mbedtls/library/psa_crypto_core.h | 995 + .../mbedtls/library/psa_crypto_core_common.h | 52 + .../library/psa_crypto_driver_wrappers.h | 2896 ++ .../psa_crypto_driver_wrappers_no_static.c | 256 + .../psa_crypto_driver_wrappers_no_static.h | 31 + .../mbedtls/library/psa_crypto_ecp.c | 594 + .../mbedtls/library/psa_crypto_ecp.h | 267 + .../mbedtls/library/psa_crypto_ffdh.c | 321 + .../mbedtls/library/psa_crypto_ffdh.h | 131 + .../mbedtls/library/psa_crypto_hash.c | 470 + .../mbedtls/library/psa_crypto_hash.h | 211 + .../mbedtls/library/psa_crypto_invasive.h | 92 + .../mbedtls/library/psa_crypto_its.h | 131 + .../mbedtls/library/psa_crypto_mac.c | 505 + .../mbedtls/library/psa_crypto_mac.h | 264 + .../mbedtls/library/psa_crypto_pake.c | 571 + .../mbedtls/library/psa_crypto_pake.h | 159 + .../mbedtls/library/psa_crypto_random_impl.h | 126 + .../mbedtls/library/psa_crypto_rsa.c | 705 + .../mbedtls/library/psa_crypto_rsa.h | 321 + .../mbedtls/library/psa_crypto_se.c | 373 + .../mbedtls/library/psa_crypto_se.h | 192 + .../library/psa_crypto_slot_management.c | 1131 + .../library/psa_crypto_slot_management.h | 344 + .../mbedtls/library/psa_crypto_storage.c | 481 + .../mbedtls/library/psa_crypto_storage.h | 392 + .../mbedtls/library/psa_its_file.c | 254 + .../third-party/mbedtls/library/psa_util.c | 614 + .../mbedtls/library/psa_util_internal.h | 100 + .../third-party/mbedtls/library/ripemd160.c | 490 + deps/LIEF/third-party/mbedtls/library/rsa.c | 3066 +++ .../mbedtls/library/rsa_alt_helpers.c | 447 + .../mbedtls/library/rsa_alt_helpers.h | 206 + .../mbedtls/library/rsa_internal.h | 121 + deps/LIEF/third-party/mbedtls/library/sha1.c | 480 + .../LIEF/third-party/mbedtls/library/sha256.c | 980 + deps/LIEF/third-party/mbedtls/library/sha3.c | 721 + .../LIEF/third-party/mbedtls/library/sha512.c | 1112 + .../third-party/mbedtls/library/ssl_cache.c | 410 + .../mbedtls/library/ssl_ciphersuites.c | 2050 ++ .../library/ssl_ciphersuites_internal.h | 154 + .../third-party/mbedtls/library/ssl_client.c | 1019 + .../third-party/mbedtls/library/ssl_client.h | 22 + .../third-party/mbedtls/library/ssl_cookie.c | 384 + .../mbedtls/library/ssl_debug_helpers.h | 83 + .../library/ssl_debug_helpers_generated.c | 251 + .../third-party/mbedtls/library/ssl_misc.h | 3105 +++ .../third-party/mbedtls/library/ssl_msg.c | 6515 +++++ .../third-party/mbedtls/library/ssl_ticket.c | 556 + .../third-party/mbedtls/library/ssl_tls.c | 10187 +++++++ .../mbedtls/library/ssl_tls12_client.c | 3603 +++ .../mbedtls/library/ssl_tls12_server.c | 4417 +++ .../mbedtls/library/ssl_tls13_client.c | 3187 +++ .../mbedtls/library/ssl_tls13_generic.c | 1754 ++ .../mbedtls/library/ssl_tls13_invasive.h | 23 + .../mbedtls/library/ssl_tls13_keys.c | 1918 ++ .../mbedtls/library/ssl_tls13_keys.h | 668 + .../mbedtls/library/ssl_tls13_server.c | 3611 +++ .../third-party/mbedtls/library/threading.c | 195 + .../LIEF/third-party/mbedtls/library/timing.c | 154 + .../third-party/mbedtls/library/version.c | 32 + .../mbedtls/library/version_features.c | 853 + deps/LIEF/third-party/mbedtls/library/x509.c | 1776 ++ .../third-party/mbedtls/library/x509_create.c | 567 + .../third-party/mbedtls/library/x509_crl.c | 713 + .../third-party/mbedtls/library/x509_crt.c | 3303 +++ .../third-party/mbedtls/library/x509_csr.c | 639 + .../mbedtls/library/x509_internal.h | 86 + .../third-party/mbedtls/library/x509write.c | 174 + .../mbedtls/library/x509write_crt.c | 688 + .../mbedtls/library/x509write_csr.c | 336 + deps/LIEF/third-party/spdlog/LICENSE | 26 + deps/LIEF/third-party/spdlog/README.md | 529 + .../third-party/spdlog/include/spdlog/async.h | 99 + .../spdlog/include/spdlog/async_logger-inl.h | 84 + .../spdlog/include/spdlog/async_logger.h | 74 + .../spdlog/include/spdlog/cfg/argv.h | 40 + .../spdlog/include/spdlog/cfg/env.h | 36 + .../spdlog/include/spdlog/cfg/helpers-inl.h | 107 + .../spdlog/include/spdlog/cfg/helpers.h | 29 + .../spdlog/include/spdlog/common-inl.h | 68 + .../spdlog/include/spdlog/common.h | 406 + .../include/spdlog/details/backtracer-inl.h | 63 + .../include/spdlog/details/backtracer.h | 45 + .../include/spdlog/details/circular_q.h | 115 + .../include/spdlog/details/console_globals.h | 28 + .../include/spdlog/details/file_helper-inl.h | 153 + .../include/spdlog/details/file_helper.h | 61 + .../include/spdlog/details/fmt_helper.h | 141 + .../include/spdlog/details/log_msg-inl.h | 44 + .../spdlog/include/spdlog/details/log_msg.h | 40 + .../spdlog/details/log_msg_buffer-inl.h | 54 + .../include/spdlog/details/log_msg_buffer.h | 32 + .../include/spdlog/details/mpmc_blocking_q.h | 177 + .../include/spdlog/details/null_mutex.h | 35 + .../spdlog/include/spdlog/details/os-inl.h | 606 + .../spdlog/include/spdlog/details/os.h | 127 + .../spdlog/details/periodic_worker-inl.h | 26 + .../include/spdlog/details/periodic_worker.h | 58 + .../include/spdlog/details/registry-inl.h | 270 + .../spdlog/include/spdlog/details/registry.h | 131 + .../spdlog/details/synchronous_factory.h | 22 + .../spdlog/details/tcp_client-windows.h | 135 + .../include/spdlog/details/tcp_client.h | 127 + .../include/spdlog/details/thread_pool-inl.h | 126 + .../include/spdlog/details/thread_pool.h | 117 + .../spdlog/details/udp_client-windows.h | 98 + .../include/spdlog/details/udp_client.h | 81 + .../include/spdlog/details/windows_include.h | 11 + .../spdlog/include/spdlog/fmt/bin_to_hex.h | 224 + .../spdlog/include/spdlog/fmt/bundled/args.h | 220 + .../spdlog/include/spdlog/fmt/bundled/base.h | 2989 +++ .../include/spdlog/fmt/bundled/chrono.h | 2330 ++ .../spdlog/include/spdlog/fmt/bundled/color.h | 637 + .../include/spdlog/fmt/bundled/compile.h | 539 + .../spdlog/include/spdlog/fmt/bundled/core.h | 5 + .../spdlog/fmt/bundled/fmt.license.rst | 27 + .../include/spdlog/fmt/bundled/format-inl.h | 1948 ++ .../include/spdlog/fmt/bundled/format.h | 4244 +++ .../spdlog/include/spdlog/fmt/bundled/os.h | 427 + .../include/spdlog/fmt/bundled/ostream.h | 167 + .../include/spdlog/fmt/bundled/printf.h | 633 + .../include/spdlog/fmt/bundled/ranges.h | 850 + .../spdlog/include/spdlog/fmt/bundled/std.h | 728 + .../spdlog/include/spdlog/fmt/bundled/xchar.h | 369 + .../spdlog/include/spdlog/fmt/chrono.h | 23 + .../spdlog/include/spdlog/fmt/compile.h | 23 + .../spdlog/include/spdlog/fmt/fmt.h | 30 + .../spdlog/include/spdlog/fmt/ostr.h | 23 + .../spdlog/include/spdlog/fmt/ranges.h | 23 + .../spdlog/include/spdlog/fmt/std.h | 24 + .../spdlog/include/spdlog/fmt/xchar.h | 23 + .../spdlog/include/spdlog/formatter.h | 17 + .../third-party/spdlog/include/spdlog/fwd.h | 18 + .../spdlog/include/spdlog/logger-inl.h | 198 + .../spdlog/include/spdlog/logger.h | 379 + .../third-party/spdlog/include/spdlog/mdc.h | 52 + .../include/spdlog/pattern_formatter-inl.h | 1340 + .../spdlog/include/spdlog/pattern_formatter.h | 118 + .../include/spdlog/sinks/android_sink.h | 137 + .../include/spdlog/sinks/ansicolor_sink-inl.h | 142 + .../include/spdlog/sinks/ansicolor_sink.h | 116 + .../include/spdlog/sinks/base_sink-inl.h | 59 + .../spdlog/include/spdlog/sinks/base_sink.h | 51 + .../spdlog/sinks/basic_file_sink-inl.h | 48 + .../include/spdlog/sinks/basic_file_sink.h | 66 + .../include/spdlog/sinks/callback_sink.h | 56 + .../include/spdlog/sinks/daily_file_sink.h | 254 + .../spdlog/include/spdlog/sinks/dist_sink.h | 81 + .../include/spdlog/sinks/dup_filter_sink.h | 91 + .../include/spdlog/sinks/hourly_file_sink.h | 193 + .../spdlog/include/spdlog/sinks/kafka_sink.h | 119 + .../spdlog/include/spdlog/sinks/mongo_sink.h | 108 + .../spdlog/include/spdlog/sinks/msvc_sink.h | 68 + .../spdlog/include/spdlog/sinks/null_sink.h | 41 + .../include/spdlog/sinks/ostream_sink.h | 43 + .../spdlog/include/spdlog/sinks/qt_sinks.h | 304 + .../include/spdlog/sinks/ringbuffer_sink.h | 67 + .../spdlog/sinks/rotating_file_sink-inl.h | 179 + .../include/spdlog/sinks/rotating_file_sink.h | 93 + .../spdlog/include/spdlog/sinks/sink-inl.h | 22 + .../spdlog/include/spdlog/sinks/sink.h | 34 + .../spdlog/sinks/stdout_color_sinks-inl.h | 38 + .../include/spdlog/sinks/stdout_color_sinks.h | 49 + .../include/spdlog/sinks/stdout_sinks-inl.h | 127 + .../include/spdlog/sinks/stdout_sinks.h | 84 + .../spdlog/include/spdlog/sinks/syslog_sink.h | 104 + .../include/spdlog/sinks/systemd_sink.h | 121 + .../spdlog/include/spdlog/sinks/tcp_sink.h | 75 + .../spdlog/include/spdlog/sinks/udp_sink.h | 69 + .../include/spdlog/sinks/win_eventlog_sink.h | 260 + .../include/spdlog/sinks/wincolor_sink-inl.h | 172 + .../include/spdlog/sinks/wincolor_sink.h | 82 + .../spdlog/include/spdlog/spdlog-inl.h | 96 + .../spdlog/include/spdlog/spdlog.h | 357 + .../spdlog/include/spdlog/stopwatch.h | 66 + .../spdlog/include/spdlog/tweakme.h | 148 + .../spdlog/include/spdlog/version.h | 11 + deps/LIEF/third-party/spdlog/src/async.cpp | 11 + .../spdlog/src/bundled_fmtlib_format.cpp | 49 + deps/LIEF/third-party/spdlog/src/cfg.cpp | 8 + .../third-party/spdlog/src/color_sinks.cpp | 55 + .../third-party/spdlog/src/file_sinks.cpp | 20 + deps/LIEF/third-party/spdlog/src/spdlog.cpp | 28 + .../third-party/spdlog/src/stdout_sinks.cpp | 37 + deps/LIEF/third-party/tcb-span/span.hpp | 620 + deps/LIEF/third-party/utfcpp/LICENSE | 23 + deps/LIEF/third-party/utfcpp/README.md | 2131 ++ deps/LIEF/third-party/utfcpp/source/utf8.h | 46 + .../third-party/utfcpp/source/utf8/checked.h | 359 + .../third-party/utfcpp/source/utf8/core.h | 492 + .../third-party/utfcpp/source/utf8/cpp11.h | 70 + .../third-party/utfcpp/source/utf8/cpp17.h | 96 + .../third-party/utfcpp/source/utf8/cpp20.h | 124 + .../utfcpp/source/utf8/unchecked.h | 287 + 1374 files changed, 480633 insertions(+) create mode 100644 deps/LIEF/config/mbedtls/config.h create mode 100644 deps/LIEF/include/LIEF/ART.hpp create mode 100644 deps/LIEF/include/LIEF/ART/EnumToString.hpp create mode 100644 deps/LIEF/include/LIEF/ART/File.hpp create mode 100644 deps/LIEF/include/LIEF/ART/Header.hpp create mode 100644 deps/LIEF/include/LIEF/ART/Parser.hpp create mode 100644 deps/LIEF/include/LIEF/ART/enums.hpp create mode 100644 deps/LIEF/include/LIEF/ART/hash.hpp create mode 100644 deps/LIEF/include/LIEF/ART/java_structures.hpp create mode 100644 deps/LIEF/include/LIEF/ART/json.hpp create mode 100644 deps/LIEF/include/LIEF/ART/types.hpp create mode 100644 deps/LIEF/include/LIEF/ART/utils.hpp create mode 100644 deps/LIEF/include/LIEF/ASM.hpp create mode 100644 deps/LIEF/include/LIEF/Abstract.hpp create mode 100644 deps/LIEF/include/LIEF/Abstract/Binary.hpp create mode 100644 deps/LIEF/include/LIEF/Abstract/DebugInfo.hpp create mode 100644 deps/LIEF/include/LIEF/Abstract/Function.hpp create mode 100644 deps/LIEF/include/LIEF/Abstract/Header.hpp create mode 100644 deps/LIEF/include/LIEF/Abstract/Parser.hpp create mode 100644 deps/LIEF/include/LIEF/Abstract/Relocation.hpp create mode 100644 deps/LIEF/include/LIEF/Abstract/Section.hpp create mode 100644 deps/LIEF/include/LIEF/Abstract/Symbol.hpp create mode 100644 deps/LIEF/include/LIEF/Abstract/hash.hpp create mode 100644 deps/LIEF/include/LIEF/Abstract/json.hpp create mode 100644 deps/LIEF/include/LIEF/BinaryStream/ASN1Reader.hpp create mode 100644 deps/LIEF/include/LIEF/BinaryStream/BinaryStream.hpp create mode 100644 deps/LIEF/include/LIEF/BinaryStream/FileStream.hpp create mode 100644 deps/LIEF/include/LIEF/BinaryStream/MemoryStream.hpp create mode 100644 deps/LIEF/include/LIEF/BinaryStream/SpanStream.hpp create mode 100644 deps/LIEF/include/LIEF/BinaryStream/VectorStream.hpp create mode 100644 deps/LIEF/include/LIEF/COFF.hpp create mode 100644 deps/LIEF/include/LIEF/COFF/AuxiliarySymbol.hpp create mode 100644 deps/LIEF/include/LIEF/COFF/AuxiliarySymbols/AuxiliaryCLRToken.hpp create mode 100644 deps/LIEF/include/LIEF/COFF/AuxiliarySymbols/AuxiliaryFile.hpp create mode 100644 deps/LIEF/include/LIEF/COFF/AuxiliarySymbols/AuxiliaryFunctionDefinition.hpp create mode 100644 deps/LIEF/include/LIEF/COFF/AuxiliarySymbols/AuxiliarySectionDefinition.hpp create mode 100644 deps/LIEF/include/LIEF/COFF/AuxiliarySymbols/AuxiliaryWeakExternal.hpp create mode 100644 deps/LIEF/include/LIEF/COFF/AuxiliarySymbols/AuxiliarybfAndefSymbol.hpp create mode 100644 deps/LIEF/include/LIEF/COFF/BigObjHeader.hpp create mode 100644 deps/LIEF/include/LIEF/COFF/Binary.hpp create mode 100644 deps/LIEF/include/LIEF/COFF/Header.hpp create mode 100644 deps/LIEF/include/LIEF/COFF/Parser.hpp create mode 100644 deps/LIEF/include/LIEF/COFF/ParserConfig.hpp create mode 100644 deps/LIEF/include/LIEF/COFF/RegularHeader.hpp create mode 100644 deps/LIEF/include/LIEF/COFF/Relocation.hpp create mode 100644 deps/LIEF/include/LIEF/COFF/Section.hpp create mode 100644 deps/LIEF/include/LIEF/COFF/String.hpp create mode 100644 deps/LIEF/include/LIEF/COFF/Symbol.hpp create mode 100644 deps/LIEF/include/LIEF/COFF/utils.hpp create mode 100644 deps/LIEF/include/LIEF/DEX.hpp create mode 100644 deps/LIEF/include/LIEF/DEX/Class.hpp create mode 100644 deps/LIEF/include/LIEF/DEX/CodeInfo.hpp create mode 100644 deps/LIEF/include/LIEF/DEX/EnumToString.hpp create mode 100644 deps/LIEF/include/LIEF/DEX/Field.hpp create mode 100644 deps/LIEF/include/LIEF/DEX/File.hpp create mode 100644 deps/LIEF/include/LIEF/DEX/Header.hpp create mode 100644 deps/LIEF/include/LIEF/DEX/MapItem.hpp create mode 100644 deps/LIEF/include/LIEF/DEX/MapList.hpp create mode 100644 deps/LIEF/include/LIEF/DEX/Method.hpp create mode 100644 deps/LIEF/include/LIEF/DEX/Parser.hpp create mode 100644 deps/LIEF/include/LIEF/DEX/Prototype.hpp create mode 100644 deps/LIEF/include/LIEF/DEX/Type.hpp create mode 100644 deps/LIEF/include/LIEF/DEX/deopt.hpp create mode 100644 deps/LIEF/include/LIEF/DEX/enums.hpp create mode 100644 deps/LIEF/include/LIEF/DEX/hash.hpp create mode 100644 deps/LIEF/include/LIEF/DEX/instructions.hpp create mode 100644 deps/LIEF/include/LIEF/DEX/json.hpp create mode 100644 deps/LIEF/include/LIEF/DEX/types.hpp create mode 100644 deps/LIEF/include/LIEF/DEX/utils.hpp create mode 100644 deps/LIEF/include/LIEF/DWARF.hpp create mode 100644 deps/LIEF/include/LIEF/DWARF/CompilationUnit.hpp create mode 100644 deps/LIEF/include/LIEF/DWARF/DebugInfo.hpp create mode 100644 deps/LIEF/include/LIEF/DWARF/Editor.hpp create mode 100644 deps/LIEF/include/LIEF/DWARF/Function.hpp create mode 100644 deps/LIEF/include/LIEF/DWARF/Parameter.hpp create mode 100644 deps/LIEF/include/LIEF/DWARF/Scope.hpp create mode 100644 deps/LIEF/include/LIEF/DWARF/Type.hpp create mode 100644 deps/LIEF/include/LIEF/DWARF/Variable.hpp create mode 100644 deps/LIEF/include/LIEF/DWARF/editor/ArrayType.hpp create mode 100644 deps/LIEF/include/LIEF/DWARF/editor/BaseType.hpp create mode 100644 deps/LIEF/include/LIEF/DWARF/editor/CompilationUnit.hpp create mode 100644 deps/LIEF/include/LIEF/DWARF/editor/EnumType.hpp create mode 100644 deps/LIEF/include/LIEF/DWARF/editor/Function.hpp create mode 100644 deps/LIEF/include/LIEF/DWARF/editor/FunctionType.hpp create mode 100644 deps/LIEF/include/LIEF/DWARF/editor/PointerType.hpp create mode 100644 deps/LIEF/include/LIEF/DWARF/editor/StructType.hpp create mode 100644 deps/LIEF/include/LIEF/DWARF/editor/Type.hpp create mode 100644 deps/LIEF/include/LIEF/DWARF/editor/TypeDef.hpp create mode 100644 deps/LIEF/include/LIEF/DWARF/editor/Variable.hpp create mode 100644 deps/LIEF/include/LIEF/DWARF/enums.hpp create mode 100644 deps/LIEF/include/LIEF/DWARF/types.hpp create mode 100644 deps/LIEF/include/LIEF/DWARF/types/Array.hpp create mode 100644 deps/LIEF/include/LIEF/DWARF/types/Atomic.hpp create mode 100644 deps/LIEF/include/LIEF/DWARF/types/Base.hpp create mode 100644 deps/LIEF/include/LIEF/DWARF/types/ClassLike.hpp create mode 100644 deps/LIEF/include/LIEF/DWARF/types/Coarray.hpp create mode 100644 deps/LIEF/include/LIEF/DWARF/types/Const.hpp create mode 100644 deps/LIEF/include/LIEF/DWARF/types/Dynamic.hpp create mode 100644 deps/LIEF/include/LIEF/DWARF/types/Enum.hpp create mode 100644 deps/LIEF/include/LIEF/DWARF/types/File.hpp create mode 100644 deps/LIEF/include/LIEF/DWARF/types/Immutable.hpp create mode 100644 deps/LIEF/include/LIEF/DWARF/types/Interface.hpp create mode 100644 deps/LIEF/include/LIEF/DWARF/types/Pointer.hpp create mode 100644 deps/LIEF/include/LIEF/DWARF/types/PointerToMember.hpp create mode 100644 deps/LIEF/include/LIEF/DWARF/types/RValueRef.hpp create mode 100644 deps/LIEF/include/LIEF/DWARF/types/Reference.hpp create mode 100644 deps/LIEF/include/LIEF/DWARF/types/Restrict.hpp create mode 100644 deps/LIEF/include/LIEF/DWARF/types/SetTy.hpp create mode 100644 deps/LIEF/include/LIEF/DWARF/types/Shared.hpp create mode 100644 deps/LIEF/include/LIEF/DWARF/types/StringTy.hpp create mode 100644 deps/LIEF/include/LIEF/DWARF/types/Subroutine.hpp create mode 100644 deps/LIEF/include/LIEF/DWARF/types/TemplateAlias.hpp create mode 100644 deps/LIEF/include/LIEF/DWARF/types/Thrown.hpp create mode 100644 deps/LIEF/include/LIEF/DWARF/types/Typedef.hpp create mode 100644 deps/LIEF/include/LIEF/DWARF/types/Volatile.hpp create mode 100644 deps/LIEF/include/LIEF/DyldSharedCache.hpp create mode 100644 deps/LIEF/include/LIEF/DyldSharedCache/DyldSharedCache.hpp create mode 100644 deps/LIEF/include/LIEF/DyldSharedCache/Dylib.hpp create mode 100644 deps/LIEF/include/LIEF/DyldSharedCache/MappingInfo.hpp create mode 100644 deps/LIEF/include/LIEF/DyldSharedCache/SubCache.hpp create mode 100644 deps/LIEF/include/LIEF/DyldSharedCache/caching.hpp create mode 100644 deps/LIEF/include/LIEF/DyldSharedCache/utils.hpp create mode 100644 deps/LIEF/include/LIEF/DyldSharedCache/uuid.hpp create mode 100644 deps/LIEF/include/LIEF/ELF.hpp create mode 100644 deps/LIEF/include/LIEF/ELF/Binary.hpp create mode 100644 deps/LIEF/include/LIEF/ELF/Builder.hpp create mode 100644 deps/LIEF/include/LIEF/ELF/DynamicEntry.hpp create mode 100644 deps/LIEF/include/LIEF/ELF/DynamicEntryArray.hpp create mode 100644 deps/LIEF/include/LIEF/ELF/DynamicEntryFlags.hpp create mode 100644 deps/LIEF/include/LIEF/ELF/DynamicEntryLibrary.hpp create mode 100644 deps/LIEF/include/LIEF/ELF/DynamicEntryRpath.hpp create mode 100644 deps/LIEF/include/LIEF/ELF/DynamicEntryRunPath.hpp create mode 100644 deps/LIEF/include/LIEF/ELF/DynamicSharedObject.hpp create mode 100644 deps/LIEF/include/LIEF/ELF/EnumToString.hpp create mode 100644 deps/LIEF/include/LIEF/ELF/GnuHash.hpp create mode 100644 deps/LIEF/include/LIEF/ELF/Header.hpp create mode 100644 deps/LIEF/include/LIEF/ELF/Note.hpp create mode 100644 deps/LIEF/include/LIEF/ELF/NoteDetails.hpp create mode 100644 deps/LIEF/include/LIEF/ELF/NoteDetails/AndroidIdent.hpp create mode 100644 deps/LIEF/include/LIEF/ELF/NoteDetails/Core.hpp create mode 100644 deps/LIEF/include/LIEF/ELF/NoteDetails/NoteAbi.hpp create mode 100644 deps/LIEF/include/LIEF/ELF/NoteDetails/NoteGnuProperty.hpp create mode 100644 deps/LIEF/include/LIEF/ELF/NoteDetails/Properties.hpp create mode 100644 deps/LIEF/include/LIEF/ELF/NoteDetails/QNXStack.hpp create mode 100644 deps/LIEF/include/LIEF/ELF/NoteDetails/core/CoreAuxv.hpp create mode 100644 deps/LIEF/include/LIEF/ELF/NoteDetails/core/CoreFile.hpp create mode 100644 deps/LIEF/include/LIEF/ELF/NoteDetails/core/CorePrPsInfo.hpp create mode 100644 deps/LIEF/include/LIEF/ELF/NoteDetails/core/CorePrStatus.hpp create mode 100644 deps/LIEF/include/LIEF/ELF/NoteDetails/core/CoreSigInfo.hpp create mode 100644 deps/LIEF/include/LIEF/ELF/NoteDetails/properties/AArch64Feature.hpp create mode 100644 deps/LIEF/include/LIEF/ELF/NoteDetails/properties/AArch64PAuth.hpp create mode 100644 deps/LIEF/include/LIEF/ELF/NoteDetails/properties/Generic.hpp create mode 100644 deps/LIEF/include/LIEF/ELF/NoteDetails/properties/Needed.hpp create mode 100644 deps/LIEF/include/LIEF/ELF/NoteDetails/properties/NoteNoCopyOnProtected.hpp create mode 100644 deps/LIEF/include/LIEF/ELF/NoteDetails/properties/StackSize.hpp create mode 100644 deps/LIEF/include/LIEF/ELF/NoteDetails/properties/X86Feature.hpp create mode 100644 deps/LIEF/include/LIEF/ELF/NoteDetails/properties/X86ISA.hpp create mode 100644 deps/LIEF/include/LIEF/ELF/Parser.hpp create mode 100644 deps/LIEF/include/LIEF/ELF/ParserConfig.hpp create mode 100644 deps/LIEF/include/LIEF/ELF/ProcessorFlags.hpp create mode 100644 deps/LIEF/include/LIEF/ELF/Relocation.hpp create mode 100644 deps/LIEF/include/LIEF/ELF/Relocations/AArch64.def create mode 100644 deps/LIEF/include/LIEF/ELF/Relocations/ARM.def create mode 100644 deps/LIEF/include/LIEF/ELF/Relocations/BPF.def create mode 100644 deps/LIEF/include/LIEF/ELF/Relocations/Hexagon.def create mode 100644 deps/LIEF/include/LIEF/ELF/Relocations/LoongArch.def create mode 100644 deps/LIEF/include/LIEF/ELF/Relocations/Mips.def create mode 100644 deps/LIEF/include/LIEF/ELF/Relocations/PowerPC.def create mode 100644 deps/LIEF/include/LIEF/ELF/Relocations/PowerPC64.def create mode 100644 deps/LIEF/include/LIEF/ELF/Relocations/RISCV.def create mode 100644 deps/LIEF/include/LIEF/ELF/Relocations/SH4.def create mode 100644 deps/LIEF/include/LIEF/ELF/Relocations/Sparc.def create mode 100644 deps/LIEF/include/LIEF/ELF/Relocations/SystemZ.def create mode 100644 deps/LIEF/include/LIEF/ELF/Relocations/i386.def create mode 100644 deps/LIEF/include/LIEF/ELF/Relocations/x86_64.def create mode 100644 deps/LIEF/include/LIEF/ELF/Section.hpp create mode 100644 deps/LIEF/include/LIEF/ELF/Segment.hpp create mode 100644 deps/LIEF/include/LIEF/ELF/Symbol.hpp create mode 100644 deps/LIEF/include/LIEF/ELF/SymbolVersion.hpp create mode 100644 deps/LIEF/include/LIEF/ELF/SymbolVersionAux.hpp create mode 100644 deps/LIEF/include/LIEF/ELF/SymbolVersionAuxRequirement.hpp create mode 100644 deps/LIEF/include/LIEF/ELF/SymbolVersionDefinition.hpp create mode 100644 deps/LIEF/include/LIEF/ELF/SymbolVersionRequirement.hpp create mode 100644 deps/LIEF/include/LIEF/ELF/SysvHash.hpp create mode 100644 deps/LIEF/include/LIEF/ELF/enums.hpp create mode 100644 deps/LIEF/include/LIEF/ELF/enums.inc create mode 100644 deps/LIEF/include/LIEF/ELF/hash.hpp create mode 100644 deps/LIEF/include/LIEF/ELF/json.hpp create mode 100644 deps/LIEF/include/LIEF/ELF/utils.hpp create mode 100644 deps/LIEF/include/LIEF/LIEF.hpp create mode 100644 deps/LIEF/include/LIEF/MachO.hpp create mode 100644 deps/LIEF/include/LIEF/MachO/AtomInfo.hpp create mode 100644 deps/LIEF/include/LIEF/MachO/Binary.hpp create mode 100644 deps/LIEF/include/LIEF/MachO/BinaryParser.hpp create mode 100644 deps/LIEF/include/LIEF/MachO/BindingInfo.hpp create mode 100644 deps/LIEF/include/LIEF/MachO/BindingInfoIterator.hpp create mode 100644 deps/LIEF/include/LIEF/MachO/BuildToolVersion.hpp create mode 100644 deps/LIEF/include/LIEF/MachO/BuildVersion.hpp create mode 100644 deps/LIEF/include/LIEF/MachO/Builder.hpp create mode 100644 deps/LIEF/include/LIEF/MachO/ChainedBindingInfo.hpp create mode 100644 deps/LIEF/include/LIEF/MachO/ChainedPointerAnalysis.hpp create mode 100644 deps/LIEF/include/LIEF/MachO/CodeSignature.hpp create mode 100644 deps/LIEF/include/LIEF/MachO/CodeSignatureDir.hpp create mode 100644 deps/LIEF/include/LIEF/MachO/DataCodeEntry.hpp create mode 100644 deps/LIEF/include/LIEF/MachO/DataInCode.hpp create mode 100644 deps/LIEF/include/LIEF/MachO/DyldBindingInfo.hpp create mode 100644 deps/LIEF/include/LIEF/MachO/DyldChainedFixups.hpp create mode 100644 deps/LIEF/include/LIEF/MachO/DyldChainedFixupsCreator.hpp create mode 100644 deps/LIEF/include/LIEF/MachO/DyldChainedFormat.hpp create mode 100644 deps/LIEF/include/LIEF/MachO/DyldEnvironment.hpp create mode 100644 deps/LIEF/include/LIEF/MachO/DyldExportsTrie.hpp create mode 100644 deps/LIEF/include/LIEF/MachO/DyldInfo.hpp create mode 100644 deps/LIEF/include/LIEF/MachO/DylibCommand.hpp create mode 100644 deps/LIEF/include/LIEF/MachO/DylinkerCommand.hpp create mode 100644 deps/LIEF/include/LIEF/MachO/DynamicSymbolCommand.hpp create mode 100644 deps/LIEF/include/LIEF/MachO/EncryptionInfo.hpp create mode 100644 deps/LIEF/include/LIEF/MachO/EnumToString.hpp create mode 100644 deps/LIEF/include/LIEF/MachO/ExportInfo.hpp create mode 100644 deps/LIEF/include/LIEF/MachO/FatBinary.hpp create mode 100644 deps/LIEF/include/LIEF/MachO/FilesetCommand.hpp create mode 100644 deps/LIEF/include/LIEF/MachO/FunctionStarts.hpp create mode 100644 deps/LIEF/include/LIEF/MachO/FunctionVariantFixups.hpp create mode 100644 deps/LIEF/include/LIEF/MachO/FunctionVariants.hpp create mode 100644 deps/LIEF/include/LIEF/MachO/FunctionVariants/Arm64.def create mode 100644 deps/LIEF/include/LIEF/MachO/FunctionVariants/PerProcess.def create mode 100644 deps/LIEF/include/LIEF/MachO/FunctionVariants/SystemWide.def create mode 100644 deps/LIEF/include/LIEF/MachO/FunctionVariants/X86_64.def create mode 100644 deps/LIEF/include/LIEF/MachO/Header.hpp create mode 100644 deps/LIEF/include/LIEF/MachO/IndirectBindingInfo.hpp create mode 100644 deps/LIEF/include/LIEF/MachO/LinkEdit.hpp create mode 100644 deps/LIEF/include/LIEF/MachO/LinkerOptHint.hpp create mode 100644 deps/LIEF/include/LIEF/MachO/LoadCommand.hpp create mode 100644 deps/LIEF/include/LIEF/MachO/MainCommand.hpp create mode 100644 deps/LIEF/include/LIEF/MachO/NoteCommand.hpp create mode 100644 deps/LIEF/include/LIEF/MachO/Parser.hpp create mode 100644 deps/LIEF/include/LIEF/MachO/ParserConfig.hpp create mode 100644 deps/LIEF/include/LIEF/MachO/RPathCommand.hpp create mode 100644 deps/LIEF/include/LIEF/MachO/Relocation.hpp create mode 100644 deps/LIEF/include/LIEF/MachO/RelocationDyld.hpp create mode 100644 deps/LIEF/include/LIEF/MachO/RelocationFixup.hpp create mode 100644 deps/LIEF/include/LIEF/MachO/RelocationObject.hpp create mode 100644 deps/LIEF/include/LIEF/MachO/Routine.hpp create mode 100644 deps/LIEF/include/LIEF/MachO/Section.hpp create mode 100644 deps/LIEF/include/LIEF/MachO/SegmentCommand.hpp create mode 100644 deps/LIEF/include/LIEF/MachO/SegmentSplitInfo.hpp create mode 100644 deps/LIEF/include/LIEF/MachO/SourceVersion.hpp create mode 100644 deps/LIEF/include/LIEF/MachO/Stub.hpp create mode 100644 deps/LIEF/include/LIEF/MachO/SubClient.hpp create mode 100644 deps/LIEF/include/LIEF/MachO/SubFramework.hpp create mode 100644 deps/LIEF/include/LIEF/MachO/Symbol.hpp create mode 100644 deps/LIEF/include/LIEF/MachO/SymbolCommand.hpp create mode 100644 deps/LIEF/include/LIEF/MachO/ThreadCommand.hpp create mode 100644 deps/LIEF/include/LIEF/MachO/TwoLevelHints.hpp create mode 100644 deps/LIEF/include/LIEF/MachO/UUIDCommand.hpp create mode 100644 deps/LIEF/include/LIEF/MachO/UnknownCommand.hpp create mode 100644 deps/LIEF/include/LIEF/MachO/VersionMin.hpp create mode 100644 deps/LIEF/include/LIEF/MachO/enums.hpp create mode 100644 deps/LIEF/include/LIEF/MachO/enums.inc create mode 100644 deps/LIEF/include/LIEF/MachO/hash.hpp create mode 100644 deps/LIEF/include/LIEF/MachO/json.hpp create mode 100644 deps/LIEF/include/LIEF/MachO/type_traits.hpp create mode 100644 deps/LIEF/include/LIEF/MachO/utils.hpp create mode 100644 deps/LIEF/include/LIEF/OAT.hpp create mode 100644 deps/LIEF/include/LIEF/OAT/Binary.hpp create mode 100644 deps/LIEF/include/LIEF/OAT/Class.hpp create mode 100644 deps/LIEF/include/LIEF/OAT/DexFile.hpp create mode 100644 deps/LIEF/include/LIEF/OAT/EnumToString.hpp create mode 100644 deps/LIEF/include/LIEF/OAT/Header.hpp create mode 100644 deps/LIEF/include/LIEF/OAT/Method.hpp create mode 100644 deps/LIEF/include/LIEF/OAT/Parser.hpp create mode 100644 deps/LIEF/include/LIEF/OAT/enums.hpp create mode 100644 deps/LIEF/include/LIEF/OAT/hash.hpp create mode 100644 deps/LIEF/include/LIEF/OAT/json.hpp create mode 100644 deps/LIEF/include/LIEF/OAT/type_traits.hpp create mode 100644 deps/LIEF/include/LIEF/OAT/utils.hpp create mode 100644 deps/LIEF/include/LIEF/ObjC.hpp create mode 100644 deps/LIEF/include/LIEF/ObjC/Class.hpp create mode 100644 deps/LIEF/include/LIEF/ObjC/DeclOpt.hpp create mode 100644 deps/LIEF/include/LIEF/ObjC/IVar.hpp create mode 100644 deps/LIEF/include/LIEF/ObjC/Metadata.hpp create mode 100644 deps/LIEF/include/LIEF/ObjC/Method.hpp create mode 100644 deps/LIEF/include/LIEF/ObjC/Property.hpp create mode 100644 deps/LIEF/include/LIEF/ObjC/Protocol.hpp create mode 100644 deps/LIEF/include/LIEF/Object.hpp create mode 100644 deps/LIEF/include/LIEF/PDB.hpp create mode 100644 deps/LIEF/include/LIEF/PDB/BuildMetadata.hpp create mode 100644 deps/LIEF/include/LIEF/PDB/CompilationUnit.hpp create mode 100644 deps/LIEF/include/LIEF/PDB/DebugInfo.hpp create mode 100644 deps/LIEF/include/LIEF/PDB/Function.hpp create mode 100644 deps/LIEF/include/LIEF/PDB/PublicSymbol.hpp create mode 100644 deps/LIEF/include/LIEF/PDB/Type.hpp create mode 100644 deps/LIEF/include/LIEF/PDB/types.hpp create mode 100644 deps/LIEF/include/LIEF/PDB/types/Array.hpp create mode 100644 deps/LIEF/include/LIEF/PDB/types/Attribute.hpp create mode 100644 deps/LIEF/include/LIEF/PDB/types/BitField.hpp create mode 100644 deps/LIEF/include/LIEF/PDB/types/ClassLike.hpp create mode 100644 deps/LIEF/include/LIEF/PDB/types/Enum.hpp create mode 100644 deps/LIEF/include/LIEF/PDB/types/Function.hpp create mode 100644 deps/LIEF/include/LIEF/PDB/types/Method.hpp create mode 100644 deps/LIEF/include/LIEF/PDB/types/Modifier.hpp create mode 100644 deps/LIEF/include/LIEF/PDB/types/Pointer.hpp create mode 100644 deps/LIEF/include/LIEF/PDB/types/Simple.hpp create mode 100644 deps/LIEF/include/LIEF/PDB/types/Union.hpp create mode 100644 deps/LIEF/include/LIEF/PDB/utils.hpp create mode 100644 deps/LIEF/include/LIEF/PE.hpp create mode 100644 deps/LIEF/include/LIEF/PE/Binary.hpp create mode 100644 deps/LIEF/include/LIEF/PE/Builder.hpp create mode 100644 deps/LIEF/include/LIEF/PE/CodeIntegrity.hpp create mode 100644 deps/LIEF/include/LIEF/PE/CodePage.hpp create mode 100644 deps/LIEF/include/LIEF/PE/DataDirectory.hpp create mode 100644 deps/LIEF/include/LIEF/PE/Debug.hpp create mode 100644 deps/LIEF/include/LIEF/PE/DelayImport.hpp create mode 100644 deps/LIEF/include/LIEF/PE/DelayImportEntry.hpp create mode 100644 deps/LIEF/include/LIEF/PE/DosHeader.hpp create mode 100644 deps/LIEF/include/LIEF/PE/EnumToString.hpp create mode 100644 deps/LIEF/include/LIEF/PE/ExceptionInfo.hpp create mode 100644 deps/LIEF/include/LIEF/PE/Export.hpp create mode 100644 deps/LIEF/include/LIEF/PE/ExportEntry.hpp create mode 100644 deps/LIEF/include/LIEF/PE/Factory.hpp create mode 100644 deps/LIEF/include/LIEF/PE/Header.hpp create mode 100644 deps/LIEF/include/LIEF/PE/Import.hpp create mode 100644 deps/LIEF/include/LIEF/PE/ImportEntry.hpp create mode 100644 deps/LIEF/include/LIEF/PE/LoadConfigurations.hpp create mode 100644 deps/LIEF/include/LIEF/PE/LoadConfigurations/CHPEMetadata.hpp create mode 100644 deps/LIEF/include/LIEF/PE/LoadConfigurations/CHPEMetadata/Metadata.hpp create mode 100644 deps/LIEF/include/LIEF/PE/LoadConfigurations/CHPEMetadata/MetadataARM64.hpp create mode 100644 deps/LIEF/include/LIEF/PE/LoadConfigurations/CHPEMetadata/MetadataX86.hpp create mode 100644 deps/LIEF/include/LIEF/PE/LoadConfigurations/DynamicRelocation.hpp create mode 100644 deps/LIEF/include/LIEF/PE/LoadConfigurations/DynamicRelocation/DynamicFixup.hpp create mode 100644 deps/LIEF/include/LIEF/PE/LoadConfigurations/DynamicRelocation/DynamicFixupARM64Kernel.hpp create mode 100644 deps/LIEF/include/LIEF/PE/LoadConfigurations/DynamicRelocation/DynamicFixupARM64X.hpp create mode 100644 deps/LIEF/include/LIEF/PE/LoadConfigurations/DynamicRelocation/DynamicFixupControlTransfer.hpp create mode 100644 deps/LIEF/include/LIEF/PE/LoadConfigurations/DynamicRelocation/DynamicFixupGeneric.hpp create mode 100644 deps/LIEF/include/LIEF/PE/LoadConfigurations/DynamicRelocation/DynamicFixupUnknown.hpp create mode 100644 deps/LIEF/include/LIEF/PE/LoadConfigurations/DynamicRelocation/DynamicRelocationBase.hpp create mode 100644 deps/LIEF/include/LIEF/PE/LoadConfigurations/DynamicRelocation/DynamicRelocationV1.hpp create mode 100644 deps/LIEF/include/LIEF/PE/LoadConfigurations/DynamicRelocation/DynamicRelocationV2.hpp create mode 100644 deps/LIEF/include/LIEF/PE/LoadConfigurations/DynamicRelocation/FunctionOverride.hpp create mode 100644 deps/LIEF/include/LIEF/PE/LoadConfigurations/DynamicRelocation/FunctionOverrideInfo.hpp create mode 100644 deps/LIEF/include/LIEF/PE/LoadConfigurations/EnclaveConfiguration.hpp create mode 100644 deps/LIEF/include/LIEF/PE/LoadConfigurations/EnclaveImport.hpp create mode 100644 deps/LIEF/include/LIEF/PE/LoadConfigurations/LoadConfiguration.hpp create mode 100644 deps/LIEF/include/LIEF/PE/LoadConfigurations/VolatileMetadata.hpp create mode 100644 deps/LIEF/include/LIEF/PE/OptionalHeader.hpp create mode 100644 deps/LIEF/include/LIEF/PE/Parser.hpp create mode 100644 deps/LIEF/include/LIEF/PE/ParserConfig.hpp create mode 100644 deps/LIEF/include/LIEF/PE/Relocation.hpp create mode 100644 deps/LIEF/include/LIEF/PE/RelocationEntry.hpp create mode 100644 deps/LIEF/include/LIEF/PE/ResourceData.hpp create mode 100644 deps/LIEF/include/LIEF/PE/ResourceDirectory.hpp create mode 100644 deps/LIEF/include/LIEF/PE/ResourceNode.hpp create mode 100644 deps/LIEF/include/LIEF/PE/ResourcesManager.hpp create mode 100644 deps/LIEF/include/LIEF/PE/RichEntry.hpp create mode 100644 deps/LIEF/include/LIEF/PE/RichHeader.hpp create mode 100644 deps/LIEF/include/LIEF/PE/Section.hpp create mode 100644 deps/LIEF/include/LIEF/PE/TLS.hpp create mode 100644 deps/LIEF/include/LIEF/PE/debug/CodeView.hpp create mode 100644 deps/LIEF/include/LIEF/PE/debug/CodeViewPDB.hpp create mode 100644 deps/LIEF/include/LIEF/PE/debug/Debug.hpp create mode 100644 deps/LIEF/include/LIEF/PE/debug/ExDllCharacteristics.hpp create mode 100644 deps/LIEF/include/LIEF/PE/debug/FPO.hpp create mode 100644 deps/LIEF/include/LIEF/PE/debug/PDBChecksum.hpp create mode 100644 deps/LIEF/include/LIEF/PE/debug/Pogo.hpp create mode 100644 deps/LIEF/include/LIEF/PE/debug/PogoEntry.hpp create mode 100644 deps/LIEF/include/LIEF/PE/debug/Repro.hpp create mode 100644 deps/LIEF/include/LIEF/PE/debug/VCFeature.hpp create mode 100644 deps/LIEF/include/LIEF/PE/enums.hpp create mode 100644 deps/LIEF/include/LIEF/PE/enums.inc create mode 100644 deps/LIEF/include/LIEF/PE/exceptions_info/AArch64/PackedFunction.hpp create mode 100644 deps/LIEF/include/LIEF/PE/exceptions_info/AArch64/UnpackedFunction.hpp create mode 100644 deps/LIEF/include/LIEF/PE/exceptions_info/RuntimeFunctionAArch64.hpp create mode 100644 deps/LIEF/include/LIEF/PE/exceptions_info/RuntimeFunctionX64.hpp create mode 100644 deps/LIEF/include/LIEF/PE/exceptions_info/UnwindCodeAArch64.hpp create mode 100644 deps/LIEF/include/LIEF/PE/exceptions_info/UnwindCodeX64.hpp create mode 100644 deps/LIEF/include/LIEF/PE/exceptions_info/internal_arm64.hpp create mode 100644 deps/LIEF/include/LIEF/PE/exceptions_info/internal_x64.hpp create mode 100644 deps/LIEF/include/LIEF/PE/hash.hpp create mode 100644 deps/LIEF/include/LIEF/PE/json.hpp create mode 100644 deps/LIEF/include/LIEF/PE/resources/AcceleratorCodes.hpp create mode 100644 deps/LIEF/include/LIEF/PE/resources/ResourceAccelerator.hpp create mode 100644 deps/LIEF/include/LIEF/PE/resources/ResourceDialog.hpp create mode 100644 deps/LIEF/include/LIEF/PE/resources/ResourceDialogExtended.hpp create mode 100644 deps/LIEF/include/LIEF/PE/resources/ResourceDialogRegular.hpp create mode 100644 deps/LIEF/include/LIEF/PE/resources/ResourceIcon.hpp create mode 100644 deps/LIEF/include/LIEF/PE/resources/ResourceStringFileInfo.hpp create mode 100644 deps/LIEF/include/LIEF/PE/resources/ResourceStringTable.hpp create mode 100644 deps/LIEF/include/LIEF/PE/resources/ResourceVar.hpp create mode 100644 deps/LIEF/include/LIEF/PE/resources/ResourceVarFileInfo.hpp create mode 100644 deps/LIEF/include/LIEF/PE/resources/ResourceVersion.hpp create mode 100644 deps/LIEF/include/LIEF/PE/resources/langs.hpp create mode 100644 deps/LIEF/include/LIEF/PE/signature/Attribute.hpp create mode 100644 deps/LIEF/include/LIEF/PE/signature/ContentInfo.hpp create mode 100644 deps/LIEF/include/LIEF/PE/signature/GenericContent.hpp create mode 100644 deps/LIEF/include/LIEF/PE/signature/OIDToString.hpp create mode 100644 deps/LIEF/include/LIEF/PE/signature/PKCS9TSTInfo.hpp create mode 100644 deps/LIEF/include/LIEF/PE/signature/RsaInfo.hpp create mode 100644 deps/LIEF/include/LIEF/PE/signature/Signature.hpp create mode 100644 deps/LIEF/include/LIEF/PE/signature/SignatureParser.hpp create mode 100644 deps/LIEF/include/LIEF/PE/signature/SignerInfo.hpp create mode 100644 deps/LIEF/include/LIEF/PE/signature/SpcIndirectData.hpp create mode 100644 deps/LIEF/include/LIEF/PE/signature/attributes.hpp create mode 100644 deps/LIEF/include/LIEF/PE/signature/attributes/ContentType.hpp create mode 100644 deps/LIEF/include/LIEF/PE/signature/attributes/GenericType.hpp create mode 100644 deps/LIEF/include/LIEF/PE/signature/attributes/MsCounterSign.hpp create mode 100644 deps/LIEF/include/LIEF/PE/signature/attributes/MsManifestBinaryID.hpp create mode 100644 deps/LIEF/include/LIEF/PE/signature/attributes/MsSpcNestedSignature.hpp create mode 100644 deps/LIEF/include/LIEF/PE/signature/attributes/MsSpcStatementType.hpp create mode 100644 deps/LIEF/include/LIEF/PE/signature/attributes/PKCS9AtSequenceNumber.hpp create mode 100644 deps/LIEF/include/LIEF/PE/signature/attributes/PKCS9CounterSignature.hpp create mode 100644 deps/LIEF/include/LIEF/PE/signature/attributes/PKCS9MessageDigest.hpp create mode 100644 deps/LIEF/include/LIEF/PE/signature/attributes/PKCS9SigningTime.hpp create mode 100644 deps/LIEF/include/LIEF/PE/signature/attributes/SigningCertificateV2.hpp create mode 100644 deps/LIEF/include/LIEF/PE/signature/attributes/SpcRelaxedPeMarkerCheck.hpp create mode 100644 deps/LIEF/include/LIEF/PE/signature/attributes/SpcSpOpusInfo.hpp create mode 100644 deps/LIEF/include/LIEF/PE/signature/types.hpp create mode 100644 deps/LIEF/include/LIEF/PE/signature/x509.hpp create mode 100644 deps/LIEF/include/LIEF/PE/utils.hpp create mode 100644 deps/LIEF/include/LIEF/VDEX.hpp create mode 100644 deps/LIEF/include/LIEF/VDEX/File.hpp create mode 100644 deps/LIEF/include/LIEF/VDEX/Header.hpp create mode 100644 deps/LIEF/include/LIEF/VDEX/Parser.hpp create mode 100644 deps/LIEF/include/LIEF/VDEX/hash.hpp create mode 100644 deps/LIEF/include/LIEF/VDEX/json.hpp create mode 100644 deps/LIEF/include/LIEF/VDEX/type_traits.hpp create mode 100644 deps/LIEF/include/LIEF/VDEX/utils.hpp create mode 100644 deps/LIEF/include/LIEF/Visitor.hpp create mode 100644 deps/LIEF/include/LIEF/asm/AssemblerConfig.hpp create mode 100644 deps/LIEF/include/LIEF/asm/Engine.hpp create mode 100644 deps/LIEF/include/LIEF/asm/Instruction.hpp create mode 100644 deps/LIEF/include/LIEF/asm/aarch64.hpp create mode 100644 deps/LIEF/include/LIEF/asm/aarch64/Instruction.hpp create mode 100644 deps/LIEF/include/LIEF/asm/aarch64/Operand.hpp create mode 100644 deps/LIEF/include/LIEF/asm/aarch64/opcodes.hpp create mode 100644 deps/LIEF/include/LIEF/asm/aarch64/operands.hpp create mode 100644 deps/LIEF/include/LIEF/asm/aarch64/operands/Immediate.hpp create mode 100644 deps/LIEF/include/LIEF/asm/aarch64/operands/Memory.hpp create mode 100644 deps/LIEF/include/LIEF/asm/aarch64/operands/PCRelative.hpp create mode 100644 deps/LIEF/include/LIEF/asm/aarch64/operands/Register.hpp create mode 100644 deps/LIEF/include/LIEF/asm/aarch64/registers.hpp create mode 100644 deps/LIEF/include/LIEF/asm/arm.hpp create mode 100644 deps/LIEF/include/LIEF/asm/arm/Instruction.hpp create mode 100644 deps/LIEF/include/LIEF/asm/arm/opcodes.hpp create mode 100644 deps/LIEF/include/LIEF/asm/arm/registers.hpp create mode 100644 deps/LIEF/include/LIEF/asm/ebpf.hpp create mode 100644 deps/LIEF/include/LIEF/asm/ebpf/Instruction.hpp create mode 100644 deps/LIEF/include/LIEF/asm/ebpf/opcodes.hpp create mode 100644 deps/LIEF/include/LIEF/asm/ebpf/registers.hpp create mode 100644 deps/LIEF/include/LIEF/asm/mips.hpp create mode 100644 deps/LIEF/include/LIEF/asm/mips/Instruction.hpp create mode 100644 deps/LIEF/include/LIEF/asm/mips/opcodes.hpp create mode 100644 deps/LIEF/include/LIEF/asm/mips/registers.hpp create mode 100644 deps/LIEF/include/LIEF/asm/powerpc.hpp create mode 100644 deps/LIEF/include/LIEF/asm/powerpc/Instruction.hpp create mode 100644 deps/LIEF/include/LIEF/asm/powerpc/opcodes.hpp create mode 100644 deps/LIEF/include/LIEF/asm/powerpc/registers.hpp create mode 100644 deps/LIEF/include/LIEF/asm/riscv.hpp create mode 100644 deps/LIEF/include/LIEF/asm/riscv/Instruction.hpp create mode 100644 deps/LIEF/include/LIEF/asm/riscv/opcodes.hpp create mode 100644 deps/LIEF/include/LIEF/asm/riscv/registers.hpp create mode 100644 deps/LIEF/include/LIEF/asm/x86.hpp create mode 100644 deps/LIEF/include/LIEF/asm/x86/Instruction.hpp create mode 100644 deps/LIEF/include/LIEF/asm/x86/Operand.hpp create mode 100644 deps/LIEF/include/LIEF/asm/x86/opcodes.hpp create mode 100644 deps/LIEF/include/LIEF/asm/x86/operands.hpp create mode 100644 deps/LIEF/include/LIEF/asm/x86/operands/Immediate.hpp create mode 100644 deps/LIEF/include/LIEF/asm/x86/operands/Memory.hpp create mode 100644 deps/LIEF/include/LIEF/asm/x86/operands/PCRelative.hpp create mode 100644 deps/LIEF/include/LIEF/asm/x86/operands/Register.hpp create mode 100644 deps/LIEF/include/LIEF/asm/x86/registers.hpp create mode 100644 deps/LIEF/include/LIEF/canbe_unique.hpp create mode 100644 deps/LIEF/include/LIEF/compiler_attributes.hpp create mode 100644 deps/LIEF/include/LIEF/config.h create mode 100644 deps/LIEF/include/LIEF/config.h.in create mode 100644 deps/LIEF/include/LIEF/debug_loc.hpp create mode 100644 deps/LIEF/include/LIEF/endianness_support.hpp create mode 100644 deps/LIEF/include/LIEF/enums.hpp create mode 100644 deps/LIEF/include/LIEF/errors.hpp create mode 100644 deps/LIEF/include/LIEF/hash.hpp create mode 100644 deps/LIEF/include/LIEF/iostream.hpp create mode 100644 deps/LIEF/include/LIEF/iterators.hpp create mode 100644 deps/LIEF/include/LIEF/json.hpp create mode 100644 deps/LIEF/include/LIEF/logging.hpp create mode 100644 deps/LIEF/include/LIEF/optional.hpp create mode 100644 deps/LIEF/include/LIEF/platforms.hpp create mode 100644 deps/LIEF/include/LIEF/platforms/android.hpp create mode 100644 deps/LIEF/include/LIEF/platforms/android/version.hpp create mode 100644 deps/LIEF/include/LIEF/range.hpp create mode 100644 deps/LIEF/include/LIEF/span.hpp create mode 100644 deps/LIEF/include/LIEF/third-party/expected.hpp create mode 100644 deps/LIEF/include/LIEF/third-party/internal/expected.hpp create mode 100644 deps/LIEF/include/LIEF/third-party/internal/span.hpp create mode 100644 deps/LIEF/include/LIEF/third-party/internal/utfcpp/utf8/checked.h create mode 100644 deps/LIEF/include/LIEF/third-party/internal/utfcpp/utf8/core.h create mode 100644 deps/LIEF/include/LIEF/third-party/internal/utfcpp/utf8/cpp11.h create mode 100644 deps/LIEF/include/LIEF/third-party/internal/utfcpp/utf8/cpp17.h create mode 100644 deps/LIEF/include/LIEF/third-party/internal/utfcpp/utf8/cpp20.h create mode 100644 deps/LIEF/include/LIEF/third-party/internal/utfcpp/utf8/unchecked.h create mode 100644 deps/LIEF/include/LIEF/third-party/span.hpp create mode 100644 deps/LIEF/include/LIEF/to_json.hpp create mode 100644 deps/LIEF/include/LIEF/types.hpp create mode 100644 deps/LIEF/include/LIEF/utils.hpp create mode 100644 deps/LIEF/include/LIEF/version.h create mode 100644 deps/LIEF/include/LIEF/version.h.in create mode 100644 deps/LIEF/include/LIEF/visibility.h create mode 100644 deps/LIEF/include/LIEF/visitor_macros.hpp create mode 100644 deps/LIEF/src/ART/CMakeLists.txt create mode 100644 deps/LIEF/src/ART/EnumToString.cpp create mode 100644 deps/LIEF/src/ART/File.cpp create mode 100644 deps/LIEF/src/ART/Header.cpp create mode 100644 deps/LIEF/src/ART/Header.tcc create mode 100644 deps/LIEF/src/ART/Parser.cpp create mode 100644 deps/LIEF/src/ART/Parser.tcc create mode 100644 deps/LIEF/src/ART/Structures.cpp create mode 100644 deps/LIEF/src/ART/Structures.hpp create mode 100644 deps/LIEF/src/ART/hash.cpp create mode 100644 deps/LIEF/src/ART/json.cpp create mode 100644 deps/LIEF/src/ART/json_api.cpp create mode 100644 deps/LIEF/src/ART/json_internal.hpp create mode 100644 deps/LIEF/src/ART/utils.cpp create mode 100644 deps/LIEF/src/Abstract/Binary.cpp create mode 100644 deps/LIEF/src/Abstract/CMakeLists.txt create mode 100644 deps/LIEF/src/Abstract/Function.cpp create mode 100644 deps/LIEF/src/Abstract/Header.cpp create mode 100644 deps/LIEF/src/Abstract/Parser.cpp create mode 100644 deps/LIEF/src/Abstract/Relocation.cpp create mode 100644 deps/LIEF/src/Abstract/Section.cpp create mode 100644 deps/LIEF/src/Abstract/Section.tcc create mode 100644 deps/LIEF/src/Abstract/Symbol.cpp create mode 100644 deps/LIEF/src/Abstract/debug_info.cpp create mode 100644 deps/LIEF/src/Abstract/hash.cpp create mode 100644 deps/LIEF/src/Abstract/json.cpp create mode 100644 deps/LIEF/src/Abstract/json_api.cpp create mode 100644 deps/LIEF/src/Abstract/json_internal.hpp create mode 100644 deps/LIEF/src/BinaryStream/ASN1Reader.cpp create mode 100644 deps/LIEF/src/BinaryStream/BinaryStream.cpp create mode 100644 deps/LIEF/src/BinaryStream/CMakeLists.txt create mode 100644 deps/LIEF/src/BinaryStream/FileStream.cpp create mode 100644 deps/LIEF/src/BinaryStream/MemoryStream.cpp create mode 100644 deps/LIEF/src/BinaryStream/SpanStream.cpp create mode 100644 deps/LIEF/src/BinaryStream/VectorStream.cpp create mode 100644 deps/LIEF/src/CMakeLists.txt create mode 100644 deps/LIEF/src/COFF/AuxiliarySymbol.cpp create mode 100644 deps/LIEF/src/COFF/AuxiliarySymbols/AuxiliaryCLRToken.cpp create mode 100644 deps/LIEF/src/COFF/AuxiliarySymbols/AuxiliaryFile.cpp create mode 100644 deps/LIEF/src/COFF/AuxiliarySymbols/AuxiliaryFunctionDefinition.cpp create mode 100644 deps/LIEF/src/COFF/AuxiliarySymbols/AuxiliarySectionDefinition.cpp create mode 100644 deps/LIEF/src/COFF/AuxiliarySymbols/AuxiliaryWeakExternal.cpp create mode 100644 deps/LIEF/src/COFF/AuxiliarySymbols/AuxiliarybfAndefSymbol.cpp create mode 100644 deps/LIEF/src/COFF/AuxiliarySymbols/CMakeLists.txt create mode 100644 deps/LIEF/src/COFF/BigObjHeader.cpp create mode 100644 deps/LIEF/src/COFF/Binary.cpp create mode 100644 deps/LIEF/src/COFF/CMakeLists.txt create mode 100644 deps/LIEF/src/COFF/Header.cpp create mode 100644 deps/LIEF/src/COFF/Parser.cpp create mode 100644 deps/LIEF/src/COFF/RegularHeader.cpp create mode 100644 deps/LIEF/src/COFF/Relocation.cpp create mode 100644 deps/LIEF/src/COFF/Section.cpp create mode 100644 deps/LIEF/src/COFF/Symbol.cpp create mode 100644 deps/LIEF/src/COFF/structures.hpp create mode 100644 deps/LIEF/src/COFF/utils.cpp create mode 100644 deps/LIEF/src/DEX/CMakeLists.txt create mode 100644 deps/LIEF/src/DEX/Class.cpp create mode 100644 deps/LIEF/src/DEX/CodeInfo.cpp create mode 100644 deps/LIEF/src/DEX/EnumToString.cpp create mode 100644 deps/LIEF/src/DEX/Field.cpp create mode 100644 deps/LIEF/src/DEX/File.cpp create mode 100644 deps/LIEF/src/DEX/Header.cpp create mode 100644 deps/LIEF/src/DEX/Header.tcc create mode 100644 deps/LIEF/src/DEX/MapItem.cpp create mode 100644 deps/LIEF/src/DEX/MapList.cpp create mode 100644 deps/LIEF/src/DEX/Method.cpp create mode 100644 deps/LIEF/src/DEX/Parser.cpp create mode 100644 deps/LIEF/src/DEX/Parser.tcc create mode 100644 deps/LIEF/src/DEX/Prototype.cpp create mode 100644 deps/LIEF/src/DEX/Structures.hpp create mode 100644 deps/LIEF/src/DEX/Type.cpp create mode 100644 deps/LIEF/src/DEX/hash.cpp create mode 100644 deps/LIEF/src/DEX/instructions.cpp create mode 100644 deps/LIEF/src/DEX/json.cpp create mode 100644 deps/LIEF/src/DEX/json_api.cpp create mode 100644 deps/LIEF/src/DEX/json_internal.hpp create mode 100644 deps/LIEF/src/DEX/utils.cpp create mode 100644 deps/LIEF/src/DWARF/CMakeLists.txt create mode 100644 deps/LIEF/src/DWARF/dwarf.cpp create mode 100644 deps/LIEF/src/ELF/Binary.cpp create mode 100644 deps/LIEF/src/ELF/Binary.tcc create mode 100644 deps/LIEF/src/ELF/Builder.cpp create mode 100644 deps/LIEF/src/ELF/Builder.tcc create mode 100644 deps/LIEF/src/ELF/CMakeLists.txt create mode 100644 deps/LIEF/src/ELF/DataHandler/CMakeLists.txt create mode 100644 deps/LIEF/src/ELF/DataHandler/Handler.cpp create mode 100644 deps/LIEF/src/ELF/DataHandler/Handler.hpp create mode 100644 deps/LIEF/src/ELF/DataHandler/Node.cpp create mode 100644 deps/LIEF/src/ELF/DataHandler/Node.hpp create mode 100644 deps/LIEF/src/ELF/DynamicEntry.cpp create mode 100644 deps/LIEF/src/ELF/DynamicEntryArray.cpp create mode 100644 deps/LIEF/src/ELF/DynamicEntryFlags.cpp create mode 100644 deps/LIEF/src/ELF/DynamicEntryLibrary.cpp create mode 100644 deps/LIEF/src/ELF/DynamicEntryRpath.cpp create mode 100644 deps/LIEF/src/ELF/DynamicEntryRunPath.cpp create mode 100644 deps/LIEF/src/ELF/DynamicSharedObject.cpp create mode 100644 deps/LIEF/src/ELF/EnumToString.cpp create mode 100644 deps/LIEF/src/ELF/ExeLayout.hpp create mode 100644 deps/LIEF/src/ELF/GnuHash.cpp create mode 100644 deps/LIEF/src/ELF/Header.cpp create mode 100644 deps/LIEF/src/ELF/Layout.cpp create mode 100644 deps/LIEF/src/ELF/Layout.hpp create mode 100644 deps/LIEF/src/ELF/Note.cpp create mode 100644 deps/LIEF/src/ELF/NoteDetails/AndroidIdent.cpp create mode 100644 deps/LIEF/src/ELF/NoteDetails/CMakeLists.txt create mode 100644 deps/LIEF/src/ELF/NoteDetails/NoteAbi.cpp create mode 100644 deps/LIEF/src/ELF/NoteDetails/NoteGnuProperty.cpp create mode 100644 deps/LIEF/src/ELF/NoteDetails/QNXStack.cpp create mode 100644 deps/LIEF/src/ELF/NoteDetails/core/CMakeLists.txt create mode 100644 deps/LIEF/src/ELF/NoteDetails/core/CoreAuxv.cpp create mode 100644 deps/LIEF/src/ELF/NoteDetails/core/CoreFile.cpp create mode 100644 deps/LIEF/src/ELF/NoteDetails/core/CorePrPsInfo.cpp create mode 100644 deps/LIEF/src/ELF/NoteDetails/core/CorePrStatus.cpp create mode 100644 deps/LIEF/src/ELF/NoteDetails/core/CoreSigInfo.cpp create mode 100644 deps/LIEF/src/ELF/NoteDetails/properties/AArch64Feature.cpp create mode 100644 deps/LIEF/src/ELF/NoteDetails/properties/AArch64PAuth.cpp create mode 100644 deps/LIEF/src/ELF/NoteDetails/properties/CMakeLists.txt create mode 100644 deps/LIEF/src/ELF/NoteDetails/properties/StackSize.cpp create mode 100644 deps/LIEF/src/ELF/NoteDetails/properties/X86Feature.cpp create mode 100644 deps/LIEF/src/ELF/NoteDetails/properties/X86ISA.cpp create mode 100644 deps/LIEF/src/ELF/NoteDetails/properties/common.hpp create mode 100644 deps/LIEF/src/ELF/ObjectFileLayout.hpp create mode 100644 deps/LIEF/src/ELF/Parser.cpp create mode 100644 deps/LIEF/src/ELF/Parser.tcc create mode 100644 deps/LIEF/src/ELF/ProcessorFlags.cpp create mode 100644 deps/LIEF/src/ELF/Relocation.cpp create mode 100644 deps/LIEF/src/ELF/RelocationSizes.cpp create mode 100644 deps/LIEF/src/ELF/RelocationStrings.cpp create mode 100644 deps/LIEF/src/ELF/Section.cpp create mode 100644 deps/LIEF/src/ELF/Segment.cpp create mode 100644 deps/LIEF/src/ELF/SizingInfo.hpp create mode 100644 deps/LIEF/src/ELF/Structures.hpp create mode 100644 deps/LIEF/src/ELF/Symbol.cpp create mode 100644 deps/LIEF/src/ELF/SymbolVersion.cpp create mode 100644 deps/LIEF/src/ELF/SymbolVersionAux.cpp create mode 100644 deps/LIEF/src/ELF/SymbolVersionAuxRequirement.cpp create mode 100644 deps/LIEF/src/ELF/SymbolVersionDefinition.cpp create mode 100644 deps/LIEF/src/ELF/SymbolVersionRequirement.cpp create mode 100644 deps/LIEF/src/ELF/SysvHash.cpp create mode 100644 deps/LIEF/src/ELF/endianness_support.cpp create mode 100644 deps/LIEF/src/ELF/hash.cpp create mode 100644 deps/LIEF/src/ELF/json.cpp create mode 100644 deps/LIEF/src/ELF/json_api.cpp create mode 100644 deps/LIEF/src/ELF/json_internal.hpp create mode 100644 deps/LIEF/src/ELF/structures.inc create mode 100644 deps/LIEF/src/ELF/utils.cpp create mode 100644 deps/LIEF/src/MachO/AtomInfo.cpp create mode 100644 deps/LIEF/src/MachO/Binary.cpp create mode 100644 deps/LIEF/src/MachO/Binary.tcc create mode 100644 deps/LIEF/src/MachO/BinaryParser.cpp create mode 100644 deps/LIEF/src/MachO/BinaryParser.tcc create mode 100644 deps/LIEF/src/MachO/BindingInfo.cpp create mode 100644 deps/LIEF/src/MachO/BindingInfoIterator.cpp create mode 100644 deps/LIEF/src/MachO/BuildToolVersion.cpp create mode 100644 deps/LIEF/src/MachO/BuildVersion.cpp create mode 100644 deps/LIEF/src/MachO/Builder.cpp create mode 100644 deps/LIEF/src/MachO/Builder.tcc create mode 100644 deps/LIEF/src/MachO/CMakeLists.txt create mode 100644 deps/LIEF/src/MachO/ChainedBindingInfo.cpp create mode 100644 deps/LIEF/src/MachO/ChainedBindingInfoList.cpp create mode 100644 deps/LIEF/src/MachO/ChainedBindingInfoList.hpp create mode 100644 deps/LIEF/src/MachO/ChainedFixup.cpp create mode 100644 deps/LIEF/src/MachO/ChainedFixup.hpp create mode 100644 deps/LIEF/src/MachO/ChainedPointerAnalysis.cpp create mode 100644 deps/LIEF/src/MachO/CodeSignature.cpp create mode 100644 deps/LIEF/src/MachO/CodeSignatureDir.cpp create mode 100644 deps/LIEF/src/MachO/DataCodeEntry.cpp create mode 100644 deps/LIEF/src/MachO/DataInCode.cpp create mode 100644 deps/LIEF/src/MachO/DyldBindingInfo.cpp create mode 100644 deps/LIEF/src/MachO/DyldChainedFixups.cpp create mode 100644 deps/LIEF/src/MachO/DyldChainedFixupsCreator.cpp create mode 100644 deps/LIEF/src/MachO/DyldChainedFormat.cpp create mode 100644 deps/LIEF/src/MachO/DyldEnvironment.cpp create mode 100644 deps/LIEF/src/MachO/DyldExportsTrie.cpp create mode 100644 deps/LIEF/src/MachO/DyldInfo.cpp create mode 100644 deps/LIEF/src/MachO/DylibCommand.cpp create mode 100644 deps/LIEF/src/MachO/DylinkerCommand.cpp create mode 100644 deps/LIEF/src/MachO/DynamicSymbolCommand.cpp create mode 100644 deps/LIEF/src/MachO/EncryptionInfo.cpp create mode 100644 deps/LIEF/src/MachO/EnumToString.cpp create mode 100644 deps/LIEF/src/MachO/ExportInfo.cpp create mode 100644 deps/LIEF/src/MachO/FatBinary.cpp create mode 100644 deps/LIEF/src/MachO/FilesetCommand.cpp create mode 100644 deps/LIEF/src/MachO/FunctionStarts.cpp create mode 100644 deps/LIEF/src/MachO/FunctionVariantFixups.cpp create mode 100644 deps/LIEF/src/MachO/FunctionVariants.cpp create mode 100644 deps/LIEF/src/MachO/Header.cpp create mode 100644 deps/LIEF/src/MachO/IndirectBindingInfo.cpp create mode 100644 deps/LIEF/src/MachO/LinkEdit.cpp create mode 100644 deps/LIEF/src/MachO/LinkerOptHint.cpp create mode 100644 deps/LIEF/src/MachO/LoadCommand.cpp create mode 100644 deps/LIEF/src/MachO/MainCommand.cpp create mode 100644 deps/LIEF/src/MachO/NoteCommand.cpp create mode 100644 deps/LIEF/src/MachO/Parser.cpp create mode 100644 deps/LIEF/src/MachO/ParserConfig.cpp create mode 100644 deps/LIEF/src/MachO/RPathCommand.cpp create mode 100644 deps/LIEF/src/MachO/Relocation.cpp create mode 100644 deps/LIEF/src/MachO/RelocationDyld.cpp create mode 100644 deps/LIEF/src/MachO/RelocationFixup.cpp create mode 100644 deps/LIEF/src/MachO/RelocationObject.cpp create mode 100644 deps/LIEF/src/MachO/Routine.cpp create mode 100644 deps/LIEF/src/MachO/Section.cpp create mode 100644 deps/LIEF/src/MachO/SegmentCommand.cpp create mode 100644 deps/LIEF/src/MachO/SegmentSplitInfo.cpp create mode 100644 deps/LIEF/src/MachO/SourceVersion.cpp create mode 100644 deps/LIEF/src/MachO/Structures.hpp create mode 100644 deps/LIEF/src/MachO/Stub.cpp create mode 100644 deps/LIEF/src/MachO/SubClient.cpp create mode 100644 deps/LIEF/src/MachO/SubFramework.cpp create mode 100644 deps/LIEF/src/MachO/Symbol.cpp create mode 100644 deps/LIEF/src/MachO/SymbolCommand.cpp create mode 100644 deps/LIEF/src/MachO/ThreadCommand.cpp create mode 100644 deps/LIEF/src/MachO/TrieNode.cpp create mode 100644 deps/LIEF/src/MachO/TrieNode.hpp create mode 100644 deps/LIEF/src/MachO/TwoLevelHints.cpp create mode 100644 deps/LIEF/src/MachO/UUIDCommand.cpp create mode 100644 deps/LIEF/src/MachO/UnknownCommand.cpp create mode 100644 deps/LIEF/src/MachO/VersionMin.cpp create mode 100644 deps/LIEF/src/MachO/endianness_support.cpp create mode 100644 deps/LIEF/src/MachO/exports_trie.cpp create mode 100644 deps/LIEF/src/MachO/exports_trie.hpp create mode 100644 deps/LIEF/src/MachO/hash.cpp create mode 100644 deps/LIEF/src/MachO/json.cpp create mode 100644 deps/LIEF/src/MachO/json_api.cpp create mode 100644 deps/LIEF/src/MachO/json_internal.hpp create mode 100644 deps/LIEF/src/MachO/layout_check.cpp create mode 100644 deps/LIEF/src/MachO/structures.inc create mode 100644 deps/LIEF/src/MachO/utils.cpp create mode 100644 deps/LIEF/src/OAT/Binary.cpp create mode 100644 deps/LIEF/src/OAT/CMakeLists.txt create mode 100644 deps/LIEF/src/OAT/Class.cpp create mode 100644 deps/LIEF/src/OAT/DexFile.cpp create mode 100644 deps/LIEF/src/OAT/EnumToString.cpp create mode 100644 deps/LIEF/src/OAT/Header.cpp create mode 100644 deps/LIEF/src/OAT/Header.tcc create mode 100644 deps/LIEF/src/OAT/Method.cpp create mode 100644 deps/LIEF/src/OAT/Parser.cpp create mode 100644 deps/LIEF/src/OAT/Parser.tcc create mode 100644 deps/LIEF/src/OAT/Structures.hpp create mode 100644 deps/LIEF/src/OAT/hash.cpp create mode 100644 deps/LIEF/src/OAT/json.cpp create mode 100644 deps/LIEF/src/OAT/json_api.cpp create mode 100644 deps/LIEF/src/OAT/json_internal.hpp create mode 100644 deps/LIEF/src/OAT/oat_124.tcc create mode 100644 deps/LIEF/src/OAT/oat_131.tcc create mode 100644 deps/LIEF/src/OAT/oat_64.tcc create mode 100644 deps/LIEF/src/OAT/oat_79.tcc create mode 100644 deps/LIEF/src/OAT/utils.cpp create mode 100644 deps/LIEF/src/ObjC/CMakeLists.txt create mode 100644 deps/LIEF/src/ObjC/objc.cpp create mode 100644 deps/LIEF/src/Object.cpp create mode 100644 deps/LIEF/src/Object.tcc create mode 100644 deps/LIEF/src/PDB/CMakeLists.txt create mode 100644 deps/LIEF/src/PDB/pdb.cpp create mode 100644 deps/LIEF/src/PE/Binary.cpp create mode 100644 deps/LIEF/src/PE/Builder.cpp create mode 100644 deps/LIEF/src/PE/Builder.tcc create mode 100644 deps/LIEF/src/PE/CMakeLists.txt create mode 100644 deps/LIEF/src/PE/CodeIntegrity.cpp create mode 100644 deps/LIEF/src/PE/CodePage.cpp create mode 100644 deps/LIEF/src/PE/DataDirectory.cpp create mode 100644 deps/LIEF/src/PE/DelayImport.cpp create mode 100644 deps/LIEF/src/PE/DelayImportEntry.cpp create mode 100644 deps/LIEF/src/PE/DosHeader.cpp create mode 100644 deps/LIEF/src/PE/EnumToString.cpp create mode 100644 deps/LIEF/src/PE/ExceptionInfo.cpp create mode 100644 deps/LIEF/src/PE/Export.cpp create mode 100644 deps/LIEF/src/PE/ExportEntry.cpp create mode 100644 deps/LIEF/src/PE/Factory.cpp create mode 100644 deps/LIEF/src/PE/Header.cpp create mode 100644 deps/LIEF/src/PE/Import.cpp create mode 100644 deps/LIEF/src/PE/ImportEntry.cpp create mode 100644 deps/LIEF/src/PE/LoadConfigurations/CHPEMetadata/CMakeLists.txt create mode 100644 deps/LIEF/src/PE/LoadConfigurations/CHPEMetadata/Metadata.cpp create mode 100644 deps/LIEF/src/PE/LoadConfigurations/CHPEMetadata/MetadataARM64.cpp create mode 100644 deps/LIEF/src/PE/LoadConfigurations/CHPEMetadata/MetadataX86.cpp create mode 100644 deps/LIEF/src/PE/LoadConfigurations/CMakeLists.txt create mode 100644 deps/LIEF/src/PE/LoadConfigurations/DynamicRelocation/CMakeLists.txt create mode 100644 deps/LIEF/src/PE/LoadConfigurations/DynamicRelocation/DynamicFixup.cpp create mode 100644 deps/LIEF/src/PE/LoadConfigurations/DynamicRelocation/DynamicFixupARM64Kernel.cpp create mode 100644 deps/LIEF/src/PE/LoadConfigurations/DynamicRelocation/DynamicFixupARM64X.cpp create mode 100644 deps/LIEF/src/PE/LoadConfigurations/DynamicRelocation/DynamicFixupControlTransfer.cpp create mode 100644 deps/LIEF/src/PE/LoadConfigurations/DynamicRelocation/DynamicFixupGeneric.cpp create mode 100644 deps/LIEF/src/PE/LoadConfigurations/DynamicRelocation/DynamicRelocationBase.cpp create mode 100644 deps/LIEF/src/PE/LoadConfigurations/DynamicRelocation/DynamicRelocationV1.cpp create mode 100644 deps/LIEF/src/PE/LoadConfigurations/DynamicRelocation/DynamicRelocationV2.cpp create mode 100644 deps/LIEF/src/PE/LoadConfigurations/DynamicRelocation/FunctionOverride.cpp create mode 100644 deps/LIEF/src/PE/LoadConfigurations/DynamicRelocation/FunctionOverrideInfo.cpp create mode 100644 deps/LIEF/src/PE/LoadConfigurations/EnclaveConfiguration.cpp create mode 100644 deps/LIEF/src/PE/LoadConfigurations/EnclaveImport.cpp create mode 100644 deps/LIEF/src/PE/LoadConfigurations/LoadConfiguration.cpp create mode 100644 deps/LIEF/src/PE/LoadConfigurations/VolatileMetadata.cpp create mode 100644 deps/LIEF/src/PE/OptionalHeader.cpp create mode 100644 deps/LIEF/src/PE/Parser.cpp create mode 100644 deps/LIEF/src/PE/Parser.tcc create mode 100644 deps/LIEF/src/PE/ParserConfig.cpp create mode 100644 deps/LIEF/src/PE/Relocation.cpp create mode 100644 deps/LIEF/src/PE/RelocationEntry.cpp create mode 100644 deps/LIEF/src/PE/ResourceData.cpp create mode 100644 deps/LIEF/src/PE/ResourceDirectory.cpp create mode 100644 deps/LIEF/src/PE/ResourceNode.cpp create mode 100644 deps/LIEF/src/PE/ResourcesManager.cpp create mode 100644 deps/LIEF/src/PE/RichEntry.cpp create mode 100644 deps/LIEF/src/PE/RichHeader.cpp create mode 100644 deps/LIEF/src/PE/Section.cpp create mode 100644 deps/LIEF/src/PE/Structures.hpp create mode 100644 deps/LIEF/src/PE/TLS.cpp create mode 100644 deps/LIEF/src/PE/checksum.cpp create mode 100644 deps/LIEF/src/PE/checksum.hpp create mode 100644 deps/LIEF/src/PE/debug/CMakeLists.txt create mode 100644 deps/LIEF/src/PE/debug/CodeView.cpp create mode 100644 deps/LIEF/src/PE/debug/CodeViewPDB.cpp create mode 100644 deps/LIEF/src/PE/debug/Debug.cpp create mode 100644 deps/LIEF/src/PE/debug/ExDllCharacteristics.cpp create mode 100644 deps/LIEF/src/PE/debug/FPO.cpp create mode 100644 deps/LIEF/src/PE/debug/PDBChecksum.cpp create mode 100644 deps/LIEF/src/PE/debug/Pogo.cpp create mode 100644 deps/LIEF/src/PE/debug/PogoEntry.cpp create mode 100644 deps/LIEF/src/PE/debug/Repro.cpp create mode 100644 deps/LIEF/src/PE/debug/VCFeature.cpp create mode 100644 deps/LIEF/src/PE/endianness_support.cpp create mode 100644 deps/LIEF/src/PE/exceptions_info/AArch64/CMakeLists.txt create mode 100644 deps/LIEF/src/PE/exceptions_info/AArch64/PackedFunction.cpp create mode 100644 deps/LIEF/src/PE/exceptions_info/AArch64/UnpackedFunction.cpp create mode 100644 deps/LIEF/src/PE/exceptions_info/CMakeLists.txt create mode 100644 deps/LIEF/src/PE/exceptions_info/RuntimeFunctionAArch64.cpp create mode 100644 deps/LIEF/src/PE/exceptions_info/RuntimeFunctionX64.cpp create mode 100644 deps/LIEF/src/PE/exceptions_info/UnwindAArch64Decoder.cpp create mode 100644 deps/LIEF/src/PE/exceptions_info/UnwindAArch64Decoder.hpp create mode 100644 deps/LIEF/src/PE/exceptions_info/UnwindCodeX64.cpp create mode 100644 deps/LIEF/src/PE/hash.cpp create mode 100644 deps/LIEF/src/PE/json.cpp create mode 100644 deps/LIEF/src/PE/json_api.cpp create mode 100644 deps/LIEF/src/PE/json_internal.hpp create mode 100644 deps/LIEF/src/PE/layout_check.cpp create mode 100644 deps/LIEF/src/PE/resources/AcceleratorCodes.cpp create mode 100644 deps/LIEF/src/PE/resources/CMakeLists.txt create mode 100644 deps/LIEF/src/PE/resources/ResourceAccelerator.cpp create mode 100644 deps/LIEF/src/PE/resources/ResourceDialog.cpp create mode 100644 deps/LIEF/src/PE/resources/ResourceDialogExtended.cpp create mode 100644 deps/LIEF/src/PE/resources/ResourceDialogRegular.cpp create mode 100644 deps/LIEF/src/PE/resources/ResourceIcon.cpp create mode 100644 deps/LIEF/src/PE/resources/ResourceStringFileInfo.cpp create mode 100644 deps/LIEF/src/PE/resources/ResourceStringTable.cpp create mode 100644 deps/LIEF/src/PE/resources/ResourceVar.cpp create mode 100644 deps/LIEF/src/PE/resources/ResourceVarFileInfo.cpp create mode 100644 deps/LIEF/src/PE/resources/ResourceVersion.cpp create mode 100644 deps/LIEF/src/PE/resources/styles_array.hpp create mode 100644 deps/LIEF/src/PE/signature/Attribute.cpp create mode 100644 deps/LIEF/src/PE/signature/CMakeLists.txt create mode 100644 deps/LIEF/src/PE/signature/ContentInfo.cpp create mode 100644 deps/LIEF/src/PE/signature/GenericContent.cpp create mode 100644 deps/LIEF/src/PE/signature/OIDToString.cpp create mode 100644 deps/LIEF/src/PE/signature/PKCS9TSTInfo.cpp create mode 100644 deps/LIEF/src/PE/signature/RsaInfo.cpp create mode 100644 deps/LIEF/src/PE/signature/Signature.cpp create mode 100644 deps/LIEF/src/PE/signature/SignatureParser.cpp create mode 100644 deps/LIEF/src/PE/signature/SignerInfo.cpp create mode 100644 deps/LIEF/src/PE/signature/SpcIndirectData.cpp create mode 100644 deps/LIEF/src/PE/signature/attributes/CMakeLists.txt create mode 100644 deps/LIEF/src/PE/signature/attributes/ContentType.cpp create mode 100644 deps/LIEF/src/PE/signature/attributes/GenericType.cpp create mode 100644 deps/LIEF/src/PE/signature/attributes/MsCounterSign.cpp create mode 100644 deps/LIEF/src/PE/signature/attributes/MsManifestBinaryID.cpp create mode 100644 deps/LIEF/src/PE/signature/attributes/MsSpcNestedSignature.cpp create mode 100644 deps/LIEF/src/PE/signature/attributes/MsSpcStatementType.cpp create mode 100644 deps/LIEF/src/PE/signature/attributes/PKCS9AtSequenceNumber.cpp create mode 100644 deps/LIEF/src/PE/signature/attributes/PKCS9CounterSignature.cpp create mode 100644 deps/LIEF/src/PE/signature/attributes/PKCS9MessageDigest.cpp create mode 100644 deps/LIEF/src/PE/signature/attributes/PKCS9SigningTime.cpp create mode 100644 deps/LIEF/src/PE/signature/attributes/SigningCertificateV2.cpp create mode 100644 deps/LIEF/src/PE/signature/attributes/SpcRelaxedPeMarkerCheck.cpp create mode 100644 deps/LIEF/src/PE/signature/attributes/SpcSpOpusInfo.cpp create mode 100644 deps/LIEF/src/PE/signature/pkcs7.h create mode 100644 deps/LIEF/src/PE/signature/x509.cpp create mode 100644 deps/LIEF/src/PE/structures.inc create mode 100644 deps/LIEF/src/PE/utils.cpp create mode 100644 deps/LIEF/src/PE/utils/ordinals_lookup_tables/advapi32_dll_lookup.hpp create mode 100644 deps/LIEF/src/PE/utils/ordinals_lookup_tables/comctl32_dll_lookup.hpp create mode 100644 deps/LIEF/src/PE/utils/ordinals_lookup_tables/gdi32_dll_lookup.hpp create mode 100644 deps/LIEF/src/PE/utils/ordinals_lookup_tables/kernel32_dll_lookup.hpp create mode 100644 deps/LIEF/src/PE/utils/ordinals_lookup_tables/libraries_table.hpp create mode 100644 deps/LIEF/src/PE/utils/ordinals_lookup_tables/mfc42u_dll_lookup.hpp create mode 100644 deps/LIEF/src/PE/utils/ordinals_lookup_tables/msvcp110_dll_lookup.hpp create mode 100644 deps/LIEF/src/PE/utils/ordinals_lookup_tables/msvcp120_dll_lookup.hpp create mode 100644 deps/LIEF/src/PE/utils/ordinals_lookup_tables/msvcr100_dll_lookup.hpp create mode 100644 deps/LIEF/src/PE/utils/ordinals_lookup_tables/msvcr110_dll_lookup.hpp create mode 100644 deps/LIEF/src/PE/utils/ordinals_lookup_tables/msvcr120_dll_lookup.hpp create mode 100644 deps/LIEF/src/PE/utils/ordinals_lookup_tables/msvcrt_dll_lookup.hpp create mode 100644 deps/LIEF/src/PE/utils/ordinals_lookup_tables/ntdll_dll_lookup.hpp create mode 100644 deps/LIEF/src/PE/utils/ordinals_lookup_tables/ole32_dll_lookup.hpp create mode 100644 deps/LIEF/src/PE/utils/ordinals_lookup_tables/oleaut32_dll_lookup.hpp create mode 100644 deps/LIEF/src/PE/utils/ordinals_lookup_tables/shcore_dll_lookup.hpp create mode 100644 deps/LIEF/src/PE/utils/ordinals_lookup_tables/shell32_dll_lookup.hpp create mode 100644 deps/LIEF/src/PE/utils/ordinals_lookup_tables/shlwapi_dll_lookup.hpp create mode 100644 deps/LIEF/src/PE/utils/ordinals_lookup_tables/user32_dll_lookup.hpp create mode 100644 deps/LIEF/src/PE/utils/ordinals_lookup_tables/ws2_32_dll_lookup.hpp create mode 100644 deps/LIEF/src/PE/utils/ordinals_lookup_tables_std/README.md create mode 100644 deps/LIEF/src/PE/utils/ordinals_lookup_tables_std/libraries_table.hpp create mode 100644 deps/LIEF/src/PE/utils/ordinals_lookup_tables_std/oleauth32_dll_lookup.hpp create mode 100644 deps/LIEF/src/PE/utils/ordinals_lookup_tables_std/ws2_32_dll_lookup.hpp create mode 100644 deps/LIEF/src/VDEX/CMakeLists.txt create mode 100644 deps/LIEF/src/VDEX/File.cpp create mode 100644 deps/LIEF/src/VDEX/Header.cpp create mode 100644 deps/LIEF/src/VDEX/Header.tcc create mode 100644 deps/LIEF/src/VDEX/Parser.cpp create mode 100644 deps/LIEF/src/VDEX/Parser.tcc create mode 100644 deps/LIEF/src/VDEX/Structures.hpp create mode 100644 deps/LIEF/src/VDEX/hash.cpp create mode 100644 deps/LIEF/src/VDEX/json.cpp create mode 100644 deps/LIEF/src/VDEX/json_api.cpp create mode 100644 deps/LIEF/src/VDEX/json_internal.hpp create mode 100644 deps/LIEF/src/VDEX/utils.cpp create mode 100644 deps/LIEF/src/Visitor.cpp create mode 100644 deps/LIEF/src/asm/CMakeLists.txt create mode 100644 deps/LIEF/src/asm/asm.cpp create mode 100644 deps/LIEF/src/compiler_support.h create mode 100644 deps/LIEF/src/compiler_support.h.in create mode 100644 deps/LIEF/src/dyld-shared-cache/CMakeLists.txt create mode 100644 deps/LIEF/src/dyld-shared-cache/dyldsc.cpp create mode 100644 deps/LIEF/src/endianness_support.cpp create mode 100644 deps/LIEF/src/errors.cpp create mode 100644 deps/LIEF/src/fmt_formatter.hpp create mode 100644 deps/LIEF/src/frozen.hpp create mode 100644 deps/LIEF/src/hash_stream.cpp create mode 100644 deps/LIEF/src/hash_stream.hpp create mode 100644 deps/LIEF/src/internal_utils.cpp create mode 100644 deps/LIEF/src/internal_utils.hpp create mode 100644 deps/LIEF/src/intmem.h create mode 100644 deps/LIEF/src/iostream.cpp create mode 100644 deps/LIEF/src/json_api.cpp create mode 100644 deps/LIEF/src/logging.cpp create mode 100644 deps/LIEF/src/logging.hpp create mode 100644 deps/LIEF/src/messages.hpp create mode 100644 deps/LIEF/src/overflow_check.hpp create mode 100644 deps/LIEF/src/overload_cast.hpp create mode 100644 deps/LIEF/src/paging.cpp create mode 100644 deps/LIEF/src/paging.hpp create mode 100644 deps/LIEF/src/platforms/CMakeLists.txt create mode 100644 deps/LIEF/src/platforms/android/CMakeLists.txt create mode 100644 deps/LIEF/src/platforms/android/version.cpp create mode 100644 deps/LIEF/src/profiling.hpp create mode 100644 deps/LIEF/src/range.cpp create mode 100644 deps/LIEF/src/third-party/utfcpp.hpp create mode 100644 deps/LIEF/src/utils.cpp create mode 100644 deps/LIEF/src/visitors/hash.cpp create mode 100644 deps/LIEF/src/visitors/json.cpp create mode 100644 deps/LIEF/src/visitors/json.hpp create mode 100644 deps/LIEF/third-party/expected/COPYING create mode 100644 deps/LIEF/third-party/expected/README.md create mode 100644 deps/LIEF/third-party/expected/include/tl/expected.hpp create mode 100644 deps/LIEF/third-party/frozen/LICENSE create mode 100644 deps/LIEF/third-party/frozen/README.rst create mode 100644 deps/LIEF/third-party/frozen/include/frozen/CMakeLists.txt create mode 100644 deps/LIEF/third-party/frozen/include/frozen/algorithm.h create mode 100644 deps/LIEF/third-party/frozen/include/frozen/bits/algorithms.h create mode 100644 deps/LIEF/third-party/frozen/include/frozen/bits/basic_types.h create mode 100644 deps/LIEF/third-party/frozen/include/frozen/bits/constexpr_assert.h create mode 100644 deps/LIEF/third-party/frozen/include/frozen/bits/defines.h create mode 100644 deps/LIEF/third-party/frozen/include/frozen/bits/elsa.h create mode 100644 deps/LIEF/third-party/frozen/include/frozen/bits/elsa_std.h create mode 100644 deps/LIEF/third-party/frozen/include/frozen/bits/exceptions.h create mode 100644 deps/LIEF/third-party/frozen/include/frozen/bits/hash_string.h create mode 100644 deps/LIEF/third-party/frozen/include/frozen/bits/pmh.h create mode 100644 deps/LIEF/third-party/frozen/include/frozen/bits/version.h create mode 100644 deps/LIEF/third-party/frozen/include/frozen/map.h create mode 100644 deps/LIEF/third-party/frozen/include/frozen/random.h create mode 100644 deps/LIEF/third-party/frozen/include/frozen/set.h create mode 100644 deps/LIEF/third-party/frozen/include/frozen/string.h create mode 100644 deps/LIEF/third-party/frozen/include/frozen/unordered_map.h create mode 100644 deps/LIEF/third-party/frozen/include/frozen/unordered_set.h create mode 100644 deps/LIEF/third-party/mbedtls/LICENSE create mode 100644 deps/LIEF/third-party/mbedtls/README.md create mode 100644 deps/LIEF/third-party/mbedtls/include/.gitignore create mode 100644 deps/LIEF/third-party/mbedtls/include/CMakeLists.txt create mode 100644 deps/LIEF/third-party/mbedtls/include/mbedtls/aes.h create mode 100644 deps/LIEF/third-party/mbedtls/include/mbedtls/aria.h create mode 100644 deps/LIEF/third-party/mbedtls/include/mbedtls/asn1.h create mode 100644 deps/LIEF/third-party/mbedtls/include/mbedtls/asn1write.h create mode 100644 deps/LIEF/third-party/mbedtls/include/mbedtls/base64.h create mode 100644 deps/LIEF/third-party/mbedtls/include/mbedtls/bignum.h create mode 100644 deps/LIEF/third-party/mbedtls/include/mbedtls/block_cipher.h create mode 100644 deps/LIEF/third-party/mbedtls/include/mbedtls/build_info.h create mode 100644 deps/LIEF/third-party/mbedtls/include/mbedtls/camellia.h create mode 100644 deps/LIEF/third-party/mbedtls/include/mbedtls/ccm.h create mode 100644 deps/LIEF/third-party/mbedtls/include/mbedtls/chacha20.h create mode 100644 deps/LIEF/third-party/mbedtls/include/mbedtls/chachapoly.h create mode 100644 deps/LIEF/third-party/mbedtls/include/mbedtls/check_config.h create mode 100644 deps/LIEF/third-party/mbedtls/include/mbedtls/cipher.h create mode 100644 deps/LIEF/third-party/mbedtls/include/mbedtls/cmac.h create mode 100644 deps/LIEF/third-party/mbedtls/include/mbedtls/compat-2.x.h create mode 100644 deps/LIEF/third-party/mbedtls/include/mbedtls/config_adjust_legacy_crypto.h create mode 100644 deps/LIEF/third-party/mbedtls/include/mbedtls/config_adjust_legacy_from_psa.h create mode 100644 deps/LIEF/third-party/mbedtls/include/mbedtls/config_adjust_psa_from_legacy.h create mode 100644 deps/LIEF/third-party/mbedtls/include/mbedtls/config_adjust_psa_superset_legacy.h create mode 100644 deps/LIEF/third-party/mbedtls/include/mbedtls/config_adjust_ssl.h create mode 100644 deps/LIEF/third-party/mbedtls/include/mbedtls/config_adjust_x509.h create mode 100644 deps/LIEF/third-party/mbedtls/include/mbedtls/config_psa.h create mode 100644 deps/LIEF/third-party/mbedtls/include/mbedtls/constant_time.h create mode 100644 deps/LIEF/third-party/mbedtls/include/mbedtls/ctr_drbg.h create mode 100644 deps/LIEF/third-party/mbedtls/include/mbedtls/debug.h create mode 100644 deps/LIEF/third-party/mbedtls/include/mbedtls/des.h create mode 100644 deps/LIEF/third-party/mbedtls/include/mbedtls/dhm.h create mode 100644 deps/LIEF/third-party/mbedtls/include/mbedtls/ecdh.h create mode 100644 deps/LIEF/third-party/mbedtls/include/mbedtls/ecdsa.h create mode 100644 deps/LIEF/third-party/mbedtls/include/mbedtls/ecjpake.h create mode 100644 deps/LIEF/third-party/mbedtls/include/mbedtls/ecp.h create mode 100644 deps/LIEF/third-party/mbedtls/include/mbedtls/entropy.h create mode 100644 deps/LIEF/third-party/mbedtls/include/mbedtls/error.h create mode 100644 deps/LIEF/third-party/mbedtls/include/mbedtls/gcm.h create mode 100644 deps/LIEF/third-party/mbedtls/include/mbedtls/hkdf.h create mode 100644 deps/LIEF/third-party/mbedtls/include/mbedtls/hmac_drbg.h create mode 100644 deps/LIEF/third-party/mbedtls/include/mbedtls/lms.h create mode 100644 deps/LIEF/third-party/mbedtls/include/mbedtls/mbedtls_config.h create mode 100644 deps/LIEF/third-party/mbedtls/include/mbedtls/md.h create mode 100644 deps/LIEF/third-party/mbedtls/include/mbedtls/md5.h create mode 100644 deps/LIEF/third-party/mbedtls/include/mbedtls/memory_buffer_alloc.h create mode 100644 deps/LIEF/third-party/mbedtls/include/mbedtls/net_sockets.h create mode 100644 deps/LIEF/third-party/mbedtls/include/mbedtls/nist_kw.h create mode 100644 deps/LIEF/third-party/mbedtls/include/mbedtls/oid.h create mode 100644 deps/LIEF/third-party/mbedtls/include/mbedtls/pem.h create mode 100644 deps/LIEF/third-party/mbedtls/include/mbedtls/pk.h create mode 100644 deps/LIEF/third-party/mbedtls/include/mbedtls/pkcs12.h create mode 100644 deps/LIEF/third-party/mbedtls/include/mbedtls/pkcs5.h create mode 100644 deps/LIEF/third-party/mbedtls/include/mbedtls/pkcs7.h create mode 100644 deps/LIEF/third-party/mbedtls/include/mbedtls/platform.h create mode 100644 deps/LIEF/third-party/mbedtls/include/mbedtls/platform_time.h create mode 100644 deps/LIEF/third-party/mbedtls/include/mbedtls/platform_util.h create mode 100644 deps/LIEF/third-party/mbedtls/include/mbedtls/poly1305.h create mode 100644 deps/LIEF/third-party/mbedtls/include/mbedtls/private_access.h create mode 100644 deps/LIEF/third-party/mbedtls/include/mbedtls/psa_util.h create mode 100644 deps/LIEF/third-party/mbedtls/include/mbedtls/ripemd160.h create mode 100644 deps/LIEF/third-party/mbedtls/include/mbedtls/rsa.h create mode 100644 deps/LIEF/third-party/mbedtls/include/mbedtls/sha1.h create mode 100644 deps/LIEF/third-party/mbedtls/include/mbedtls/sha256.h create mode 100644 deps/LIEF/third-party/mbedtls/include/mbedtls/sha3.h create mode 100644 deps/LIEF/third-party/mbedtls/include/mbedtls/sha512.h create mode 100644 deps/LIEF/third-party/mbedtls/include/mbedtls/ssl.h create mode 100644 deps/LIEF/third-party/mbedtls/include/mbedtls/ssl_cache.h create mode 100644 deps/LIEF/third-party/mbedtls/include/mbedtls/ssl_ciphersuites.h create mode 100644 deps/LIEF/third-party/mbedtls/include/mbedtls/ssl_cookie.h create mode 100644 deps/LIEF/third-party/mbedtls/include/mbedtls/ssl_ticket.h create mode 100644 deps/LIEF/third-party/mbedtls/include/mbedtls/threading.h create mode 100644 deps/LIEF/third-party/mbedtls/include/mbedtls/timing.h create mode 100644 deps/LIEF/third-party/mbedtls/include/mbedtls/version.h create mode 100644 deps/LIEF/third-party/mbedtls/include/mbedtls/x509.h create mode 100644 deps/LIEF/third-party/mbedtls/include/mbedtls/x509_crl.h create mode 100644 deps/LIEF/third-party/mbedtls/include/mbedtls/x509_crt.h create mode 100644 deps/LIEF/third-party/mbedtls/include/mbedtls/x509_csr.h create mode 100644 deps/LIEF/third-party/mbedtls/include/psa/build_info.h create mode 100644 deps/LIEF/third-party/mbedtls/include/psa/crypto.h create mode 100644 deps/LIEF/third-party/mbedtls/include/psa/crypto_adjust_auto_enabled.h create mode 100644 deps/LIEF/third-party/mbedtls/include/psa/crypto_adjust_config_dependencies.h create mode 100644 deps/LIEF/third-party/mbedtls/include/psa/crypto_adjust_config_key_pair_types.h create mode 100644 deps/LIEF/third-party/mbedtls/include/psa/crypto_adjust_config_synonyms.h create mode 100644 deps/LIEF/third-party/mbedtls/include/psa/crypto_builtin_composites.h create mode 100644 deps/LIEF/third-party/mbedtls/include/psa/crypto_builtin_key_derivation.h create mode 100644 deps/LIEF/third-party/mbedtls/include/psa/crypto_builtin_primitives.h create mode 100644 deps/LIEF/third-party/mbedtls/include/psa/crypto_compat.h create mode 100644 deps/LIEF/third-party/mbedtls/include/psa/crypto_config.h create mode 100644 deps/LIEF/third-party/mbedtls/include/psa/crypto_driver_common.h create mode 100644 deps/LIEF/third-party/mbedtls/include/psa/crypto_driver_contexts_composites.h create mode 100644 deps/LIEF/third-party/mbedtls/include/psa/crypto_driver_contexts_key_derivation.h create mode 100644 deps/LIEF/third-party/mbedtls/include/psa/crypto_driver_contexts_primitives.h create mode 100644 deps/LIEF/third-party/mbedtls/include/psa/crypto_extra.h create mode 100644 deps/LIEF/third-party/mbedtls/include/psa/crypto_legacy.h create mode 100644 deps/LIEF/third-party/mbedtls/include/psa/crypto_platform.h create mode 100644 deps/LIEF/third-party/mbedtls/include/psa/crypto_se_driver.h create mode 100644 deps/LIEF/third-party/mbedtls/include/psa/crypto_sizes.h create mode 100644 deps/LIEF/third-party/mbedtls/include/psa/crypto_struct.h create mode 100644 deps/LIEF/third-party/mbedtls/include/psa/crypto_types.h create mode 100644 deps/LIEF/third-party/mbedtls/include/psa/crypto_values.h create mode 100644 deps/LIEF/third-party/mbedtls/library/.gitignore create mode 100644 deps/LIEF/third-party/mbedtls/library/CMakeLists.txt create mode 100644 deps/LIEF/third-party/mbedtls/library/Makefile create mode 100644 deps/LIEF/third-party/mbedtls/library/aes.c create mode 100644 deps/LIEF/third-party/mbedtls/library/aesce.c create mode 100644 deps/LIEF/third-party/mbedtls/library/aesce.h create mode 100644 deps/LIEF/third-party/mbedtls/library/aesni.c create mode 100644 deps/LIEF/third-party/mbedtls/library/aesni.h create mode 100644 deps/LIEF/third-party/mbedtls/library/alignment.h create mode 100644 deps/LIEF/third-party/mbedtls/library/aria.c create mode 100644 deps/LIEF/third-party/mbedtls/library/asn1parse.c create mode 100644 deps/LIEF/third-party/mbedtls/library/asn1write.c create mode 100644 deps/LIEF/third-party/mbedtls/library/base64.c create mode 100644 deps/LIEF/third-party/mbedtls/library/base64_internal.h create mode 100644 deps/LIEF/third-party/mbedtls/library/bignum.c create mode 100644 deps/LIEF/third-party/mbedtls/library/bignum_core.c create mode 100644 deps/LIEF/third-party/mbedtls/library/bignum_core.h create mode 100644 deps/LIEF/third-party/mbedtls/library/bignum_core_invasive.h create mode 100644 deps/LIEF/third-party/mbedtls/library/bignum_internal.h create mode 100644 deps/LIEF/third-party/mbedtls/library/bignum_mod.c create mode 100644 deps/LIEF/third-party/mbedtls/library/bignum_mod.h create mode 100644 deps/LIEF/third-party/mbedtls/library/bignum_mod_raw.c create mode 100644 deps/LIEF/third-party/mbedtls/library/bignum_mod_raw.h create mode 100644 deps/LIEF/third-party/mbedtls/library/bignum_mod_raw_invasive.h create mode 100644 deps/LIEF/third-party/mbedtls/library/block_cipher.c create mode 100644 deps/LIEF/third-party/mbedtls/library/block_cipher_internal.h create mode 100644 deps/LIEF/third-party/mbedtls/library/bn_mul.h create mode 100644 deps/LIEF/third-party/mbedtls/library/camellia.c create mode 100644 deps/LIEF/third-party/mbedtls/library/ccm.c create mode 100644 deps/LIEF/third-party/mbedtls/library/chacha20.c create mode 100644 deps/LIEF/third-party/mbedtls/library/chachapoly.c create mode 100644 deps/LIEF/third-party/mbedtls/library/check_crypto_config.h create mode 100644 deps/LIEF/third-party/mbedtls/library/cipher.c create mode 100644 deps/LIEF/third-party/mbedtls/library/cipher_invasive.h create mode 100644 deps/LIEF/third-party/mbedtls/library/cipher_wrap.c create mode 100644 deps/LIEF/third-party/mbedtls/library/cipher_wrap.h create mode 100644 deps/LIEF/third-party/mbedtls/library/cmac.c create mode 100644 deps/LIEF/third-party/mbedtls/library/common.h create mode 100644 deps/LIEF/third-party/mbedtls/library/constant_time.c create mode 100644 deps/LIEF/third-party/mbedtls/library/constant_time_impl.h create mode 100644 deps/LIEF/third-party/mbedtls/library/constant_time_internal.h create mode 100644 deps/LIEF/third-party/mbedtls/library/ctr.h create mode 100644 deps/LIEF/third-party/mbedtls/library/ctr_drbg.c create mode 100644 deps/LIEF/third-party/mbedtls/library/debug.c create mode 100644 deps/LIEF/third-party/mbedtls/library/debug_internal.h create mode 100644 deps/LIEF/third-party/mbedtls/library/des.c create mode 100644 deps/LIEF/third-party/mbedtls/library/dhm.c create mode 100644 deps/LIEF/third-party/mbedtls/library/ecdh.c create mode 100644 deps/LIEF/third-party/mbedtls/library/ecdsa.c create mode 100644 deps/LIEF/third-party/mbedtls/library/ecjpake.c create mode 100644 deps/LIEF/third-party/mbedtls/library/ecp.c create mode 100644 deps/LIEF/third-party/mbedtls/library/ecp_curves.c create mode 100644 deps/LIEF/third-party/mbedtls/library/ecp_curves_new.c create mode 100644 deps/LIEF/third-party/mbedtls/library/ecp_internal_alt.h create mode 100644 deps/LIEF/third-party/mbedtls/library/ecp_invasive.h create mode 100644 deps/LIEF/third-party/mbedtls/library/entropy.c create mode 100644 deps/LIEF/third-party/mbedtls/library/entropy_poll.c create mode 100644 deps/LIEF/third-party/mbedtls/library/entropy_poll.h create mode 100644 deps/LIEF/third-party/mbedtls/library/error.c create mode 100644 deps/LIEF/third-party/mbedtls/library/gcm.c create mode 100644 deps/LIEF/third-party/mbedtls/library/hkdf.c create mode 100644 deps/LIEF/third-party/mbedtls/library/hmac_drbg.c create mode 100644 deps/LIEF/third-party/mbedtls/library/lmots.c create mode 100644 deps/LIEF/third-party/mbedtls/library/lmots.h create mode 100644 deps/LIEF/third-party/mbedtls/library/lms.c create mode 100644 deps/LIEF/third-party/mbedtls/library/md.c create mode 100644 deps/LIEF/third-party/mbedtls/library/md5.c create mode 100644 deps/LIEF/third-party/mbedtls/library/md_psa.h create mode 100644 deps/LIEF/third-party/mbedtls/library/md_wrap.h create mode 100644 deps/LIEF/third-party/mbedtls/library/memory_buffer_alloc.c create mode 100644 deps/LIEF/third-party/mbedtls/library/mps_common.h create mode 100644 deps/LIEF/third-party/mbedtls/library/mps_error.h create mode 100644 deps/LIEF/third-party/mbedtls/library/mps_reader.c create mode 100644 deps/LIEF/third-party/mbedtls/library/mps_reader.h create mode 100644 deps/LIEF/third-party/mbedtls/library/mps_trace.c create mode 100644 deps/LIEF/third-party/mbedtls/library/mps_trace.h create mode 100644 deps/LIEF/third-party/mbedtls/library/net_sockets.c create mode 100644 deps/LIEF/third-party/mbedtls/library/nist_kw.c create mode 100644 deps/LIEF/third-party/mbedtls/library/oid.c create mode 100644 deps/LIEF/third-party/mbedtls/library/padlock.c create mode 100644 deps/LIEF/third-party/mbedtls/library/padlock.h create mode 100644 deps/LIEF/third-party/mbedtls/library/pem.c create mode 100644 deps/LIEF/third-party/mbedtls/library/pk.c create mode 100644 deps/LIEF/third-party/mbedtls/library/pk_ecc.c create mode 100644 deps/LIEF/third-party/mbedtls/library/pk_internal.h create mode 100644 deps/LIEF/third-party/mbedtls/library/pk_wrap.c create mode 100644 deps/LIEF/third-party/mbedtls/library/pk_wrap.h create mode 100644 deps/LIEF/third-party/mbedtls/library/pkcs12.c create mode 100644 deps/LIEF/third-party/mbedtls/library/pkcs5.c create mode 100644 deps/LIEF/third-party/mbedtls/library/pkcs7.c create mode 100644 deps/LIEF/third-party/mbedtls/library/pkparse.c create mode 100644 deps/LIEF/third-party/mbedtls/library/pkwrite.c create mode 100644 deps/LIEF/third-party/mbedtls/library/pkwrite.h create mode 100644 deps/LIEF/third-party/mbedtls/library/platform.c create mode 100644 deps/LIEF/third-party/mbedtls/library/platform_util.c create mode 100644 deps/LIEF/third-party/mbedtls/library/poly1305.c create mode 100644 deps/LIEF/third-party/mbedtls/library/psa_crypto.c create mode 100644 deps/LIEF/third-party/mbedtls/library/psa_crypto_aead.c create mode 100644 deps/LIEF/third-party/mbedtls/library/psa_crypto_aead.h create mode 100644 deps/LIEF/third-party/mbedtls/library/psa_crypto_cipher.c create mode 100644 deps/LIEF/third-party/mbedtls/library/psa_crypto_cipher.h create mode 100644 deps/LIEF/third-party/mbedtls/library/psa_crypto_client.c create mode 100644 deps/LIEF/third-party/mbedtls/library/psa_crypto_core.h create mode 100644 deps/LIEF/third-party/mbedtls/library/psa_crypto_core_common.h create mode 100644 deps/LIEF/third-party/mbedtls/library/psa_crypto_driver_wrappers.h create mode 100644 deps/LIEF/third-party/mbedtls/library/psa_crypto_driver_wrappers_no_static.c create mode 100644 deps/LIEF/third-party/mbedtls/library/psa_crypto_driver_wrappers_no_static.h create mode 100644 deps/LIEF/third-party/mbedtls/library/psa_crypto_ecp.c create mode 100644 deps/LIEF/third-party/mbedtls/library/psa_crypto_ecp.h create mode 100644 deps/LIEF/third-party/mbedtls/library/psa_crypto_ffdh.c create mode 100644 deps/LIEF/third-party/mbedtls/library/psa_crypto_ffdh.h create mode 100644 deps/LIEF/third-party/mbedtls/library/psa_crypto_hash.c create mode 100644 deps/LIEF/third-party/mbedtls/library/psa_crypto_hash.h create mode 100644 deps/LIEF/third-party/mbedtls/library/psa_crypto_invasive.h create mode 100644 deps/LIEF/third-party/mbedtls/library/psa_crypto_its.h create mode 100644 deps/LIEF/third-party/mbedtls/library/psa_crypto_mac.c create mode 100644 deps/LIEF/third-party/mbedtls/library/psa_crypto_mac.h create mode 100644 deps/LIEF/third-party/mbedtls/library/psa_crypto_pake.c create mode 100644 deps/LIEF/third-party/mbedtls/library/psa_crypto_pake.h create mode 100644 deps/LIEF/third-party/mbedtls/library/psa_crypto_random_impl.h create mode 100644 deps/LIEF/third-party/mbedtls/library/psa_crypto_rsa.c create mode 100644 deps/LIEF/third-party/mbedtls/library/psa_crypto_rsa.h create mode 100644 deps/LIEF/third-party/mbedtls/library/psa_crypto_se.c create mode 100644 deps/LIEF/third-party/mbedtls/library/psa_crypto_se.h create mode 100644 deps/LIEF/third-party/mbedtls/library/psa_crypto_slot_management.c create mode 100644 deps/LIEF/third-party/mbedtls/library/psa_crypto_slot_management.h create mode 100644 deps/LIEF/third-party/mbedtls/library/psa_crypto_storage.c create mode 100644 deps/LIEF/third-party/mbedtls/library/psa_crypto_storage.h create mode 100644 deps/LIEF/third-party/mbedtls/library/psa_its_file.c create mode 100644 deps/LIEF/third-party/mbedtls/library/psa_util.c create mode 100644 deps/LIEF/third-party/mbedtls/library/psa_util_internal.h create mode 100644 deps/LIEF/third-party/mbedtls/library/ripemd160.c create mode 100644 deps/LIEF/third-party/mbedtls/library/rsa.c create mode 100644 deps/LIEF/third-party/mbedtls/library/rsa_alt_helpers.c create mode 100644 deps/LIEF/third-party/mbedtls/library/rsa_alt_helpers.h create mode 100644 deps/LIEF/third-party/mbedtls/library/rsa_internal.h create mode 100644 deps/LIEF/third-party/mbedtls/library/sha1.c create mode 100644 deps/LIEF/third-party/mbedtls/library/sha256.c create mode 100644 deps/LIEF/third-party/mbedtls/library/sha3.c create mode 100644 deps/LIEF/third-party/mbedtls/library/sha512.c create mode 100644 deps/LIEF/third-party/mbedtls/library/ssl_cache.c create mode 100644 deps/LIEF/third-party/mbedtls/library/ssl_ciphersuites.c create mode 100644 deps/LIEF/third-party/mbedtls/library/ssl_ciphersuites_internal.h create mode 100644 deps/LIEF/third-party/mbedtls/library/ssl_client.c create mode 100644 deps/LIEF/third-party/mbedtls/library/ssl_client.h create mode 100644 deps/LIEF/third-party/mbedtls/library/ssl_cookie.c create mode 100644 deps/LIEF/third-party/mbedtls/library/ssl_debug_helpers.h create mode 100644 deps/LIEF/third-party/mbedtls/library/ssl_debug_helpers_generated.c create mode 100644 deps/LIEF/third-party/mbedtls/library/ssl_misc.h create mode 100644 deps/LIEF/third-party/mbedtls/library/ssl_msg.c create mode 100644 deps/LIEF/third-party/mbedtls/library/ssl_ticket.c create mode 100644 deps/LIEF/third-party/mbedtls/library/ssl_tls.c create mode 100644 deps/LIEF/third-party/mbedtls/library/ssl_tls12_client.c create mode 100644 deps/LIEF/third-party/mbedtls/library/ssl_tls12_server.c create mode 100644 deps/LIEF/third-party/mbedtls/library/ssl_tls13_client.c create mode 100644 deps/LIEF/third-party/mbedtls/library/ssl_tls13_generic.c create mode 100644 deps/LIEF/third-party/mbedtls/library/ssl_tls13_invasive.h create mode 100644 deps/LIEF/third-party/mbedtls/library/ssl_tls13_keys.c create mode 100644 deps/LIEF/third-party/mbedtls/library/ssl_tls13_keys.h create mode 100644 deps/LIEF/third-party/mbedtls/library/ssl_tls13_server.c create mode 100644 deps/LIEF/third-party/mbedtls/library/threading.c create mode 100644 deps/LIEF/third-party/mbedtls/library/timing.c create mode 100644 deps/LIEF/third-party/mbedtls/library/version.c create mode 100644 deps/LIEF/third-party/mbedtls/library/version_features.c create mode 100644 deps/LIEF/third-party/mbedtls/library/x509.c create mode 100644 deps/LIEF/third-party/mbedtls/library/x509_create.c create mode 100644 deps/LIEF/third-party/mbedtls/library/x509_crl.c create mode 100644 deps/LIEF/third-party/mbedtls/library/x509_crt.c create mode 100644 deps/LIEF/third-party/mbedtls/library/x509_csr.c create mode 100644 deps/LIEF/third-party/mbedtls/library/x509_internal.h create mode 100644 deps/LIEF/third-party/mbedtls/library/x509write.c create mode 100644 deps/LIEF/third-party/mbedtls/library/x509write_crt.c create mode 100644 deps/LIEF/third-party/mbedtls/library/x509write_csr.c create mode 100644 deps/LIEF/third-party/spdlog/LICENSE create mode 100644 deps/LIEF/third-party/spdlog/README.md create mode 100644 deps/LIEF/third-party/spdlog/include/spdlog/async.h create mode 100644 deps/LIEF/third-party/spdlog/include/spdlog/async_logger-inl.h create mode 100644 deps/LIEF/third-party/spdlog/include/spdlog/async_logger.h create mode 100644 deps/LIEF/third-party/spdlog/include/spdlog/cfg/argv.h create mode 100644 deps/LIEF/third-party/spdlog/include/spdlog/cfg/env.h create mode 100644 deps/LIEF/third-party/spdlog/include/spdlog/cfg/helpers-inl.h create mode 100644 deps/LIEF/third-party/spdlog/include/spdlog/cfg/helpers.h create mode 100644 deps/LIEF/third-party/spdlog/include/spdlog/common-inl.h create mode 100644 deps/LIEF/third-party/spdlog/include/spdlog/common.h create mode 100644 deps/LIEF/third-party/spdlog/include/spdlog/details/backtracer-inl.h create mode 100644 deps/LIEF/third-party/spdlog/include/spdlog/details/backtracer.h create mode 100644 deps/LIEF/third-party/spdlog/include/spdlog/details/circular_q.h create mode 100644 deps/LIEF/third-party/spdlog/include/spdlog/details/console_globals.h create mode 100644 deps/LIEF/third-party/spdlog/include/spdlog/details/file_helper-inl.h create mode 100644 deps/LIEF/third-party/spdlog/include/spdlog/details/file_helper.h create mode 100644 deps/LIEF/third-party/spdlog/include/spdlog/details/fmt_helper.h create mode 100644 deps/LIEF/third-party/spdlog/include/spdlog/details/log_msg-inl.h create mode 100644 deps/LIEF/third-party/spdlog/include/spdlog/details/log_msg.h create mode 100644 deps/LIEF/third-party/spdlog/include/spdlog/details/log_msg_buffer-inl.h create mode 100644 deps/LIEF/third-party/spdlog/include/spdlog/details/log_msg_buffer.h create mode 100644 deps/LIEF/third-party/spdlog/include/spdlog/details/mpmc_blocking_q.h create mode 100644 deps/LIEF/third-party/spdlog/include/spdlog/details/null_mutex.h create mode 100644 deps/LIEF/third-party/spdlog/include/spdlog/details/os-inl.h create mode 100644 deps/LIEF/third-party/spdlog/include/spdlog/details/os.h create mode 100644 deps/LIEF/third-party/spdlog/include/spdlog/details/periodic_worker-inl.h create mode 100644 deps/LIEF/third-party/spdlog/include/spdlog/details/periodic_worker.h create mode 100644 deps/LIEF/third-party/spdlog/include/spdlog/details/registry-inl.h create mode 100644 deps/LIEF/third-party/spdlog/include/spdlog/details/registry.h create mode 100644 deps/LIEF/third-party/spdlog/include/spdlog/details/synchronous_factory.h create mode 100644 deps/LIEF/third-party/spdlog/include/spdlog/details/tcp_client-windows.h create mode 100644 deps/LIEF/third-party/spdlog/include/spdlog/details/tcp_client.h create mode 100644 deps/LIEF/third-party/spdlog/include/spdlog/details/thread_pool-inl.h create mode 100644 deps/LIEF/third-party/spdlog/include/spdlog/details/thread_pool.h create mode 100644 deps/LIEF/third-party/spdlog/include/spdlog/details/udp_client-windows.h create mode 100644 deps/LIEF/third-party/spdlog/include/spdlog/details/udp_client.h create mode 100644 deps/LIEF/third-party/spdlog/include/spdlog/details/windows_include.h create mode 100644 deps/LIEF/third-party/spdlog/include/spdlog/fmt/bin_to_hex.h create mode 100644 deps/LIEF/third-party/spdlog/include/spdlog/fmt/bundled/args.h create mode 100644 deps/LIEF/third-party/spdlog/include/spdlog/fmt/bundled/base.h create mode 100644 deps/LIEF/third-party/spdlog/include/spdlog/fmt/bundled/chrono.h create mode 100644 deps/LIEF/third-party/spdlog/include/spdlog/fmt/bundled/color.h create mode 100644 deps/LIEF/third-party/spdlog/include/spdlog/fmt/bundled/compile.h create mode 100644 deps/LIEF/third-party/spdlog/include/spdlog/fmt/bundled/core.h create mode 100644 deps/LIEF/third-party/spdlog/include/spdlog/fmt/bundled/fmt.license.rst create mode 100644 deps/LIEF/third-party/spdlog/include/spdlog/fmt/bundled/format-inl.h create mode 100644 deps/LIEF/third-party/spdlog/include/spdlog/fmt/bundled/format.h create mode 100644 deps/LIEF/third-party/spdlog/include/spdlog/fmt/bundled/os.h create mode 100644 deps/LIEF/third-party/spdlog/include/spdlog/fmt/bundled/ostream.h create mode 100644 deps/LIEF/third-party/spdlog/include/spdlog/fmt/bundled/printf.h create mode 100644 deps/LIEF/third-party/spdlog/include/spdlog/fmt/bundled/ranges.h create mode 100644 deps/LIEF/third-party/spdlog/include/spdlog/fmt/bundled/std.h create mode 100644 deps/LIEF/third-party/spdlog/include/spdlog/fmt/bundled/xchar.h create mode 100644 deps/LIEF/third-party/spdlog/include/spdlog/fmt/chrono.h create mode 100644 deps/LIEF/third-party/spdlog/include/spdlog/fmt/compile.h create mode 100644 deps/LIEF/third-party/spdlog/include/spdlog/fmt/fmt.h create mode 100644 deps/LIEF/third-party/spdlog/include/spdlog/fmt/ostr.h create mode 100644 deps/LIEF/third-party/spdlog/include/spdlog/fmt/ranges.h create mode 100644 deps/LIEF/third-party/spdlog/include/spdlog/fmt/std.h create mode 100644 deps/LIEF/third-party/spdlog/include/spdlog/fmt/xchar.h create mode 100644 deps/LIEF/third-party/spdlog/include/spdlog/formatter.h create mode 100644 deps/LIEF/third-party/spdlog/include/spdlog/fwd.h create mode 100644 deps/LIEF/third-party/spdlog/include/spdlog/logger-inl.h create mode 100644 deps/LIEF/third-party/spdlog/include/spdlog/logger.h create mode 100644 deps/LIEF/third-party/spdlog/include/spdlog/mdc.h create mode 100644 deps/LIEF/third-party/spdlog/include/spdlog/pattern_formatter-inl.h create mode 100644 deps/LIEF/third-party/spdlog/include/spdlog/pattern_formatter.h create mode 100644 deps/LIEF/third-party/spdlog/include/spdlog/sinks/android_sink.h create mode 100644 deps/LIEF/third-party/spdlog/include/spdlog/sinks/ansicolor_sink-inl.h create mode 100644 deps/LIEF/third-party/spdlog/include/spdlog/sinks/ansicolor_sink.h create mode 100644 deps/LIEF/third-party/spdlog/include/spdlog/sinks/base_sink-inl.h create mode 100644 deps/LIEF/third-party/spdlog/include/spdlog/sinks/base_sink.h create mode 100644 deps/LIEF/third-party/spdlog/include/spdlog/sinks/basic_file_sink-inl.h create mode 100644 deps/LIEF/third-party/spdlog/include/spdlog/sinks/basic_file_sink.h create mode 100644 deps/LIEF/third-party/spdlog/include/spdlog/sinks/callback_sink.h create mode 100644 deps/LIEF/third-party/spdlog/include/spdlog/sinks/daily_file_sink.h create mode 100644 deps/LIEF/third-party/spdlog/include/spdlog/sinks/dist_sink.h create mode 100644 deps/LIEF/third-party/spdlog/include/spdlog/sinks/dup_filter_sink.h create mode 100644 deps/LIEF/third-party/spdlog/include/spdlog/sinks/hourly_file_sink.h create mode 100644 deps/LIEF/third-party/spdlog/include/spdlog/sinks/kafka_sink.h create mode 100644 deps/LIEF/third-party/spdlog/include/spdlog/sinks/mongo_sink.h create mode 100644 deps/LIEF/third-party/spdlog/include/spdlog/sinks/msvc_sink.h create mode 100644 deps/LIEF/third-party/spdlog/include/spdlog/sinks/null_sink.h create mode 100644 deps/LIEF/third-party/spdlog/include/spdlog/sinks/ostream_sink.h create mode 100644 deps/LIEF/third-party/spdlog/include/spdlog/sinks/qt_sinks.h create mode 100644 deps/LIEF/third-party/spdlog/include/spdlog/sinks/ringbuffer_sink.h create mode 100644 deps/LIEF/third-party/spdlog/include/spdlog/sinks/rotating_file_sink-inl.h create mode 100644 deps/LIEF/third-party/spdlog/include/spdlog/sinks/rotating_file_sink.h create mode 100644 deps/LIEF/third-party/spdlog/include/spdlog/sinks/sink-inl.h create mode 100644 deps/LIEF/third-party/spdlog/include/spdlog/sinks/sink.h create mode 100644 deps/LIEF/third-party/spdlog/include/spdlog/sinks/stdout_color_sinks-inl.h create mode 100644 deps/LIEF/third-party/spdlog/include/spdlog/sinks/stdout_color_sinks.h create mode 100644 deps/LIEF/third-party/spdlog/include/spdlog/sinks/stdout_sinks-inl.h create mode 100644 deps/LIEF/third-party/spdlog/include/spdlog/sinks/stdout_sinks.h create mode 100644 deps/LIEF/third-party/spdlog/include/spdlog/sinks/syslog_sink.h create mode 100644 deps/LIEF/third-party/spdlog/include/spdlog/sinks/systemd_sink.h create mode 100644 deps/LIEF/third-party/spdlog/include/spdlog/sinks/tcp_sink.h create mode 100644 deps/LIEF/third-party/spdlog/include/spdlog/sinks/udp_sink.h create mode 100644 deps/LIEF/third-party/spdlog/include/spdlog/sinks/win_eventlog_sink.h create mode 100644 deps/LIEF/third-party/spdlog/include/spdlog/sinks/wincolor_sink-inl.h create mode 100644 deps/LIEF/third-party/spdlog/include/spdlog/sinks/wincolor_sink.h create mode 100644 deps/LIEF/third-party/spdlog/include/spdlog/spdlog-inl.h create mode 100644 deps/LIEF/third-party/spdlog/include/spdlog/spdlog.h create mode 100644 deps/LIEF/third-party/spdlog/include/spdlog/stopwatch.h create mode 100644 deps/LIEF/third-party/spdlog/include/spdlog/tweakme.h create mode 100644 deps/LIEF/third-party/spdlog/include/spdlog/version.h create mode 100644 deps/LIEF/third-party/spdlog/src/async.cpp create mode 100644 deps/LIEF/third-party/spdlog/src/bundled_fmtlib_format.cpp create mode 100644 deps/LIEF/third-party/spdlog/src/cfg.cpp create mode 100644 deps/LIEF/third-party/spdlog/src/color_sinks.cpp create mode 100644 deps/LIEF/third-party/spdlog/src/file_sinks.cpp create mode 100644 deps/LIEF/third-party/spdlog/src/spdlog.cpp create mode 100644 deps/LIEF/third-party/spdlog/src/stdout_sinks.cpp create mode 100644 deps/LIEF/third-party/tcb-span/span.hpp create mode 100644 deps/LIEF/third-party/utfcpp/LICENSE create mode 100644 deps/LIEF/third-party/utfcpp/README.md create mode 100644 deps/LIEF/third-party/utfcpp/source/utf8.h create mode 100644 deps/LIEF/third-party/utfcpp/source/utf8/checked.h create mode 100644 deps/LIEF/third-party/utfcpp/source/utf8/core.h create mode 100644 deps/LIEF/third-party/utfcpp/source/utf8/cpp11.h create mode 100644 deps/LIEF/third-party/utfcpp/source/utf8/cpp17.h create mode 100644 deps/LIEF/third-party/utfcpp/source/utf8/cpp20.h create mode 100644 deps/LIEF/third-party/utfcpp/source/utf8/unchecked.h diff --git a/deps/LIEF/config/mbedtls/config.h b/deps/LIEF/config/mbedtls/config.h new file mode 100644 index 00000000000000..1007c99aee06ab --- /dev/null +++ b/deps/LIEF/config/mbedtls/config.h @@ -0,0 +1,5 @@ +#include "mbedtls/mbedtls_config.h" + +#if defined (MBEDTLS_ARCH_IS_X86) +#undef MBEDTLS_AESNI_C +#endif diff --git a/deps/LIEF/include/LIEF/ART.hpp b/deps/LIEF/include/LIEF/ART.hpp new file mode 100644 index 00000000000000..7d920b61be47c4 --- /dev/null +++ b/deps/LIEF/include/LIEF/ART.hpp @@ -0,0 +1,28 @@ +/* Copyright 2017 - 2025 R. Thomas + * Copyright 2017 - 2025 Quarkslab + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef LIEF_ART_H +#define LIEF_ART_H + +#include "LIEF/config.h" + +#if defined(LIEF_ART_SUPPORT) +#include "LIEF/ART/Parser.hpp" +#include "LIEF/ART/utils.hpp" +#include "LIEF/ART/File.hpp" +#include "LIEF/ART/EnumToString.hpp" +#endif + +#endif diff --git a/deps/LIEF/include/LIEF/ART/EnumToString.hpp b/deps/LIEF/include/LIEF/ART/EnumToString.hpp new file mode 100644 index 00000000000000..a377b91a35764b --- /dev/null +++ b/deps/LIEF/include/LIEF/ART/EnumToString.hpp @@ -0,0 +1,40 @@ +/* Copyright 2017 - 2025 R. Thomas + * Copyright 2017 - 2025 Quarkslab + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef LIEF_ART_ENUM_TO_STRING_H +#define LIEF_ART_ENUM_TO_STRING_H +#include "LIEF/visibility.h" +#include "LIEF/ART/enums.hpp" + +namespace LIEF { +namespace ART { + +LIEF_API const char* to_string(STORAGE_MODES e); + +LIEF_API const char* to_string(ART_17::IMAGE_SECTIONS e); +LIEF_API const char* to_string(ART_29::IMAGE_SECTIONS e); +LIEF_API const char* to_string(ART_30::IMAGE_SECTIONS e); + +LIEF_API const char* to_string(ART_17::IMAGE_METHODS e); +LIEF_API const char* to_string(ART_44::IMAGE_METHODS e); + +LIEF_API const char* to_string(ART_17::IMAGE_ROOTS e); +LIEF_API const char* to_string(ART_44::IMAGE_ROOTS e); + +} // namespace ART +} // namespace LIEF + +#endif + diff --git a/deps/LIEF/include/LIEF/ART/File.hpp b/deps/LIEF/include/LIEF/ART/File.hpp new file mode 100644 index 00000000000000..ea00a53ac186da --- /dev/null +++ b/deps/LIEF/include/LIEF/ART/File.hpp @@ -0,0 +1,55 @@ +/* Copyright 2017 - 2025 R. Thomas + * Copyright 2017 - 2025 Quarkslab + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef LIEF_ART_FILE_H +#define LIEF_ART_FILE_H +#include + +#include "LIEF/ART/Header.hpp" + +#include "LIEF/visibility.h" +#include "LIEF/Object.hpp" + +namespace LIEF { +namespace ART { +class Parser; + +class LIEF_API File : public Object { + friend class Parser; + + public: + File& operator=(const File& copy) = delete; + File(const File& copy) = delete; + + const Header& header() const; + Header& header(); + + void accept(Visitor& visitor) const override; + + + ~File() override; + + LIEF_API friend std::ostream& operator<<(std::ostream& os, const File& art_file); + + private: + File(); + + Header header_; +}; + +} +} + +#endif diff --git a/deps/LIEF/include/LIEF/ART/Header.hpp b/deps/LIEF/include/LIEF/ART/Header.hpp new file mode 100644 index 00000000000000..3aef2eb4e20a9a --- /dev/null +++ b/deps/LIEF/include/LIEF/ART/Header.hpp @@ -0,0 +1,130 @@ +/* Copyright 2017 - 2025 R. Thomas + * Copyright 2017 - 2025 Quarkslab + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef LIEF_ART_HEADER_H +#define LIEF_ART_HEADER_H + +#include +#include + +#include "LIEF/ART/types.hpp" +#include "LIEF/ART/enums.hpp" + +#include "LIEF/visibility.h" +#include "LIEF/Object.hpp" + +namespace LIEF { +namespace ART { +class Parser; + +class LIEF_API Header : public Object { + friend class Parser; + + public: + using magic_t = std::array; + + Header(); + + template + LIEF_LOCAL Header(const T* header); + + Header(const Header&); + Header& operator=(const Header&); + + magic_t magic() const; + art_version_t version() const; + + uint32_t image_begin() const; + uint32_t image_size() const; + + uint32_t oat_checksum() const; + + uint32_t oat_file_begin() const; + uint32_t oat_file_end() const; + + uint32_t oat_data_begin() const; + uint32_t oat_data_end() const; + + int32_t patch_delta() const; + + uint32_t image_roots() const; + + uint32_t pointer_size() const; + bool compile_pic() const; + + uint32_t nb_sections() const; + uint32_t nb_methods() const; + + uint32_t boot_image_begin() const; + uint32_t boot_image_size() const; + + uint32_t boot_oat_begin() const; + uint32_t boot_oat_size() const; + + STORAGE_MODES storage_mode() const; + + uint32_t data_size() const; + + void accept(Visitor& visitor) const override; + + + LIEF_API friend std::ostream& operator<<(std::ostream& os, const Header& hdr); + + ~Header() override; + + private: + magic_t magic_; + art_version_t version_; + + uint32_t image_begin_; + uint32_t image_size_; + + uint32_t oat_checksum_; + + uint32_t oat_file_begin_; + uint32_t oat_file_end_; + + uint32_t oat_data_begin_; + uint32_t oat_data_end_; + + int32_t patch_delta_; + uint32_t image_roots_; + + uint32_t pointer_size_; + + bool compile_pic_; + + uint32_t nb_sections_; + uint32_t nb_methods_; + + bool is_pic_; + + // From ART 29 + // =========== + uint32_t boot_image_begin_; + uint32_t boot_image_size_; + + uint32_t boot_oat_begin_; + uint32_t boot_oat_size_; + + STORAGE_MODES storage_mode_; + + uint32_t data_size_; +}; + +} // Namespace ART +} // Namespace LIEF + +#endif diff --git a/deps/LIEF/include/LIEF/ART/Parser.hpp b/deps/LIEF/include/LIEF/ART/Parser.hpp new file mode 100644 index 00000000000000..21d2250e4e92fa --- /dev/null +++ b/deps/LIEF/include/LIEF/ART/Parser.hpp @@ -0,0 +1,107 @@ +/* Copyright 2017 - 2025 R. Thomas + * Copyright 2017 - 2025 Quarkslab + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef LIEF_ART_PARSER_H +#define LIEF_ART_PARSER_H +#include +#include +#include + +#include "LIEF/ART/types.hpp" +#include "LIEF/visibility.h" + +namespace LIEF { +class BinaryStream; +namespace ART { +class File; + + +/// Class which parses an ART file and transform into a ART::File object +class LIEF_API Parser { + public: + static std::unique_ptr parse(const std::string& file); + static std::unique_ptr parse(std::vector data, const std::string& name = ""); + + Parser& operator=(const Parser& copy) = delete; + Parser(const Parser& copy) = delete; + + private: + Parser(); + Parser(const std::string& file); + Parser(std::vector data); + virtual ~Parser(); + + void init(const std::string& name, art_version_t version); + + template + void parse_file(); + + template + size_t parse_header(); + + template + void parse_sections(); + + template + void parse_roots(); + + template + void parse_methods(); + + // Section parsing + template + void parse_objects(size_t offset, size_t size); + + template + void parse_art_fields(size_t offset, size_t size); + + template + void parse_art_methods(size_t offset, size_t size); + + template + void parse_interned_strings(size_t offset, size_t size); + + // Parse an **Array** of java.lang.DexCache objects + template + void parse_dex_caches(size_t offset, size_t size); + + // Parse a **Single** java.lang.DexCache object + template + void parse_dex_cache(size_t object_offset); + + // Parse an **Array** of java.lang.Class objects + template + void parse_class_roots(size_t offset, size_t size); + + // Parse java.lang.Class objects + template + void parse_class(size_t offset); + + // Parse java.lang.String objects + template + void parse_jstring(size_t offset); + + + //// Parse a **Single** java.lang.DexCache object + //template + //void parse_class_roots(size_t object_offset); + + std::unique_ptr file_; + std::unique_ptr stream_; + uint32_t imagebase_ = 0; +}; +} // namespace ART +} // namespace LIEF +#endif diff --git a/deps/LIEF/include/LIEF/ART/enums.hpp b/deps/LIEF/include/LIEF/ART/enums.hpp new file mode 100644 index 00000000000000..2165ea497bd7ce --- /dev/null +++ b/deps/LIEF/include/LIEF/ART/enums.hpp @@ -0,0 +1,133 @@ +/* Copyright 2017 - 2025 R. Thomas + * Copyright 2017 - 2025 Quarkslab + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef LIEF_ART_ENUMS_H +#define LIEF_ART_ENUMS_H + +namespace LIEF { +namespace ART { + +enum STORAGE_MODES { + STORAGE_UNCOMPRESSED = 0, + STORAGE_LZ4 = 1, + STORAGE_LZ4HC = 2, +}; + +namespace ART_17 { + +enum IMAGE_METHODS { + RESOLUTION_METHOD = 0, + IMT_CONFLICT_METHOD = 1, + IMT_UNIMPLEMENTED_METHOD = 2, + CALLEE_SAVE_METHOD = 3, + REFS_ONLY_SAVE_METHOD = 4, + REFS_AND_ARGS_SAVE_METHOD = 5, +}; + +enum IMAGE_SECTIONS { + SECTION_OBJECTS = 0, + SECTION_ART_FIELDS = 1, + SECTION_ART_METHODS = 2, + SECTION_INTERNED_STRINGS = 3, + SECTION_IMAGE_BITMAP = 4, +}; + +enum IMAGE_ROOTS { + DEX_CACHES = 0, + CLASS_ROOTS = 1, +}; + + +} // Namespace ART_17 + + +namespace ART_29 { + +using ART_17::IMAGE_METHODS; +using ART_17::IMAGE_ROOTS; + +enum IMAGE_SECTIONS { + SECTION_OBJECTS = 0, + SECTION_ART_FIELDS = 1, + SECTION_ART_METHODS = 2, + SECTION_RUNTIME_METHODS = 3, // New in ART 29 + SECTION_IMT_CONFLICT_TABLES = 4, // New in ART 29 + SECTION_DEX_CACHE_ARRAYS = 5, // New in ART 29 + SECTION_INTERNED_STRINGS = 6, + SECTION_CLASS_TABLE = 7, // New in ART 29 + SECTION_IMAGE_BITMAP = 8, +}; + + + +} // Namespace ART_29 + + +namespace ART_30 { + +using ART_29::IMAGE_METHODS; +using ART_29::IMAGE_ROOTS; + +enum IMAGE_SECTIONS { + SECTION_OBJECTS = 0, + SECTION_ART_FIELDS = 1, + SECTION_ART_METHODS = 2, + SECTION_RUNTIME_METHODS = 3, + SECTION_IM_TABLES = 4, // New in ART 30 + SECTION_IMT_CONFLICT_TABLES = 5, + SECTION_DEX_CACHE_ARRAYS = 6, + SECTION_INTERNED_STRINGS = 7, + SECTION_CLASS_TABLE = 8, + SECTION_IMAGE_BITMAP = 9, +}; + +} // Namespace ART_30 + +namespace ART_44 { + +using ART_30::IMAGE_SECTIONS; + +enum IMAGE_METHODS { + RESOLUTION_METHOD = 0, + IMT_CONFLICT_METHOD = 1, + IMT_UNIMPLEMENTED_METHOD = 2, + SAVE_ALL_CALLEE_SAVES_METHOD = 3, // New in ART 44 + SAVE_REFS_ONLY_METHOD = 4, // New in ART 44 + SAVE_REFS_AND_ARGS_METHOD = 5, // New in ART 44 + SAVE_EVERYTHING_METHOD = 6, // New in ART 44 +}; + + +enum IMAGE_ROOTS { + DEX_CACHES = 0, + CLASS_ROOTS = 1, + CLASS_LOADER = 2, // New in ART 44 +}; + +} // Namespace ART_44 + + +namespace ART_46 { + +using ART_30::IMAGE_SECTIONS; +using ART_30::IMAGE_METHODS; +using ART_30::IMAGE_ROOTS; + + +} // Namespace ART_46 + +} +} +#endif diff --git a/deps/LIEF/include/LIEF/ART/hash.hpp b/deps/LIEF/include/LIEF/ART/hash.hpp new file mode 100644 index 00000000000000..1aaa7d3acd9211 --- /dev/null +++ b/deps/LIEF/include/LIEF/ART/hash.hpp @@ -0,0 +1,47 @@ +/* Copyright 2017 - 2025 R. Thomas + * Copyright 2017 - 2025 Quarkslab + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef LIEF_ART_HASH_H +#define LIEF_ART_HASH_H + +#include "LIEF/visibility.h" +#include "LIEF/hash.hpp" + +namespace LIEF { +class Object; + +namespace ART { +class File; +class Header; + +class LIEF_API Hash : public LIEF::Hash { + public: + static LIEF::Hash::value_type hash(const Object& obj); + + public: + using LIEF::Hash::Hash; + using LIEF::Hash::visit; + + public: + void visit(const File& file) override; + void visit(const Header& header) override; + + ~Hash() override; +}; + +} +} + +#endif diff --git a/deps/LIEF/include/LIEF/ART/java_structures.hpp b/deps/LIEF/include/LIEF/ART/java_structures.hpp new file mode 100644 index 00000000000000..da3514aaffe6dc --- /dev/null +++ b/deps/LIEF/include/LIEF/ART/java_structures.hpp @@ -0,0 +1,397 @@ +/* Copyright 2017 - 2025 R. Thomas + * Copyright 2017 - 2025 Quarkslab + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef LIEF_ART_JAVA_STRUCTURES_H +#define LIEF_ART_JAVA_STRUCTURES_H + +#include +#include + +#include "LIEF/types.hpp" +#include "LIEF/ART/enums.hpp" +#include "LIEF/ART/types.hpp" + +namespace LIEF { +/// Namespace related to the LIEF's ART module +namespace ART { + +namespace details { + +struct no_brooks_read_barrier_t {}; + +// ====================== +// Android 6.0.1 - ART 17 +// ====================== +namespace ART_17 { + +/// Namespace related to the Java part of ART 17 +namespace Java { + +using heap_reference_t = uint32_t; + +struct brooks_read_barrier_t { + uint32_t x_rb_ptr; + uint32_t x_xpadding; +}; + +template +struct jobject_t { + heap_reference_t klass; + uint32_t monitor; + T brooks_read_barrier; +}; + +template<> +struct jobject_t { + heap_reference_t klass; + uint32_t monitor; +}; +template +struct ALIGNED_(4) jarray_t { + jobject_t object; + int32_t length; + uint32_t* elements; +}; + +template +struct ALIGNED_(4) jclass_t { + jobject_t object; + + heap_reference_t class_loader; + heap_reference_t component_type; + heap_reference_t dex_cache; + heap_reference_t dex_cache_strings; + heap_reference_t iftable; + heap_reference_t name; + heap_reference_t super_class; + heap_reference_t verify_error_class; + heap_reference_t vtable; + + uint32_t access_flags; + uint64_t direct_methods; + uint64_t ifields; + uint64_t sfields; + uint64_t virtual_methods; + uint32_t class_size; + uint32_t clinit_thread_id; + int32_t dex_class_def_idx; + int32_t dex_type_idx; + uint32_t num_direct_methods; + uint32_t num_instance_fields; + uint32_t num_reference_instance_fields; + uint32_t num_reference_static_fields; + uint32_t num_static_fields; + uint32_t num_virtual_methods; + uint32_t object_size; + uint32_t primitive_type; + uint32_t reference_instance_offsets; + int32_t status; +}; + +template +struct ALIGNED_(4) jstring_t { + jobject_t object; + int32_t count; + uint32_t hash_code; + uint16_t* value; +}; + +template +struct ALIGNED_(4) jdex_cache_t { + jobject_t object; + + heap_reference_t dex; + heap_reference_t location; + heap_reference_t resolved_fields; + heap_reference_t resolved_methods; + heap_reference_t resolved_types; + heap_reference_t strings; + uint64_t dex_file; +}; + + +} // Namespace Java +} // Namespace ART_17 + +// ====================== +// Android 7.0.0 - ART 29 +// ====================== +namespace ART_29 { + +/// Namespace related to the Java part of ART 29 +namespace Java { +using heap_reference_t = ART_17::Java::heap_reference_t; +using brooks_read_barrier_t = ART_17::Java::brooks_read_barrier_t; + +template +using jobject_t = ART_17::Java::jobject_t; + +template +using jarray_t = ART_17::Java::jarray_t; + +template +struct ALIGNED_(4) jclass_t { + jobject_t object; + + heap_reference_t annotation_type; // ADDED in ART 29 + heap_reference_t class_loader; + heap_reference_t component_type; + heap_reference_t dex_cache; + // heap_reference_t dex_cache_strings; // REMOVED in ART 29 + heap_reference_t iftable; + heap_reference_t name; + heap_reference_t super_class; + heap_reference_t verify_error; // Type CHANGED from Class to Object + heap_reference_t vtable; + + uint32_t access_flags; + uint64_t dex_cache_strings; // direct_methods REPLACED with dex_cache_string + uint64_t ifields; + uint64_t methods; // ADDED in ART 29 + uint64_t sfields; + uint32_t class_flags; // virtual_methods REPLACED with class_flags + uint32_t class_size; + uint32_t clinit_thread_id; + int32_t dex_class_def_idx; + int32_t dex_type_idx; + // uint32_t num_direct_methods; // REMOVED in ART 29 + // uint32_t num_instance_fields; // REMOVED in ART 29 + uint32_t num_reference_instance_fields; + uint32_t num_reference_static_fields; + // uint32_t num_static_fields; // REMOVED in ART 29 + // uint32_t num_virtual_methods; // REMOVED in ART 29 + uint32_t object_size; + uint32_t primitive_type; + uint32_t reference_instance_offsets; + int32_t status; + + uint16_t copied_methods_offset; // ADDED in ART 29 + uint16_t virtual_methods_offset; // ADDED in ART 29 +}; + + +// No changes in jstring structure +template +using jstring_t = ART_17::Java::jstring_t; + +template +struct ALIGNED_(4) jdex_cache_t { + jobject_t object; + + heap_reference_t dex; + heap_reference_t location; + uint64_t dex_file; // LOCATION CHANGED + uint64_t resolved_fields; // TYPE CHANGED from heap_reference_t to uint64_t + uint64_t resolved_methods; // TYPE CHANGED from heap_reference_t to uint64_t + uint64_t resolved_types; // TYPE CHANGED from heap_reference_t to uint64_t + uint64_t strings; // TYPE CHANGED from heap_reference_t to uint64_t + uint32_t num_resolved_fields; // ADDED in ART 29 + uint32_t num_resolved_methods; // ADDED in ART 29 + uint32_t num_resolved_types; // ADDED in ART 29 + uint32_t num_strings; // ADDED in ART 29 +}; + + + + +} // Namespace Java +} // Namespace ART_29 + + +// ====================== +// Android 7.1.X - ART 30 +// ====================== +namespace ART_30 { + +/// Namespace related to the Java part of ART 30 +namespace Java { + +using heap_reference_t = ART_29::Java::heap_reference_t; +using brooks_read_barrier_t = ART_29::Java::brooks_read_barrier_t; + +template +using jobject_t = ART_29::Java::jobject_t; + +template +using jarray_t = ART_29::Java::jarray_t; + +template +using jclass_t = ART_29::Java::jclass_t; + +// No changes in jstring structure +template +using jstring_t = ART_29::Java::jstring_t; + +// No changes in jdex_cache structure +template +using jdex_cache_t = ART_29::Java::jdex_cache_t; + +} // Namespace Java +} // Namespace ART_30 + +// ====================== +// Android 8.0.0 - ART 44 +// ====================== +namespace ART_44 { + +/// Namespace related to the Java part of ART 44 +namespace Java { + + +using heap_reference_t = ART_30::Java::heap_reference_t; +using brooks_read_barrier_t = ART_30::Java::brooks_read_barrier_t; + +template +using jobject_t = ART_30::Java::jobject_t; + +template +using jarray_t = ART_30::Java::jarray_t; + +template +struct ALIGNED_(4) jclass_t { + jobject_t object; + + // heap_reference_t annotation_type; // REMOVED in ART 44 + heap_reference_t class_loader; + heap_reference_t component_type; + heap_reference_t dex_cache; + heap_reference_t ext_data; // ADDED in ART 44 + heap_reference_t iftable; + heap_reference_t name; + heap_reference_t super_class; + // heap_reference_t verify_error; // REMOVED in ART 44 + heap_reference_t vtable; + + // uint32_t access_flags; // REMOVED in ART 44 + // uint64_t dex_cache_strings; // REMOVED in ART 44 + uint64_t ifields; + uint64_t methods; + uint64_t sfields; + uint32_t access_flags; // ADDED in ART 44 + uint32_t class_flags; + uint32_t class_size; + uint32_t clinit_thread_id; + int32_t dex_class_def_idx; + int32_t dex_type_idx; + uint32_t num_reference_instance_fields; + uint32_t num_reference_static_fields; + uint32_t object_size; + uint32_t object_size_alloc_fast_path; // ADDED in ART 44 + uint32_t primitive_type; + uint32_t reference_instance_offsets; + int32_t status; + uint16_t copied_methods_offset; + uint16_t virtual_methods_offset; +}; + + +// No changes in jstring structure but string can be +// encoded as as char16_t or char (compressed) +// count[0] (LSB) == 1 ----> compressed +// count[0] (LSB) == 0 ----> chat16_t +template +using jstring_t = ART_30::Java::jstring_t; + +template +struct ALIGNED_(4) jdex_cache_t { + jobject_t object; + + // heap_reference_t dex; // REMOVED in ART 44 + heap_reference_t location; + uint32_t num_resolved_call_sites; // ADDED in ART 44 (related to DEX38 format) + uint64_t dex_file; + uint64_t resolved_call_sites; // ADDED in ART 44 (related to DEX38 format) + uint64_t resolved_fields; + uint64_t resolved_method_types; // ADDED in ART 44 + uint64_t resolved_methods; + uint64_t resolved_types; + uint64_t strings; + uint32_t num_resolved_fields; + uint32_t num_resolved_methods_types; // ADDED in ART 44 + uint32_t num_resolved_methods; + uint32_t num_resolved_types; + uint32_t num_strings; +}; + + +} // Namespace Java +} // Namespace ART_44 + + +// ====================== +// Android 8.1.X - ART 46 +// ====================== +namespace ART_46 { + +/// Namespace related to the Java part of ART 46 +namespace Java { + +using heap_reference_t = ART_44::Java::heap_reference_t; +using brooks_read_barrier_t = ART_44::Java::brooks_read_barrier_t; + +template +using jobject_t = ART_44::Java::jobject_t; + +template +using jarray_t = ART_44::Java::jarray_t; + +template +using jclass_t = ART_44::Java::jclass_t; + +template +using jstring_t = ART_44::Java::jstring_t; + +template +using jdex_cache_t = ART_44::Java::jdex_cache_t; + +} // Namespace Java +} // Namespace ART_46 + +// ====================== +// Android 9.0.0 - ART 66 +// ====================== +namespace ART_56 { + +/// Namespace related to the Java part of ART 46 +namespace Java { + +using heap_reference_t = ART_46::Java::heap_reference_t; +using brooks_read_barrier_t = ART_46::Java::brooks_read_barrier_t; + +template +using jobject_t = ART_46::Java::jobject_t; + +template +using jarray_t = ART_46::Java::jarray_t; + +template +using jclass_t = ART_46::Java::jclass_t; + +template +using jstring_t = ART_46::Java::jstring_t; + +template +using jdex_cache_t = ART_46::Java::jdex_cache_t; + +} // Namespace Java +} // Namespace ART_56 + +} // namespace details +} // Namespace ART +} // Namespace LIEF + + + +#endif diff --git a/deps/LIEF/include/LIEF/ART/json.hpp b/deps/LIEF/include/LIEF/ART/json.hpp new file mode 100644 index 00000000000000..3302272bd8c51a --- /dev/null +++ b/deps/LIEF/include/LIEF/ART/json.hpp @@ -0,0 +1,31 @@ +/* Copyright 2017 - 2025 R. Thomas + * Copyright 2017 - 2025 Quarkslab + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef LIEF_ART_PUBLIC_JSON_H +#define LIEF_ART_PUBLIC_JSON_H + +#include "LIEF/visibility.h" +#include + +namespace LIEF { +class Object; +namespace ART { + +LIEF_API std::string to_json(const Object& v); + +} +} + +#endif diff --git a/deps/LIEF/include/LIEF/ART/types.hpp b/deps/LIEF/include/LIEF/ART/types.hpp new file mode 100644 index 00000000000000..706e4143d08fbc --- /dev/null +++ b/deps/LIEF/include/LIEF/ART/types.hpp @@ -0,0 +1,31 @@ +/* Copyright 2017 - 2025 R. Thomas + * Copyright 2017 - 2025 Quarkslab + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef LIEF_ART_TYPE_TRAITS_H +#define LIEF_ART_TYPE_TRAITS_H + +#include +#include +#include "LIEF/iterators.hpp" + +namespace LIEF { +namespace ART { + +using art_version_t = uint32_t; + +} // Namesapce ART +} // Namespace LIEF + +#endif diff --git a/deps/LIEF/include/LIEF/ART/utils.hpp b/deps/LIEF/include/LIEF/ART/utils.hpp new file mode 100644 index 00000000000000..fc4bcd8e3eede0 --- /dev/null +++ b/deps/LIEF/include/LIEF/ART/utils.hpp @@ -0,0 +1,51 @@ +/* Copyright 2017 - 2025 R. Thomas + * Copyright 2017 - 2025 Quarkslab + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef LIEF_ART_UTILS_H +#define LIEF_ART_UTILS_H + +#include +#include + +#include "LIEF/ART/types.hpp" + +#include "LIEF/platforms/android.hpp" + +#include "LIEF/types.hpp" +#include "LIEF/visibility.h" + +namespace LIEF { +namespace ART { + +/// Check if the given file is an ART one. +LIEF_API bool is_art(const std::string& file); + +/// Check if the given raw data is an ART one. +LIEF_API bool is_art(const std::vector& raw); + +/// Return the ART version of the given file +LIEF_API art_version_t version(const std::string& file); + +/// Return the ART version of the raw data +LIEF_API art_version_t version(const std::vector& raw); + +/// Return the ANDROID_VERSIONS associated with the given ART version +LIEF_API LIEF::Android::ANDROID_VERSIONS android_version(art_version_t version); + +} +} + + +#endif diff --git a/deps/LIEF/include/LIEF/ASM.hpp b/deps/LIEF/include/LIEF/ASM.hpp new file mode 100644 index 00000000000000..5bc1a376b2c5ba --- /dev/null +++ b/deps/LIEF/include/LIEF/ASM.hpp @@ -0,0 +1,28 @@ +/* Copyright 2017 - 2025 R. Thomas + * Copyright 2017 - 2025 Quarkslab + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef LIEF_ASM_H +#define LIEF_ASM_H +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#endif diff --git a/deps/LIEF/include/LIEF/Abstract.hpp b/deps/LIEF/include/LIEF/Abstract.hpp new file mode 100644 index 00000000000000..bc10e669486524 --- /dev/null +++ b/deps/LIEF/include/LIEF/Abstract.hpp @@ -0,0 +1,26 @@ +/* Copyright 2017 - 2025 R. Thomas + * Copyright 2017 - 2025 Quarkslab + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef LIEF_ABSTRACT_H +#define LIEF_ABSTRACT_H + +#include +#include +#include +#include +#include +#include + +#endif diff --git a/deps/LIEF/include/LIEF/Abstract/Binary.hpp b/deps/LIEF/include/LIEF/Abstract/Binary.hpp new file mode 100644 index 00000000000000..8e4f738a76efdb --- /dev/null +++ b/deps/LIEF/include/LIEF/Abstract/Binary.hpp @@ -0,0 +1,441 @@ +/* Copyright 2017 - 2025 R. Thomas + * Copyright 2017 - 2025 Quarkslab + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef LIEF_ABSTRACT_BINARY_H +#define LIEF_ABSTRACT_BINARY_H + +#include +#include +#include + +#include "LIEF/visibility.h" +#include "LIEF/Object.hpp" +#include "LIEF/iterators.hpp" +#include "LIEF/errors.hpp" +#include "LIEF/span.hpp" + +#include "LIEF/Abstract/Header.hpp" +#include "LIEF/Abstract/Function.hpp" + +#include "LIEF/asm/Instruction.hpp" +#include "LIEF/asm/AssemblerConfig.hpp" + +namespace llvm { +class MCInst; +} + +/// LIEF namespace +namespace LIEF { +class Section; +class Relocation; +class Symbol; + +class DebugInfo; + +namespace assembly { +class Engine; +} + +/// Generic interface representing a binary executable. +/// +/// This class provides a unified interface across multiple binary formats +/// such as ELF, PE, Mach-O, and others. It enables users to access binary +/// components like headers, sections, symbols, relocations, +/// and functions in a format-agnostic way. +/// +/// Subclasses like LIEF::PE::Binary implement format-specific API +class LIEF_API Binary : public Object { + public: + + /// Enumeration of virtual address types used for patching and memory access. + enum class VA_TYPES { + /// Automatically determine if the address is absolute or relative + /// (default behavior). + AUTO = 0, + + /// Relative Virtual Address (RVA), offset from image base. + RVA = 1, + + /// Absolute Virtual Address. + VA = 2 + }; + + enum FORMATS { + UNKNOWN = 0, + ELF, + PE, + MACHO, + OAT, + }; + + using functions_t = std::vector; + + /// Internal container + using sections_t = std::vector; + + /// Iterator that outputs LIEF::Section& + using it_sections = ref_iterator; + + /// Iterator that outputs const LIEF::Section& + using it_const_sections = const_ref_iterator; + + /// Internal container + using symbols_t = std::vector; + + /// Iterator that outputs LIEF::Symbol& + using it_symbols = ref_iterator; + + /// Iterator that outputs const LIEF::Symbol& + using it_const_symbols = const_ref_iterator; + + /// Internal container + using relocations_t = std::vector; + + /// Iterator that outputs LIEF::Relocation& + using it_relocations = ref_iterator; + + /// Iterator that outputs const LIEF::Relocation& + using it_const_relocations = const_ref_iterator; + + /// Instruction iterator + using instructions_it = iterator_range; + + public: + Binary(); + Binary(FORMATS fmt); + + ~Binary() override; + + Binary& operator=(const Binary&) = delete; + Binary(const Binary&) = delete; + + /// Executable format (ELF, PE, Mach-O) of the underlying binary + FORMATS format() const { + return format_; + } + + /// Return the abstract header of the binary + Header header() const { + return get_abstract_header(); + } + + /// Return an iterator over the abstracted symbols in which the elements **can** be modified + it_symbols symbols() { + return get_abstract_symbols(); + } + + /// Return an iterator over the abstracted symbols in which the elements **can't** be modified + it_const_symbols symbols() const { + return const_cast(this)->get_abstract_symbols(); + } + + /// Check if a Symbol with the given name exists + bool has_symbol(const std::string& name) const { + return get_symbol(name) != nullptr; + } + + /// Return the Symbol with the given name + /// If the symbol does not exist, return a nullptr + const Symbol* get_symbol(const std::string& name) const; + + Symbol* get_symbol(const std::string& name) { + return const_cast(static_cast(this)->get_symbol(name)); + } + + /// Return an iterator over the binary's sections (LIEF::Section) + it_sections sections() { + return get_abstract_sections(); + } + + it_const_sections sections() const { + return const_cast(this)->get_abstract_sections(); + } + + /// Remove **all** the sections in the underlying binary + virtual void remove_section(const std::string& name, bool clear = false) = 0; + + /// Return an iterator over the binary relocation (LIEF::Relocation) + it_relocations relocations() { + return get_abstract_relocations(); + } + + it_const_relocations relocations() const { + return const_cast(this)->get_abstract_relocations(); + } + + /// Binary's entrypoint (if any) + virtual uint64_t entrypoint() const = 0; + + /// Binary's original size + uint64_t original_size() const { + return original_size_; + } + + /// Return the functions exported by the binary + functions_t exported_functions() const { + return get_abstract_exported_functions(); + } + + /// Return libraries which are imported by the binary + std::vector imported_libraries() const { + return get_abstract_imported_libraries(); + } + + /// Return functions imported by the binary + functions_t imported_functions() const { + return get_abstract_imported_functions(); + } + + /// Return the address of the given function name + virtual result get_function_address(const std::string& func_name) const; + + /// Method so that a ``visitor`` can visit us + void accept(Visitor& visitor) const override; + + std::vector xref(uint64_t address) const; + + /// Patch the content at virtual address @p address with @p patch_value + /// + /// @param[in] address Address to patch + /// @param[in] patch_value Patch to apply + /// @param[in] addr_type Specify if the address should be used as an + /// absolute virtual address or a RVA + virtual void patch_address(uint64_t address, const std::vector& patch_value, + VA_TYPES addr_type = VA_TYPES::AUTO) = 0; + + /// Patch the address with the given value + /// + /// @param[in] address Address to patch + /// @param[in] patch_value Patch to apply + /// @param[in] size Size of the value in **bytes** (1, 2, ... 8) + /// @param[in] addr_type Specify if the address should be used as an absolute virtual address or an RVA + virtual void patch_address(uint64_t address, uint64_t patch_value, size_t size = sizeof(uint64_t), + VA_TYPES addr_type = VA_TYPES::AUTO) = 0; + + /// Return the content located at the given virtual address + virtual span + get_content_from_virtual_address(uint64_t virtual_address, uint64_t size, + VA_TYPES addr_type = VA_TYPES::AUTO) const = 0; + + /// Get the integer value at the given virtual address + template + LIEF::result get_int_from_virtual_address( + uint64_t va, VA_TYPES addr_type = VA_TYPES::AUTO) const + { + T value; + static_assert(std::is_integral::value, "Require an integral type"); + span raw = get_content_from_virtual_address(va, sizeof(T), addr_type); + if (raw.empty() || raw.size() < sizeof(T)) { + return make_error_code(lief_errors::read_error); + } + + std::copy(raw.data(), raw.data() + sizeof(T), + reinterpret_cast(&value)); + return value; + } + + /// Change binary's original size. + /// + /// @warning + /// This function should be used carefully as some optimizations + /// can be performed with this value + void original_size(uint64_t size) { + original_size_ = size; + } + + /// Check if the binary is position independent + virtual bool is_pie() const = 0; + + /// Check if the binary uses ``NX`` protection + virtual bool has_nx() const = 0; + + /// Default image base address if the ASLR is not enabled. + virtual uint64_t imagebase() const = 0; + + /// Constructor functions that are called prior any other functions + virtual functions_t ctor_functions() const = 0; + + /// Convert the given offset into a virtual address. + /// + /// @param[in] offset The offset to convert. + /// @param[in] slide If not 0, it will replace the default base address (if any) + virtual result offset_to_virtual_address(uint64_t offset, uint64_t slide = 0) const = 0; + + virtual std::ostream& print(std::ostream& os) const { + return os; + } + + LIEF_API friend std::ostream& operator<<(std::ostream& os, const Binary& binary) { + binary.print(os); + return os; + } + + /// Return the debug info if present. It can be either a + /// LIEF::dwarf::DebugInfo or a LIEF::pdb::DebugInfo + /// + /// For ELF and Mach-O binaries, it returns the given DebugInfo object **only** + /// if the binary embeds the DWARF debug info in the binary itself. + /// + /// For PE file, this function tries to find the **external** PDB using + /// the LIEF::PE::CodeViewPDB::filename() output (if present). One can also + /// use LIEF::pdb::load() or LIEF::pdb::DebugInfo::from_file() to get PDB debug + /// info. + /// + /// \warning This function requires LIEF's extended version otherwise it + /// **always** return a nullptr + DebugInfo* debug_info() const; + + /// Disassemble code starting at the given virtual address and with the given + /// size. + /// + /// ```cpp + /// auto insts = binary->disassemble(0xacde, 100); + /// for (std::unique_ptr inst : insts) { + /// std::cout << inst->to_string() << '\n'; + /// } + /// ``` + /// + /// \see LIEF::assembly::Instruction + instructions_it disassemble(uint64_t address, size_t size) const; + + /// Disassemble code starting at the given virtual address + /// + /// ```cpp + /// auto insts = binary->disassemble(0xacde); + /// for (std::unique_ptr inst : insts) { + /// std::cout << inst->to_string() << '\n'; + /// } + /// ``` + /// + /// \see LIEF::assembly::Instruction + instructions_it disassemble(uint64_t address) const; + + /// Disassemble code for the given symbol name + /// + /// ```cpp + /// auto insts = binary->disassemble("__libc_start_main"); + /// for (std::unique_ptr inst : insts) { + /// std::cout << inst->to_string() << '\n'; + /// } + /// ``` + /// + /// \see LIEF::assembly::Instruction + instructions_it disassemble(const std::string& function) const; + + /// Disassemble code provided by the given buffer at the specified + /// `address` parameter. + /// + /// \see LIEF::assembly::Instruction + instructions_it disassemble(const uint8_t* buffer, size_t size, + uint64_t address = 0) const; + + + /// Disassemble code provided by the given vector of bytes at the specified + /// `address` parameter. + /// + /// \see LIEF::assembly::Instruction + instructions_it disassemble(const std::vector& buffer, + uint64_t address = 0) const { + return disassemble(buffer.data(), buffer.size(), address); + } + + instructions_it disassemble(LIEF::span buffer, + uint64_t address = 0) const { + return disassemble(buffer.data(), buffer.size(), address); + } + + instructions_it disassemble(LIEF::span buffer, uint64_t address = 0) const { + return disassemble(buffer.data(), buffer.size(), address); + } + + /// Assemble **and patch** the provided assembly code at the specified address. + /// + /// The function returns the generated assembly bytes + /// + /// ```cpp + /// bin->assemble(0x12000440, R"asm( + /// xor rax, rbx; + /// mov rcx, rax; + /// )asm"); + /// ``` + /// + /// If you need to configure the assembly engine or to define addresses for + /// symbols, you can provide your own assembly::AssemblerConfig. + std::vector assemble(uint64_t address, const std::string& Asm, + assembly::AssemblerConfig& config = assembly::AssemblerConfig::default_config()); + + /// Assemble **and patch** the address with the given LLVM MCInst. + /// + /// \warning Because of ABI compatibility, this MCInst can **only be used** + /// with the **same** version of LLVM used by LIEF (see documentation) + std::vector assemble(uint64_t address, const llvm::MCInst& inst); + + /// Assemble **and patch** the address with the given LLVM MCInst. + /// + /// \warning Because of ABI compatibility, this MCInst can **only be used** + /// with the **same** version of LLVM used by LIEF (see documentation) + std::vector assemble(uint64_t address, + const std::vector& insts); + + /// Get the default memory page size according to the architecture and + /// the format of the current binary + virtual uint64_t page_size() const; + + /// Load and associate an external debug file (e.g., DWARF or PDB) with this binary. + /// + /// This method attempts to load the debug information from the file located at the given path, + /// and binds it to the current binary instance. If successful, it returns a pointer to the + /// loaded DebugInfo object. + /// + /// \param path Path to the external debug file (e.g., `.dwarf`, `.pdb`) + /// \return Pointer to the loaded DebugInfo object on success, or `nullptr` on failure. + /// + /// \warning It is the caller's responsibility to ensure that the debug file is + /// compatible with the binary. Incorrect associations may lead to + /// inconsistent or invalid results. + /// + /// \note This function does not verify that the debug file matches the binary's unique + /// identifier (e.g., build ID, GUID). + DebugInfo* load_debug_info(const std::string& path); + + protected: + FORMATS format_ = FORMATS::UNKNOWN; + mutable std::unique_ptr debug_info_; + mutable std::unordered_map> engines_; + uint64_t original_size_ = 0; + + assembly::Engine* get_engine(uint64_t address) const; + + template + LIEF_LOCAL assembly::Engine* get_cache_engine(uint64_t address, F&& f) const; + + // These functions need to be overloaded by the object that claims to extend this Abstract Binary + virtual Header get_abstract_header() const = 0; + virtual symbols_t get_abstract_symbols() = 0; + virtual sections_t get_abstract_sections() = 0; + virtual relocations_t get_abstract_relocations() = 0; + + virtual functions_t get_abstract_exported_functions() const = 0; + virtual functions_t get_abstract_imported_functions() const = 0; + virtual std::vector get_abstract_imported_libraries() const = 0; +}; + +LIEF_API const char* to_string(Binary::VA_TYPES e); +LIEF_API const char* to_string(Binary::FORMATS e); + +} + + +#endif diff --git a/deps/LIEF/include/LIEF/Abstract/DebugInfo.hpp b/deps/LIEF/include/LIEF/Abstract/DebugInfo.hpp new file mode 100644 index 00000000000000..24961cf791341b --- /dev/null +++ b/deps/LIEF/include/LIEF/Abstract/DebugInfo.hpp @@ -0,0 +1,79 @@ +/* Copyright 2022 - 2025 R. Thomas + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef LIEF_DEBUGINFO_H +#define LIEF_DEBUGINFO_H +#include +#include +#include + +#include "LIEF/visibility.h" +#include "LIEF/optional.hpp" +namespace LIEF { + +class Binary; + +namespace details { +class DebugInfo; +} + +/// This class provides a generic interface for accessing debug information +/// from different formats such as DWARF and PDB. +/// +/// Users can use this interface to access high-level debug features like +/// resolving function addresses. +/// +/// See: LIEF::pdb::DebugInfo, LIEF::dwarf::DebugInfo +class LIEF_API DebugInfo { + public: + friend class Binary; + enum class FORMAT { + UNKNOWN = 0, + DWARF, PDB, + }; + DebugInfo(std::unique_ptr impl); + + virtual ~DebugInfo(); + + virtual FORMAT format() const { + return FORMAT::UNKNOWN; + } + + /// This function can be used to **down cast** a DebugInfo instance: + /// + /// ```cpp + /// std::unique_ptr dbg = bin->debug_info(); + /// if (const auto* dwarf = inst->as()) { + /// dwarf->find_function("main"); + /// } + /// ``` + template + const T* as() const { + static_assert(std::is_base_of::value, + "Require Instruction inheritance"); + if (T::classof(this)) { + return static_cast(this); + } + return nullptr; + } + + /// Attempt to resolve the address of the function specified by `name`. + virtual optional find_function_address(const std::string& name) const = 0; + + protected: + std::unique_ptr impl_; +}; + +} +#endif diff --git a/deps/LIEF/include/LIEF/Abstract/Function.hpp b/deps/LIEF/include/LIEF/Abstract/Function.hpp new file mode 100644 index 00000000000000..66004763d6eca7 --- /dev/null +++ b/deps/LIEF/include/LIEF/Abstract/Function.hpp @@ -0,0 +1,121 @@ +/* Copyright 2017 - 2025 R. Thomas + * Copyright 2017 - 2025 Quarkslab + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef LIEF_ABSTRACT_FUNCTION_H +#define LIEF_ABSTRACT_FUNCTION_H + +#include +#include + +#include "LIEF/Abstract/Symbol.hpp" +#include "LIEF/visibility.h" +#include "LIEF/enums.hpp" + +namespace LIEF { + +/// Class that represents a function in the binary +class LIEF_API Function : public Symbol { + public: + /// Flags used to characterize the semantics of the function + enum class FLAGS : uint32_t { + NONE = 0, + /// The function acts as a constructor. + /// + /// Usually this flag is associated with functions + /// that are located in the `.init_array`, `__mod_init_func` or `.tls` sections + CONSTRUCTOR = 1 << 0, + + /// The function acts as a destructor. + /// + /// Usually this flag is associated with functions + /// that are located in the `.fini_array` or `__mod_term_func` sections + DESTRUCTOR = 1 << 1, + + /// The function is associated with Debug information + DEBUG_INFO = 1 << 2, + + /// The function is exported by the binary and the address() method + /// returns its virtual address in the binary + EXPORTED = 1 << 3, + + /// The function is **imported** by the binary and the address() should return 0 + IMPORTED = 1 << 4, + }; + + public: + Function() = default; + Function(const std::string& name) : + Symbol(name) + {} + Function(uint64_t address) : + Function("", address) + {} + Function(const std::string& name, uint64_t address) : + Symbol(name, address) + {} + Function(const std::string& name, uint64_t address, FLAGS flags) : + Function(name, address) + { + flags_ = flags; + } + + Function(const Function&) = default; + Function& operator=(const Function&) = default; + + ~Function() override = default; + + /// List of FLAGS + std::vector flags_list() const; + + FLAGS flags() const { + return flags_; + } + + /// Add a flag to the current function + Function& add(FLAGS f) { + flags_ = (FLAGS)((uint32_t)flags_ | (uint32_t)f); + return *this; + } + + /// Check if the function has the given flag + bool has(FLAGS f) const { + return ((uint32_t)flags_ & (uint32_t)f) != 0; + } + + /// Address of the current function. For functions that are set with the FLAGS::IMPORTED flag, + /// this value is likely 0. + uint64_t address() const { + return value_; + } + + void address(uint64_t address) { + value_ = address; + } + + void accept(Visitor& visitor) const override; + + LIEF_API friend std::ostream& operator<<(std::ostream& os, const Function& entry); + + protected: + FLAGS flags_ = FLAGS::NONE; +}; + +LIEF_API const char* to_string(Function::FLAGS e); +} + +ENABLE_BITMASK_OPERATORS(LIEF::Function::FLAGS); + +#endif + diff --git a/deps/LIEF/include/LIEF/Abstract/Header.hpp b/deps/LIEF/include/LIEF/Abstract/Header.hpp new file mode 100644 index 00000000000000..036e64cf5a5459 --- /dev/null +++ b/deps/LIEF/include/LIEF/Abstract/Header.hpp @@ -0,0 +1,147 @@ +/* Copyright 2017 - 2025 R. Thomas + * Copyright 2017 - 2025 Quarkslab + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef LIEF_ABSTRACT_HEADER_H +#define LIEF_ABSTRACT_HEADER_H + +#include +#include +#include + +#include "LIEF/Object.hpp" +#include "LIEF/visibility.h" +#include "LIEF/enums.hpp" + +namespace LIEF { +namespace ELF { +class Binary; +} + +namespace PE { +class Binary; +} + +namespace MachO { +class Binary; +} + +class LIEF_API Header : public Object { + public: + enum class ARCHITECTURES { + UNKNOWN = 0, + ARM, + ARM64, + MIPS, + X86, + X86_64, + PPC, + SPARC, + SYSZ, + XCORE, + RISCV, + LOONGARCH, + PPC64, + }; + + enum class ENDIANNESS { + UNKNOWN = 0, + BIG, + LITTLE, + }; + + enum MODES : uint64_t { + NONE = 0, + + BITS_16 = 1LLU << 0, /// 16-bits architecture + BITS_32 = 1LLU << 1, /// 32-bits architecture + BITS_64 = 1LLU << 2, /// 64-bits architecture + THUMB = 1LLU << 3, /// Support ARM Thumb mode + + ARM64E = 1LLU << 4, /// ARM64 with extended (security) features + }; + + enum class OBJECT_TYPES { + UNKNOWN = 0, + EXECUTABLE, + LIBRARY, + OBJECT, + }; + + static Header from(const LIEF::ELF::Binary& elf); + static Header from(const LIEF::PE::Binary& pe); + static Header from(const LIEF::MachO::Binary& macho); + + Header() = default; + Header(const Header&) = default; + Header& operator=(const Header&) = default; + ~Header() override = default; + + /// Target architecture + ARCHITECTURES architecture() const { + return architecture_; + } + + /// Optional features for the given architecture + MODES modes() const { + return modes_; + } + + /// MODES as a vector + std::vector modes_list() const; + + bool is(MODES m) const { + return ((uint64_t)m & (uint64_t)modes_) != 0; + } + + OBJECT_TYPES object_type() const { + return object_type_; + } + uint64_t entrypoint() const { + return entrypoint_; + } + + ENDIANNESS endianness() const { + return endianness_; + } + + bool is_32() const { + return ((uint64_t)modes_ & (uint64_t)MODES::BITS_32) != 0; + } + + bool is_64() const { + return ((uint64_t)modes_ & (uint64_t)MODES::BITS_64) != 0; + } + + void accept(Visitor& visitor) const override; + + LIEF_API friend std::ostream& operator<<(std::ostream& os, const Header& hdr); + + protected: + ARCHITECTURES architecture_ = ARCHITECTURES::UNKNOWN; + OBJECT_TYPES object_type_ = OBJECT_TYPES::UNKNOWN; + uint64_t entrypoint_ = 0; + ENDIANNESS endianness_ = ENDIANNESS::UNKNOWN; + MODES modes_ = MODES::NONE; +}; + +LIEF_API const char* to_string(Header::ARCHITECTURES e); +LIEF_API const char* to_string(Header::OBJECT_TYPES e); +LIEF_API const char* to_string(Header::MODES e); +LIEF_API const char* to_string(Header::ENDIANNESS e); +} + +ENABLE_BITMASK_OPERATORS(LIEF::Header::MODES); + +#endif diff --git a/deps/LIEF/include/LIEF/Abstract/Parser.hpp b/deps/LIEF/include/LIEF/Abstract/Parser.hpp new file mode 100644 index 00000000000000..9a3665192bb635 --- /dev/null +++ b/deps/LIEF/include/LIEF/Abstract/Parser.hpp @@ -0,0 +1,60 @@ +/* Copyright 2017 - 2025 R. Thomas + * Copyright 2017 - 2025 Quarkslab + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef LIEF_ABSTRACT_PARSER_H +#define LIEF_ABSTRACT_PARSER_H + +#include +#include +#include + +#include "LIEF/visibility.h" + +namespace LIEF { +class BinaryStream; +class Binary; + +/// Main interface to parse an executable regardless of its format +class LIEF_API Parser { + public: + /// Construct an LIEF::Binary from the given filename + /// + /// @warning If the target file is a FAT Mach-O, it will return the **last** one + /// @see LIEF::MachO::Parser::parse + static std::unique_ptr parse(const std::string& filename); + + + /// Construct an LIEF::Binary from the given raw data + /// + /// @warning If the target file is a FAT Mach-O, it will return the **last** one + /// @see LIEF::MachO::Parser::parse + static std::unique_ptr parse(const std::vector& raw); + + /// Construct an LIEF::Binary from the given stream + /// + /// @warning If the target file is a FAT Mach-O, it will return the **last** one + /// @see LIEF::MachO::Parser::parse + static std::unique_ptr parse(std::unique_ptr stream); + + protected: + Parser(const std::string& file); + uint64_t binary_size_ = 0; + + virtual ~Parser(); + Parser(); +}; +} + +#endif diff --git a/deps/LIEF/include/LIEF/Abstract/Relocation.hpp b/deps/LIEF/include/LIEF/Abstract/Relocation.hpp new file mode 100644 index 00000000000000..c22f8e7a508cf6 --- /dev/null +++ b/deps/LIEF/include/LIEF/Abstract/Relocation.hpp @@ -0,0 +1,98 @@ +/* Copyright 2017 - 2025 R. Thomas + * Copyright 2017 - 2025 Quarkslab + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef LIEF_ABSTRACT_RELOCATION_H +#define LIEF_ABSTRACT_RELOCATION_H + +#include +#include + +#include "LIEF/Object.hpp" +#include "LIEF/visibility.h" + +namespace LIEF { +/// Class which represents an abstracted Relocation +class LIEF_API Relocation : public Object { + + public: + Relocation() = default; + + /// Constructor from a relocation's address and size + Relocation(uint64_t address, uint8_t size) : + address_(address), + size_(size) + {} + + ~Relocation() override = default; + + Relocation& operator=(const Relocation&) = default; + Relocation(const Relocation&) = default; + void swap(Relocation& other) { + std::swap(address_, other.address_); + std::swap(size_, other.size_); + } + + /// Relocation's address + virtual uint64_t address() const { + return address_; + } + + /// Relocation size in **bits** + virtual size_t size() const { + return size_; + } + + virtual void address(uint64_t address) { + address_ = address; + } + + virtual void size(size_t size) { + size_ = (uint8_t)size; + } + + /// Method so that the ``visitor`` can visit us + void accept(Visitor& visitor) const override; + + + /// Comparaison based on the Relocation's **address** + virtual bool operator<(const Relocation& rhs) const { + return address() < rhs.address(); + } + + /// Comparaison based on the Relocation's **address** + virtual bool operator<=(const Relocation& rhs) const { + return !(address() > rhs.address()); + } + + /// Comparaison based on the Relocation's **address** + virtual bool operator>(const Relocation& rhs) const { + return address() > rhs.address(); + } + + /// Comparaison based on the Relocation's **address** + virtual bool operator>=(const Relocation& rhs) const { + return !(address() < rhs.address()); + } + + LIEF_API friend std::ostream& operator<<(std::ostream& os, const Relocation& entry); + + protected: + uint64_t address_ = 0; + uint8_t size_ = 0; +}; + + +} +#endif diff --git a/deps/LIEF/include/LIEF/Abstract/Section.hpp b/deps/LIEF/include/LIEF/Abstract/Section.hpp new file mode 100644 index 00000000000000..eb89b42ccc57a4 --- /dev/null +++ b/deps/LIEF/include/LIEF/Abstract/Section.hpp @@ -0,0 +1,131 @@ +/* Copyright 2017 - 2025 R. Thomas + * Copyright 2017 - 2025 Quarkslab + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef LIEF_ABSTRACT_SECTION_H +#define LIEF_ABSTRACT_SECTION_H + +#include +#include +#include + +#include "LIEF/span.hpp" +#include "LIEF/Object.hpp" +#include "LIEF/visibility.h" + +namespace LIEF { +/// Class which represents an abstracted section +class LIEF_API Section : public Object { + public: + static constexpr size_t npos = -1; + + Section() = default; + Section(std::string name) : + name_(std::move(name)) + {} + + ~Section() override = default; + + Section& operator=(const Section&) = default; + Section(const Section&) = default; + + /// section's name + virtual std::string name() const { + return name_.c_str(); + } + + /// Return the **complete** section's name which might + /// trailing (``0``) bytes + virtual const std::string& fullname() const { + return name_; + } + + /// section's content + virtual span content() const { + return {}; + } + + /// Change the section size + virtual void size(uint64_t size) { + size_ = size; + } + + /// section's size (size in the binary, not the virtual size) + virtual uint64_t size() const { + return size_; + } + + /// Offset in the binary + virtual uint64_t offset() const { + return offset_; + } + + /// Address where the section should be mapped + virtual uint64_t virtual_address() const { + return virtual_address_; + } + + virtual void virtual_address(uint64_t virtual_address) { + virtual_address_ = virtual_address; + } + + /// Change the section's name + virtual void name(std::string name) { + name_ = std::move(name); + } + + /// Change section content + virtual void content(const std::vector&) {} + + virtual void offset(uint64_t offset) { + offset_ = offset; + } + + /// Section's entropy + double entropy() const; + + // Search functions + // ================ + size_t search(uint64_t integer, size_t pos, size_t size) const; + size_t search(const std::vector& pattern, size_t pos = 0) const; + size_t search(const std::string& pattern, size_t pos = 0) const; + size_t search(uint64_t integer, size_t pos = 0) const; + + // Search all functions + // ==================== + std::vector search_all(uint64_t v, size_t size) const; + + std::vector search_all(uint64_t v) const; + + std::vector search_all(const std::string& v) const; + + /// Method so that the ``visitor`` can visit us + void accept(Visitor& visitor) const override; + + + LIEF_API friend std::ostream& operator<<(std::ostream& os, const Section& entry); + + protected: + std::string name_; + uint64_t virtual_address_ = 0; + uint64_t size_ = 0; + uint64_t offset_ = 0; + + private: + template + std::vector search_all_(const T& v) const; +}; +} + +#endif diff --git a/deps/LIEF/include/LIEF/Abstract/Symbol.hpp b/deps/LIEF/include/LIEF/Abstract/Symbol.hpp new file mode 100644 index 00000000000000..8d9802beec346c --- /dev/null +++ b/deps/LIEF/include/LIEF/Abstract/Symbol.hpp @@ -0,0 +1,97 @@ +/* Copyright 2017 - 2025 R. Thomas + * Copyright 2017 - 2025 Quarkslab + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef LIEF_ABSTRACT_SYMBOLS_H +#define LIEF_ABSTRACT_SYMBOLS_H + +#include +#include + +#include "LIEF/Object.hpp" +#include "LIEF/visibility.h" + +namespace LIEF { + +/// This class represents a symbol in an executable format. +class LIEF_API Symbol : public Object { + public: + Symbol() = default; + Symbol(std::string name) : + name_(std::move(name)) + {} + + Symbol(std::string name, uint64_t value) : + name_(std::move(name)), value_(value) + {} + + Symbol(std::string name, uint64_t value, uint64_t size) : + name_(std::move(name)), value_(value), size_(size) + {} + + Symbol(const Symbol&) = default; + Symbol& operator=(const Symbol&) = default; + + Symbol(Symbol&&) = default; + Symbol& operator=(Symbol&&) = default; + + ~Symbol() override = default; + + void swap(Symbol& other) noexcept; + + /// Return the symbol's name + virtual const std::string& name() const { + return name_; + } + + virtual std::string& name() { + return name_; + } + + /// Set symbol name + virtual void name(std::string name) { + name_ = std::move(name); + } + + // Symbol's value which is usually the **address** of the symbol + virtual uint64_t value() const { + return value_; + } + virtual void value(uint64_t value) { + value_ = value; + } + + /// This size of the symbol (when applicable) + virtual uint64_t size() const { + return size_; + } + + virtual void size(uint64_t value) { + size_ = value; + } + + /// Method so that the ``visitor`` can visit us + void accept(Visitor& visitor) const override; + + LIEF_API friend std::ostream& operator<<(std::ostream& os, const Symbol& entry); + + protected: + std::string name_; + uint64_t value_ = 0; + uint64_t size_ = 0; +}; +} + +#endif + diff --git a/deps/LIEF/include/LIEF/Abstract/hash.hpp b/deps/LIEF/include/LIEF/Abstract/hash.hpp new file mode 100644 index 00000000000000..26f4a375f446e6 --- /dev/null +++ b/deps/LIEF/include/LIEF/Abstract/hash.hpp @@ -0,0 +1,49 @@ +/* Copyright 2017 - 2025 R. Thomas + * Copyright 2017 - 2025 Quarkslab + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef LIEF_ABSTRACT_HASH_H +#define LIEF_ABSTRACT_HASH_H + +#include "LIEF/visibility.h" +#include "LIEF/hash.hpp" + +namespace LIEF { +class Binary; +class Header; +class Relocation; +class Object; + +class LIEF_API AbstractHash : public LIEF::Hash { + public: + static LIEF::Hash::value_type hash(const Object& obj); + + public: + using LIEF::Hash::Hash; + using LIEF::Hash::visit; + + public: + void visit(const Binary& binary) override; + void visit(const Header& header) override; + void visit(const Section& section) override; + void visit(const Symbol& symbol) override; + void visit(const Relocation& relocation) override; + void visit(const Function& function) override; + + ~AbstractHash() override; +}; + +} + +#endif diff --git a/deps/LIEF/include/LIEF/Abstract/json.hpp b/deps/LIEF/include/LIEF/Abstract/json.hpp new file mode 100644 index 00000000000000..fa05cec3458482 --- /dev/null +++ b/deps/LIEF/include/LIEF/Abstract/json.hpp @@ -0,0 +1,30 @@ +/* Copyright 2017 - 2025 R. Thomas + * Copyright 2017 - 2025 Quarkslab + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef LIEF_ABSTRACT_JSON_H +#define LIEF_ABSTRACT_JSON_H + +#include "LIEF/visibility.h" +#include + +namespace LIEF { +class Object; + +LIEF_API std::string to_json_from_abstract(const Object& v); + +} + +#endif // LIEF_JSON_SUPPORT + diff --git a/deps/LIEF/include/LIEF/BinaryStream/ASN1Reader.hpp b/deps/LIEF/include/LIEF/BinaryStream/ASN1Reader.hpp new file mode 100644 index 00000000000000..385bb35dd22c08 --- /dev/null +++ b/deps/LIEF/include/LIEF/BinaryStream/ASN1Reader.hpp @@ -0,0 +1,72 @@ +/* Copyright 2017 - 2025 R. Thomas + * Copyright 2017 - 2025 Quarkslab + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef LIEF_ASN1_READER_H +#define LIEF_ASN1_READER_H + +#include +#include +#include +#include + +#include "LIEF/errors.hpp" + +struct mbedtls_x509_crt; +struct mbedtls_x509_time; + +namespace LIEF { +class BinaryStream; + +class ASN1Reader { + public: + ASN1Reader() = delete; + + ASN1Reader(BinaryStream& stream) : + stream_(stream) + {} + + ASN1Reader(const ASN1Reader&) = delete; + ASN1Reader& operator=(const ASN1Reader&) = delete; + + + result is_tag(int tag); + + result read_tag(int tag); + result read_len(); + result read_alg(); + result read_oid(); + result read_bool(); + result read_int(); + result read_int64(); + result> read_large_int(); + + result> read_bitstring(); + result> read_octet_string(); + result read_utf8_string(); + result> read_cert(); + result x509_read_names(); + result> x509_read_serial(); + result> x509_read_time(); + + std::string get_str_tag(); + + static std::string tag2str(int tag); + + private: + BinaryStream& stream_; +}; + +} +#endif diff --git a/deps/LIEF/include/LIEF/BinaryStream/BinaryStream.hpp b/deps/LIEF/include/LIEF/BinaryStream/BinaryStream.hpp new file mode 100644 index 00000000000000..48c16034e1df4f --- /dev/null +++ b/deps/LIEF/include/LIEF/BinaryStream/BinaryStream.hpp @@ -0,0 +1,476 @@ +/* Copyright 2017 - 2025 R. Thomas + * Copyright 2017 - 2025 Quarkslab + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef LIEF_BINARY_STREAM_H +#define LIEF_BINARY_STREAM_H + +#include +#include +#include +#include +#include + +#include "LIEF/endianness_support.hpp" +#include "LIEF/errors.hpp" +#include "LIEF/visibility.h" + +namespace LIEF { +class ASN1Reader; + +/// Class that is used to a read stream of data from different sources +class LIEF_API BinaryStream { + public: + friend class ASN1Reader; + + enum class STREAM_TYPE { + UNKNOWN = 0, + VECTOR, + MEMORY, + SPAN, + FILE, + + ELF_DATA_HANDLER, + }; + + BinaryStream(STREAM_TYPE type) : + stype_(type) + {} + virtual ~BinaryStream() = default; + virtual uint64_t size() const = 0; + + STREAM_TYPE type() const { + return stype_; + } + + result read_uleb128(size_t* size = nullptr) const; + result read_sleb128(size_t* size = nullptr) const; + + result read_dwarf_encoded(uint8_t encoding) const; + + result read_string(size_t maxsize = ~static_cast(0)) const; + result peek_string(size_t maxsize = ~static_cast(0)) const; + result peek_string_at(size_t offset, size_t maxsize = ~static_cast(0)) const; + + result read_u16string() const; + result peek_u16string() const; + + result read_mutf8(size_t maxsize = ~static_cast(0)) const; + + result read_u16string(size_t length) const; + result peek_u16string(size_t length) const; + result peek_u16string_at(size_t offset, size_t length) const; + + + virtual ok_error_t peek_data(std::vector& container, + uint64_t offset, uint64_t size, + uint64_t virtual_address = 0) + { + if (size == 0) { + return ok(); + } + // Even though offset + size < ... => offset < ... + // the addition could overflow so it's worth checking both + const bool read_ok = offset <= this->size() && (offset + size) <= this->size() + /* Check for an overflow */ + && (static_cast(offset) >= 0 && static_cast(size) >= 0) + && (static_cast(offset + size) >= 0); + if (!read_ok) { + return make_error_code(lief_errors::read_error); + } + container.resize(size); + if (peek_in(container.data(), offset, size, virtual_address)) { + return ok(); + } + return make_error_code(lief_errors::read_error); + } + + virtual ok_error_t read_data(std::vector& container, uint64_t size) { + if (!peek_data(container, pos(), size)) { + return make_error_code(lief_errors::read_error); + } + + increment_pos(size); + return ok(); + } + + ok_error_t read_data(std::vector& container) { + const size_t size = this->size() - this->pos(); + return read_data(container, size); + } + + template + ok_error_t read_objects(std::vector& container, uint64_t count) { + if (count == 0) { + return ok(); + } + const size_t size = count * sizeof(T); + auto ret = peek_objects(container, count); + if (!ret) { + return make_error_code(lief_errors::read_error); + } + increment_pos(size); + return ok(); + } + + template + ok_error_t peek_objects(std::vector& container, uint64_t count) { + return peek_objects_at(pos(), container, count); + } + + template + ok_error_t peek_objects_at(uint64_t offset, std::vector& container, uint64_t count) { + if (count == 0) { + return ok(); + } + const auto current_p = pos(); + setpos(offset); + + const size_t size = count * sizeof(T); + + if (!can_read(offset, size)) { + setpos(current_p); + return make_error_code(lief_errors::read_error); + } + + container.resize(count); + + if (!peek_in(container.data(), pos(), size)) { + setpos(current_p); + return make_error_code(lief_errors::read_error); + } + + setpos(current_p); + return ok(); + } + + void setpos(size_t pos) const { + pos_ = pos; + } + + const BinaryStream& increment_pos(size_t value) const { + pos_ += value; + return *this; + } + + void decrement_pos(size_t value) const { + if (pos_ > value) { + pos_ -= value; + } else { + pos_ = 0; + } + } + + size_t pos() const { + return pos_; + } + + operator bool() const { + return pos_ < size(); + } + + template + const T* read_array(size_t size) const; + + template + ok_error_t peek_array(std::array& dst) const { + if /*constexpr*/ (N == 0) { + return ok(); + } + // Even though offset + size < ... => offset < ... + // the addition could overflow so it's worth checking both + const bool read_ok = pos_ <= size() && (pos_ + N) <= size() + /* Check for an overflow */ + && (static_cast(pos_) >= 0 && static_cast(N) >= 0) + && (static_cast(pos_ + N) >= 0); + + if (!read_ok) { + return make_error_code(lief_errors::read_error); + } + if (peek_in(dst.data(), pos_, N)) { + return ok(); + } + return make_error_code(lief_errors::read_error); + } + + template + ok_error_t read_array(std::array& dst) const { + if (!peek_array(dst)) { + return make_error_code(lief_errors::read_error); + } + + increment_pos(N); + return ok(); + } + + template + result peek() const; + + template + result peek(size_t offset) const; + + template + const T* peek_array(size_t size) const; + + template + const T* peek_array(size_t offset, size_t size) const; + + template + result read() const; + + template + bool can_read() const; + + template + bool can_read(size_t offset) const; + + bool can_read(int64_t offset, int64_t size) const { + return offset < (int64_t)this->size() && (offset + size) < (int64_t)this->size(); + } + + size_t align(size_t align_on) const; + + void set_endian_swap(bool swap) { + endian_swap_ = swap; + } + + template + static bool is_all_zero(const T& buffer) { + const auto* ptr = reinterpret_cast(&buffer); + return std::all_of(ptr, ptr + sizeof(T), + [] (uint8_t x) { return x == 0; }); + } + + bool should_swap() const { + return endian_swap_; + } + + virtual const uint8_t* p() const { + return nullptr; + } + + virtual uint8_t* start() { + return const_cast(static_cast(this)->start()); + } + + virtual uint8_t* p() { + return const_cast(static_cast(this)->p()); + } + + virtual uint8_t* end() { + return const_cast(static_cast(this)->end()); + } + + virtual const uint8_t* start() const { + return nullptr; + } + + virtual const uint8_t* end() const { + return nullptr; + } + + virtual result read_at(uint64_t offset, uint64_t size, + uint64_t virtual_address = 0) const = 0; + virtual ok_error_t peek_in(void* dst, uint64_t offset, uint64_t size, + uint64_t virtual_address = 0) const { + if (auto raw = read_at(offset, size, virtual_address)) { + if (dst == nullptr) { + return make_error_code(lief_errors::read_error); + } + + const void* ptr = *raw; + + if (ptr == nullptr) { + return make_error_code(lief_errors::read_error); + } + + memcpy(dst, ptr, size); + return ok(); + } + return make_error_code(lief_errors::read_error); + } + + protected: + BinaryStream() = default; + + mutable size_t pos_ = 0; + bool endian_swap_ = false; + STREAM_TYPE stype_ = STREAM_TYPE::UNKNOWN; +}; + +class ScopedStream { + public: + ScopedStream(const ScopedStream&) = delete; + ScopedStream& operator=(const ScopedStream&) = delete; + + ScopedStream(ScopedStream&&) = delete; + ScopedStream& operator=(ScopedStream&&) = delete; + + explicit ScopedStream(BinaryStream& stream, uint64_t pos) : + pos_{stream.pos()}, + stream_{stream} + { + stream_.setpos(pos); + } + + explicit ScopedStream(BinaryStream& stream) : + pos_{stream.pos()}, + stream_{stream} + {} + + ~ScopedStream() { + stream_.setpos(pos_); + } + + BinaryStream* operator->() { + return &stream_; + } + + BinaryStream& operator*() { + return stream_; + } + + const BinaryStream& operator*() const { + return stream_; + } + + private: + uint64_t pos_ = 0; + BinaryStream& stream_; +}; + +class ToggleEndianness { + public: + ToggleEndianness(const ToggleEndianness&) = delete; + ToggleEndianness& operator=(const ToggleEndianness&) = delete; + + ToggleEndianness(ToggleEndianness&&) = delete; + ToggleEndianness& operator=(ToggleEndianness&&) = delete; + + explicit ToggleEndianness(BinaryStream& stream, bool value) : + endian_swap_(stream.should_swap()), + stream_{stream} + { + stream.set_endian_swap(value); + } + + explicit ToggleEndianness(BinaryStream& stream) : + endian_swap_(stream.should_swap()), + stream_{stream} + { + stream.set_endian_swap(!stream_.should_swap()); + } + + ~ToggleEndianness() { + stream_.set_endian_swap(endian_swap_); + } + + BinaryStream* operator->() { + return &stream_; + } + + BinaryStream& operator*() { + return stream_; + } + + const BinaryStream& operator*() const { + return stream_; + } + + private: + bool endian_swap_ = false; + BinaryStream& stream_; +}; + + +template +result BinaryStream::read() const { + result tmp = this->peek(); + if (!tmp) { + return tmp; + } + this->increment_pos(sizeof(T)); + return tmp; +} + +template +result BinaryStream::peek() const { + const auto current_p = pos(); + T ret{}; + if (auto res = peek_in(&ret, pos(), sizeof(T))) { + setpos(current_p); + if (endian_swap_) { + swap_endian(&ret); + } + return ret; + } + + setpos(current_p); + return make_error_code(lief_errors::read_error); +} + +template +result BinaryStream::peek(size_t offset) const { + const size_t saved_offset = this->pos(); + this->setpos(offset); + result r = this->peek(); + this->setpos(saved_offset); + return r; +} + + +template +const T* BinaryStream::peek_array(size_t size) const { + result raw = this->read_at(this->pos(), sizeof(T) * size); + if (!raw) { + return nullptr; + } + return reinterpret_cast(raw.value()); +} + +template +const T* BinaryStream::peek_array(size_t offset, size_t size) const { + const size_t saved_offset = this->pos(); + this->setpos(offset); + const T* r = this->peek_array(size); + this->setpos(saved_offset); + return r; +} + + +template +bool BinaryStream::can_read() const { + // Even though pos_ + sizeof(T) < ... => pos_ < ... + // the addition could overflow so it's worth checking both + return pos_ < size() && (pos_ + sizeof(T)) < size(); +} + + +template +bool BinaryStream::can_read(size_t offset) const { + // Even though offset + sizeof(T) < ... => offset < ... + // the addition could overflow so it's worth checking both + return offset < size() && (offset + sizeof(T)) < size(); +} + + +template +const T* BinaryStream::read_array(size_t size) const { + const T* tmp = this->peek_array(size); + this->increment_pos(sizeof(T) * size); + return tmp; +} + +} +#endif diff --git a/deps/LIEF/include/LIEF/BinaryStream/FileStream.hpp b/deps/LIEF/include/LIEF/BinaryStream/FileStream.hpp new file mode 100644 index 00000000000000..0e5d3e5cc86d9e --- /dev/null +++ b/deps/LIEF/include/LIEF/BinaryStream/FileStream.hpp @@ -0,0 +1,80 @@ +/* Copyright 2017 - 2025 R. Thomas + * Copyright 2017 - 2025 Quarkslab + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef LIEF_FILE_STREAM_H +#define LIEF_FILE_STREAM_H + +#include +#include +#include + +#include "LIEF/errors.hpp" +#include "LIEF/BinaryStream/BinaryStream.hpp" +#include "LIEF/visibility.h" + +namespace LIEF { + +/// Stream interface over a `std::ifstream` +class LIEF_API FileStream : public BinaryStream { + public: + static result from_file(const std::string& file); + FileStream(std::ifstream fs, uint64_t size) : + BinaryStream(STREAM_TYPE::FILE), + ifs_(std::move(fs)), + size_(size) + {} + + FileStream() = delete; + + FileStream(const FileStream&) = delete; + FileStream& operator=(const FileStream&) = delete; + + FileStream(FileStream&& other) noexcept = default; + FileStream& operator=(FileStream&& other) noexcept = default; + + uint64_t size() const override { + return size_; + } + + std::vector content() const; + ~FileStream() override = default; + + static bool classof(const BinaryStream& stream) { + return stream.type() == STREAM_TYPE::FILE; + } + + ok_error_t peek_in(void* dst, uint64_t offset, uint64_t size, + uint64_t /* virtual_address */= 0) const override { + if (offset > size_ || offset + size > size_) { + return make_error_code(lief_errors::read_error); + } + const auto pos = ifs_.tellg(); + ifs_.seekg(offset); + ifs_.read(static_cast(dst), size); + ifs_.seekg(pos); + return ok(); + } + + result read_at(uint64_t, uint64_t, uint64_t) const override { + return make_error_code(lief_errors::not_supported); + } + + protected: + mutable std::ifstream ifs_; + uint64_t size_ = 0; +}; +} + +#endif diff --git a/deps/LIEF/include/LIEF/BinaryStream/MemoryStream.hpp b/deps/LIEF/include/LIEF/BinaryStream/MemoryStream.hpp new file mode 100644 index 00000000000000..9bce7e764be3e9 --- /dev/null +++ b/deps/LIEF/include/LIEF/BinaryStream/MemoryStream.hpp @@ -0,0 +1,89 @@ +/* Copyright 2017 - 2025 R. Thomas + * Copyright 2017 - 2025 Quarkslab + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef LIEF_MEMORY_STREAM_H +#define LIEF_MEMORY_STREAM_H + +#include + +#include "LIEF/errors.hpp" +#include "LIEF/visibility.h" +#include "LIEF/BinaryStream/BinaryStream.hpp" + +namespace LIEF { +class Binary; +class LIEF_API MemoryStream : public BinaryStream { + public: + using BinaryStream::p; + using BinaryStream::end; + using BinaryStream::start; + + MemoryStream() = delete; + MemoryStream(uintptr_t base_address); + MemoryStream(uintptr_t base_address, uint64_t size) : + BinaryStream(BinaryStream::STREAM_TYPE::MEMORY), + baseaddr_(base_address), + size_(size) + {} + + MemoryStream(const MemoryStream&) = delete; + MemoryStream& operator=(const MemoryStream&) = delete; + + MemoryStream(MemoryStream&&) noexcept = default; + MemoryStream& operator=(MemoryStream&&) noexcept = default; + + uintptr_t base_address() const { + return this->baseaddr_; + } + + const uint8_t* p() const override { + return start() + pos(); + } + + const uint8_t* start() const override { + return reinterpret_cast(baseaddr_); + } + + const uint8_t* end() const override { + return start() + size_; + } + + void binary(Binary& bin) { + this->binary_ = &bin; + } + + Binary* binary() { + return this->binary_; + } + + uint64_t size() const override { + return size_; + } + + ~MemoryStream() override = default; + + static bool classof(const BinaryStream& stream) { + return stream.type() == BinaryStream::STREAM_TYPE::MEMORY; + } + + protected: + result read_at(uint64_t offset, uint64_t size, uint64_t va) const override; + uintptr_t baseaddr_ = 0; + uint64_t size_ = 0; + Binary* binary_ = nullptr; +}; +} + +#endif diff --git a/deps/LIEF/include/LIEF/BinaryStream/SpanStream.hpp b/deps/LIEF/include/LIEF/BinaryStream/SpanStream.hpp new file mode 100644 index 00000000000000..ce7e8b4c003322 --- /dev/null +++ b/deps/LIEF/include/LIEF/BinaryStream/SpanStream.hpp @@ -0,0 +1,129 @@ +/* Copyright 2017 - 2025 R. Thomas + * Copyright 2017 - 2025 Quarkslab + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef LIEF_SPAN_STREAM_H +#define LIEF_SPAN_STREAM_H + +#include +#include +#include +#include +#include + +#include "LIEF/errors.hpp" +#include "LIEF/span.hpp" +#include "LIEF/visibility.h" +#include "LIEF/BinaryStream/BinaryStream.hpp" + +namespace LIEF { +class VectorStream; +class LIEF_API SpanStream : public BinaryStream { + public: + using BinaryStream::p; + using BinaryStream::end; + using BinaryStream::start; + + static result from_vector(const std::vector& data) { + return SpanStream(data); + } + + template + static result from_array(const std::array& data) { + return SpanStream(data.data(), N); + } + + SpanStream(span data) : + SpanStream(data.data(), data.size()) + {} + + SpanStream(span data) : + SpanStream(data.data(), data.size()) + {} + + SpanStream(const uint8_t* p, size_t size) : + BinaryStream(BinaryStream::STREAM_TYPE::SPAN), + data_{p, p + size} + {} + + SpanStream(const std::vector& data) : + SpanStream(data.data(), data.size()) + {} + + std::unique_ptr clone() const { + return std::unique_ptr(new SpanStream(*this)); + } + + SpanStream() = delete; + + SpanStream(const SpanStream& other) = default; + SpanStream& operator=(const SpanStream& other) = default; + + SpanStream(SpanStream&& other) noexcept = default; + SpanStream& operator=(SpanStream&& other) noexcept = default; + + uint64_t size() const override { + return data_.size(); + } + + const uint8_t* p() const override { + return data_.data() + this->pos(); + } + + const uint8_t* start() const override { + return data_.data(); + } + + const uint8_t* end() const override { + return data_.data() + size(); + } + + std::vector content() const { + return {data_.begin(), data_.end()}; + } + + result slice(size_t offset, size_t size) const { + if (offset > data_.size() || (offset + size) > data_.size()) { + return make_error_code(lief_errors::read_out_of_bound); + } + return data_.subspan(offset, size); + } + result slice(size_t offset) const { + if (offset > data_.size()) { + return make_error_code(lief_errors::read_out_of_bound); + } + return data_.subspan(offset, data_.size() - offset); + } + + std::unique_ptr to_vector() const; + + static bool classof(const BinaryStream& stream) { + return stream.type() == BinaryStream::STREAM_TYPE::SPAN; + } + + ~SpanStream() override = default; + + protected: + result read_at(uint64_t offset, uint64_t size, uint64_t /*va*/) const override { + const uint64_t stream_size = this->size(); + if (offset > stream_size || (offset + size) > stream_size) { + return make_error_code(lief_errors::read_error); + } + return data_.data() + offset; + } + span data_; +}; +} + +#endif diff --git a/deps/LIEF/include/LIEF/BinaryStream/VectorStream.hpp b/deps/LIEF/include/LIEF/BinaryStream/VectorStream.hpp new file mode 100644 index 00000000000000..44293aa8c85795 --- /dev/null +++ b/deps/LIEF/include/LIEF/BinaryStream/VectorStream.hpp @@ -0,0 +1,97 @@ +/* Copyright 2017 - 2025 R. Thomas + * Copyright 2017 - 2025 Quarkslab + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef LIEF_VECTOR_STREAM_H +#define LIEF_VECTOR_STREAM_H + +#include +#include +#include + +#include "LIEF/errors.hpp" +#include "LIEF/visibility.h" +#include "LIEF/BinaryStream/BinaryStream.hpp" + +namespace LIEF { +class SpanStream; +class LIEF_API VectorStream : public BinaryStream { + public: + using BinaryStream::p; + using BinaryStream::end; + using BinaryStream::start; + + static result from_file(const std::string& file); + VectorStream(std::vector data) : + BinaryStream(BinaryStream::STREAM_TYPE::VECTOR), + binary_(std::move(data)), + size_(binary_.size()) + {} + + VectorStream() = delete; + + // VectorStream should not be copyable for performances reasons + VectorStream(const VectorStream&) = delete; + VectorStream& operator=(const VectorStream&) = delete; + + VectorStream(VectorStream&& other) noexcept = default; + VectorStream& operator=(VectorStream&& other) noexcept = default; + + uint64_t size() const override { + return size_; + } + + const std::vector& content() const { + return binary_; + } + + std::vector&& move_content() { + size_ = 0; + return std::move(binary_); + } + + const uint8_t* p() const override { + return this->binary_.data() + this->pos(); + } + + const uint8_t* start() const override { + return this->binary_.data(); + } + + const uint8_t* end() const override { + return this->binary_.data() + this->binary_.size(); + } + + + std::unique_ptr slice(uint32_t offset, size_t size) const; + std::unique_ptr slice(uint32_t offset) const; + + static bool classof(const BinaryStream& stream) { + return stream.type() == STREAM_TYPE::VECTOR; + } + + protected: + result read_at(uint64_t offset, uint64_t size, uint64_t /*va*/) const override { + const uint64_t stream_size = this->size(); + if (offset > stream_size || (offset + size) > stream_size) { + return make_error_code(lief_errors::read_error); + } + return binary_.data() + offset; + } + std::vector binary_; + uint64_t size_ = 0; // Original size without alignment +}; +} + +#endif diff --git a/deps/LIEF/include/LIEF/COFF.hpp b/deps/LIEF/include/LIEF/COFF.hpp new file mode 100644 index 00000000000000..dcc13dbde0d3e8 --- /dev/null +++ b/deps/LIEF/include/LIEF/COFF.hpp @@ -0,0 +1,42 @@ +/* Copyright 2017 - 2025 R. Thomas + * Copyright 2017 - 2025 Quarkslab + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef LIEF_COFF_H +#define LIEF_COFF_H +#include "LIEF/config.h" + +#if defined(LIEF_COFF_SUPPORT) +#include "LIEF/COFF/Binary.hpp" +#include "LIEF/COFF/utils.hpp" +#include "LIEF/COFF/Parser.hpp" +#include "LIEF/COFF/Header.hpp" +#include "LIEF/COFF/BigObjHeader.hpp" +#include "LIEF/COFF/RegularHeader.hpp" +#include "LIEF/COFF/ParserConfig.hpp" +#include "LIEF/COFF/Section.hpp" +#include "LIEF/COFF/Relocation.hpp" +#include "LIEF/COFF/Symbol.hpp" +#include "LIEF/COFF/String.hpp" + +#include "LIEF/COFF/AuxiliarySymbol.hpp" +#include "LIEF/COFF/AuxiliarySymbols/AuxiliarybfAndefSymbol.hpp" +#include "LIEF/COFF/AuxiliarySymbols/AuxiliaryCLRToken.hpp" +#include "LIEF/COFF/AuxiliarySymbols/AuxiliaryFile.hpp" +#include "LIEF/COFF/AuxiliarySymbols/AuxiliaryFunctionDefinition.hpp" +#include "LIEF/COFF/AuxiliarySymbols/AuxiliarySectionDefinition.hpp" +#include "LIEF/COFF/AuxiliarySymbols/AuxiliaryWeakExternal.hpp" +#endif + +#endif diff --git a/deps/LIEF/include/LIEF/COFF/AuxiliarySymbol.hpp b/deps/LIEF/include/LIEF/COFF/AuxiliarySymbol.hpp new file mode 100644 index 00000000000000..398776a324d418 --- /dev/null +++ b/deps/LIEF/include/LIEF/COFF/AuxiliarySymbol.hpp @@ -0,0 +1,125 @@ +/* Copyright 2017 - 2025 R. Thomas + * Copyright 2017 - 2025 Quarkslab + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef LIEF_COFF_AUXILIARY_SYMBOL_H +#define LIEF_COFF_AUXILIARY_SYMBOL_H + +#include +#include +#include + +#include "LIEF/visibility.h" +#include "LIEF/span.hpp" + +namespace LIEF { +class BinaryStream; + +namespace COFF { +class Symbol; + +/// Class that represents an auxiliary symbol. +/// +/// An auxiliary symbol has the same size as a regular LIEF::PE::Symbol (18 +/// bytes) but its content depends on the the parent symbol. +class LIEF_API AuxiliarySymbol { + public: + AuxiliarySymbol() = default; + AuxiliarySymbol(std::vector payload) : + type_(TYPE::UNKNOWN), + payload_(std::move(payload)) + {} + AuxiliarySymbol(const AuxiliarySymbol&) = default; + AuxiliarySymbol& operator=(const AuxiliarySymbol&) = default; + + AuxiliarySymbol(AuxiliarySymbol&&) = default; + AuxiliarySymbol& operator=(AuxiliarySymbol&&) = default; + + LIEF_LOCAL static std::unique_ptr + parse(Symbol& sym, std::vector payload); + + virtual std::unique_ptr clone() const { + return std::unique_ptr(new AuxiliarySymbol(*this)); + } + + /// Type discriminator for the subclasses + enum class TYPE { + UNKNOWN = 0, + CLR_TOKEN, + /// Auxiliary Format 1 from the PE-COFF documentation + FUNC_DEF, + /// Auxiliary Format 2: .bf and .ef Symbols from the PE-COFF documentation + BF_AND_EF, + /// Auxiliary Format 3: Weak Externals from the PE-COFF documentation + WEAK_EXTERNAL, + /// Auxiliary Format 4: Files from the PE-COFF documentation + FILE, + /// Auxiliary Format 5: Section Definitions from the PE-COFF documentation + SEC_DEF, + }; + + AuxiliarySymbol(TYPE ty) : + type_(ty) + {} + + static TYPE get_aux_type(const Symbol& sym); + + TYPE type() const { + return type_; + } + + /// For unknown type **only**, return the raw representation of this symbol + span payload() const { + return payload_; + } + + span payload() { + return payload_; + } + + virtual std::string to_string() const; + + virtual ~AuxiliarySymbol() = default; + + /// Helper to **downcast** a AuxiliarySymbol into a concrete implementation + template + const T* as() const { + static_assert(std::is_base_of::value, + "Require AuxiliarySymbol inheritance"); + if (T::classof(this)) { + return static_cast(this); + } + return nullptr; + } + + template + T* as() { + return const_cast(static_cast(this)->as()); + } + + LIEF_API friend + std::ostream& operator<<(std::ostream& os, const AuxiliarySymbol& aux) + { + os << aux.to_string(); + return os; + } + + protected: + TYPE type_ = TYPE::UNKNOWN; + std::vector payload_; +}; + +} +} +#endif diff --git a/deps/LIEF/include/LIEF/COFF/AuxiliarySymbols/AuxiliaryCLRToken.hpp b/deps/LIEF/include/LIEF/COFF/AuxiliarySymbols/AuxiliaryCLRToken.hpp new file mode 100644 index 00000000000000..cc2ee5feb71fb1 --- /dev/null +++ b/deps/LIEF/include/LIEF/COFF/AuxiliarySymbols/AuxiliaryCLRToken.hpp @@ -0,0 +1,106 @@ +/* Copyright 2017 - 2025 R. Thomas + * Copyright 2017 - 2025 Quarkslab + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef LIEF_COFF_AUXILIARY_CLR_TOKEN_H +#define LIEF_COFF_AUXILIARY_CLR_TOKEN_H + +#include + +#include "LIEF/visibility.h" +#include "LIEF/COFF/AuxiliarySymbol.hpp" + +namespace LIEF { +namespace COFF { +class Symbol; +class Parser; + +/// Auxiliary symbol associated with the `CLR_TOKEN` storage class +class LIEF_API AuxiliaryCLRToken : public AuxiliarySymbol { + public: + friend class Parser; + + LIEF_LOCAL static std::unique_ptr + parse(const std::vector& payload); + + AuxiliaryCLRToken() : + AuxiliarySymbol(AuxiliarySymbol::TYPE::CLR_TOKEN) + {} + + AuxiliaryCLRToken(uint8_t aux_type, uint8_t reserved, uint32_t symbol_idx, + std::vector rgb_reserved) : + AuxiliarySymbol(AuxiliarySymbol::TYPE::CLR_TOKEN), + aux_type_(aux_type), + reserved_(reserved), + symbol_idx_(symbol_idx), + rgb_reserved_(std::move(rgb_reserved)) + {} + + AuxiliaryCLRToken(const AuxiliaryCLRToken&) = default; + AuxiliaryCLRToken& operator=(const AuxiliaryCLRToken&) = default; + + AuxiliaryCLRToken(AuxiliaryCLRToken&&) = default; + AuxiliaryCLRToken& operator=(AuxiliaryCLRToken&&) = default; + + std::unique_ptr clone() const override { + return std::unique_ptr(new AuxiliaryCLRToken{*this}); + } + + /// `IMAGE_AUX_SYMBOL_TYPE` which should be `IMAGE_AUX_SYMBOL_TYPE_TOKEN_DEF` (1) + uint8_t aux_type() const { + return aux_type_; + } + + /// Reserved value (should be 0) + uint8_t reserved() const { + return aux_type_; + } + + /// Index in the symbol table + uint32_t symbol_idx() const { + return symbol_idx_; + } + + /// Symbol referenced by symbol_idx() (if resolved) + const Symbol* symbol() const { + return sym_; + } + + Symbol* symbol() { + return sym_; + } + + /// Reserved (padding) values. Should be 0 + span rgb_reserved() const { + return rgb_reserved_; + } + + std::string to_string() const override; + + static bool classof(const AuxiliarySymbol* sym) { + return sym->type() == AuxiliarySymbol::TYPE::CLR_TOKEN; + } + + ~AuxiliaryCLRToken() override = default; + private: + uint8_t aux_type_ = 0; + uint8_t reserved_ = 0; + uint32_t symbol_idx_ = 0; + std::vector rgb_reserved_; + Symbol* sym_ = nullptr; +}; + +} +} +#endif diff --git a/deps/LIEF/include/LIEF/COFF/AuxiliarySymbols/AuxiliaryFile.hpp b/deps/LIEF/include/LIEF/COFF/AuxiliarySymbols/AuxiliaryFile.hpp new file mode 100644 index 00000000000000..28ed0142d3415b --- /dev/null +++ b/deps/LIEF/include/LIEF/COFF/AuxiliarySymbols/AuxiliaryFile.hpp @@ -0,0 +1,85 @@ +/* Copyright 2017 - 2025 R. Thomas + * Copyright 2017 - 2025 Quarkslab + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef LIEF_PE_AUXILIARY_FILE_H +#define LIEF_PE_AUXILIARY_FILE_H + +#include + +#include "LIEF/visibility.h" +#include "LIEF/COFF/AuxiliarySymbol.hpp" + +namespace LIEF { +namespace COFF { + +/// This auxiliary symbol represents a filename (auxiliary format 4) +/// +/// The Symbol::name itself should start with `.file`, and this auxiliary record +/// gives the name of a source-code file. +/// +/// Reference: https://learn.microsoft.com/en-us/windows/win32/debug/pe-format#auxiliary-format-4-files +class LIEF_API AuxiliaryFile : public AuxiliarySymbol { + public: + LIEF_LOCAL static std::unique_ptr + parse(const std::vector& payload); + + AuxiliaryFile() : + AuxiliarySymbol(AuxiliarySymbol::TYPE::FILE) + {} + + AuxiliaryFile(std::string file) : + AuxiliarySymbol(AuxiliarySymbol::TYPE::FILE), + filename_(std::move(file)) + {} + + AuxiliaryFile(const AuxiliaryFile&) = default; + AuxiliaryFile& operator=(const AuxiliaryFile&) = default; + + AuxiliaryFile(AuxiliaryFile&&) = default; + AuxiliaryFile& operator=(AuxiliaryFile&&) = default; + + std::unique_ptr clone() const override { + return std::unique_ptr(new AuxiliaryFile{*this}); + } + + /// The associated filename + const std::string& filename() const { + return filename_; + } + + AuxiliaryFile& filename(std::string file) { + filename_ = std::move(file); + return *this; + } + + std::string to_string() const override { + std::string out = "AuxiliaryFile {\n"; + out += " " + filename_ + "\n}"; + return out; + } + + ~AuxiliaryFile() override = default; + + static bool classof(const AuxiliarySymbol* sym) { + return sym->type() == AuxiliarySymbol::TYPE::FILE; + } + + protected: + std::string filename_; +}; + +} +} +#endif diff --git a/deps/LIEF/include/LIEF/COFF/AuxiliarySymbols/AuxiliaryFunctionDefinition.hpp b/deps/LIEF/include/LIEF/COFF/AuxiliarySymbols/AuxiliaryFunctionDefinition.hpp new file mode 100644 index 00000000000000..a3f184ff761041 --- /dev/null +++ b/deps/LIEF/include/LIEF/COFF/AuxiliarySymbols/AuxiliaryFunctionDefinition.hpp @@ -0,0 +1,110 @@ +/* Copyright 2017 - 2025 R. Thomas + * Copyright 2017 - 2025 Quarkslab + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef LIEF_COFF_AUXILIARY_FUNCTION_DEF_H +#define LIEF_COFF_AUXILIARY_FUNCTION_DEF_H + +#include + +#include "LIEF/visibility.h" +#include "LIEF/COFF/AuxiliarySymbol.hpp" + +namespace LIEF { +namespace COFF { + +/// This auxiliary symbols marks the beginning of a function definition. +/// +/// Reference: https://learn.microsoft.com/en-us/windows/win32/debug/pe-format#auxiliary-format-1-function-definitions +class LIEF_API AuxiliaryFunctionDefinition : public AuxiliarySymbol { + public: + LIEF_LOCAL static std::unique_ptr + parse(const std::vector& payload); + + AuxiliaryFunctionDefinition() : + AuxiliarySymbol(AuxiliarySymbol::TYPE::FUNC_DEF) + {} + + AuxiliaryFunctionDefinition(uint32_t tagidx, uint32_t totalsz, + uint32_t ptr_line, uint32_t ptr_next_func, + uint16_t padding) : + AuxiliarySymbol(AuxiliarySymbol::TYPE::FUNC_DEF), + tag_index_(tagidx), + total_size_(totalsz), + ptr_to_linenb_(ptr_line), + ptr_to_next_func_(ptr_next_func), + padding_(padding) + {} + + AuxiliaryFunctionDefinition(const AuxiliaryFunctionDefinition&) = default; + AuxiliaryFunctionDefinition& operator=(const AuxiliaryFunctionDefinition&) = default; + + AuxiliaryFunctionDefinition(AuxiliaryFunctionDefinition&&) = default; + AuxiliaryFunctionDefinition& operator=(AuxiliaryFunctionDefinition&&) = default; + + std::unique_ptr clone() const override { + return std::unique_ptr(new AuxiliaryFunctionDefinition{*this}); + } + + /// The symbol-table index of the corresponding `.bf` (begin function) + /// symbol record. + uint32_t tag_index() const { + return tag_index_; + } + + /// The size of the executable code for the function itself. + /// + /// If the function is in its own section, the `SizeOfRawData` in the section + /// header is greater or equal to this field, depending on alignment + /// considerations. + uint32_t total_size() const { + return total_size_; + } + + /// The file offset of the first COFF line-number entry for the function, + /// or zero if none exists (deprecated) + uint32_t ptr_to_line_number() const { + return ptr_to_linenb_; + } + + /// The symbol-table index of the record for the next function. If the function + /// is the last in the symbol table, this field is set to zero. + uint32_t ptr_to_next_func() const { + return ptr_to_next_func_; + } + + /// Padding value (should be 0) + uint16_t padding() const { + return padding_; + } + + std::string to_string() const override; + + static bool classof(const AuxiliarySymbol* sym) { + return sym->type() == AuxiliarySymbol::TYPE::FUNC_DEF; + } + + ~AuxiliaryFunctionDefinition() override = default; + + private: + uint32_t tag_index_ = 0; + uint32_t total_size_ = 0; + uint32_t ptr_to_linenb_ = 0; + uint32_t ptr_to_next_func_ = 0; + uint16_t padding_ = 0; +}; + +} +} +#endif diff --git a/deps/LIEF/include/LIEF/COFF/AuxiliarySymbols/AuxiliarySectionDefinition.hpp b/deps/LIEF/include/LIEF/COFF/AuxiliarySymbols/AuxiliarySectionDefinition.hpp new file mode 100644 index 00000000000000..9037b7700af3c9 --- /dev/null +++ b/deps/LIEF/include/LIEF/COFF/AuxiliarySymbols/AuxiliarySectionDefinition.hpp @@ -0,0 +1,166 @@ +/* Copyright 2017 - 2025 R. Thomas + * Copyright 2017 - 2025 Quarkslab + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef LIEF_COFF_AUXILIARY_SEC_DEF_H +#define LIEF_COFF_AUXILIARY_SEC_DEF_H + +#include + +#include "LIEF/visibility.h" +#include "LIEF/COFF/AuxiliarySymbol.hpp" + +namespace LIEF { +namespace COFF { + +/// This auxiliary symbol exposes information about the associated section. +/// +/// It **duplicates** some information that are provided in the section header +class LIEF_API AuxiliarySectionDefinition : public AuxiliarySymbol { + public: + LIEF_LOCAL static std::unique_ptr + parse(const std::vector& payload); + + AuxiliarySectionDefinition() : + AuxiliarySymbol(AuxiliarySymbol::TYPE::SEC_DEF) + {} + + AuxiliarySectionDefinition(uint32_t length, uint16_t nb_relocs, + uint16_t nb_lines, uint32_t checksum, + uint32_t sec_idx, uint8_t selection, + uint8_t reserved) : + AuxiliarySymbol(AuxiliarySymbol::TYPE::SEC_DEF), + length_(length), + nb_relocs_(nb_relocs), + nb_lines_(nb_lines), + checksum_(checksum), + sec_idx_(sec_idx), + selection_((COMDAT_SELECTION)selection), + reserved_(reserved) + {} + + AuxiliarySectionDefinition(const AuxiliarySectionDefinition&) = default; + AuxiliarySectionDefinition& operator=(const AuxiliarySectionDefinition&) = default; + + AuxiliarySectionDefinition(AuxiliarySectionDefinition&&) = default; + AuxiliarySectionDefinition& operator=(AuxiliarySectionDefinition&&) = default; + + std::unique_ptr clone() const override { + return std::unique_ptr(new AuxiliarySectionDefinition{*this}); + } + + /// Values for the AuxiliarySectionDefinition::selection attribute + /// + /// See: https://learn.microsoft.com/en-us/windows/win32/debug/pe-format#comdat-sections-object-only + enum class COMDAT_SELECTION : uint8_t { + NONE = 0, + + /// If this symbol is already defined, the linker issues a `multiply defined symbol` + /// error. + NODUPLICATES = 1, + + /// Any section that defines the same COMDAT symbol can be linked; the rest + /// are removed. + ANY, + + /// The linker chooses an arbitrary section among the definitions for this + /// symbol. If all definitions are not the same size, a `multiply defined symbol` + /// error is issued. + SAME_SIZE, + + /// The linker chooses an arbitrary section among the definitions for this + /// symbol. If all definitions do not match exactly, a + /// `multiply defined symbol` error is issued. + EXACT_MATCH, + + /// The section is linked if a certain other COMDAT section is linked. + /// This other section is indicated by the Number field of the auxiliary + /// symbol record for the section definition. This setting is useful for + /// definitions that have components in multiple sections + /// (for example, code in one and data in another), but where all must be + /// linked or discarded as a set. The other section this section is + /// associated with must be a COMDAT section, which can be another + /// associative COMDAT section. An associative COMDAT section's section + /// association chain can't form a loop. The section association chain must + /// eventually come to a COMDAT section that doesn't have + /// COMDAT_SELECTION::ASSOCIATIVE set. + ASSOCIATIVE, + + /// The linker chooses the largest definition from among all of the definitions + /// for this symbol. If multiple definitions have this size, the choice + /// between them is arbitrary. + LARGEST + }; + + /// The size of section data. The same as `SizeOfRawData` in the section header. + uint32_t length() const { + return length_; + } + + /// The number of relocation entries for the section. + uint16_t nb_relocs() const { + return nb_relocs_; + } + + /// The number of line-number entries for the section. + uint16_t nb_line_numbers() const { + return nb_lines_; + } + + /// The checksum for communal data. It is applicable if the + /// `IMAGE_SCN_LNK_COMDAT` flag is set in the section header. + uint32_t checksum() const { + return checksum_; + } + + /// One-based index into the section table for the associated section. + /// This is used when the COMDAT selection setting is 5. + uint32_t section_idx() const { + return sec_idx_; + } + + /// The COMDAT selection number. This is applicable if the section is a + /// COMDAT section. + COMDAT_SELECTION selection() const { + return selection_; + } + + /// Reserved value (should be 0) + uint8_t reserved() const { + return reserved_; + } + + std::string to_string() const override; + + static bool classof(const AuxiliarySymbol* sym) { + return sym->type() == AuxiliarySymbol::TYPE::SEC_DEF; + } + + ~AuxiliarySectionDefinition() override = default; + + private: + uint32_t length_ = 0; + uint16_t nb_relocs_ = 0; + uint16_t nb_lines_ = 0; + uint32_t checksum_ = 0; + uint32_t sec_idx_ = 0; + COMDAT_SELECTION selection_ = COMDAT_SELECTION::NONE; + uint8_t reserved_ = 0; +}; + +LIEF_API const char* to_string(AuxiliarySectionDefinition::COMDAT_SELECTION e); + +} +} +#endif diff --git a/deps/LIEF/include/LIEF/COFF/AuxiliarySymbols/AuxiliaryWeakExternal.hpp b/deps/LIEF/include/LIEF/COFF/AuxiliarySymbols/AuxiliaryWeakExternal.hpp new file mode 100644 index 00000000000000..488f787dec126c --- /dev/null +++ b/deps/LIEF/include/LIEF/COFF/AuxiliarySymbols/AuxiliaryWeakExternal.hpp @@ -0,0 +1,113 @@ +/* Copyright 2017 - 2025 R. Thomas + * Copyright 2017 - 2025 Quarkslab + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef LIEF_COFF_AUXILIARY_WEAK_EXTERNAL_H +#define LIEF_COFF_AUXILIARY_WEAK_EXTERNAL_H + +#include +#include + +#include "LIEF/visibility.h" +#include "LIEF/COFF/AuxiliarySymbol.hpp" + +namespace LIEF { + +namespace COFF { + +/// "Weak externals" are a mechanism for object files that allows flexibility at +/// link time. A module can contain an unresolved external symbol (`sym1`), but +/// it can also include an auxiliary record that indicates that if `sym1` is not +/// present at link time, another external symbol (`sym2`) is used to resolve +/// references instead. +/// +/// If a definition of `sym1` is linked, then an external reference to the +/// symbol is resolved normally. If a definition of `sym1` is not linked, then all +/// references to the weak external for `sym1` refer to `sym2` instead. The external +/// symbol, `sym2`, must always be linked; typically, it is defined in the module +/// that contains the weak reference to `sym1`. +/// +/// Reference: https://learn.microsoft.com/en-us/windows/win32/debug/pe-format#auxiliary-format-3-weak-externals +class LIEF_API AuxiliaryWeakExternal : public AuxiliarySymbol { + public: + enum class CHARACTERISTICS : uint32_t { + /// No library search for `sym1` should be performed. + SEARCH_NOLIBRARY = 1, + ///A library search for `sym1` should be performed. + SEARCH_LIBRARY = 2, + /// `sym1` is an alias for sym2 + SEARCH_ALIAS = 3, + ANTI_DEPENDENCY = 4 + }; + + LIEF_LOCAL static std::unique_ptr + parse(const std::vector& payload); + + AuxiliaryWeakExternal() : + AuxiliarySymbol(AuxiliarySymbol::TYPE::WEAK_EXTERNAL) + {} + + AuxiliaryWeakExternal(uint32_t sym_idx, uint32_t characteristics, + std::vector padding) : + AuxiliarySymbol(AuxiliarySymbol::TYPE::WEAK_EXTERNAL), + sym_idx_(sym_idx), + characteristics_(characteristics), + padding_(std::move(padding)) + { + assert(padding_.size() == 10); + } + + AuxiliaryWeakExternal(const AuxiliaryWeakExternal&) = default; + AuxiliaryWeakExternal& operator=(const AuxiliaryWeakExternal&) = default; + + AuxiliaryWeakExternal(AuxiliaryWeakExternal&&) = default; + AuxiliaryWeakExternal& operator=(AuxiliaryWeakExternal&&) = default; + + std::unique_ptr clone() const override { + return std::unique_ptr(new AuxiliaryWeakExternal{*this}); + } + + /// The symbol-table index of `sym2`, the symbol to be linked if `sym1` is not + /// found. + uint32_t sym_idx() const { + return sym_idx_; + } + + CHARACTERISTICS characteristics() const { + return (CHARACTERISTICS)characteristics_; + } + + span padding() const { + return padding_; + } + + std::string to_string() const override; + + static bool classof(const AuxiliarySymbol* sym) { + return sym->type() == AuxiliarySymbol::TYPE::WEAK_EXTERNAL; + } + + ~AuxiliaryWeakExternal() override = default; + + private: + uint32_t sym_idx_ = 0; + uint32_t characteristics_ = 0; + std::vector padding_; +}; + +LIEF_API const char* to_string(AuxiliaryWeakExternal::CHARACTERISTICS e); + +} +} +#endif diff --git a/deps/LIEF/include/LIEF/COFF/AuxiliarySymbols/AuxiliarybfAndefSymbol.hpp b/deps/LIEF/include/LIEF/COFF/AuxiliarySymbols/AuxiliarybfAndefSymbol.hpp new file mode 100644 index 00000000000000..53b0666b588842 --- /dev/null +++ b/deps/LIEF/include/LIEF/COFF/AuxiliarySymbols/AuxiliarybfAndefSymbol.hpp @@ -0,0 +1,60 @@ +/* Copyright 2017 - 2025 R. Thomas + * Copyright 2017 - 2025 Quarkslab + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef LIEF_COFF_AUXILIARY_BF_AND_EF_H +#define LIEF_COFF_AUXILIARY_BF_AND_EF_H + +#include + +#include "LIEF/visibility.h" +#include "LIEF/COFF/AuxiliarySymbol.hpp" + +namespace LIEF { + +namespace COFF { + +class LIEF_API AuxiliarybfAndefSymbol : public AuxiliarySymbol { + public: + LIEF_LOCAL static std::unique_ptr + parse(Symbol& sym, const std::vector& payload); + + AuxiliarybfAndefSymbol() : + AuxiliarySymbol(AuxiliarySymbol::TYPE::BF_AND_EF) + {} + + AuxiliarybfAndefSymbol(const AuxiliarybfAndefSymbol&) = default; + AuxiliarybfAndefSymbol& operator=(const AuxiliarybfAndefSymbol&) = default; + + AuxiliarybfAndefSymbol(AuxiliarybfAndefSymbol&&) = default; + AuxiliarybfAndefSymbol& operator=(AuxiliarybfAndefSymbol&&) = default; + + std::unique_ptr clone() const override { + return std::unique_ptr(new AuxiliarybfAndefSymbol{*this}); + } + + std::string to_string() const override { + return "AuxiliarybfAndefSymbol"; + } + + static bool classof(const AuxiliarySymbol* sym) { + return sym->type() == AuxiliarySymbol::TYPE::BF_AND_EF; + } + + ~AuxiliarybfAndefSymbol() override = default; +}; + +} +} +#endif diff --git a/deps/LIEF/include/LIEF/COFF/BigObjHeader.hpp b/deps/LIEF/include/LIEF/COFF/BigObjHeader.hpp new file mode 100644 index 00000000000000..a793092cd64887 --- /dev/null +++ b/deps/LIEF/include/LIEF/COFF/BigObjHeader.hpp @@ -0,0 +1,123 @@ +/* Copyright 2017 - 2025 R. Thomas + * Copyright 2017 - 2025 Quarkslab + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef LIEF_COFF_BIGOBJ_HEADER_H +#define LIEF_COFF_BIGOBJ_HEADER_H +#include +#include + +#include "LIEF/COFF/Header.hpp" + +#include "LIEF/visibility.h" +#include "LIEF/span.hpp" + +namespace LIEF { +namespace COFF { + +/// This class represents the header for a COFF object compiled +/// with `/bigobj` support (i.e. the number of sections can exceed 65536). +/// +/// The raw definition of the bigobj header is located in `winnt.h` and named +/// `ANON_OBJECT_HEADER_BIGOBJ` +class LIEF_API BigObjHeader : public Header { + public: + static constexpr auto UUID_SZ = 16; + BigObjHeader() : + Header(KIND::BIGOBJ) + {} + + static std::unique_ptr create(BinaryStream& stream); + + BigObjHeader& operator=(const BigObjHeader&) = default; + BigObjHeader(const BigObjHeader&) = default; + + BigObjHeader& operator=(BigObjHeader&&) = default; + BigObjHeader(BigObjHeader&&) = default; + + std::unique_ptr
clone() const override { + return std::unique_ptr
(new BigObjHeader(*this)); + } + + /// The version of this header which must be >= 2 + uint16_t version() const { + return version_; + } + + /// Originally named `ClassID`, this uuid should match: `{D1BAA1C7-BAEE-4ba9-AF20-FAF66AA4DCB8}` + span uuid() const { + return uuid_; + } + + /// Size of data that follows the header + uint32_t sizeof_data() const { + return sizeof_data_; + } + + /// 1 means that it contains metadata + uint32_t flags() const { + return flags_; + } + + /// Size of CLR metadata + uint32_t metadata_size() const { + return metadata_size_; + } + + /// Offset of CLR metadata + uint32_t metadata_offset() const { + return metadata_offset_; + } + + void version(uint16_t value) { + version_ = value; + } + + void sizeof_data(uint32_t value) { + sizeof_data_ = value; + } + + void flags(uint32_t value) { + flags_ = value; + } + + void metadata_size(uint32_t value) { + metadata_size_ = value; + } + + void metadata_offset(uint32_t value) { + metadata_offset_ = value; + } + + static bool classof(const Header* header) { + return header->kind() == Header::KIND::BIGOBJ; + } + + ~BigObjHeader() override = default; + + std::string to_string() const override; + + protected: + uint16_t version_ = 0; + std::array uuid_ = {}; + + uint32_t sizeof_data_ = 0; + uint32_t flags_ = 0; + uint32_t metadata_size_ = 0; + uint32_t metadata_offset_ = 0; +}; + +} +} +#endif diff --git a/deps/LIEF/include/LIEF/COFF/Binary.hpp b/deps/LIEF/include/LIEF/COFF/Binary.hpp new file mode 100644 index 00000000000000..9467836970e76b --- /dev/null +++ b/deps/LIEF/include/LIEF/COFF/Binary.hpp @@ -0,0 +1,252 @@ +/* Copyright 2017 - 2025 R. Thomas + * Copyright 2017 - 2025 Quarkslab + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef LIEF_COFF_BINARY_H +#define LIEF_COFF_BINARY_H +#include "LIEF/visibility.h" +#include "LIEF/iterators.hpp" +#include "LIEF/span.hpp" + +#include "LIEF/COFF/String.hpp" + +#include "LIEF/asm/Instruction.hpp" + +#include +#include +#include + +namespace LIEF { + +namespace assembly { +class Engine; +} + +namespace COFF { +class Header; +class Parser; +class Section; +class Relocation; +class Symbol; + +/// Class that represents a COFF Binary +class LIEF_API Binary { + public: + friend class Parser; + + /// Internal container used to store COFF's section + using sections_t = std::vector>; + + /// Iterator that outputs Section& object + using it_sections = ref_iterator; + + /// Iterator that outputs const Section& object + using it_const_sections = const_ref_iterator; + + /// Internal container used to store COFF's relocations + using relocations_t = std::vector>; + + /// Iterator that outputs Relocation& object + using it_relocations = ref_iterator; + + /// Iterator that outputs const Relocation& object + using it_const_relocations = const_ref_iterator; + + /// Internal container used to store COFF's strings + using strings_table_t = std::vector; + + /// Iterator that outputs String& object + using it_strings_table = ref_iterator; + + /// Iterator that outputs const String& object + using it_const_strings_table = const_ref_iterator; + + /// Internal container used to store COFF's symbols + using symbols_t = std::vector>; + + /// Iterator that outputs Symbol& object + using it_symbols = ref_iterator; + + /// Iterator that outputs Symbol& object + using it_const_symbols = const_ref_iterator; + + /// Instruction iterator + using instructions_it = iterator_range; + + /// Iterator which outputs COFF symbols representing functions + using it_functions = filter_iterator; + + /// Iterator which outputs COFF symbols representing functions + using it_const_function = const_filter_iterator; + + /// The COFF header + const Header& header() const { + return *header_; + } + + Header& header() { + return *header_; + } + + /// Iterator over the different sections located in this COFF binary + it_sections sections() { + return sections_; + } + + it_const_sections sections() const { + return sections_; + } + + /// Iterator over **all** the relocations used by this COFF binary + it_relocations relocations() { + return relocations_; + } + + it_const_relocations relocations() const { + return relocations_; + } + + /// Iterator over the COFF's symbols + it_symbols symbols() { + return symbols_; + } + + it_const_symbols symbols() const { + return symbols_; + } + + /// Iterator over the COFF's strings + it_const_strings_table string_table() const { + return strings_table_; + } + + it_strings_table string_table() { + return strings_table_; + } + + /// Try to find the COFF string at the given offset in the COFF string table. + /// + /// \warning This offset must include the first 4 bytes holding the size of + /// the table. Hence, the first string starts a the offset 4. + String* find_string(uint32_t offset) { + auto it = std::find_if(strings_table_.begin(), strings_table_.end(), + [offset] (const String& item) { + return offset == item.offset(); + } + ); + return it == strings_table_.end() ? nullptr : &*it; + } + + const String* find_string(uint32_t offset) const { + return const_cast(this)->find_string(offset); + } + + /// Iterator over the functions implemented in this COFF + it_const_function functions() const; + + it_functions functions(); + + /// Try to find the function (symbol) with the given name + const Symbol* find_function(const std::string& name) const; + + Symbol* find_function(const std::string& name) { + return const_cast(static_cast(this)->find_function(name)); + } + + /// Try to find the function (symbol) with the given **demangled** name + const Symbol* find_demangled_function(const std::string& name) const; + + Symbol* find_demangled_function(const std::string& name) { + return const_cast(static_cast(this)->find_demangled_function(name)); + } + + /// Disassemble code for the given symbol + /// + /// ```cpp + /// const Symbol* func = binary->find_demangled_function("int __cdecl my_function(int, int)"); + /// auto insts = binary->disassemble(*func); + /// for (std::unique_ptr inst : insts) { + /// std::cout << inst->to_string() << '\n'; + /// } + /// ``` + /// + /// \see LIEF::assembly::Instruction + instructions_it disassemble(const Symbol& symbol) const; + + /// Disassemble code for the given symbol name + /// + /// ```cpp + /// auto insts = binary->disassemble("main"); + /// for (std::unique_ptr inst : insts) { + /// std::cout << inst->to_string() << '\n'; + /// } + /// ``` + /// + /// \see LIEF::assembly::Instruction + instructions_it disassemble(const std::string& symbol) const; + + /// Disassemble code provided by the given buffer at the specified + /// `address` parameter. + /// + /// \see LIEF::assembly::Instruction + instructions_it disassemble(const uint8_t* buffer, size_t size, + uint64_t address = 0) const; + + + /// Disassemble code provided by the given vector of bytes at the specified + /// `address` parameter. + /// + /// \see LIEF::assembly::Instruction + instructions_it disassemble(const std::vector& buffer, + uint64_t address = 0) const { + return disassemble(buffer.data(), buffer.size(), address); + } + + instructions_it disassemble(LIEF::span buffer, + uint64_t address = 0) const { + return disassemble(buffer.data(), buffer.size(), address); + } + + instructions_it disassemble(LIEF::span buffer, uint64_t address = 0) const { + return disassemble(buffer.data(), buffer.size(), address); + } + + std::string to_string() const; + + LIEF_API friend std::ostream& operator<<(std::ostream& os, const Binary& bin) { + os << bin.to_string(); + return os; + } + + ~Binary(); + + private: + Binary(); + std::unique_ptr
header_; + sections_t sections_; + relocations_t relocations_; + strings_table_t strings_table_; + symbols_t symbols_; + + mutable std::unordered_map> engines_; + + assembly::Engine* get_engine(uint64_t address) const; + + template + LIEF_LOCAL assembly::Engine* get_cache_engine(uint64_t address, F&& f) const; +}; + +} +} +#endif diff --git a/deps/LIEF/include/LIEF/COFF/Header.hpp b/deps/LIEF/include/LIEF/COFF/Header.hpp new file mode 100644 index 00000000000000..5239b73faa4979 --- /dev/null +++ b/deps/LIEF/include/LIEF/COFF/Header.hpp @@ -0,0 +1,155 @@ +/* Copyright 2017 - 2025 R. Thomas + * Copyright 2017 - 2025 Quarkslab + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef LIEF_COFF_HEADER_H +#define LIEF_COFF_HEADER_H +#include +#include +#include + +#include "LIEF/visibility.h" +#include "LIEF/PE/Header.hpp" + +namespace LIEF { +class BinaryStream; + +namespace COFF { + +/// Class that represents the COFF header. It is subclassed by +/// LIEF::COFF::RegularHeader and LIEF::COFF::BigObjHeader for normal vs +/// `/bigobj` files +class LIEF_API Header { + public: + + enum class KIND { + UNKNOWN = 0, + REGULAR, + BIGOBJ + }; + + /// The different architectures (mirrored from PE) + using MACHINE_TYPES = LIEF::PE::Header::MACHINE_TYPES; + + /// Create a header from the given stream + static std::unique_ptr
create(BinaryStream& stream); + static std::unique_ptr
create(BinaryStream& stream, KIND kind); + + Header() = default; + Header(KIND kind) : + kind_(kind) + {} + + Header& operator=(const Header&) = default; + Header(const Header&) = default; + + Header& operator=(Header&&) = default; + Header(Header&&) = default; + + virtual std::unique_ptr
clone() const = 0; + + /// The type of this header: whether it is regular or using the `/bigobj` + /// format + KIND kind() const { + return kind_; + } + + /// The machine type targeted by this COFF + MACHINE_TYPES machine() const { + return machine_; + } + + /// The number of sections + uint32_t nb_sections() const { + return nb_sections_; + } + + /// Offset of the symbols table + uint32_t pointerto_symbol_table() const { + return pointerto_symbol_table_; + } + + /// Number of symbols (including auxiliary symbols) + uint32_t nb_symbols() const { + return nb_symbols_; + } + + /// Timestamp when the COFF has been generated + uint32_t timedatestamp() const { + return timedatestamp_; + } + + void machine(MACHINE_TYPES machine) { + machine_ = machine; + } + + void nb_sections(uint32_t value) { + nb_sections_ = value; + } + + void pointerto_symbol_table(uint32_t value) { + pointerto_symbol_table_ = value; + } + + void nb_symbols(uint32_t value) { + nb_symbols_ = value; + } + + void timedatestamp(uint32_t value) { + timedatestamp_ = value; + } + + virtual std::string to_string() const; + + LIEF_API friend std::ostream& operator<<(std::ostream& os, const Header& hdr) { + os << hdr.to_string(); + return os; + } + + template + const T* as() const { + static_assert(std::is_base_of::value, + "Require Header inheritance"); + if (T::classof(this)) { + return static_cast(this); + } + return nullptr; + } + + virtual ~Header() = default; + + protected: + KIND kind_ = KIND::UNKNOWN; + MACHINE_TYPES machine_ = MACHINE_TYPES::UNKNOWN; + uint32_t nb_sections_ = 0; + uint32_t pointerto_symbol_table_ = 0; + uint32_t nb_symbols_ = 0; + uint32_t timedatestamp_ = 0; +}; + +LIEF_API inline const char* to_string(Header::KIND kind) { + switch (kind) { + case Header::KIND::UNKNOWN: return "UNKNOWN"; + case Header::KIND::REGULAR: return "REGULAR"; + case Header::KIND::BIGOBJ: return "BIGOBJ"; + } + return "UNKNOWN"; +} + +LIEF_API inline const char* to_string(Header::MACHINE_TYPES machine) { + return LIEF::PE::to_string(machine); +} +} +} +#endif diff --git a/deps/LIEF/include/LIEF/COFF/Parser.hpp b/deps/LIEF/include/LIEF/COFF/Parser.hpp new file mode 100644 index 00000000000000..fa1a5ff79d7d54 --- /dev/null +++ b/deps/LIEF/include/LIEF/COFF/Parser.hpp @@ -0,0 +1,109 @@ +/* Copyright 2017 - 2025 R. Thomas + * Copyright 2017 - 2025 Quarkslab + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef LIEF_COFF_PARSER_H +#define LIEF_COFF_PARSER_H +#include +#include "LIEF/visibility.h" + +#include "LIEF/BinaryStream/VectorStream.hpp" +#include "LIEF/BinaryStream/SpanStream.hpp" + +#include "LIEF/COFF/ParserConfig.hpp" +#include "LIEF/COFF/Header.hpp" + +namespace LIEF { +namespace COFF { +class Binary; +class Section; +class String; +class Symbol; + +class Parser { + public: + /// Parse the COFF binary referenced by the `stream` argument with the + /// given config + static LIEF_API + std::unique_ptr parse(std::unique_ptr stream, + const ParserConfig& config = ParserConfig::default_conf()); + + /// Parse the COFF binary pointed by the `file` argument with the given config + static std::unique_ptr parse(const std::string& file, + const ParserConfig& config = ParserConfig::default_conf()) + { + if (auto strm = VectorStream::from_file(file)) { + return parse(std::unique_ptr(new VectorStream(std::move(*strm))), config); + } + return nullptr; + } + + /// \private + struct SymSec { + size_t sec_idx = 0; + Symbol* symbol = nullptr; + + friend bool operator<(const SymSec& lhs, const SymSec& rhs) { + return lhs.sec_idx < rhs.sec_idx; + } + + friend bool operator==(const SymSec& lhs, const SymSec& rhs) { + return lhs.sec_idx == rhs.sec_idx && lhs.symbol == rhs.symbol; + } + + friend bool operator!=(const SymSec& lhs, const SymSec& rhs) { + return !(lhs == rhs); + } + }; + + /// <=> std::unordered_multimap
+ using SymSecMap = std::vector; + + /// \private + LIEF_LOCAL void memoize(String str); + + /// \private + LIEF_LOCAL String* find_coff_string(uint32_t offset) const; + + ~Parser(); + + private: + Parser(std::unique_ptr stream, const ParserConfig& config, + Header::KIND kind) : + stream_(std::move(stream)), + kind_(kind), + config_(config) + {} + + ok_error_t process(); + ok_error_t parse_header(); + ok_error_t parse_optional_header(); + ok_error_t parse_sections(); + ok_error_t parse_relocations(Section& section); + ok_error_t parse_symbols(); + ok_error_t parse_string_table(); + + std::unique_ptr stream_; + std::unique_ptr bin_; + Header::KIND kind_ = Header::KIND::UNKNOWN; + + std::map memoize_coff_str_; + std::map symbol_idx_; + SymSecMap symsec_; + + ParserConfig config_; +}; +} +} +#endif diff --git a/deps/LIEF/include/LIEF/COFF/ParserConfig.hpp b/deps/LIEF/include/LIEF/COFF/ParserConfig.hpp new file mode 100644 index 00000000000000..3d0a09636b5262 --- /dev/null +++ b/deps/LIEF/include/LIEF/COFF/ParserConfig.hpp @@ -0,0 +1,38 @@ +/* Copyright 2017 - 2025 R. Thomas + * Copyright 2017 - 2025 Quarkslab + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef LIEF_COFF_PARSER_CONFIG_H +#define LIEF_COFF_PARSER_CONFIG_H + +#include "LIEF/visibility.h" + +namespace LIEF { +namespace COFF { +/// Class used to configure the COFF parser +class LIEF_API ParserConfig { + public: + static const ParserConfig& default_conf() { + static const ParserConfig DEFAULT; + return DEFAULT; + } + + static const ParserConfig& all() { + // To be updated when there is options that are off by default + return default_conf(); + } +}; +} +} +#endif diff --git a/deps/LIEF/include/LIEF/COFF/RegularHeader.hpp b/deps/LIEF/include/LIEF/COFF/RegularHeader.hpp new file mode 100644 index 00000000000000..1aab5525400d38 --- /dev/null +++ b/deps/LIEF/include/LIEF/COFF/RegularHeader.hpp @@ -0,0 +1,78 @@ +/* Copyright 2017 - 2025 R. Thomas + * Copyright 2017 - 2025 Quarkslab + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef LIEF_COFF_REGULAR_HEADER_H +#define LIEF_COFF_REGULAR_HEADER_H +#include +#include "LIEF/COFF/Header.hpp" +#include "LIEF/visibility.h" + +namespace LIEF { +namespace COFF { + +/// This class represents the COFF header for non-bigobj +class LIEF_API RegularHeader : public Header { + public: + RegularHeader() : + Header(KIND::REGULAR) + {} + + /// Create a RegularHeader from the given stream + static std::unique_ptr create(BinaryStream& stream); + + RegularHeader& operator=(const RegularHeader&) = default; + RegularHeader(const RegularHeader&) = default; + + RegularHeader& operator=(RegularHeader&&) = default; + RegularHeader(RegularHeader&&) = default; + + std::unique_ptr
clone() const override { + return std::unique_ptr
(new RegularHeader(*this)); + } + + /// The size of the optional header that follows this header (should be 0) + uint16_t sizeof_optionalheader() const { + return sizeof_optionalheader_; + } + + /// Characteristics + uint16_t characteristics() const { + return characteristics_; + } + + void sizeof_optionalheader(uint16_t value) { + sizeof_optionalheader_ = value; + } + + void characteristics(uint16_t value) { + characteristics_ = value; + } + + static bool classof(const Header* header) { + return header->kind() == Header::KIND::REGULAR; + } + + ~RegularHeader() override = default; + + std::string to_string() const override; + + protected: + uint16_t sizeof_optionalheader_ = 0; + uint16_t characteristics_ = 0; +}; + +} +} +#endif diff --git a/deps/LIEF/include/LIEF/COFF/Relocation.hpp b/deps/LIEF/include/LIEF/COFF/Relocation.hpp new file mode 100644 index 00000000000000..960caf0ad8b3c0 --- /dev/null +++ b/deps/LIEF/include/LIEF/COFF/Relocation.hpp @@ -0,0 +1,218 @@ +/* Copyright 2017 - 2025 R. Thomas + * Copyright 2017 - 2025 Quarkslab + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef LIEF_COFF_RELOCATION_H +#define LIEF_COFF_RELOCATION_H +#include +#include +#include + +#include "LIEF/visibility.h" +#include "LIEF/COFF/Header.hpp" +#include "LIEF/Abstract/Relocation.hpp" + +namespace LIEF { +class BinaryStream; +namespace COFF { +class Section; +class Parser; +class Symbol; + +/// This class represents a COFF relocation +class LIEF_API Relocation : public LIEF::Relocation { + public: + friend class Parser; + + static constexpr uint32_t I386 = 1 << 17; + static constexpr uint32_t X64 = 1 << 18; + static constexpr uint32_t ARM = 1 << 19; + static constexpr uint32_t ARM64 = 1 << 20; + static constexpr uint32_t MIPS = 1 << 21; + + /// The different relocation types. + /// + /// Please note that the original type is encoded on 16 bits but we encode + /// the type on 32-bits by adding a discriminator from the 17th bit + enum class TYPE : uint32_t { + UNKNOWN = uint32_t(-1), + I386_ABSOLUTE = I386 + 0x0000, + I386_DIR16 = I386 + 0x0001, + I386_REL16 = I386 + 0x0002, + I386_DIR32 = I386 + 0x0006, + I386_DIR32NB = I386 + 0x0007, + I386_SEG12 = I386 + 0x0009, + I386_SECTION = I386 + 0x000A, + I386_SECREL = I386 + 0x000B, + I386_TOKEN = I386 + 0x000C, + I386_SECREL7 = I386 + 0x000D, + I386_REL32 = I386 + 0x0014, + + AMD64_ABSOLUTE = X64 + 0x0000, + AMD64_ADDR64 = X64 + 0x0001, + AMD64_ADDR32 = X64 + 0x0002, + AMD64_ADDR32NB = X64 + 0x0003, + AMD64_REL32 = X64 + 0x0004, + AMD64_REL32_1 = X64 + 0x0005, + AMD64_REL32_2 = X64 + 0x0006, + AMD64_REL32_3 = X64 + 0x0007, + AMD64_REL32_4 = X64 + 0x0008, + AMD64_REL32_5 = X64 + 0x0009, + AMD64_SECTION = X64 + 0x000A, + AMD64_SECREL = X64 + 0x000B, + AMD64_SECREL7 = X64 + 0x000C, + AMD64_TOKEN = X64 + 0x000D, + AMD64_SREL32 = X64 + 0x000E, + AMD64_PAIR = X64 + 0x000F, + AMD64_SSPAN32 = X64 + 0x0010, + + ARM_ABSOLUTE = ARM + 0x0000, + ARM_ADDR32 = ARM + 0x0001, + ARM_ADDR32NB = ARM + 0x0002, + ARM_BRANCH24 = ARM + 0x0003, + ARM_BRANCH11 = ARM + 0x0004, + ARM_TOKEN = ARM + 0x0005, + ARM_BLX24 = ARM + 0x0008, + ARM_BLX11 = ARM + 0x0009, + ARM_REL32 = ARM + 0x000A, + ARM_SECTION = ARM + 0x000E, + ARM_SECREL = ARM + 0x000F, + ARM_MOV32A = ARM + 0x0010, + ARM_MOV32T = ARM + 0x0011, + ARM_BRANCH20T = ARM + 0x0012, + ARM_BRANCH24T = ARM + 0x0014, + ARM_BLX23T = ARM + 0x0015, + ARM_PAIR = ARM + 0x0016, + + ARM64_ABSOLUTE = ARM64 + 0x0000, + ARM64_ADDR32 = ARM64 + 0x0001, + ARM64_ADDR32NB = ARM64 + 0x0002, + ARM64_BRANCH26 = ARM64 + 0x0003, + ARM64_PAGEBASE_REL21 = ARM64 + 0x0004, + ARM64_REL21 = ARM64 + 0x0005, + ARM64_PAGEOFFSET_12A = ARM64 + 0x0006, + ARM64_PAGEOFFSET_12L = ARM64 + 0x0007, + ARM64_SECREL = ARM64 + 0x0008, + ARM64_SECREL_LOW12A = ARM64 + 0x0009, + ARM64_SECREL_HIGH12A = ARM64 + 0x000A, + ARM64_SECREL_LOW12L = ARM64 + 0x000B, + ARM64_TOKEN = ARM64 + 0x000C, + ARM64_SECTION = ARM64 + 0x000D, + ARM64_ADDR64 = ARM64 + 0x000E, + ARM64_BRANCH19 = ARM64 + 0x000F, + ARM64_BRANCH14 = ARM64 + 0x0010, + ARM64_REL32 = ARM64 + 0x0011, + + MIPS_ABSOLUTE = MIPS + 0x0000, + MIPS_REFHALF = MIPS + 0x0001, + MIPS_REFWORD = MIPS + 0x0002, + MIPS_JMPADDR = MIPS + 0x0003, + MIPS_REFHI = MIPS + 0x0004, + MIPS_REFLO = MIPS + 0x0005, + MIPS_GPREL = MIPS + 0x0006, + MIPS_LITERAL = MIPS + 0x0007, + MIPS_SECTION = MIPS + 0x000A, + MIPS_SECREL = MIPS + 0x000B, + MIPS_SECRELLO = MIPS + 0x000C, + MIPS_SECRELHI = MIPS + 0x000D, + MIPS_JMPADDR16 = MIPS + 0x0010, + MIPS_REFWORDNB = MIPS + 0x0022, + MIPS_PAIR = MIPS + 0x0025, + }; + + /// Convert a relocation enum type into a 16-bits value. + static uint16_t to_value(TYPE rtype) { + return (uint16_t)rtype; + } + + /// Create a relocation type from its raw value and the architecture + static TYPE from_value(uint16_t value, Header::MACHINE_TYPES arch) { + switch (arch) { + case Header::MACHINE_TYPES::ARM64: + return TYPE(value + ARM64); + + case Header::MACHINE_TYPES::AMD64: + return TYPE(value + X64); + + case Header::MACHINE_TYPES::I386: + return TYPE(value + I386); + + case Header::MACHINE_TYPES::ARM: + case Header::MACHINE_TYPES::ARMNT: + case Header::MACHINE_TYPES::THUMB: + return TYPE(value + ARM); + + case Header::MACHINE_TYPES::R4000: + return TYPE(value + MIPS); + + default: + return TYPE::UNKNOWN; + } + return TYPE::UNKNOWN; + } + + /// Create a relocation from the given stream + static std::unique_ptr parse( + BinaryStream& stream, Header::MACHINE_TYPES arch); + + /// Symbol index associated with this relocation + uint32_t symbol_idx() const { + return symbol_idx_; + } + + /// Symbol associated with the relocation (if any) + Symbol* symbol() { + return symbol_; + } + + const Symbol* symbol() const { + return symbol_; + } + + /// Type of the relocation + TYPE type() const { + return type_; + } + + /// Section in which the relocation takes place + Section* section() { + return section_; + } + + const Section* section() const { + return section_; + } + + std::string to_string() const; + + LIEF_API friend std::ostream& operator<<(std::ostream& os, const Relocation& R) { + os << R.to_string(); + return os; + } + + ~Relocation() override = default; + + private: + Relocation() = default; + uint32_t symbol_idx_ = 0; + TYPE type_ = TYPE::UNKNOWN; + Section* section_ = nullptr; + Symbol* symbol_ = nullptr; +}; + +LIEF_API const char* to_string(Relocation::TYPE e); + +} +} +#endif diff --git a/deps/LIEF/include/LIEF/COFF/Section.hpp b/deps/LIEF/include/LIEF/COFF/Section.hpp new file mode 100644 index 00000000000000..d70a3117adf5e2 --- /dev/null +++ b/deps/LIEF/include/LIEF/COFF/Section.hpp @@ -0,0 +1,250 @@ +/* Copyright 2017 - 2025 R. Thomas + * Copyright 2017 - 2025 Quarkslab + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef LIEF_COFF_SECTION_H +#define LIEF_COFF_SECTION_H +#include +#include +#include + +#include "LIEF/visibility.h" +#include "LIEF/Abstract/Section.hpp" +#include "LIEF/PE/Section.hpp" +#include "LIEF/COFF/AuxiliarySymbols/AuxiliarySectionDefinition.hpp" +#include "LIEF/iterators.hpp" +#include "LIEF/optional.hpp" + +namespace LIEF { +class BinaryStream; + +namespace COFF { +class Relocation; +class Parser; +class Symbol; + + +/// This class represents a COFF section +class LIEF_API Section : public LIEF::Section { + public: + friend class Parser; + using LIEF::Section::name; + + using COMDAT_SELECTION = AuxiliarySectionDefinition::COMDAT_SELECTION; + + /// This structure wraps comdat information which is composed of the symbol + /// associated with the comdat section and its selection flag + struct LIEF_API ComdatInfo { + Symbol* symbol = nullptr; + COMDAT_SELECTION kind = COMDAT_SELECTION::NONE; + }; + + /// Mirror Characteristics from PE + using CHARACTERISTICS = LIEF::PE::Section::CHARACTERISTICS; + + /// Container for the relocations in this section (owned by the Binary object) + using relocations_t = std::vector; + + /// Iterator that outputs Relocation& + using it_relocations = ref_iterator; + + /// Iterator that outputs const Relocation& + using it_const_relocations = const_ref_iterator; + + /// Container for the symbols associated with this section (owned by the Binary object) + using symbols_t = std::vector; + + /// Iterator that outputs Symbol& + using it_symbols = ref_iterator; + + /// Iterator that outputs const Symbol& + using it_const_symbols = const_ref_iterator; + + /// Parse a section from the given stream + static std::unique_ptr
parse(BinaryStream& stream); + + /// Return the size of the data in the section. + uint32_t sizeof_raw_data() const { + return size_; + } + + /// Virtual size of the section (should be 0) + uint32_t virtual_size() const { + return virtual_size_; + } + + /// Content wrapped by this section + span content() const override { + return content_; + } + + /// Offset to the section's content + uint32_t pointerto_raw_data() const { + return offset_; + } + + /// Offset to the relocation table + uint32_t pointerto_relocation() const { + return pointer_to_relocations_; + } + + /// The file pointer to the beginning of line-number entries for the section. + /// + /// This is set to zero if there are no COFF line numbers. + /// This value should be zero for an image because COFF debugging information + /// is deprecated and modern debug information relies on the PDB files. + uint32_t pointerto_line_numbers() const { + return pointer_to_linenumbers_; + } + + /// Number of relocations. + /// + /// \warning If the number of relocations is greater than 0xFFFF (maximum + /// value for 16-bits integer), then the number of relocations is + /// stored in the virtual address of the **first** relocation. + uint16_t numberof_relocations() const { + return number_of_relocations_; + } + + /// Number of line number entries (if any). + uint16_t numberof_line_numbers() const { + return number_of_linenumbers_; + } + + /// Characteristics of the section: it provides information about + /// the permissions of the section when mapped. It can also provide + /// information about the *purpose* of the section (contain code, BSS-like, ...) + uint32_t characteristics() const { + return characteristics_; + } + + /// Check if the section has the given CHARACTERISTICS + bool has_characteristic(CHARACTERISTICS c) const { + return (characteristics() & (uint32_t)c) > 0; + } + + /// List of the section characteristics + std::vector characteristics_list() const { + return LIEF::PE::Section::characteristics_to_list(characteristics_); + } + + /// True if the section can be discarded as needed. + /// + /// This is typically the case for debug-related sections + bool is_discardable() const { + return has_characteristic(CHARACTERISTICS::MEM_DISCARDABLE); + } + + void clear(uint8_t c) { + std::fill(content_.begin(), content_.end(), c); + } + + /// Iterator over the relocations associated with this section + it_relocations relocations() { + return relocations_; + } + + it_const_relocations relocations() const { + return relocations_; + } + + /// Iterator over the symbols associated with this section + it_symbols symbols() { + return symbols_; + } + + it_const_symbols symbols() const { + return symbols_; + } + + /// Return comdat infomration (only if the section has the + /// CHARACTERISTICS::LNK_COMDAT characteristic) + optional comdat_info() const; + + /// Whether there is a large number of relocations whose number need + /// to be stored in the virtual address attribute + bool has_extended_relocations() const { + return has_characteristic(CHARACTERISTICS::LNK_NRELOC_OVFL) && + numberof_relocations() == std::numeric_limits::max(); + } + + void content(const std::vector& data) override { + content_ = data; + } + + void name(std::string name) override; + + void virtual_size(uint32_t virtual_sz) { + virtual_size_ = virtual_sz; + } + + void pointerto_raw_data(uint32_t ptr) { + offset(ptr); + } + + void pointerto_relocation(uint32_t ptr) { + pointer_to_relocations_ = ptr; + } + + void pointerto_line_numbers(uint32_t ptr) { + pointer_to_linenumbers_ = ptr; + } + + void numberof_relocations(uint16_t nb) { + number_of_relocations_ = nb; + } + + void numberof_line_numbers(uint16_t nb) { + number_of_linenumbers_ = nb; + } + + void sizeof_raw_data(uint32_t size) { + this->size(size); + } + + void characteristics(uint32_t characteristics) { + characteristics_ = characteristics; + } + + std::string to_string() const; + + LIEF_API friend std::ostream& operator<<(std::ostream& os, const Section& sec) { + os << sec.to_string(); + return os; + } + + ~Section() override = default; + + private: + Section() = default; + + std::vector content_; + uint32_t virtual_size_ = 0; + uint32_t pointer_to_relocations_ = 0; + uint32_t pointer_to_linenumbers_ = 0; + uint16_t number_of_relocations_ = 0; + uint16_t number_of_linenumbers_ = 0; + uint32_t characteristics_ = 0; + + relocations_t relocations_; + symbols_t symbols_; +}; + +inline const char* to_string(Section::CHARACTERISTICS e) { + return LIEF::PE::to_string(e); +} + +} +} +#endif diff --git a/deps/LIEF/include/LIEF/COFF/String.hpp b/deps/LIEF/include/LIEF/COFF/String.hpp new file mode 100644 index 00000000000000..8e678762642dc8 --- /dev/null +++ b/deps/LIEF/include/LIEF/COFF/String.hpp @@ -0,0 +1,83 @@ +/* Copyright 2017 - 2025 R. Thomas + * Copyright 2017 - 2025 Quarkslab + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef LIEF_COFF_STRING_H +#define LIEF_COFF_STRING_H +#include +#include +#include + +#include "LIEF/visibility.h" + +namespace LIEF { +namespace COFF { + +/// This class represents a string located in the COFF string table. +/// +/// Some of these strings can be used for section names that are greater than 8 +/// bytes. See: LIEF::PE::Section::coff_string() +/// +/// Reference: https://learn.microsoft.com/en-us/windows/win32/debug/pe-format#coff-string-table +class LIEF_API String { + public: + String() = default; + String(uint32_t offset, std::string str) : + str_(std::move(str)), + offset_(offset) + {} + + String(const String&) = default; + String& operator=(const String&) = default; + + String(String&&) = default; + String& operator=(String&&) = default; + + ~String() = default; + + /// The actual string + const std::string& str() const { + return str_; + } + + /// The offset of this string the in the COFF string table. + /// This offset includes the first 4-bytes that holds the table size + uint32_t offset() const { + return offset_; + } + + String& str(std::string str) { + str_ = std::move(str); + return *this; + } + + String& offset(uint32_t value) { + offset_ = value; + return *this; + } + + friend LIEF_API + std::ostream& operator<<(std::ostream& os, const String& str) + { + os << str.str(); + return os; + } + + private: + std::string str_; + uint32_t offset_ = 0; +}; +} +} +#endif diff --git a/deps/LIEF/include/LIEF/COFF/Symbol.hpp b/deps/LIEF/include/LIEF/COFF/Symbol.hpp new file mode 100644 index 00000000000000..3a9d8a97fcb4b7 --- /dev/null +++ b/deps/LIEF/include/LIEF/COFF/Symbol.hpp @@ -0,0 +1,286 @@ +/* Copyright 2017 - 2025 R. Thomas + * Copyright 2017 - 2025 Quarkslab + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef LIEF_COFF_SYMBOL_H +#define LIEF_COFF_SYMBOL_H + +#include "LIEF/Abstract/Symbol.hpp" +#include "LIEF/visibility.h" +#include "LIEF/iterators.hpp" + +#include +#include + +namespace LIEF { +class BinaryStream; +namespace COFF { +class Parser; +class AuxiliarySymbol; +class String; +class Section; + +/// This class represents a COFF symbol +class LIEF_API Symbol : public LIEF::Symbol { + public: + friend class Parser; + + using auxiliary_symbols_t = std::vector>; + using it_auxiliary_symbols_t = ref_iterator; + using it_const_auxiliary_symbols_t = const_ref_iterator; + + struct parsing_context_t { + std::function find_string; + bool is_bigobj; + }; + static std::unique_ptr parse( + parsing_context_t& ctx, BinaryStream& stream, size_t* idx); + + Symbol(); + Symbol(const Symbol&); + Symbol& operator=(const Symbol&); + + Symbol(Symbol&&); + Symbol& operator=(Symbol&&); + + /// The symbol provides general type or debugging information but does not + /// correspond to a section. Microsoft tools use this setting along with + /// `.file` records. + static constexpr auto SYM_SEC_IDX_DEBUG = -2; + /// The symbol has an absolute (non-relocatable) value and is not an address. + static constexpr auto SYM_SEC_IDX_ABS = -1; + /// The symbol record is not yet assigned a section. A value of zero indicates + /// that a reference to an external symbol is defined elsewhere. A value of + /// non-zero is a common symbol with a size that is specified by the value. + static constexpr auto SYM_SEC_IDX_UNDEF = 0; + + static constexpr auto SYM_COMPLEX_TYPE_SHIFT = 4; + + /// Reference: https://learn.microsoft.com/en-us/windows/win32/debug/pe-format#storage-class + enum class STORAGE_CLASS : int32_t { + INVALID = 0xFF, + + END_OF_FUNCTION = -1, ///< Physical end of function + NONE = 0, ///< No symbol + AUTOMATIC = 1, ///< Stack variable + EXTERNAL = 2, ///< External symbol + STATIC = 3, ///< Static + REGISTER = 4, ///< Register variable + EXTERNAL_DEF = 5, ///< External definition + LABEL = 6, ///< Label + UNDEFINED_LABEL = 7, ///< Undefined label + MEMBER_OF_STRUCT = 8, ///< Member of structure + ARGUMENT = 9, ///< Function argument + STRUCT_TAG = 10, ///< Structure tag + MEMBER_OF_UNION = 11, ///< Member of union + UNION_TAG = 12, ///< Union tag + TYPE_DEFINITION = 13, ///< Type definition + UNDEFINED_STATIC = 14, ///< Undefined static + ENUM_TAG = 15, ///< Enumeration tag + MEMBER_OF_ENUM = 16, ///< Member of enumeration + REGISTER_PARAM = 17, ///< Register parameter + BIT_FIELD = 18, ///< Bit field + BLOCK = 100, + FUNCTION = 101, + END_OF_STRUCT = 102, ///< End of structure + FILE = 103, ///< File name + SECTION = 104, + WEAK_EXTERNAL = 105, ///< Duplicate tag + CLR_TOKEN = 107 + }; + + enum class BASE_TYPE : uint32_t { + TY_NULL = 0, ///< No type information or unknown base type. + TY_VOID = 1, ///< Used with void pointers and functions. + TY_CHAR = 2, ///< A character (signed byte). + TY_SHORT = 3, ///< A 2-byte signed integer. + TY_INT = 4, ///< A natural integer type on the target. + TY_LONG = 5, ///< A 4-byte signed integer. + TY_FLOAT = 6, ///< A 4-byte floating-point number. + TY_DOUBLE = 7, ///< An 8-byte floating-point number. + TY_STRUCT = 8, ///< A structure. + TY_UNION = 9, ///< An union. + TY_ENUM = 10, ///< An enumerated type. + TY_MOE = 11, ///< A member of enumeration (a specific value). + TY_BYTE = 12, ///< A byte; unsigned 1-byte integer. + TY_WORD = 13, ///< A word; unsigned 2-byte integer. + TY_UINT = 14, ///< An unsigned integer of natural size. + TY_DWORD = 15 ///< An unsigned 4-byte integer. + }; + + enum class COMPLEX_TYPE : uint32_t { + TY_NULL = 0, ///< No complex type; simple scalar variable. + TY_POINTER = 1, ///< A pointer to base type. + TY_FUNCTION = 2, ///< A function that returns a base type. + TY_ARRAY = 3, ///< An array of base type. + }; + + /// Check if the given section index is a reserved value + static constexpr bool is_reversed_sec_idx(int16_t idx) { + return idx <= 0; + } + + /// The symbol type. The first byte represents the base type (see: base_type()) + /// while the upper byte represents the complex type, if any (see: + /// complex_type()). + uint16_t type() const { + return type_; + } + + /// Storage class of the symbol which indicates what kind of definition a + /// symbol represents. + STORAGE_CLASS storage_class() const { + return (STORAGE_CLASS)storage_class_; + } + + /// The simple (base) data type + BASE_TYPE base_type() const { + return (BASE_TYPE)(type_ & 0x0F); + } + + /// The complex type (if any) + COMPLEX_TYPE complex_type() const { + return (COMPLEX_TYPE)((type_ & 0xF0) >> SYM_COMPLEX_TYPE_SHIFT); + } + + /// The signed integer that identifies the section, using a one-based index + /// into the section table. Some values have special meaning: + /// + /// * 0: The symbol record is not yet assigned a section. A value of zero + /// indicates that a reference to an external symbol is defined elsewhere. + /// A value of non-zero is a common symbol with a size that is specified + /// by the value. + /// * -1: The symbol has an absolute (non-relocatable) value and is not an + /// address. + /// * -2: The symbol provides general type or debugging information but does + /// not correspond to a section. Microsoft tools use this setting along + /// with `.file` records + int16_t section_idx() const { + return section_idx_; + } + + /// Section associated with this symbol (if any) + Section* section() { + return section_; + } + + const Section* section() const { + return section_; + } + + bool is_external() const { + return storage_class() == STORAGE_CLASS::EXTERNAL; + } + + bool is_weak_external() const { + return storage_class() == STORAGE_CLASS::WEAK_EXTERNAL; + } + + bool is_absolute() const { + return section_idx() == SYM_SEC_IDX_ABS; + } + + bool is_undefined() const { + return is_external() && section_idx() == SYM_SEC_IDX_UNDEF && + value() == 0; + } + + bool is_function_line_info() const { + return storage_class() == STORAGE_CLASS::FUNCTION; + } + + bool is_function() const { + return complex_type() == COMPLEX_TYPE::TY_FUNCTION; + } + + bool is_file_record() const { + return storage_class() == STORAGE_CLASS::FILE; + } + + /// Auxiliary symbols associated with this symbol. + it_auxiliary_symbols_t auxiliary_symbols() { + return auxiliary_symbols_; + } + + it_const_auxiliary_symbols_t auxiliary_symbols() const { + return auxiliary_symbols_; + } + + /// Name of the symbol. If the symbol does not use a short name, it returns + /// the string pointed by the COFF string offset + const std::string& name() const override; + + std::string& name() override; + + /// COFF string used to represents the (long) symbol name + const String* coff_name() const { + return coff_name_; + } + + String* coff_name() { + return coff_name_; + } + + /// Demangled representation of the symbol or an empty string if it can't + /// be demangled + std::string demangled_name() const; + + Symbol& type(uint16_t ty) { + type_ = ty; + return *this; + } + + Symbol& storage_class(uint8_t value) { + storage_class_ = value; + return *this; + } + + Symbol& section_idx(int16_t idx) { + section_idx_ = idx; + return *this; + } + + /// Add a new auxiliary record + AuxiliarySymbol& add_aux(std::unique_ptr sym); + + std::string to_string() const; + + LIEF_API friend + std::ostream& operator<<(std::ostream& os, const Symbol& entry) + { + os << entry.to_string(); + return os; + } + + ~Symbol() override; + + private: + template + static std::unique_ptr parse_impl( + parsing_context_t& ctx, BinaryStream& stream, size_t* idx); + String* coff_name_ = nullptr; + uint16_t type_ = 0; + uint8_t storage_class_ = 0; + int16_t section_idx_ = 0; + auxiliary_symbols_t auxiliary_symbols_; + Section* section_ = nullptr; +}; + +LIEF_API const char* to_string(Symbol::STORAGE_CLASS e); +LIEF_API const char* to_string(Symbol::BASE_TYPE e); +LIEF_API const char* to_string(Symbol::COMPLEX_TYPE e); + +} +} +#endif diff --git a/deps/LIEF/include/LIEF/COFF/utils.hpp b/deps/LIEF/include/LIEF/COFF/utils.hpp new file mode 100644 index 00000000000000..73cb9fbf34ad82 --- /dev/null +++ b/deps/LIEF/include/LIEF/COFF/utils.hpp @@ -0,0 +1,63 @@ +/* Copyright 2017 - 2025 R. Thomas + * Copyright 2017 - 2025 Quarkslab + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef LIEF_COFF_UTILS_H +#define LIEF_COFF_UTILS_H +#include "LIEF/visibility.h" +#include "LIEF/COFF/Header.hpp" +#include "LIEF/BinaryStream/FileStream.hpp" +#include "LIEF/BinaryStream/SpanStream.hpp" +#include + +namespace LIEF { +namespace COFF { + +/// This function determines if the given stream wraps a COFF binary and if so, +/// whether it's a regular or bigobj COFF. +LIEF_API Header::KIND get_kind(BinaryStream& stream); + +/// Check if the given stream wraps a COFF file +LIEF_API inline bool is_coff(BinaryStream& stream) { + return get_kind(stream) != Header::KIND::UNKNOWN; +} + +/// Check if the `file` is a COFF +LIEF_API bool is_coff(const std::string& file); + +/// Check if the given buffer points to a COFF file +LIEF_API inline bool is_coff(const uint8_t* buffer, size_t size) { + LIEF::SpanStream strm(buffer, size); + return is_coff(strm); +} + +/// Check if the given buffer points to a COFF file +LIEF_API inline bool is_coff(const std::vector& buffer) { + return is_coff(buffer.data(), buffer.size()); +} + +/// Check if the COFF file wrapped by the given stream is a `bigobj` +LIEF_API inline bool is_bigobj(BinaryStream& stream) { + return get_kind(stream) == Header::KIND::BIGOBJ; +} + +/// Check if the COFF file wrapped by the given stream is regular +/// (i.e. not a bigobj) +LIEF_API inline bool is_regular(BinaryStream& stream) { + return get_kind(stream) == Header::KIND::REGULAR; +} + +} +} +#endif diff --git a/deps/LIEF/include/LIEF/DEX.hpp b/deps/LIEF/include/LIEF/DEX.hpp new file mode 100644 index 00000000000000..f976b08117d525 --- /dev/null +++ b/deps/LIEF/include/LIEF/DEX.hpp @@ -0,0 +1,32 @@ +/* Copyright 2017 - 2025 R. Thomas + * Copyright 2017 - 2025 Quarkslab + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef LIEF_DEX_H +#define LIEF_DEX_H +#include "LIEF/config.h" + +#if defined(LIEF_DEX_SUPPORT) +#include "LIEF/DEX/Parser.hpp" +#include "LIEF/DEX/utils.hpp" +#include "LIEF/DEX/File.hpp" +#include "LIEF/DEX/Class.hpp" +#include "LIEF/DEX/Prototype.hpp" +#include "LIEF/DEX/Header.hpp" +#include "LIEF/DEX/Method.hpp" +#include "LIEF/DEX/Field.hpp" +#include "LIEF/DEX/EnumToString.hpp" +#endif + +#endif diff --git a/deps/LIEF/include/LIEF/DEX/Class.hpp b/deps/LIEF/include/LIEF/DEX/Class.hpp new file mode 100644 index 00000000000000..0b1baff36ad5f2 --- /dev/null +++ b/deps/LIEF/include/LIEF/DEX/Class.hpp @@ -0,0 +1,138 @@ +/* Copyright 2017 - 2025 R. Thomas + * Copyright 2017 - 2025 Quarkslab + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef LIEF_DEX_CLASS_H +#define LIEF_DEX_CLASS_H + +#include +#include + +#include "LIEF/visibility.h" +#include "LIEF/Object.hpp" +#include "LIEF/iterators.hpp" + +#include "LIEF/DEX/enums.hpp" +#include "LIEF/DEX/deopt.hpp" + +namespace LIEF { +namespace DEX { +class Parser; +class Field; +class Method; + +/// Class which represents a DEX Class (i.e. a Java/Kotlin class) +class LIEF_API Class : public Object { + friend class Parser; + + public: + using access_flags_list_t = std::vector; + + using methods_t = std::vector; + using it_methods = ref_iterator; + using it_const_methods = const_ref_iterator; + + using fields_t = std::vector; + using it_fields = ref_iterator; + using it_const_fields = const_ref_iterator; + + using it_named_methods = filter_iterator; + using it_const_named_methods = const_filter_iterator; + + using it_named_fields = filter_iterator; + using it_const_named_fields = const_filter_iterator; + + public: + static std::string package_normalized(const std::string& pkg_name); + static std::string fullname_normalized(const std::string& pkg_cls); + static std::string fullname_normalized(const std::string& pkg, const std::string& cls_name); + + Class(); + Class(const Class&) = delete; + Class& operator=(const Class&) = delete; + + Class(std::string fullname, uint32_t access_flags = ACCESS_FLAGS::ACC_UNKNOWN, + Class* parent = nullptr, std::string source_filename = ""); + + /// Mangled class name (e.g. ``Lcom/example/android/MyActivity;``) + const std::string& fullname() const; + + /// Package Name + std::string package_name() const; + + /// Class name + std::string name() const; + + /// Demangled class name + std::string pretty_name() const; + + /// Check if the class has the given access flag + bool has(ACCESS_FLAGS f) const; + + /// Access flags used by this class + access_flags_list_t access_flags() const; + + /// Filename associated with this class (if any) + const std::string& source_filename() const; + + /// True if the current class extends another one + bool has_parent() const; + + /// Parent class + const Class* parent() const; + Class* parent(); + + /// Methods implemented in this class + it_const_methods methods() const; + it_methods methods(); + + /// Return Methods having the given name + it_named_methods methods(const std::string& name); + it_const_named_methods methods(const std::string& name) const; + + /// Fields implemented in this class + it_const_fields fields() const; + it_fields fields(); + + /// Return Fields having the given name + it_named_fields fields(const std::string& name); + it_const_named_fields fields(const std::string& name) const; + + /// De-optimize information + dex2dex_class_info_t dex2dex_info() const; + + /// Original index in the DEX class pool + size_t index() const; + + void accept(Visitor& visitor) const override; + + + LIEF_API friend std::ostream& operator<<(std::ostream& os, const Class& cls); + + ~Class() override; + + private: + std::string fullname_; + uint32_t access_flags_ = ACCESS_FLAGS::ACC_UNKNOWN; + Class* parent_ = nullptr; + methods_t methods_; + fields_t fields_; + std::string source_filename_; + + uint32_t original_index_ = UINT_MAX; +}; + +} // Namespace DEX +} // Namespace LIEF +#endif diff --git a/deps/LIEF/include/LIEF/DEX/CodeInfo.hpp b/deps/LIEF/include/LIEF/DEX/CodeInfo.hpp new file mode 100644 index 00000000000000..85410e665b1700 --- /dev/null +++ b/deps/LIEF/include/LIEF/DEX/CodeInfo.hpp @@ -0,0 +1,60 @@ +/* Copyright 2017 - 2025 R. Thomas + * Copyright 2017 - 2025 Quarkslab + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef LIEF_DEX_CODE_INFO_H +#define LIEF_DEX_CODE_INFO_H + +#include +#include + +#include "LIEF/visibility.h" +#include "LIEF/Object.hpp" + +namespace LIEF { +namespace DEX { +namespace details { +struct code_item; +} + +class Parser; + +class LIEF_API CodeInfo : public Object { + friend class Parser; + + public: + CodeInfo(); + CodeInfo(const details::code_item& codeitem); + + CodeInfo(const CodeInfo&); + CodeInfo& operator=(const CodeInfo&); + + void accept(Visitor& visitor) const override; + + uint16_t nb_registers() const; + + ~CodeInfo() override; + + LIEF_API friend std::ostream& operator<<(std::ostream& os, const CodeInfo& cinfo); + + private: + uint16_t nb_registers_ = 0; + uint16_t args_input_sizes_ = 0; + uint16_t output_sizes_ = 0; + +}; + +} // Namespace DEX +} // Namespace LIEF +#endif diff --git a/deps/LIEF/include/LIEF/DEX/EnumToString.hpp b/deps/LIEF/include/LIEF/DEX/EnumToString.hpp new file mode 100644 index 00000000000000..18336a7028b940 --- /dev/null +++ b/deps/LIEF/include/LIEF/DEX/EnumToString.hpp @@ -0,0 +1,35 @@ +/* Copyright 2017 - 2025 R. Thomas + * Copyright 2017 - 2025 Quarkslab + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef LIEF_DEX_ENUM_TO_STRING_H +#define LIEF_DEX_ENUM_TO_STRING_H +#include "LIEF/visibility.h" +#include "LIEF/DEX/enums.hpp" +#include "LIEF/DEX/MapItem.hpp" +#include "LIEF/DEX/Type.hpp" + +namespace LIEF { +namespace DEX { + +LIEF_API const char* to_string(MapItem::TYPES e); +LIEF_API const char* to_string(ACCESS_FLAGS e); +LIEF_API const char* to_string(Type::TYPES e); +LIEF_API const char* to_string(Type::PRIMITIVES e); + +} // namespace DEX +} // namespace LIEF + +#endif + diff --git a/deps/LIEF/include/LIEF/DEX/Field.hpp b/deps/LIEF/include/LIEF/DEX/Field.hpp new file mode 100644 index 00000000000000..25283a81e00718 --- /dev/null +++ b/deps/LIEF/include/LIEF/DEX/Field.hpp @@ -0,0 +1,94 @@ +/* Copyright 2021 - 2025 R. Thomas + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef LIEF_DEX_FIELD_H +#define LIEF_DEX_FIELD_H + +#include +#include + +#include "LIEF/DEX/enums.hpp" + +#include "LIEF/visibility.h" +#include "LIEF/Object.hpp" + +#include "LIEF/DEX/Type.hpp" + +namespace LIEF { +namespace DEX { +class Parser; +class Class; + +/// Class which represent a DEX Field +class LIEF_API Field : public Object { + friend class Parser; + public: + using access_flags_list_t = std::vector; + + public: + Field(); + Field(std::string name, Class* parent = nullptr); + + Field(const Field&); + Field& operator=(const Field&); + + /// Name of the Field + const std::string& name() const; + + /// True if a class is associated with this field + /// (which should be the case) + bool has_class() const; + + /// Class associated with this Field + const Class* cls() const; + Class* cls(); + + /// Index in the DEX Fields pool + size_t index() const; + + /// True if this field is a static one. + bool is_static() const; + + /// Field's prototype + const Type* type() const; + Type* type(); + + void accept(Visitor& visitor) const override; + + /// Check if the field has the given ACCESS_FLAGS + bool has(ACCESS_FLAGS f) const; + + /// ACCESS_FLAGS as a list + access_flags_list_t access_flags() const; + + + LIEF_API friend std::ostream& operator<<(std::ostream& os, const Field& mtd); + + ~Field() override; + + private: + void set_static(bool v); + + private: + std::string name_; + Class* parent_ = nullptr; + Type* type_ = nullptr; + uint32_t access_flags_ = 0; + uint32_t original_index_ = UINT_MAX; + bool is_static_ = false; +}; + +} // Namespace DEX +} // Namespace LIEF +#endif diff --git a/deps/LIEF/include/LIEF/DEX/File.hpp b/deps/LIEF/include/LIEF/DEX/File.hpp new file mode 100644 index 00000000000000..6cf6240d82c8de --- /dev/null +++ b/deps/LIEF/include/LIEF/DEX/File.hpp @@ -0,0 +1,176 @@ +/* Copyright 2017 - 2025 R. Thomas + * Copyright 2017 - 2025 Quarkslab + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef LIEF_DEX_FILE_H +#define LIEF_DEX_FILE_H +#include + +#include "LIEF/visibility.h" +#include "LIEF/Object.hpp" + +#include "LIEF/DEX/Header.hpp" +#include "LIEF/DEX/MapList.hpp" +#include "LIEF/DEX/instructions.hpp" +#include "LIEF/DEX/deopt.hpp" +#include "LIEF/DEX/types.hpp" + +namespace LIEF { +namespace DEX { +class Parser; +class Class; +class Method; +class Type; +class Prototype; +class Field; + +/// Class that represents a DEX file +class LIEF_API File : public Object { + friend class Parser; + + public: + using classes_t = std::unordered_map; + using classes_list_t = std::vector>; + using it_classes = ref_iterator; + using it_const_classes = const_ref_iterator; + + using methods_t = std::vector>; + using it_methods = ref_iterator; + using it_const_methods = const_ref_iterator; + + using strings_t = std::vector>; + using it_strings = ref_iterator; + using it_const_strings = const_ref_iterator; + + using types_t = std::vector>; + using it_types = ref_iterator; + using it_const_types = const_ref_iterator; + + using prototypes_t = std::vector>; + using it_prototypes = ref_iterator; + using it_const_prototypes = const_ref_iterator; + + using fields_t = std::vector>; + using it_fields = ref_iterator; + using it_const_fields = const_ref_iterator; + + public: + File& operator=(const File& copy) = delete; + File(const File& copy) = delete; + + /// Version of the current DEX file + dex_version_t version() const; + + /// Name of this file + const std::string& name() const; + + void name(const std::string& name); + + /// Location of this file + const std::string& location() const; + void location(const std::string& location); + + /// DEX header + const Header& header() const; + Header& header(); + + /// **All** classes used in the DEX file + it_const_classes classes() const; + it_classes classes(); + + /// Check if the given class name exists + bool has_class(const std::string& class_name) const; + + /// Return the DEX::Class object associated with the given name + const Class* get_class(const std::string& class_name) const; + + Class* get_class(const std::string& class_name); + + /// Return the DEX::Class object associated with the given index + const Class* get_class(size_t index) const; + + Class* get_class(size_t index); + + /// De-optimize information + dex2dex_info_t dex2dex_info() const; + + /// De-optimize information as JSON + std::string dex2dex_json_info() const; + + /// Return an iterator over **all** the DEX::Method used in this DEX file + it_const_methods methods() const; + it_methods methods(); + + /// Return an iterator over **all** the DEX::Field used in this DEX file + it_const_fields fields() const; + it_fields fields(); + + /// String pool + it_const_strings strings() const; + it_strings strings(); + + /// Type pool + it_const_types types() const; + it_types types(); + + /// Prototype pool + it_prototypes prototypes(); + it_const_prototypes prototypes() const; + + /// DEX Map + const MapList& map() const; + MapList& map(); + + /// Extract the current dex file and deoptimize it + std::string save(const std::string& path = "", bool deoptimize = true) const; + + std::vector raw(bool deoptimize = true) const; + + void accept(Visitor& visitor) const override; + + + ~File() override; + + LIEF_API friend std::ostream& operator<<(std::ostream& os, const File& file); + + private: + File(); + + void add_class(std::unique_ptr cls); + + static void deoptimize_nop(uint8_t* inst_ptr, uint32_t value); + static void deoptimize_return(uint8_t* inst_ptr, uint32_t value); + static void deoptimize_invoke_virtual(uint8_t* inst_ptr, uint32_t value, OPCODES new_inst); + static void deoptimize_instance_field_access(uint8_t* inst_ptr, uint32_t value, OPCODES new_inst); + + std::string name_; + std::string location_; + + Header header_; + classes_t classes_; + methods_t methods_; + fields_t fields_; + strings_t strings_; + types_t types_; + prototypes_t prototypes_; + MapList map_; + + classes_list_t class_list_; + std::vector original_data_; +}; + +} +} + +#endif diff --git a/deps/LIEF/include/LIEF/DEX/Header.hpp b/deps/LIEF/include/LIEF/DEX/Header.hpp new file mode 100644 index 00000000000000..b1d269f7a2119a --- /dev/null +++ b/deps/LIEF/include/LIEF/DEX/Header.hpp @@ -0,0 +1,136 @@ + +/* Copyright 2017 - 2025 R. Thomas + * Copyright 2017 - 2025 Quarkslab + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef LIEF_DEX_HEADER_H +#define LIEF_DEX_HEADER_H + +#include +#include +#include +#include + +#include "LIEF/visibility.h" +#include "LIEF/Object.hpp" + +namespace LIEF { +class Visitor; + +namespace DEX { +class Parser; + +/// Class which represents the DEX header. +/// This is the first structure that begins the DEX format. +/// +/// The official documentation is provided here: +/// https://source.android.com/devices/tech/dalvik/dex-format#header-item +class LIEF_API Header : public Object { + friend class Parser; + + public: + using location_t = std::pair; + + using magic_t = std::array; + using signature_t = std::array; + + Header(); + Header(const Header&); + Header& operator=(const Header&); + + template + LIEF_LOCAL Header(const T& header); + + /// The DEX magic bytes (``DEX\n`` followed by the DEX version) + magic_t magic() const; + + /// The file checksum + uint32_t checksum() const; + + /// SHA-1 DEX signature (which is not really used as a signature) + signature_t signature() const; + + /// Size of the entire file (including the current the header) + uint32_t file_size() const; + + /// Size of this header. It should be 0x70 + uint32_t header_size() const; + + /// File endianess of the file + uint32_t endian_tag() const; + + /// Offset from the start of the file to the map list (see: DEX::MapList) + uint32_t map() const; + + /// Offset and size of the string pool + location_t strings() const; + location_t link() const; + location_t types() const; + location_t prototypes() const; + location_t fields() const; + location_t methods() const; + location_t classes() const; + location_t data() const; + + uint32_t nb_classes() const; + + uint32_t nb_methods() const; + + void accept(Visitor& visitor) const override; + + + LIEF_API friend std::ostream& operator<<(std::ostream& os, const Header& hdr); + + ~Header() override; + + private: + magic_t magic_; + uint32_t checksum_; + signature_t signature_; + uint32_t file_size_; + + uint32_t header_size_; + uint32_t endian_tag_; + + uint32_t link_size_; + uint32_t link_off_; + + uint32_t map_off_; + + uint32_t string_ids_size_; + uint32_t string_ids_off_; + + uint32_t type_ids_size_; + uint32_t type_ids_off_; + + uint32_t proto_ids_size_; + uint32_t proto_ids_off_; + + uint32_t field_ids_size_; + uint32_t field_ids_off_; + + uint32_t method_ids_size_; + uint32_t method_ids_off_; + + uint32_t class_defs_size_; + uint32_t class_defs_off_; + + uint32_t data_size_; + uint32_t data_off_; +}; + +} // Namespace DEX +} // Namespace LIEF + +#endif diff --git a/deps/LIEF/include/LIEF/DEX/MapItem.hpp b/deps/LIEF/include/LIEF/DEX/MapItem.hpp new file mode 100644 index 00000000000000..bb791c472e18f1 --- /dev/null +++ b/deps/LIEF/include/LIEF/DEX/MapItem.hpp @@ -0,0 +1,96 @@ +/* Copyright 2017 - 2025 R. Thomas + * Copyright 2017 - 2025 Quarkslab + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef LIEF_MAP_ITEM_H +#define LIEF_MAP_ITEM_H + +#include +#include + +#include "LIEF/visibility.h" +#include "LIEF/Object.hpp" + +namespace LIEF { +namespace DEX { +class Parser; +class Class; + +/// Class which represents an element of the MapList object +class LIEF_API MapItem : public Object { + friend class Parser; + + public: + enum class TYPES : uint16_t { + HEADER = 0x0000, + STRING_ID = 0x0001, + TYPE_ID = 0x0002, + PROTO_ID = 0x0003, + FIELD_ID = 0x0004, + METHOD_ID = 0x0005, + CLASS_DEF = 0x0006, + CALL_SITE_ID = 0x0007, + METHOD_HANDLE = 0x0008, + MAP_LIST = 0x1000, + TYPE_LIST = 0x1001, + ANNOTATION_SET_REF_LIST = 0x1002, + ANNOTATION_SET = 0x1003, + CLASS_DATA = 0x2000, + CODE = 0x2001, + STRING_DATA = 0x2002, + DEBUG_INFO = 0x2003, + ANNOTATION = 0x2004, + ENCODED_ARRAY = 0x2005, + ANNOTATIONS_DIRECTORY = 0x2006, + + }; + + public: + MapItem(); + MapItem(TYPES type, uint32_t offset, uint32_t size, uint16_t reserved = 0); + + MapItem(const MapItem&); + MapItem& operator=(const MapItem&); + + /// The type of the item + TYPES type() const; + + /// Reserved value (likely for alignment prupose) + uint16_t reserved() const; + + /// The number of elements (the real meaning depends on the type) + uint32_t size() const; + + /// Offset from the start of the DEX file to the items associated with + /// the underlying TYPES + uint32_t offset() const; + + void accept(Visitor& visitor) const override; + + + LIEF_API friend std::ostream& operator<<(std::ostream& os, const MapItem& item); + + ~MapItem() override; + + private: + TYPES type_; + uint16_t reserved_; + uint32_t size_; + uint32_t offset_; + +}; + +} // Namespace DEX +} // Namespace LIEF +#endif diff --git a/deps/LIEF/include/LIEF/DEX/MapList.hpp b/deps/LIEF/include/LIEF/DEX/MapList.hpp new file mode 100644 index 00000000000000..c0c59ee83b1657 --- /dev/null +++ b/deps/LIEF/include/LIEF/DEX/MapList.hpp @@ -0,0 +1,84 @@ +/* Copyright 2017 - 2025 R. Thomas + * Copyright 2017 - 2025 Quarkslab + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef LIEF_MAP_LIST_H +#define LIEF_MAP_LIST_H +#include +#include + +#include "LIEF/visibility.h" +#include "LIEF/iterators.hpp" +#include "LIEF/Object.hpp" + +#include "LIEF/DEX/MapItem.hpp" + +namespace LIEF { +namespace DEX { +class Parser; +class Class; + +/// Class which represents the ``map_list`` structure that +/// follows the main DEX header. +/// +/// This MapList aims at referencing the location of other DEX structures as +/// described in https://source.android.com/devices/tech/dalvik/dex-format#map-item +class LIEF_API MapList : public Object { + friend class Parser; + + public: + using items_t = std::map; + using it_items_t = ref_iterator>; + using it_const_items_t = const_ref_iterator>; + + public: + MapList(); + + MapList(const MapList&); + MapList& operator=(const MapList&); + + /// Iterator over LIEF::DEX::MapItem + it_items_t items(); + it_const_items_t items() const; + + /// Check if the given type exists + bool has(MapItem::TYPES type) const; + + /// Return the LIEF::DEX::MapItem associated with the given type + const MapItem& get(MapItem::TYPES type) const; + + /// Return the LIEF::DEX::MapItem associated with the given type + MapItem& get(MapItem::TYPES type); + + /// Return the LIEF::DEX::MapItem associated with the given type + const MapItem& operator[](MapItem::TYPES type) const; + + /// Return the LIEF::DEX::MapItem associated with the given type + MapItem& operator[](MapItem::TYPES type); + + void accept(Visitor& visitor) const override; + + + LIEF_API friend std::ostream& operator<<(std::ostream& os, const MapList& mtd); + + ~MapList() override; + + private: + items_t items_; + +}; + +} // Namespace DEX +} // Namespace LIEF +#endif diff --git a/deps/LIEF/include/LIEF/DEX/Method.hpp b/deps/LIEF/include/LIEF/DEX/Method.hpp new file mode 100644 index 00000000000000..54eec9bd6627f1 --- /dev/null +++ b/deps/LIEF/include/LIEF/DEX/Method.hpp @@ -0,0 +1,118 @@ +/* Copyright 2017 - 2025 R. Thomas + * Copyright 2017 - 2025 Quarkslab + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef LIEF_DEX_METHOD_H +#define LIEF_DEX_METHOD_H + +#include +#include + +#include "LIEF/visibility.h" +#include "LIEF/Object.hpp" + +#include "LIEF/DEX/enums.hpp" +#include "LIEF/DEX/CodeInfo.hpp" +#include "LIEF/DEX/deopt.hpp" + +namespace LIEF { +namespace DEX { +class Parser; +class Class; +class Prototype; + +/// Class which represents a DEX::Method +class LIEF_API Method : public Object { + friend class Parser; + public: + using access_flags_list_t = std::vector; + + public: + using bytecode_t = std::vector; + Method(); + Method(std::string name, Class* parent = nullptr); + + Method(const Method&); + Method& operator=(const Method&); + + /// Name of the Method + const std::string& name() const; + + /// True if a class is associated with this method + bool has_class() const; + + /// DEX::Class associated with this Method or a nullptr + /// if not resolved + const Class* cls() const; + Class* cls(); + + /// Offset to the Dalvik Bytecode + uint64_t code_offset() const; + + /// Dalvik Bytecode as bytes + const bytecode_t& bytecode() const; + + /// Index in the DEX Methods pool + size_t index() const; + + /// True if this method is a virtual one. + /// i.e. not **static**, **private**, **finale** or constructor + bool is_virtual() const; + + /// Method's prototype or a nullptr if it is not resolved + const Prototype* prototype() const; + Prototype* prototype(); + + void insert_dex2dex_info(uint32_t pc, uint32_t index); + + void accept(Visitor& visitor) const override; + + const dex2dex_method_info_t& dex2dex_info() const; + + /// Check if the current method has the given ACCESS_FLAGS + bool has(ACCESS_FLAGS f) const; + + /// ACCESS_FLAGS as an std::set + access_flags_list_t access_flags() const; + + // CodeInfo to get additional data about a method i.e. argument count + const CodeInfo& code_info() const; + + LIEF_API friend std::ostream& operator<<(std::ostream& os, const Method& mtd); + + ~Method() override; + + private: + void set_virtual(bool v); + + private: + std::string name_; + Class* parent_ = nullptr; + Prototype* prototype_ = nullptr; + uint32_t access_flags_ = ACCESS_FLAGS::ACC_UNKNOWN; + uint32_t original_index_ = UINT_MAX; + bool is_virtual_ = false; + + uint64_t code_offset_ = 0; + std::vector bytecode_; + + CodeInfo code_info_; + + dex2dex_method_info_t dex2dex_info_; + +}; + +} // Namespace DEX +} // Namespace LIEF +#endif diff --git a/deps/LIEF/include/LIEF/DEX/Parser.hpp b/deps/LIEF/include/LIEF/DEX/Parser.hpp new file mode 100644 index 00000000000000..7b925d129da240 --- /dev/null +++ b/deps/LIEF/include/LIEF/DEX/Parser.hpp @@ -0,0 +1,124 @@ +/* Copyright 2017 - 2025 R. Thomas + * Copyright 2017 - 2025 Quarkslab + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef LIEF_DEX_PARSER_H +#define LIEF_DEX_PARSER_H + +#include +#include +#include +#include + +#include "LIEF/visibility.h" +#include "LIEF/DEX/types.hpp" + +namespace LIEF { +class VectorStream; + +namespace DEX { +class Class; +class Method; +class Field; +class File; +class Type; + +/// Class which parses a DEX file to produce a DEX::File object +class LIEF_API Parser { + public: + + /// Parse the DEX file from the file path given in parameter + static std::unique_ptr parse(const std::string& file); + static std::unique_ptr parse(std::vector data, const std::string& name = ""); + + Parser& operator=(const Parser& copy) = delete; + Parser(const Parser& copy) = delete; + + private: + Parser(); + Parser(const std::string& file); + Parser(std::vector data); + ~Parser(); + + void init(const std::string& name, dex_version_t version); + + template + void parse_file(); + + template + void parse_header(); + + template + void parse_map(); + + template + void parse_strings(); + + template + void parse_types(); + + template + void parse_fields(); + + template + void parse_prototypes(); + + template + void parse_methods(); + + template + void parse_classes(); + + template + void parse_class_data(uint32_t offset, Class& cls); + + template + void parse_field(size_t index, Class& cls, bool is_static); + + template + void parse_method(size_t index, Class& cls, bool is_virtual); + + template + void parse_code_info(uint32_t offset, Method& method); + + void resolve_inheritance(); + + void resolve_external_methods(); + + void resolve_external_fields(); + + void resolve_types(); + + std::unique_ptr file_; + + // Map of inheritance relationship when parsing classes ('parse_classes') + // The key is the parent class name of the value + std::unordered_multimap inheritance_; + + // Map of method/class relationship when parsing methods ('parse_methods') + // The key is the Class name in which the method is defined + std::unordered_multimap class_method_map_; + + // Map of field/class relationship when parsing fields ('parse_fields') + // The key is the Class name in which the field is defined + std::unordered_multimap class_field_map_; + + std::unordered_multimap class_type_map_; + + std::unique_ptr stream_; +}; + +} // namespace DEX +} // namespace LIEF +#endif diff --git a/deps/LIEF/include/LIEF/DEX/Prototype.hpp b/deps/LIEF/include/LIEF/DEX/Prototype.hpp new file mode 100644 index 00000000000000..ff6413a5c0b88e --- /dev/null +++ b/deps/LIEF/include/LIEF/DEX/Prototype.hpp @@ -0,0 +1,64 @@ +/* Copyright 2017 - 2025 R. Thomas + * Copyright 2017 - 2025 Quarkslab + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef LIEF_DEX_PROTOTYPE_H +#define LIEF_DEX_PROTOTYPE_H + +#include "LIEF/visibility.h" +#include "LIEF/Object.hpp" +#include "LIEF/iterators.hpp" + +namespace LIEF { +namespace DEX { +class Parser; +class Type; + +/// Class which represents a DEX method prototype +class LIEF_API Prototype : public Object { + friend class Parser; + + public: + using parameters_type_t = std::vector; + using it_params = ref_iterator; + using it_const_params = const_ref_iterator; + + public: + Prototype(); + Prototype(const Prototype& other); + + /// Type returned or a nullptr if not resolved + const Type* return_type() const; + Type* return_type(); + + /// Types of the parameters + it_const_params parameters_type() const; + it_params parameters_type(); + + void accept(Visitor& visitor) const override; + + + LIEF_API friend std::ostream& operator<<(std::ostream& os, const Prototype& type); + + ~Prototype() override; + + private: + Type* return_type_ = nullptr; + parameters_type_t params_; + +}; + +} // Namespace DEX +} // Namespace LIEF +#endif diff --git a/deps/LIEF/include/LIEF/DEX/Type.hpp b/deps/LIEF/include/LIEF/DEX/Type.hpp new file mode 100644 index 00000000000000..0c93f4922f7ea8 --- /dev/null +++ b/deps/LIEF/include/LIEF/DEX/Type.hpp @@ -0,0 +1,113 @@ +/* Copyright 2017 - 2025 R. Thomas + * Copyright 2017 - 2025 Quarkslab + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef LIEF_DEX_TYPE_H +#define LIEF_DEX_TYPE_H + +#include +#include +#include + +#include "LIEF/visibility.h" +#include "LIEF/Object.hpp" + +namespace LIEF { +namespace DEX { +class Parser; +class Class; + +/// Class which represents a DEX type as described in the +/// format specifications: https://source.android.com/devices/tech/dalvik/dex-format#typedescriptor +class LIEF_API Type : public Object { + friend class Parser; + + public: + enum class TYPES { + UNKNOWN = 0, + PRIMITIVE = 1, + CLASS = 2, + ARRAY = 3, + }; + + enum class PRIMITIVES { + VOID_T = 0x01, + BOOLEAN = 0x02, + BYTE = 0x03, + SHORT = 0x04, + CHAR = 0x05, + INT = 0x06, + LONG = 0x07, + FLOAT = 0x08, + DOUBLE = 0x09, + }; + + using array_t = std::vector; + + public: + static std::string pretty_name(PRIMITIVES p); + + public: + Type(); + Type(const std::string& mangled); + Type(const Type& other); + + /// Whether it is a primitive type, a class, ... + TYPES type() const; + + const Class& cls() const; + const array_t& array() const; + const PRIMITIVES& primitive() const; + + /// **IF** the current type is a TYPES::CLASS, return the + /// associated DEX::CLASS. Otherwise the returned value is **undefined**. + Class& cls(); + + /// **IF** the current type is a TYPES::ARRAY, return the + /// associated array. Otherwise the returned value is **undefined**. + array_t& array(); + + /// **IF** the current type is a TYPES::PRIMITIVE, return the + /// associated PRIMITIVES. Otherwise the returned value is **undefined**. + PRIMITIVES& primitive(); + + /// Return the array dimension if the current type is + /// an array. Otherwise it returns 0 + size_t dim() const; + + /// In the case of a TYPES::ARRAY, return the array's type + const Type& underlying_array_type() const; + Type& underlying_array_type(); + + void accept(Visitor& visitor) const override; + + + LIEF_API friend std::ostream& operator<<(std::ostream& os, const Type& type); + + ~Type() override; + + private: + void parse(const std::string& type); + + TYPES type_{TYPES::UNKNOWN}; + union { + Class* cls_{nullptr}; + array_t* array_; + PRIMITIVES* basic_; + }; +}; + +} // Namespace DEX +} // Namespace LIEF +#endif diff --git a/deps/LIEF/include/LIEF/DEX/deopt.hpp b/deps/LIEF/include/LIEF/DEX/deopt.hpp new file mode 100644 index 00000000000000..4164a8ffecc43b --- /dev/null +++ b/deps/LIEF/include/LIEF/DEX/deopt.hpp @@ -0,0 +1,34 @@ +/* Copyright 2017 - 2025 R. Thomas + * Copyright 2017 - 2025 Quarkslab + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef LIEF_DEX_DEOPT_TYPES_H +#define LIEF_DEX_DEOPT_TYPES_H +#include +#include + +namespace LIEF { +namespace DEX { +class Class; +class Method; + +// Method Index: {dex_pc: index, ...} +using dex2dex_method_info_t = std::unordered_map; +using dex2dex_class_info_t = std::unordered_map; +using dex2dex_info_t = std::unordered_map; + +} +} + +#endif diff --git a/deps/LIEF/include/LIEF/DEX/enums.hpp b/deps/LIEF/include/LIEF/DEX/enums.hpp new file mode 100644 index 00000000000000..4e808d8f9b76d1 --- /dev/null +++ b/deps/LIEF/include/LIEF/DEX/enums.hpp @@ -0,0 +1,82 @@ +/* Copyright 2017 - 2025 R. Thomas + * Copyright 2017 - 2025 Quarkslab + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef LIEF_DEX_ENUMS_H +#define LIEF_DEX_ENUMS_H + +namespace LIEF { +namespace DEX { + +enum ACCESS_FLAGS { + ACC_UNKNOWN = 0x0, + ACC_PUBLIC = 0x1, + ACC_PRIVATE = 0x2, + ACC_PROTECTED = 0x4, + ACC_STATIC = 0x8, + ACC_FINAL = 0x10, + ACC_SYNCHRONIZED = 0x20, + ACC_VOLATILE = 0x40, + ACC_BRIDGE = 0x40, + ACC_TRANSIENT = 0x80, + ACC_VARARGS = 0x80, + ACC_NATIVE = 0x100, + ACC_INTERFACE = 0x200, + ACC_ABSTRACT = 0x400, + ACC_STRICT = 0x800, + ACC_SYNTHETIC = 0x1000, + ACC_ANNOTATION = 0x2000, + ACC_ENUM = 0x4000, + ACC_CONSTRUCTOR = 0x10000, + ACC_DECLARED_SYNCHRONIZED = 0x20000 +}; + + +enum METHOD_TYPES { + METHOD_UNKNOWN = 0x00, + METHOD_VIRTUAL = 0x01, + METHOD_DIRECT = 0x02, // Deprecated + + METHOD_EXTERN = 0x03, + METHOD_CTOR = 0x04, + METHOD_STATIC = 0x05, + METHOD_STATIC_CTOR = 0x06, +}; + +static const ACCESS_FLAGS access_flags_list[] = { + ACCESS_FLAGS::ACC_UNKNOWN, + ACCESS_FLAGS::ACC_PUBLIC, + ACCESS_FLAGS::ACC_PRIVATE, + ACCESS_FLAGS::ACC_PROTECTED, + ACCESS_FLAGS::ACC_STATIC, + ACCESS_FLAGS::ACC_FINAL, + ACCESS_FLAGS::ACC_SYNCHRONIZED, + ACCESS_FLAGS::ACC_VOLATILE, + ACCESS_FLAGS::ACC_BRIDGE, + ACCESS_FLAGS::ACC_TRANSIENT, + ACCESS_FLAGS::ACC_VARARGS, + ACCESS_FLAGS::ACC_NATIVE, + ACCESS_FLAGS::ACC_INTERFACE, + ACCESS_FLAGS::ACC_ABSTRACT, + ACCESS_FLAGS::ACC_STRICT, + ACCESS_FLAGS::ACC_SYNTHETIC, + ACCESS_FLAGS::ACC_ANNOTATION, + ACCESS_FLAGS::ACC_ENUM, + ACCESS_FLAGS::ACC_CONSTRUCTOR, + ACCESS_FLAGS::ACC_DECLARED_SYNCHRONIZED, +}; + +} +} +#endif diff --git a/deps/LIEF/include/LIEF/DEX/hash.hpp b/deps/LIEF/include/LIEF/DEX/hash.hpp new file mode 100644 index 00000000000000..42184a42af9ef1 --- /dev/null +++ b/deps/LIEF/include/LIEF/DEX/hash.hpp @@ -0,0 +1,66 @@ +/* Copyright 2017 - 2025 R. Thomas + * Copyright 2017 - 2025 Quarkslab + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef LIEF_DEX_HASH_H +#define LIEF_DEX_HASH_H + +#include "LIEF/visibility.h" +#include "LIEF/hash.hpp" + +namespace LIEF { +class Object; + +namespace DEX { + +class Class; +class Field; +class File; +class Header; +class MapItem; +class MapList; +class Method; +class Prototype; +class CodeInfo; +class Type; + +/// Class which implements a visitor to compute +/// a **deterministic** hash for LIEF DEX objects +class LIEF_API Hash : public LIEF::Hash { + public: + static LIEF::Hash::value_type hash(const Object& obj); + + public: + using LIEF::Hash::Hash; + using LIEF::Hash::visit; + + public: + void visit(const File& file) override; + void visit(const Header& header) override; + void visit(const Class& cls) override; + void visit(const Field& field) override; + void visit(const Method& method) override; + void visit(const CodeInfo& code_info) override; + void visit(const Type& type) override; + void visit(const Prototype& type) override; + void visit(const MapItem& item) override; + void visit(const MapList& list) override; + + ~Hash() override; +}; + +} +} + +#endif diff --git a/deps/LIEF/include/LIEF/DEX/instructions.hpp b/deps/LIEF/include/LIEF/DEX/instructions.hpp new file mode 100644 index 00000000000000..4c076d4575fabb --- /dev/null +++ b/deps/LIEF/include/LIEF/DEX/instructions.hpp @@ -0,0 +1,356 @@ +/* Copyright 2017 - 2025 R. Thomas + * Copyright 2017 - 2025 Quarkslab + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef LIEF_DEX_INSTRUCTIONS_H +#define LIEF_DEX_INSTRUCTIONS_H +#include "LIEF/visibility.h" +#include "LIEF/types.hpp" +#include + +namespace LIEF { +namespace DEX { + +enum SWITCH_ARRAY_IDENT : uint16_t { + IDENT_PACKED_SWITCH = 0x0100, + IDENT_SPARSE_SWITCH = 0x0200, + IDENT_FILL_ARRAY = 0x0300, +}; + +/// The Dalvik Opcodes +enum OPCODES : uint8_t { + OP_NOP = 0x00, + OP_MOVE = 0x01, + OP_MOVE_FROM_16 = 0x02, + OP_MOVE_16 = 0x03, + OP_MOVE_WIDE = 0x04, + OP_MOVE_WIDE_FROM_16 = 0x05, + OP_MOVE_WIDE_16 = 0x06, + OP_MOVE_OBJECT = 0x07, + OP_MOVE_OBJECT_FROM_16 = 0x08, + OP_MOVE_OBJECT_16 = 0x09, + OP_MOVE_RESULT = 0x0a, + OP_MOVE_RESULT_WIDE = 0x0b, + OP_MOVE_RESULT_OBJECT = 0x0c, + OP_MOVE_EXCEPTION = 0x0d, + OP_RETURN_VOID = 0x0e, + OP_RETURN = 0x0f, + OP_RETURN_WIDE = 0x10, + OP_RETURN_OBJECT = 0x11, + OP_CONST_4 = 0x12, + OP_CONST_16 = 0x13, + OP_CONST = 0x14, + OP_CONST_HIGH_16 = 0x15, + OP_CONST_WIDE_16 = 0x16, + OP_CONST_WIDE_32 = 0x17, + OP_CONST_WIDE = 0x18, + OP_CONST_WIDE_HIGH_16 = 0x19, + OP_CONST_STRING = 0x1a, + OP_CONST_STRING_JUMBO = 0x1b, + OP_CONST_CLASS = 0x1c, + OP_MONITOR_ENTER = 0x1d, + OP_MONITOR_EXIT = 0x1e, + OP_CHECK_CAST = 0x1f, + OP_INSTANCE_OF = 0x20, + OP_ARRAY_LENGTH = 0x21, + OP_NEW_INSTANCE = 0x22, + OP_NEW_ARRAY = 0x23, + OP_FILLED_NEW_ARRAY = 0x24, + OP_FILLED_NEW_ARRAY_RANGE = 0x25, + OP_FILL_ARRAY_DATA = 0x26, + OP_THROW = 0x27, + OP_GOTO = 0x28, + OP_GOTO_16 = 0x29, + OP_GOTO_32 = 0x2a, + OP_PACKED_SWITCH = 0x2b, + OP_SPARSE_SWITCH = 0x2c, + OP_CMPL_FLOAT = 0x2d, + OP_CMPG_FLOAT = 0x2e, + OP_CMPL_DOUBLE = 0x2f, + OP_CMPG_DOUBLE = 0x30, + OP_CMP_LONG = 0x31, + OP_IF_EQ = 0x32, + OP_IF_NE = 0x33, + OP_IF_LT = 0x34, + OP_IF_GE = 0x35, + OP_IF_GT = 0x36, + OP_IF_LE = 0x37, + OP_IF_EQZ = 0x38, + OP_IF_NEZ = 0x39, + OP_IF_LTZ = 0x3a, + OP_IF_GEZ = 0x3b, + OP_IF_GTZ = 0x3c, + OP_IF_LEZ = 0x3d, + OP_AGET = 0x44, + OP_AGET_WIDE = 0x45, + OP_AGET_OBJECT = 0x46, + OP_AGET_BOOLEAN = 0x47, + OP_AGET_BYTE = 0x48, + OP_AGET_CHAR = 0x49, + OP_AGET_SHORT = 0x4a, + OP_APUT = 0x4b, + OP_APUT_WIDE = 0x4c, + OP_APUT_OBJECT = 0x4d, + OP_APUT_BOOLEAN = 0x4e, + OP_APUT_BYTE = 0x4f, + OP_APUT_CHAR = 0x50, + OP_APUT_SHORT = 0x51, + OP_IGET = 0x52, + OP_IGET_WIDE = 0x53, + OP_IGET_OBJECT = 0x54, + OP_IGET_BOOLEAN = 0x55, + OP_IGET_BYTE = 0x56, + OP_IGET_CHAR = 0x57, + OP_IGET_SHORT = 0x58, + OP_IPUT = 0x59, + OP_IPUT_WIDE = 0x5a, + OP_IPUT_OBJECT = 0x5b, + OP_IPUT_BOOLEAN = 0x5c, + OP_IPUT_BYTE = 0x5d, + OP_IPUT_CHAR = 0x5e, + OP_IPUT_SHORT = 0x5f, + OP_SGET = 0x60, + OP_SGET_WIDE = 0x61, + OP_SGET_OBJECT = 0x62, + OP_SGET_BOOLEAN = 0x63, + OP_SGET_BYTE = 0x64, + OP_SGET_CHAR = 0x65, + OP_SGET_SHORT = 0x66, + OP_SPUT = 0x67, + OP_SPUT_WIDE = 0x68, + OP_SPUT_OBJECT = 0x69, + OP_SPUT_BOOLEAN = 0x6a, + OP_SPUT_BYTE = 0x6b, + OP_SPUT_CHAR = 0x6c, + OP_SPUT_SHORT = 0x6d, + OP_INVOKE_VIRTUAL = 0x6e, + OP_INVOKE_SUPER = 0x6f, + OP_INVOKE_DIRECT = 0x70, + OP_INVOKE_STATIC = 0x71, + OP_INVOKE_INTERFACE = 0x72, + OP_RETURN_VOID_NO_BARRIER = 0x73, + OP_INVOKE_VIRTUAL_RANGE = 0x74, + OP_INVOKE_SUPER_RANGE = 0x75, + OP_INVOKE_DIRECT_RANGE = 0x76, + OP_INVOKE_STATIC_RANGE = 0x77, + OP_INVOKE_INTERFACE_RANGE = 0x78, + OP_NEG_INT = 0x7b, + OP_NOT_INT = 0x7c, + OP_NEG_LONG = 0x7d, + OP_NOT_LONG = 0x7e, + OP_NEG_FLOAT = 0x7f, + OP_NEG_DOUBLE = 0x80, + OP_INT_TO_LONG = 0x81, + OP_INT_TO_FLOAT = 0x82, + OP_INT_TO_DOUBLE = 0x83, + OP_LONG_TO_INT = 0x84, + OP_LONG_TO_FLOAT = 0x85, + OP_LONG_TO_DOUBLE = 0x86, + OP_FLOAT_TO_INT = 0x87, + OP_FLOAT_TO_LONG = 0x88, + OP_FLOAT_TO_DOUBLE = 0x89, + OP_DOUBLE_TO_INT = 0x8a, + OP_DOUBLE_TO_LONG = 0x8b, + OP_DOUBLE_TO_FLOAT = 0x8c, + OP_INT_TO_BYTE = 0x8d, + OP_INT_TO_CHAR = 0x8e, + OP_INT_TO_SHORT = 0x8f, + OP_ADD_INT = 0x90, + OP_SUB_INT = 0x91, + OP_MUL_INT = 0x92, + OP_DIV_INT = 0x93, + OP_REM_INT = 0x94, + OP_AND_INT = 0x95, + OP_OR_INT = 0x96, + OP_XOR_INT = 0x97, + OP_SHL_INT = 0x98, + OP_SHR_INT = 0x99, + OP_USHR_INT = 0x9a, + OP_ADD_LONG = 0x9b, + OP_SUB_LONG = 0x9c, + OP_MUL_LONG = 0x9d, + OP_DIV_LONG = 0x9e, + OP_REM_LONG = 0x9f, + OP_AND_LONG = 0xa0, + OP_OR_LONG = 0xa1, + OP_XOR_LONG = 0xa2, + OP_SHL_LONG = 0xa3, + OP_SHR_LONG = 0xa4, + OP_USHR_LONG = 0xa5, + OP_ADD_FLOAT = 0xa6, + OP_SUB_FLOAT = 0xa7, + OP_MUL_FLOAT = 0xa8, + OP_DIV_FLOAT = 0xa9, + OP_REM_FLOAT = 0xaa, + OP_ADD_DOUBLE = 0xab, + OP_SUB_DOUBLE = 0xac, + OP_MUL_DOUBLE = 0xad, + OP_DIV_DOUBLE = 0xae, + OP_REM_DOUBLE = 0xaf, + OP_ADD_INT_2_ADDR = 0xb0, + OP_SUB_INT_2_ADDR = 0xb1, + OP_MUL_INT_2_ADDR = 0xb2, + OP_DIV_INT_2_ADDR = 0xb3, + OP_REM_INT_2_ADDR = 0xb4, + OP_AND_INT_2_ADDR = 0xb5, + OP_OR_INT_2_ADDR = 0xb6, + OP_XOR_INT_2_ADDR = 0xb7, + OP_SHL_INT_2_ADDR = 0xb8, + OP_SHR_INT_2_ADDR = 0xb9, + OP_USHR_INT_2_ADDR = 0xba, + OP_ADD_LONG_2_ADDR = 0xbb, + OP_SUB_LONG_2_ADDR = 0xbc, + OP_MUL_LONG_2_ADDR = 0xbd, + OP_DIV_LONG_2_ADDR = 0xbe, + OP_REM_LONG_2_ADDR = 0xbf, + OP_AND_LONG_2_ADDR = 0xc0, + OP_OR_LONG_2_ADDR = 0xc1, + OP_XOR_LONG_2_ADDR = 0xc2, + OP_SHL_LONG_2_ADDR = 0xc3, + OP_SHR_LONG_2_ADDR = 0xc4, + OP_USHR_LONG_2_ADDR = 0xc5, + OP_ADD_FLOAT_2_ADDR = 0xc6, + OP_SUB_FLOAT_2_ADDR = 0xc7, + OP_MUL_FLOAT_2_ADDR = 0xc8, + OP_DIV_FLOAT_2_ADDR = 0xc9, + OP_REM_FLOAT_2_ADDR = 0xca, + OP_ADD_DOUBLE_2_ADDR = 0xcb, + OP_SUB_DOUBLE_2_ADDR = 0xcc, + OP_MUL_DOUBLE_2_ADDR = 0xcd, + OP_DIV_DOUBLE_2_ADDR = 0xce, + OP_REM_DOUBLE_2_ADDR = 0xcf, + OP_ADD_INT_LIT_16 = 0xd0, + OP_RSUB_INT = 0xd1, + OP_MUL_INT_LIT_16 = 0xd2, + OP_DIV_INT_LIT_16 = 0xd3, + OP_REM_INT_LIT_16 = 0xd4, + OP_AND_INT_LIT_16 = 0xd5, + OP_OR_INT_LIT_16 = 0xd6, + OP_XOR_INT_LIT_16 = 0xd7, + OP_ADD_INT_LIT_8 = 0xd8, + OP_RSUB_INT_LIT_8 = 0xd9, + OP_MUL_INT_LIT_8 = 0xda, + OP_DIV_INT_LIT_8 = 0xdb, + OP_REM_INT_LIT_8 = 0xdc, + OP_AND_INT_LIT_8 = 0xdd, + OP_OR_INT_LIT_8 = 0xde, + OP_XOR_INT_LIT_8 = 0xdf, + OP_SHL_INT_LIT_8 = 0xe0, + OP_SHR_INT_LIT_8 = 0xe1, + OP_USHR_INT_LIT_8 = 0xe2, + + // ODEX + OP_IGET_QUICK = 0xe3, + OP_IGET_WIDE_QUICK = 0xe4, + OP_IGET_OBJECT_QUICK = 0xe5, + OP_IPUT_QUICK = 0xe6, + OP_IPUT_WIDE_QUICK = 0xe7, + OP_IPUT_OBJECT_QUICK = 0xe8, + OP_INVOKE_VIRTUAL_QUICK = 0xe9, + OP_INVOKE_VIRTUAL_RANGE_QUICK = 0xea, + OP_IPUT_BOOLEAN_QUICK = 0xeb, + OP_IPUT_BYTE_QUICK = 0xec, + OP_IPUT_CHAR_QUICK = 0xed, + OP_IPUT_SHORT_QUICK = 0xee, + OP_IGET_BOOLEAN_QUICK = 0xef, + OP_IGET_BYTE_QUICK = 0xf0, + OP_IGET_CHAR_QUICK = 0xf1, + OP_IGET_SHORT_QUICK = 0xf2, + + // From DEX 38 + OP_INVOKE_POLYMORPHIC = 0xfa, + OP_INVOKE_POLYMORPHIC_RANGE = 0xfb, + OP_INVOKE_CUSTOM = 0xfc, + OP_INVOKE_CUSTOM_RANGE = 0xfd, + + // From DEX 39 + OP_CONST_METHOD_HANDLE = 0xfe, + OP_CONST_METHOD_TYPE = 0xff, +}; + +enum INST_FORMATS : uint8_t { + F_00x = 0, + F_10x, + F_12x, + F_11n, + F_11x, + F_10t, + F_20t, + F_20bc, + F_22x, + F_21t, + F_21s, + F_21h, + F_21c, + F_23x, + F_22b, + F_22t, + F_22s, + F_22c, + F_22cs, + F_30t, + F_32x, + F_31i, + F_31t, + F_31c, + F_35c, + F_35ms, + F_35mi, + F_3rc, + F_3rms, + F_3rmi, + F_51l, + + // Since DEX 38 + F_45cc, + F_4rcc, +}; + +struct packed_switch { + uint16_t ident; // 0x0100 + uint16_t size; + uint32_t first_key; + // uint32_t targets[size] +}; + + +struct sparse_switch { + uint16_t ident; // 0x0200 + uint16_t size; + // uint32_t targets[size] +}; + +struct fill_array_data { + uint16_t ident; + uint16_t element_width; + uint32_t size; + //uint8_t data[size]; +}; + + +/// Return the INST_FORMATS format associated with the given opcode +LIEF_API INST_FORMATS inst_format_from_opcode(OPCODES op); + +LIEF_API size_t inst_size_from_format(INST_FORMATS fmt); +LIEF_API size_t inst_size_from_opcode(OPCODES op); + +LIEF_API bool is_switch_array(const uint8_t* ptr, const uint8_t* end); + +LIEF_API size_t switch_array_size(const uint8_t* ptr, const uint8_t* end); + +} // Namespace LIEF +} // Namespace DEX + +#endif + diff --git a/deps/LIEF/include/LIEF/DEX/json.hpp b/deps/LIEF/include/LIEF/DEX/json.hpp new file mode 100644 index 00000000000000..74b79fe48e4584 --- /dev/null +++ b/deps/LIEF/include/LIEF/DEX/json.hpp @@ -0,0 +1,33 @@ +/* Copyright 2017 - 2025 R. Thomas + * Copyright 2017 - 2025 Quarkslab + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef LIEF_DEX_PUBLIC_JSON_H +#define LIEF_DEX_PUBLIC_JSON_H + +#include "LIEF/visibility.h" +#include + +namespace LIEF { +class Object; + +namespace DEX { + +LIEF_API std::string to_json(const Object& v); + +} +} + + +#endif diff --git a/deps/LIEF/include/LIEF/DEX/types.hpp b/deps/LIEF/include/LIEF/DEX/types.hpp new file mode 100644 index 00000000000000..e38b44ea5aeba9 --- /dev/null +++ b/deps/LIEF/include/LIEF/DEX/types.hpp @@ -0,0 +1,28 @@ +/* Copyright 2017 - 2025 R. Thomas + * Copyright 2017 - 2025 Quarkslab + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef LIEF_DEX_TYPEDEF_H +#define LIEF_DEX_TYPEDEF_H +#include + +namespace LIEF { +namespace DEX { + +using dex_version_t = uint32_t; + +} +} + +#endif diff --git a/deps/LIEF/include/LIEF/DEX/utils.hpp b/deps/LIEF/include/LIEF/DEX/utils.hpp new file mode 100644 index 00000000000000..ceecc6b0a0a8cc --- /dev/null +++ b/deps/LIEF/include/LIEF/DEX/utils.hpp @@ -0,0 +1,49 @@ +/* Copyright 2017 - 2025 R. Thomas + * Copyright 2017 - 2025 Quarkslab + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef LIEF_DEX_UTILS_H +#define LIEF_DEX_UTILS_H + +#include +#include + +#include "LIEF/DEX/types.hpp" + +#include "LIEF/types.hpp" +#include "LIEF/visibility.h" + +namespace LIEF { +class BinaryStream; +namespace DEX { + +/// Check if the given file is a DEX. +LIEF_API bool is_dex(const std::string& file); + +/// Check if the given raw data is a DEX. +LIEF_API bool is_dex(const std::vector& raw); + +/// Return the DEX version of the given file +LIEF_API dex_version_t version(const std::string& file); + +/// Return the DEX version of the raw data +LIEF_API dex_version_t version(const std::vector& raw); + +dex_version_t version(BinaryStream& stream); + +} +} + + +#endif diff --git a/deps/LIEF/include/LIEF/DWARF.hpp b/deps/LIEF/include/LIEF/DWARF.hpp new file mode 100644 index 00000000000000..39c516b5e6cbf0 --- /dev/null +++ b/deps/LIEF/include/LIEF/DWARF.hpp @@ -0,0 +1,42 @@ +/* Copyright 2017 - 2025 R. Thomas + * Copyright 2017 - 2025 Quarkslab + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef LIEF_DWARF_H +#define LIEF_DWARF_H + +#include "LIEF/DWARF/enums.hpp" +#include "LIEF/DWARF/DebugInfo.hpp" +#include "LIEF/DWARF/CompilationUnit.hpp" +#include "LIEF/DWARF/Function.hpp" +#include "LIEF/DWARF/Variable.hpp" +#include "LIEF/DWARF/Scope.hpp" +#include "LIEF/DWARF/Type.hpp" +#include "LIEF/DWARF/types.hpp" +#include "LIEF/DWARF/Parameter.hpp" +#include "LIEF/DWARF/Editor.hpp" + +#include "LIEF/DWARF/editor/CompilationUnit.hpp" +#include "LIEF/DWARF/editor/Function.hpp" +#include "LIEF/DWARF/editor/Variable.hpp" +#include "LIEF/DWARF/editor/Type.hpp" +#include "LIEF/DWARF/editor/PointerType.hpp" +#include "LIEF/DWARF/editor/EnumType.hpp" +#include "LIEF/DWARF/editor/BaseType.hpp" +#include "LIEF/DWARF/editor/ArrayType.hpp" +#include "LIEF/DWARF/editor/FunctionType.hpp" +#include "LIEF/DWARF/editor/TypeDef.hpp" +#include "LIEF/DWARF/editor/StructType.hpp" + +#endif diff --git a/deps/LIEF/include/LIEF/DWARF/CompilationUnit.hpp b/deps/LIEF/include/LIEF/DWARF/CompilationUnit.hpp new file mode 100644 index 00000000000000..c9491b530d4099 --- /dev/null +++ b/deps/LIEF/include/LIEF/DWARF/CompilationUnit.hpp @@ -0,0 +1,282 @@ +/* Copyright 2022 - 2025 R. Thomas + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef LIEF_DWARF_COMPILATION_UNIT_H +#define LIEF_DWARF_COMPILATION_UNIT_H +#include +#include +#include + +#include "LIEF/visibility.h" +#include "LIEF/range.hpp" +#include "LIEF/iterators.hpp" +#include "LIEF/DWARF/Function.hpp" +#include "LIEF/DWARF/Type.hpp" + +namespace LIEF { +namespace dwarf { + +namespace details { +class CompilationUnit; +class CompilationUnitIt; +} + +/// This class represents a DWARF compilation unit +class LIEF_API CompilationUnit { + public: + class LIEF_API Iterator { + public: + using iterator_category = std::bidirectional_iterator_tag; + using value_type = std::unique_ptr; + using difference_type = std::ptrdiff_t; + using pointer = CompilationUnit*; + using reference = std::unique_ptr&; + using implementation = details::CompilationUnitIt; + + class LIEF_API PointerProxy { + // Inspired from LLVM's iterator_facade_base + friend class Iterator; + public: + pointer operator->() const { return R.get(); } + + private: + value_type R; + + template + PointerProxy(RefT &&R) : R(std::forward(R)) {} // NOLINT(bugprone-forwarding-reference-overload) + }; + + Iterator(const Iterator&); + Iterator(Iterator&&) noexcept; + Iterator(std::unique_ptr impl); + ~Iterator(); + + friend LIEF_API bool operator==(const Iterator& LHS, const Iterator& RHS); + friend LIEF_API bool operator!=(const Iterator& LHS, const Iterator& RHS) { + return !(LHS == RHS); + } + + Iterator& operator++(); + Iterator& operator--(); + + Iterator operator--(int) { + Iterator tmp = *static_cast(this); + --*static_cast(this); + return tmp; + } + + Iterator operator++(int) { + Iterator tmp = *static_cast(this); + ++*static_cast(this); + return tmp; + } + + std::unique_ptr operator*() const; + + PointerProxy operator->() const { + return static_cast(this)->operator*(); + } + + private: + std::unique_ptr impl_; + }; + + /// Iterator over the dwarf::Function + using functions_it = iterator_range; + + /// Iterator over the dwarf::Type + using types_it = iterator_range; + + /// Iterator over the CompilationUnit's variables + using vars_it = iterator_range; + + /// Languages supported by the DWARF (v5) format. + /// See: https://dwarfstd.org/languages.html + /// + /// Some languages (like C++11, C++17, ..) have a version (11, 17, ...) which + /// is stored in a dedicated attribute: #version + class Language { + public: + enum LANG : uint32_t { + UNKNOWN = 0, + C, + CPP, + RUST, + DART, + MODULA, + FORTRAN, + SWIFT, + D, + JAVA, + COBOL, + }; + + /// The language itself + LANG lang = UNKNOWN; + + /// Version of the language (e.g. 17 for C++17) + uint32_t version = 0; + + Language() = default; + Language(LANG lang, uint32_t version) : + lang(lang), version(version) + {} + Language(LANG lang) : + Language(lang, 0) + {} + + Language(const Language&) = default; + Language& operator=(const Language&) = default; + Language(Language&&) = default; + Language& operator=(Language&&) = default; + ~Language() = default; + }; + CompilationUnit(std::unique_ptr impl); + ~CompilationUnit(); + + /// Name of the file associated with this compilation unit (e.g. `test.cpp`) + /// Return an **empty** string if the name is not found or can't be resolved + /// + /// This value matches the `DW_AT_name` attribute + std::string name() const; + + /// Information about the program (or library) that generated this compilation + /// unit. For instance, it can output: `Debian clang version 17.0.6`. + /// + /// It returns an **empty** string if the producer is not present or can't be + /// resolved + /// + /// This value matches the `DW_AT_producer` attribute + std::string producer() const; + + /// Return the path to the directory in which the compilation took place for + /// compiling this compilation unit (e.g. `/workdir/build`) + /// + /// It returns an **empty** string if the entry is not present or can't be + /// resolved + /// + /// This value matches the `DW_AT_comp_dir` attribute + std::string compilation_dir() const; + + /// Original Language of this compilation unit. + /// + /// This value matches the `DW_AT_language` attribute. + Language language() const; + + /// Return the lowest virtual address owned by this compilation unit. + uint64_t low_address() const; + + /// Return the highest virtual address owned by this compilation unit. + uint64_t high_address() const; + + /// Return the size of the compilation unit according to its range of address. + /// + /// If the compilation is fragmented (i.e. there are some address ranges + /// between the lowest address and the highest that are not owned by the CU), + /// then it returns the sum of **all** the address ranges owned by this CU. + /// + /// If the compilation unit is **not** fragmented, then is basically returns + /// `high_address - low_address`. + uint64_t size() const; + + /// Return a list of address ranges owned by this compilation unit. + /// + /// If the compilation unit owns a contiguous range, it should return + /// **a single** range. + std::vector ranges() const; + + /// Try to find the function whose name is given in parameter. + /// + /// The provided name can be demangled + std::unique_ptr find_function(const std::string& name) const; + + /// Try to find the function at the given address + std::unique_ptr find_function(uint64_t addr) const; + + /// Try to find the Variable at the given address + std::unique_ptr find_variable(uint64_t addr) const; + + /// Try to find the Variable with the given name + std::unique_ptr find_variable(const std::string& name) const; + + /// Return an iterator over the functions implemented in this compilation + /// unit. + /// + /// Note that this iterator only iterates over the functions that have a + /// **concrete** implementation in the compilation unit. + /// + /// For instance with this code: + /// + /// ```cpp + /// inline const char* get_secret_env() { + /// return getenv("MY_SECRET_ENV"); + /// } + /// + /// int main() { + /// printf("%s", get_secret_env()); + /// return 0; + /// } + /// ``` + /// + /// The iterator will only return **one function** for `main` since + /// `get_secret_env` is inlined and thus, its implementation is located in + /// `main`. + functions_it functions() const; + + /// Return an iterator over the functions **imported** in this compilation + /// unit **but not** implemented. + /// + /// For instance with this code: + /// + /// ```cpp + /// #include + /// int main() { + /// printf("Hello\n"); + /// return 0; + /// } + /// ``` + /// + /// `printf` is imported from the standard libc so the function is returned by + /// the iterator. On the other hand, `main()` is implemented in this + /// compilation unit so it is not returned by imported_function() but + /// functions(). + functions_it imported_functions() const; + + /// Return an iterator over the different types defined in this + /// compilation unit. + types_it types() const; + + + /// Return an iterator over all the variables defined in the this compilation + /// unit: + /// + /// ```cpp + /// static int A = 1; // Returned by the iterator + /// static const char* B = "Hello"; // Returned by the iterator + /// + /// int get() { + /// static int C = 2; // Returned by the iterator + /// return C; + /// } + /// ``` + vars_it variables() const; + + private: + std::unique_ptr impl_; +}; + +} +} +#endif + diff --git a/deps/LIEF/include/LIEF/DWARF/DebugInfo.hpp b/deps/LIEF/include/LIEF/DWARF/DebugInfo.hpp new file mode 100644 index 00000000000000..ac76755b7906d3 --- /dev/null +++ b/deps/LIEF/include/LIEF/DWARF/DebugInfo.hpp @@ -0,0 +1,96 @@ +/* Copyright 2022 - 2025 R. Thomas + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef LIEF_DWARF_INFO_H +#define LIEF_DWARF_INFO_H +#include +#include + +#include "LIEF/iterators.hpp" +#include "LIEF/Abstract/DebugInfo.hpp" +#include "LIEF/DWARF/CompilationUnit.hpp" + +#include "LIEF/visibility.h" + +namespace LIEF { +/// Namespace for the DWARF debug format +namespace dwarf { +class Function; +class Variable; + +/// This class represents a DWARF debug information. It can embed different +/// compilation units which can be accessed through compilation_units() . +/// +/// This class can be instantiated from LIEF::Binary::debug_info() or load() +class LIEF_API DebugInfo : public LIEF::DebugInfo { + public: + using LIEF::DebugInfo::DebugInfo; + + static std::unique_ptr from_file(const std::string& path); + + /// Iterator over the CompilationUnit + using compilation_units_it = iterator_range; + + /// Try to find the function with the given name (mangled or not) + /// + /// ```cpp + /// const DebugInfo& info = ...; + /// if (auto func = info.find_function("_ZNSt6localeD1Ev")) { + /// // Found + /// } + /// if (auto func = info.find_function("std::locale::~locale()")) { + /// // Found + /// } + /// ``` + std::unique_ptr find_function(const std::string& name) const; + + /// Try to find the function at the given **virtual** address + std::unique_ptr find_function(uint64_t addr) const; + + /// Try to find the variable with the given name. This name can be mangled or + /// not. + std::unique_ptr find_variable(const std::string& name) const; + + /// Try to find the variable at the given **virtual** address + std::unique_ptr find_variable(uint64_t addr) const; + + /// Try to find the type with the given name + std::unique_ptr find_type(const std::string& name) const; + + /// Iterator on the CompilationUnit embedded in this dwarf + compilation_units_it compilation_units() const; + + /// Attempt to resolve the address of the function specified by `name`. + optional find_function_address(const std::string& name) const override; + + FORMAT format() const override { + return LIEF::DebugInfo::FORMAT::DWARF; + } + + static bool classof(const LIEF::DebugInfo* info) { + return info->format() == LIEF::DebugInfo::FORMAT::DWARF; + } + + ~DebugInfo() override = default; +}; + + +/// Load DWARF file from the given path +inline std::unique_ptr load(const std::string& dwarf_path) { + return DebugInfo::from_file(dwarf_path); +} + +} +} +#endif diff --git a/deps/LIEF/include/LIEF/DWARF/Editor.hpp b/deps/LIEF/include/LIEF/DWARF/Editor.hpp new file mode 100644 index 00000000000000..3c63c13833894a --- /dev/null +++ b/deps/LIEF/include/LIEF/DWARF/Editor.hpp @@ -0,0 +1,58 @@ +/* Copyright 2022 - 2025 R. Thomas + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef LIEF_DWARF_EDITOR_H +#define LIEF_DWARF_EDITOR_H +#include +#include + +#include "LIEF/visibility.h" + +namespace LIEF { +class Binary; +namespace dwarf { + +namespace details { +class Editor; +} + +namespace editor { +class CompilationUnit; +} + +/// This class exposes the main API to create DWARF information +class LIEF_API Editor { + public: + Editor() = delete; + Editor(std::unique_ptr impl); + + /// Instantiate an editor for the given binary object + static std::unique_ptr from_binary(LIEF::Binary& bin); + + /// Create a new compilation unit + std::unique_ptr create_compilation_unit(); + + /// Write the DWARF file to the specified output + void write(const std::string& output); + + ~Editor(); + + private: + std::unique_ptr impl_; + +}; + +} +} +#endif diff --git a/deps/LIEF/include/LIEF/DWARF/Function.hpp b/deps/LIEF/include/LIEF/DWARF/Function.hpp new file mode 100644 index 00000000000000..495cbadac72317 --- /dev/null +++ b/deps/LIEF/include/LIEF/DWARF/Function.hpp @@ -0,0 +1,180 @@ +/* Copyright 2022 - 2025 R. Thomas + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef LIEF_DWARF_FUNCTION_H +#define LIEF_DWARF_FUNCTION_H + +#include +#include + +#include "LIEF/visibility.h" +#include "LIEF/errors.hpp" +#include "LIEF/iterators.hpp" +#include "LIEF/range.hpp" +#include "LIEF/DWARF/Variable.hpp" +#include "LIEF/DWARF/Type.hpp" +#include "LIEF/asm/Instruction.hpp" + +namespace LIEF { +namespace dwarf { + +class Scope; +class Parameter; + +namespace details { +class Function; +class FunctionIt; +} + +/// This class represents a DWARF function which can be associated with either: +/// `DW_TAG_subprogram` or `DW_TAG_inlined_subroutine`. +class LIEF_API Function { + public: + class LIEF_API Iterator { + public: + using iterator_category = std::bidirectional_iterator_tag; + using value_type = std::unique_ptr; + using difference_type = std::ptrdiff_t; + using pointer = Function*; + using reference = std::unique_ptr&; + using implementation = details::FunctionIt; + + class LIEF_API PointerProxy { + // Inspired from LLVM's iterator_facade_base + friend class Iterator; + public: + pointer operator->() const { return R.get(); } + + private: + value_type R; + + template + PointerProxy(RefT &&R) : R(std::forward(R)) {} // NOLINT(bugprone-forwarding-reference-overload) + }; + + Iterator(const Iterator&); + Iterator(Iterator&&) noexcept; + Iterator(std::unique_ptr impl); + ~Iterator(); + + friend LIEF_API bool operator==(const Iterator& LHS, const Iterator& RHS); + + friend LIEF_API bool operator!=(const Iterator& LHS, const Iterator& RHS) { + return !(LHS == RHS); + } + + Iterator& operator++(); + Iterator& operator--(); + + Iterator operator--(int) { + Iterator tmp = *static_cast(this); + --*static_cast(this); + return tmp; + } + + Iterator operator++(int) { + Iterator tmp = *static_cast(this); + ++*static_cast(this); + return tmp; + } + + std::unique_ptr operator*() const; + + PointerProxy operator->() const { + return static_cast(this)->operator*(); + } + + private: + std::unique_ptr impl_; + }; + + /// Iterator over the variables defined in the scope of this function + using vars_it = iterator_range; + using parameters_t = std::vector>; + using thrown_types_t = std::vector>; + + using instructions_it = iterator_range; + + Function(std::unique_ptr impl); + + /// The name of the function (`DW_AT_name`) + std::string name() const; + + /// The name of the function which is used for linking (`DW_AT_linkage_name`). + /// + /// This name differs from name() as it is usually mangled. The function + /// return an empty string if the linkage name is not available. + std::string linkage_name() const; + + /// Return the address of the function (`DW_AT_entry_pc` or `DW_AT_low_pc`). + result address() const; + + /// Return an iterator of variables (`DW_TAG_variable`) defined within the + /// scope of this function. This includes regular stack-based variables as + /// well as static ones. + vars_it variables() const; + + /// Whether this function is created by the compiler and not + /// present in the original source code + bool is_artificial() const; + + /// Whether the function is defined **outside** the current compilation unit + /// (`DW_AT_external`). + bool is_external() const; + + /// Return the size taken by this function in the binary + uint64_t size() const; + + /// Ranges of virtual addresses owned by this function + std::vector ranges() const; + + /// Original source code location + debug_location_t debug_location() const; + + /// Return the dwarf::Type associated with the **return type** of this + /// function + std::unique_ptr type() const; + + /// Return the function's parameters (including any template parameter) + parameters_t parameters() const; + + /// List of exceptions (types) that can be thrown by the function. + /// + /// For instance, given this Swift code: + /// + /// ```swift + /// func summarize(_ ratings: [Int]) throws(StatisticsError) { + /// // ... + /// } + /// ``` + /// + /// thrown_types() returns one element associated with the Type: + /// `StatisticsError`. + thrown_types_t thrown_types() const; + + /// Return the scope in which this function is defined + std::unique_ptr scope() const; + + /// Disassemble the current function by returning an iterator over + /// the assembly::Instruction + instructions_it instructions() const; + + ~Function(); + private: + std::unique_ptr impl_; +}; + +} +} +#endif diff --git a/deps/LIEF/include/LIEF/DWARF/Parameter.hpp b/deps/LIEF/include/LIEF/DWARF/Parameter.hpp new file mode 100644 index 00000000000000..9fa7c1211deb86 --- /dev/null +++ b/deps/LIEF/include/LIEF/DWARF/Parameter.hpp @@ -0,0 +1,146 @@ +/* Copyright 2022 - 2025 R. Thomas + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef LIEF_DWARF_PARAMETER_H +#define LIEF_DWARF_PARAMETER_H + +#include "LIEF/visibility.h" + +#include +#include + +namespace LIEF { +namespace dwarf { + +class Type; + +namespace details { +class Parameter; +} + +/// This class represents a DWARF parameter which can be either: +/// - A regular function parameter (see: parameters::Formal) +/// - A template type parameter (see: parameters::TemplateType) +/// - A template value parameter (see: parameters::TemplateValue) +class LIEF_API Parameter { + public: + enum class KIND { + UNKNOWN = 0, + TEMPLATE_TYPE, ///< DW_TAG_template_type_parameter + TEMPLATE_VALUE, ///< DW_TAG_template_value_parameter + FORMAL, ///< DW_TAG_formal_parameter + }; + Parameter() = delete; + Parameter(Parameter&& other); + Parameter& operator=(Parameter&& other); + Parameter& operator=(const Parameter&) = delete; + Parameter(const Parameter&) = delete; + + KIND kind() const; + + /// Name of the parameter + std::string name() const; + + /// Type of this parameter + std::unique_ptr type() const; + + template + const T* as() const { + if (T::classof(this)) { + return static_cast(this); + } + return nullptr; + } + + virtual ~Parameter(); + + LIEF_LOCAL static + std::unique_ptr create(std::unique_ptr impl); + + protected: + Parameter(std::unique_ptr impl); + std::unique_ptr impl_; +}; + +namespace parameters { + +/// This class represents a regular function parameter. +/// +/// For instance, given this prototype: +/// +/// ```cpp +/// int main(int argc, const char** argv); +/// ``` +/// +/// The function `main` has two parameters::Formal parameters: +/// +/// 1. `argc` (Parameter::name) typed as `int` (types::Base from Parameter::type) +/// 2. `argv` (Parameter::name) typed as `const char**` +/// (types::Const from Parameter::type) +class LIEF_API Formal : public Parameter { + public: + using Parameter::Parameter; + static bool classof(const Parameter* P) { + return P->kind() == Parameter::KIND::FORMAL; + } + + ~Formal() override = default; +}; + + +/// This class represents a template **value** parameter. +/// +/// For instance, given this prototype: +/// +/// ```cpp +/// template +/// void generic(); +/// ``` +/// +/// The function `generic` has one parameters::TemplateValue parameter: `X`. +class LIEF_API TemplateValue : public Parameter { + public: + using Parameter::Parameter; + static bool classof(const Parameter* P) { + return P->kind() == Parameter::KIND::TEMPLATE_VALUE; + } + + ~TemplateValue() override = default; +}; + +/// This class represents a template **type** parameter. +/// +/// For instance, given this prototype: +/// +/// ```cpp +/// template +/// void generic(); +/// ``` +/// +/// The function `generic` has one parameters::TemplateType parameter: `Y`. +class LIEF_API TemplateType : public Parameter { +public: + using Parameter::Parameter; + static bool classof(const Parameter* P) { + return P->kind() == Parameter::KIND::TEMPLATE_TYPE; + } + + ~TemplateType() override = default; +}; + +} + +} +} +#endif diff --git a/deps/LIEF/include/LIEF/DWARF/Scope.hpp b/deps/LIEF/include/LIEF/DWARF/Scope.hpp new file mode 100644 index 00000000000000..61977c21aec5e6 --- /dev/null +++ b/deps/LIEF/include/LIEF/DWARF/Scope.hpp @@ -0,0 +1,66 @@ +/* Copyright 2022 - 2025 R. Thomas + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef LIEF_DWARF_SCOPE_H +#define LIEF_DWARF_SCOPE_H + +#include +#include +#include + +#include "LIEF/visibility.h" + +namespace LIEF { +namespace dwarf { + +namespace details { +class Scope; +} + +/// This class materializes a scope in which Function, Variable, Type, ... +/// can be defined. +class LIEF_API Scope { + public: + enum class TYPE : uint32_t { + UNKNOWN = 0, + UNION, + CLASS, + STRUCT, + NAMESPACE, + FUNCTION, + COMPILATION_UNIT, + }; + Scope(std::unique_ptr impl); + + /// Name of the scope. For instance namespace's name or function's name. + std::string name() const; + + /// Parent scope (if any) + std::unique_ptr parent() const; + + /// The current scope type + TYPE type() const; + + /// Represent the whole chain of all (parent) scopes using the provided + /// separator. E.g. `ns1::ns2::Class1::Struct2::Type` + std::string chained(const std::string& sep = "::") const; + + ~Scope(); + private: + std::unique_ptr impl_; +}; + +} +} +#endif diff --git a/deps/LIEF/include/LIEF/DWARF/Type.hpp b/deps/LIEF/include/LIEF/DWARF/Type.hpp new file mode 100644 index 00000000000000..9e13e896c0d782 --- /dev/null +++ b/deps/LIEF/include/LIEF/DWARF/Type.hpp @@ -0,0 +1,198 @@ +/* Copyright 2022 - 2025 R. Thomas + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef LIEF_DWARF_TYPE_H +#define LIEF_DWARF_TYPE_H + +#include + +#include "LIEF/visibility.h" +#include "LIEF/errors.hpp" +#include "LIEF/debug_loc.hpp" +#include "LIEF/canbe_unique.hpp" + +namespace LIEF { +namespace dwarf { +class Scope; + +namespace details { +class Type; +class TypeIt; +} + +/// This class represents a DWARF Type which includes: +/// +/// - `DW_TAG_array_type` +/// - `DW_TAG_atomic_type` +/// - `DW_TAG_base_type` +/// - `DW_TAG_class_type` +/// - `DW_TAG_coarray_type` +/// - `DW_TAG_const_type` +/// - `DW_TAG_dynamic_type` +/// - `DW_TAG_enumeration_type` +/// - `DW_TAG_file_type` +/// - `DW_TAG_immutable_type` +/// - `DW_TAG_interface_type` +/// - `DW_TAG_packed_type` +/// - `DW_TAG_pointer_type` +/// - `DW_TAG_ptr_to_member_type` +/// - `DW_TAG_reference_type` +/// - `DW_TAG_restrict_type` +/// - `DW_TAG_rvalue_reference_type` +/// - `DW_TAG_set_type` +/// - `DW_TAG_shared_type` +/// - `DW_TAG_string_type` +/// - `DW_TAG_structure_type` +/// - `DW_TAG_subroutine_type` +/// - `DW_TAG_template_alias` +/// - `DW_TAG_thrown_type` +/// - `DW_TAG_typedef` +/// - `DW_TAG_union_type` +/// - `DW_TAG_unspecified_type` +/// - `DW_TAG_volatile_type` +class LIEF_API Type { + public: + class LIEF_API Iterator { + public: + using iterator_category = std::bidirectional_iterator_tag; + using value_type = std::unique_ptr; + using difference_type = std::ptrdiff_t; + using pointer = Type*; + using reference = std::unique_ptr&; + using implementation = details::TypeIt; + + class LIEF_API PointerProxy { + // Inspired from LLVM's iterator_facade_base + friend class Iterator; + public: + pointer operator->() const { return R.get(); } + + private: + value_type R; + + template + PointerProxy(RefT &&R) : R(std::forward(R)) {} // NOLINT(bugprone-forwarding-reference-overload) + }; + + Iterator(const Iterator&); + Iterator(Iterator&&) noexcept; + Iterator(std::unique_ptr impl); + ~Iterator(); + + friend LIEF_API bool operator==(const Iterator& LHS, const Iterator& RHS); + friend LIEF_API bool operator!=(const Iterator& LHS, const Iterator& RHS) { + return !(LHS == RHS); + } + + Iterator& operator++(); + Iterator& operator--(); + + Iterator operator--(int) { + Iterator tmp = *static_cast(this); + --*static_cast(this); + return tmp; + } + + Iterator operator++(int) { + Iterator tmp = *static_cast(this); + ++*static_cast(this); + return tmp; + } + + std::unique_ptr operator*() const; + + PointerProxy operator->() const { + return static_cast(this)->operator*(); + } + + private: + std::unique_ptr impl_; + }; + + virtual ~Type(); + + enum class KIND { + UNKNOWN = 0, + UNSPECIFIED, + BASE, + CONST_KIND, + CLASS, + ARRAY, + POINTER, + STRUCT, + UNION, + TYPEDEF, + REF, + SET_TYPE, + STRING, + SUBROUTINE, + POINTER_MEMBER, + PACKED, + FILE, + THROWN, + VOLATILE, + RESTRICT, + INTERFACE, + SHARED, + RVALREF, + TEMPLATE_ALIAS, + COARRAY, + DYNAMIC, + ATOMIC, + IMMUTABLE, + ENUM, + }; + + KIND kind() const; + + /// Whether this type is a `DW_TAG_unspecified_type` + bool is_unspecified() const { + return kind() == KIND::UNSPECIFIED; + } + + /// Return the type's name using either `DW_AT_name` or `DW_AT_picture_string` + /// (if any). + result name() const; + + /// Return the size of the type or an error if it can't be computed. + /// + /// This size should match the equivalent of `sizeof(Type)`. + result size() const; + + /// Return the debug location where this type is defined. + debug_location_t location() const; + + /// Return the scope in which this type is defined + std::unique_ptr scope() const; + + template + const T* as() const { + if (T::classof(this)) { + return static_cast(this); + } + return nullptr; + } + + static std::unique_ptr create(std::unique_ptr impl); + + protected: + Type(std::unique_ptr impl); + Type(details::Type& impl); + + LIEF::details::canbe_unique impl_; +}; + +} +} +#endif diff --git a/deps/LIEF/include/LIEF/DWARF/Variable.hpp b/deps/LIEF/include/LIEF/DWARF/Variable.hpp new file mode 100644 index 00000000000000..dd457f45d6ea8e --- /dev/null +++ b/deps/LIEF/include/LIEF/DWARF/Variable.hpp @@ -0,0 +1,141 @@ +/* Copyright 2022 - 2025 R. Thomas + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef LIEF_DWARF_VARIABLE_H +#define LIEF_DWARF_VARIABLE_H + +#include + +#include "LIEF/visibility.h" +#include "LIEF/errors.hpp" +#include "LIEF/debug_loc.hpp" +#include "LIEF/DWARF/Type.hpp" + +namespace LIEF { +namespace dwarf { +class Scope; + +namespace details { +class Variable; +class VariableIt; +} + +/// This class represents a DWARF variable which can be owned by a +/// dwarf::Function or a dwarf::CompilationUnit +class LIEF_API Variable { + public: + class LIEF_API Iterator { + public: + using iterator_category = std::bidirectional_iterator_tag; + using value_type = std::unique_ptr; + using difference_type = std::ptrdiff_t; + using pointer = Variable*; + using reference = std::unique_ptr&; + using implementation = details::VariableIt; + + class LIEF_API PointerProxy { + // Inspired from LLVM's iterator_facade_base + friend class Iterator; + public: + pointer operator->() const { return R.get(); } + + private: + value_type R; + + template + PointerProxy(RefT &&R) : R(std::forward(R)) {} // NOLINT(bugprone-forwarding-reference-overload) + }; + + Iterator(const Iterator&); + Iterator(Iterator&&) noexcept; + Iterator(std::unique_ptr impl); + ~Iterator(); + + friend LIEF_API bool operator==(const Iterator& LHS, const Iterator& RHS); + friend LIEF_API bool operator!=(const Iterator& LHS, const Iterator& RHS) { + return !(LHS == RHS); + } + + Iterator& operator++(); + Iterator& operator--(); + + Iterator operator--(int) { + Iterator tmp = *static_cast(this); + --*static_cast(this); + return tmp; + } + + Iterator operator++(int) { + Iterator tmp = *static_cast(this); + ++*static_cast(this); + return tmp; + } + + std::unique_ptr operator*() const; + + PointerProxy operator->() const { + return static_cast(this)->operator*(); + } + + private: + std::unique_ptr impl_; + }; + + Variable(std::unique_ptr impl); + + /// Name of the variable (usually demangled) + std::string name() const; + + /// The name of the variable which is used for linking (`DW_AT_linkage_name`). + /// + /// This name differs from name() as it is usually mangled. The function + /// return an empty string if the linkage name is not available. + std::string linkage_name() const; + + /// Address of the variable. + /// + /// If the variable is **static**, it returns the **virtual address** + /// where it is defined. + /// If the variable is stack-based, it returns the **relative offset** from + /// the frame based register. + /// + /// If the address can't be resolved, it returns a lief_errors. + result address() const; + + /// Return the size of the variable (or a lief_errors if it can't be + /// resolved). + /// + /// This size is defined by its type. + result size() const; + + /// Whether it's a `constexpr` variable + bool is_constexpr() const; + + /// The original source location where the variable is defined. + debug_location_t debug_location() const; + + /// Return the type of this variable + std::unique_ptr type() const; + + /// Return the scope in which this variable is defined + std::unique_ptr scope() const; + + ~Variable(); + private: + std::unique_ptr impl_; +}; + +} +} +#endif diff --git a/deps/LIEF/include/LIEF/DWARF/editor/ArrayType.hpp b/deps/LIEF/include/LIEF/DWARF/editor/ArrayType.hpp new file mode 100644 index 00000000000000..2116dd9666e4b8 --- /dev/null +++ b/deps/LIEF/include/LIEF/DWARF/editor/ArrayType.hpp @@ -0,0 +1,38 @@ +/* Copyright 2022 - 2025 R. Thomas + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef LIEF_DWARF_EDITOR_ARRAY_TYPE_H +#define LIEF_DWARF_EDITOR_ARRAY_TYPE_H + +#include "LIEF/visibility.h" +#include "LIEF/DWARF/editor/Type.hpp" + +namespace LIEF { +namespace dwarf { +namespace editor { + +/// This class represents an array type (`DW_TAG_array_type`). +class LIEF_API ArrayType : public Type { + public: + using Type::Type; + + static bool classof(const Type* type); + + ~ArrayType() override = default; +}; + +} +} +} +#endif diff --git a/deps/LIEF/include/LIEF/DWARF/editor/BaseType.hpp b/deps/LIEF/include/LIEF/DWARF/editor/BaseType.hpp new file mode 100644 index 00000000000000..f06db195b0aef7 --- /dev/null +++ b/deps/LIEF/include/LIEF/DWARF/editor/BaseType.hpp @@ -0,0 +1,50 @@ +/* Copyright 2022 - 2025 R. Thomas + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef LIEF_DWARF_EDITOR_BASE_TYPE_H +#define LIEF_DWARF_EDITOR_BASE_TYPE_H + +#include +#include "LIEF/visibility.h" +#include "LIEF/DWARF/editor/Type.hpp" + +namespace LIEF { +namespace dwarf { +namespace editor { + +/// This class represents a primitive type like `int, char`. +class LIEF_API BaseType : public Type { + public: + using Type::Type; + + enum class ENCODING : uint32_t { + NONE = 0, + ADDRESS, + SIGNED, + SIGNED_CHAR, + UNSIGNED, + UNSIGNED_CHAR, + BOOLEAN, + FLOAT + }; + + static bool classof(const Type* type); + + ~BaseType() override = default; +}; + +} +} +} +#endif diff --git a/deps/LIEF/include/LIEF/DWARF/editor/CompilationUnit.hpp b/deps/LIEF/include/LIEF/DWARF/editor/CompilationUnit.hpp new file mode 100644 index 00000000000000..b6b00714d0de5f --- /dev/null +++ b/deps/LIEF/include/LIEF/DWARF/editor/CompilationUnit.hpp @@ -0,0 +1,100 @@ +/* Copyright 2022 - 2025 R. Thomas + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef LIEF_DWARF_EDITOR_COMPILATION_UNIT_H +#define LIEF_DWARF_EDITOR_COMPILATION_UNIT_H +#include +#include + +#include "LIEF/visibility.h" +#include "LIEF/DWARF/editor/StructType.hpp" +#include "LIEF/DWARF/editor/BaseType.hpp" +#include "LIEF/DWARF/editor/FunctionType.hpp" +#include "LIEF/DWARF/editor/PointerType.hpp" + +namespace LIEF { +namespace dwarf { +namespace editor { +class Function; +class Variable; +class Type; +class EnumType; +class TypeDef; +class ArrayType; + +namespace details { +class CompilationUnit; +} + +/// This class represents an **editable** DWARF compilation unit +class LIEF_API CompilationUnit { + public: + CompilationUnit() = delete; + CompilationUnit(std::unique_ptr impl); + + /// Set the `DW_AT_producer` producer attribute. + /// + /// This attribute aims to inform about the program that generated this + /// compilation unit (e.g. `LIEF Extended`) + CompilationUnit& set_producer(const std::string& producer); + + /// Create a new function owned by this compilation unit + std::unique_ptr create_function(const std::string& name); + + /// Create a new **global** variable owned by this compilation unit + std::unique_ptr create_variable(const std::string& name); + + /// Create a `DW_TAG_unspecified_type` type with the given name + std::unique_ptr create_generic_type(const std::string& name); + + /// Create an enum type (`DW_TAG_enumeration_type`) + std::unique_ptr create_enum(const std::string& name); + + /// Create a typdef with the name provided in the first parameter which aliases + /// the type provided in the second parameter + std::unique_ptr create_typedef(const std::string& name, const Type& type); + + /// Create a struct-like type (struct, class, union) with the given name. + std::unique_ptr create_structure( + const std::string& name, StructType::TYPE kind = StructType::TYPE::STRUCT); + + /// Create a primitive type with the given name and size. + std::unique_ptr create_base_type(const std::string& name, size_t size, + BaseType::ENCODING encoding = BaseType::ENCODING::NONE); + + /// Create a function type with the given name. + std::unique_ptr create_function_type(const std::string& name); + + /// Create a pointer on the provided type + std::unique_ptr create_pointer_type(const Type& ty) { + return ty.pointer_to(); + } + + /// Create a `void` type + std::unique_ptr create_void_type(); + + /// Create an array type with the given name, type and size. + std::unique_ptr + create_array(const std::string& name, const Type& type, size_t count); + + ~CompilationUnit(); + + private: + std::unique_ptr impl_; +}; + +} +} +} +#endif diff --git a/deps/LIEF/include/LIEF/DWARF/editor/EnumType.hpp b/deps/LIEF/include/LIEF/DWARF/editor/EnumType.hpp new file mode 100644 index 00000000000000..90d76fa0e91a4e --- /dev/null +++ b/deps/LIEF/include/LIEF/DWARF/editor/EnumType.hpp @@ -0,0 +1,62 @@ +/* Copyright 2022 - 2025 R. Thomas + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef LIEF_DWARF_EDITOR_ENUM_TYPE_H +#define LIEF_DWARF_EDITOR_ENUM_TYPE_H +#include +#include + +#include "LIEF/visibility.h" +#include "LIEF/DWARF/editor/Type.hpp" + +namespace LIEF { +namespace dwarf { +namespace editor { + +namespace details { +class EnumValue; +} + +/// This class represents an editable enum type (`DW_TAG_enumeration_type`) +class LIEF_API EnumType : public Type { + public: + using Type::Type; + + /// This class represents an enum value + class LIEF_API Value { + public: + Value() = delete; + Value(std::unique_ptr impl); + + ~Value(); + private: + std::unique_ptr impl_; + }; + + /// Define the number of bytes required to hold an instance of the + /// enumeration (`DW_AT_byte_size`). + EnumType& set_size(uint64_t size); + + /// Add an enum value by specifying its name and its integer value + std::unique_ptr add_value(const std::string& name, int64_t value); + + static bool classof(const Type* type); + + ~EnumType() override = default; +}; + +} +} +} +#endif diff --git a/deps/LIEF/include/LIEF/DWARF/editor/Function.hpp b/deps/LIEF/include/LIEF/DWARF/editor/Function.hpp new file mode 100644 index 00000000000000..e91f64139c055e --- /dev/null +++ b/deps/LIEF/include/LIEF/DWARF/editor/Function.hpp @@ -0,0 +1,129 @@ +/* Copyright 2022 - 2025 R. Thomas + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef LIEF_DWARF_EDITOR_FUNCTION_H +#define LIEF_DWARF_EDITOR_FUNCTION_H +#include +#include +#include +#include + +#include "LIEF/visibility.h" + +namespace LIEF { +namespace dwarf { +namespace editor { +class Type; +class Variable; + +namespace details { +class Function; +class FunctionParameter; +class FunctionLexicalBlock; +class FunctionLabel; +} + +/// This class represents an **editable** DWARF function (`DW_TAG_subprogram`) +class LIEF_API Function { + public: + struct LIEF_API range_t { + range_t() = default; + range_t(uint64_t start, uint64_t end) : + start(start), end(end) + {} + uint64_t start = 0; + uint64_t end = 0; + }; + + /// This class represents a parameter of the current function (`DW_TAG_formal_parameter`) + class LIEF_API Parameter { + public: + Parameter() = delete; + Parameter(std::unique_ptr impl); + + ~Parameter(); + private: + std::unique_ptr impl_; + }; + + /// This class mirrors the `DW_TAG_lexical_block` DWARF tag + class LIEF_API LexicalBlock { + public: + LexicalBlock() = delete; + LexicalBlock(std::unique_ptr impl); + + ~LexicalBlock(); + private: + std::unique_ptr impl_; + }; + + /// This class mirrors the `DW_TAG_label` DWARF tag + class LIEF_API Label { + public: + Label() = delete; + Label(std::unique_ptr impl); + + ~Label(); + private: + std::unique_ptr impl_; + }; + + Function() = delete; + Function(std::unique_ptr impl); + + /// Set the address of this function by defining `DW_AT_entry_pc` + Function& set_address(uint64_t addr); + + /// Set the upper and lower bound addresses for this function. This assumes + /// that the function is contiguous between `low` and `high`. + /// + /// Underneath, the function defines `DW_AT_low_pc` and `DW_AT_high_pc` + Function& set_low_high(uint64_t low, uint64_t high); + + /// Set the ranges of addresses owned by the implementation of this function + /// by setting the `DW_AT_ranges` attribute. + /// + /// This setter should be used for non-contiguous function. + Function& set_ranges(const std::vector& ranges); + + /// Set the function as external by defining `DW_AT_external` to true. + /// This means that the function is **imported** by the current compilation + /// unit. + Function& set_external(); + + /// Set the return type of this function + Function& set_return_type(const Type& type); + + /// Add a parameter to the current function + std::unique_ptr add_parameter(const std::string& name, const Type& type); + + /// Create a stack-based variable owned by the current function + std::unique_ptr create_stack_variable(const std::string& name); + + /// Add a lexical block with the given range + std::unique_ptr add_lexical_block(uint64_t start, uint64_t end); + + /// Add a label at the given address + std::unique_ptr