diff --git a/arkguard/package-lock.json b/arkguard/package-lock.json index 1861fe89611bb924c5a101065ad0256da7329026..aa554dcef7906c7e00da4480090d099f62f00a8e 100644 --- a/arkguard/package-lock.json +++ b/arkguard/package-lock.json @@ -638,6 +638,14 @@ "yargs": "16.2.0", "yargs-parser": "20.2.4", "yargs-unparser": "2.0.0" + }, + "dependencies": { + "diff": { + "version": "5.0.0", + "resolved": "https://repo.huaweicloud.com/repository/npm/diff/-/diff-5.0.0.tgz", + "integrity": "sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w==", + "dev": true + } } }, "ms": { diff --git a/arkguard/package.json b/arkguard/package.json index 944f9344aec56a59e7e7c383472e460ed3a5f384..472905b7e8ec7d6ea71586a33b6c3a470d6d3f81 100644 --- a/arkguard/package.json +++ b/arkguard/package.json @@ -33,7 +33,8 @@ "@types/node": "18.11.7", "chai": "^4.3.6", "mocha": "^10.0.0", - "ts-node": "^10.9.1" + "ts-node": "^10.9.1", + "diff": "5.0.0" }, "dependencies": { "commander": "^9.3.0", diff --git a/arkguard/scripts/execute_result_statistics.js b/arkguard/scripts/execute_result_statistics.js index d954643c93c4eb6247810fed0d34dd1bcc24aeb9..455ef203398b2254c04ba6043061d0ae5f6f0813 100644 --- a/arkguard/scripts/execute_result_statistics.js +++ b/arkguard/scripts/execute_result_statistics.js @@ -15,8 +15,10 @@ const fs = require('fs'); const path = require('path'); +const diff = require('diff'); const { execSync } = require('child_process'); import { Extension } from '../src/common/type'; +import { FileUtils } from '../src/utils/FileUtils'; const testDirectory = path.resolve('./test/local'); @@ -37,20 +39,18 @@ function runTest(filePath) { try { const command = `node ./node_modules/ts-node/dist/bin.js ${filePath}`; execSync(command); - if (compareWithExpected(filePath)) { - return true; - } else { - console.error(`Test case ${filePath} failed: Content does not match`); - return false; - } } catch (error) { console.error(`Test case ${filePath} failed:`, error); return false; } + return true; } let successCount = 0; let failureCount = 0; +let contentcomparationSuccessCount = 0; +let contentcomparationFailureCount = 0; const failedFiles = []; +const contentComparisionFailureFiles = []; function runTestsInDirectory(directoryPath) { const files = fs.readdirSync(directoryPath); @@ -77,6 +77,30 @@ function runTestsInDirectory(directoryPath) { failureCount++; failedFiles.push(filePath); } + compareContent(filePath); + } else if (filePath.endsWith(Extension.DETS) || filePath.endsWith(Extension.DTS)) { + compareContent(filePath); + } + } +} + +function compareContent(filePath) { + const sourcePath = filePath.replace('/test/local/', '/test/grammar/'); + const sourcePathAndExtension = FileUtils.getFileSuffix(sourcePath); + const expectationPath = sourcePathAndExtension.path + '_expected.txt'; + if (fs.existsSync(expectationPath)) { + const actual = fs.readFileSync(filePath).toString(); + const expectation = fs.readFileSync(expectationPath).toString(); + if (actual === expectation) { + contentcomparationSuccessCount++; + } else { + contentcomparationFailureCount++; + contentComparisionFailureFiles.push(filePath); + const differences = diff.diffLines(actual, expectation); + differences.forEach(part => { + const color = part.added ? '\x1b[32m' : part.removed ? '\x1b[31m' : '\x1b[0m'; + console.log(color + part.value + '\x1b[0m'); + }); } } } @@ -87,8 +111,17 @@ console.log('--- Grammar Test Results ---'); console.log(`Success count: ${successCount}`); console.log(`Failure count: ${failureCount}`); if (failureCount > 0) { - console.log('Failed files:'); + console.log('Execution failed files:'); for (const failedFile of failedFiles) { console.log(failedFile); } +} + +console.log(`Content fomparison success count: ${contentcomparationSuccessCount}`); +console.log(`Content fomparison sailure count: ${contentcomparationFailureCount}`); +if (contentcomparationFailureCount > 0) { + console.log('Content comparision failed files:'); + for (const failedFile of contentComparisionFailureFiles) { + console.log(failedFile); + } } \ No newline at end of file diff --git a/arkguard/src/ArkObfuscator.ts b/arkguard/src/ArkObfuscator.ts index ed4795d8c9e1021b93237a6de4ff02ae206afc36..1dc113334a7133a8343df02e06c732bcb8f141ca 100644 --- a/arkguard/src/ArkObfuscator.ts +++ b/arkguard/src/ArkObfuscator.ts @@ -320,7 +320,7 @@ export class ArkObfuscator { } else { relativePath = sourceFilePath.replace(testCasesRootPath, ''); } - resultPath = path.join(outputDir, relativePath); + resultPath = path.join(this.mCustomProfiles.mOutputDir, relativePath); fs.mkdirSync(path.dirname(resultPath), {recursive: true}); fs.writeFileSync(resultPath, mixedInfo.content); diff --git a/arkguard/src/common/ApiExtractor.ts b/arkguard/src/common/ApiExtractor.ts index c8c9754a69cb0e45076bc1635b356ea5cdbe9f6c..428eed5a359f407c0a674f050277ef0b7b9df056 100644 --- a/arkguard/src/common/ApiExtractor.ts +++ b/arkguard/src/common/ApiExtractor.ts @@ -53,8 +53,9 @@ import { getObjectProperties, getTypeAliasProperties, } from '../utils/OhsUtil'; -import {scanProjectConfig} from './ApiReader'; -import {stringPropsSet} from '../utils/OhsUtil'; +import { scanProjectConfig } from './ApiReader'; +import { stringPropsSet } from '../utils/OhsUtil'; +import type { IOptions } from '../configs/IOptions'; export namespace ApiExtractor { interface KeywordInfo { @@ -71,6 +72,7 @@ export namespace ApiExtractor { let mCurrentExportNameSet: Set = new Set(); export let mPropertySet: Set = new Set(); + export let mLibExportNameSet: Set = new Set(); /** * filter classes or interfaces with export, default, etc @@ -437,12 +439,11 @@ export namespace ApiExtractor { break; case ApiType.PROJECT_DEPENDS: case ApiType.PROJECT: + mCurrentExportNameSet.clear(); if (fileName.endsWith('.d.ts') || fileName.endsWith('.d.ets')) { forEachChild(sourceFile, visitChildNode); - break; } - mCurrentExportNameSet.clear(); forEachChild(sourceFile, visitProjectExport); forEachChild(sourceFile, visitProjectNode); if (scanProjectConfig.mKeepStringProperty) { @@ -451,6 +452,11 @@ export namespace ApiExtractor { }); stringPropsSet.clear(); } + if (scanProjectConfig.mExportObfuscation) { + mCurrentExportNameSet.forEach((element) => { + mLibExportNameSet.add(element); + }); + } mCurrentExportNameSet.clear(); break; default: @@ -539,7 +545,7 @@ export namespace ApiExtractor { * parse common project or file to extract exported api list * @return reserved api names */ - export function parseCommonProject(projectPath): string[] { + export function parseCommonProject(projectPath: string, customProfiles: IOptions): string[] { mPropertySet.clear(); if (fs.lstatSync(projectPath).isFile()) { @@ -550,7 +556,8 @@ export namespace ApiExtractor { traverseApiFiles(projectPath, ApiType.PROJECT); } - const reservedProperties: string[] = [...mPropertySet]; + const reservedProperties: string[] = customProfiles.mExportObfuscation ? [] : [...mPropertySet]; + mPropertySet.clear(); return reservedProperties; @@ -560,9 +567,9 @@ export namespace ApiExtractor { * parse api of third party libs like libs in node_modules * @param libPath */ - export function parseThirdPartyLibs(libPath): string[] { + export function parseThirdPartyLibs(libPath: string): {reservedProperties: string[]; reservedLibExportNames: string[] | undefined} { mPropertySet.clear(); - + mLibExportNameSet.clear(); if (fs.lstatSync(libPath).isFile()) { if (libPath.endsWith('.ets') || libPath.endsWith('.ts') || libPath.endsWith('.js')) { parseFile(libPath, ApiType.PROJECT_DEPENDS); @@ -573,11 +580,15 @@ export namespace ApiExtractor { traverseApiFiles(path.join(libPath, subPath), ApiType.PROJECT_DEPENDS); } } - + let reservedLibExportNames: string[] = undefined; + if (scanProjectConfig.mExportObfuscation) { + reservedLibExportNames = [...mLibExportNameSet]; + mLibExportNameSet.clear(); + } const reservedProperties: string[] = [...mPropertySet]; mPropertySet.clear(); - return reservedProperties; + return {reservedProperties: reservedProperties, reservedLibExportNames: reservedLibExportNames}; } /** diff --git a/arkguard/src/common/ApiReader.ts b/arkguard/src/common/ApiReader.ts index 3d9aeee44ed0763186f00733f23d4229ad1db673..26c34bc7244bc605df0f5fecfb21ab05ac32ea69 100644 --- a/arkguard/src/common/ApiReader.ts +++ b/arkguard/src/common/ApiReader.ts @@ -19,10 +19,8 @@ import {FileUtils} from '../utils/FileUtils'; import {ApiExtractor} from './ApiExtractor'; import {ListUtil} from '../utils/ListUtil'; import type {IOptions} from '../configs/IOptions'; -import es6Info from '../configs/preset/es6_reserved_properties.json'; - -export const scanProjectConfig: {mKeepStringProperty?: boolean} = {}; +export const scanProjectConfig: {mKeepStringProperty?: boolean, mExportObfuscation?: boolean} = {}; /** * if rename property is not open, api read and extract can be skipped @@ -50,9 +48,10 @@ export function initPlugin(sdkDir: string, outputDir: string): void { * @param customProfiles */ export function needReadApiInfo(customProfiles: IOptions): boolean { - return customProfiles.mNameObfuscation && + return (customProfiles.mNameObfuscation && customProfiles.mNameObfuscation.mEnable && - customProfiles.mNameObfuscation.mRenameProperties; + customProfiles.mNameObfuscation.mRenameProperties) || + customProfiles.mExportObfuscation; } /** @@ -60,23 +59,25 @@ export function needReadApiInfo(customProfiles: IOptions): boolean { * @param projectPaths can be dir or file * @param customProfiles */ -export function readProjectProperties(projectPaths: string[], customProfiles: IOptions, isOHProject?: boolean): string[] { +export function readProjectProperties(projectPaths: string[], customProfiles: IOptions, isOHProject?: boolean): + {projectAndLibsReservedProperties: string[]; libExportNames: string[]} { if (!needReadApiInfo(customProfiles) && !isOHProject) { - return []; + return {projectAndLibsReservedProperties:[], libExportNames: []}; } scanProjectConfig.mKeepStringProperty = customProfiles.mNameObfuscation?.mKeepStringProperty; + scanProjectConfig.mExportObfuscation = customProfiles.mExportObfuscation; for (const projectPath of projectPaths) { if (!fs.existsSync(projectPath)) { console.error(`File ${FileUtils.getFileName(projectPath)} is not found.`); - return []; + return {projectAndLibsReservedProperties:[], libExportNames: []}; } const sourcPath = isOHProject ? path.join(projectPath, 'src', 'main') : projectPath; - const projProperties: string[] = ApiExtractor.parseCommonProject(sourcPath); - const sdkProperties: string[] = readThirdPartyLibProperties(projectPath); - + const projProperties: string[] = ApiExtractor.parseCommonProject(sourcPath, customProfiles); + const libExportNamesAndReservedProps = readThirdPartyLibProperties(projectPath); + const sdkProperties = libExportNamesAndReservedProps?.reservedProperties; // read project code export names customProfiles.mNameObfuscation.mReservedProperties = ListUtil.uniqueMergeList(projProperties, customProfiles.mNameObfuscation.mReservedProperties); @@ -86,12 +87,20 @@ export function readProjectProperties(projectPaths: string[], customProfiles: IO customProfiles.mNameObfuscation.mReservedProperties = ListUtil.uniqueMergeList(sdkProperties, customProfiles.mNameObfuscation.mReservedProperties); } + + if (scanProjectConfig.mExportObfuscation && libExportNamesAndReservedProps?.reservedLibExportNames) { + customProfiles.mNameObfuscation.mReservedNames = ListUtil.uniqueMergeList(libExportNamesAndReservedProps.reservedLibExportNames, + customProfiles.mNameObfuscation.mReservedNames); + } } - return customProfiles.mNameObfuscation.mReservedProperties; + + return { + projectAndLibsReservedProperties: customProfiles.mNameObfuscation.mReservedProperties, + libExportNames: customProfiles.mNameObfuscation.mReservedNames + }; } -function readThirdPartyLibProperties(projectPath: string): string[] { - let reservedProperties: string[] = []; +function readThirdPartyLibProperties(projectPath: string): {reservedProperties: string[]; reservedLibExportNames: string[] | undefined} { if (!fs.lstatSync(projectPath).isDirectory()) { return undefined; @@ -115,9 +124,5 @@ function readThirdPartyLibProperties(projectPath: string): string[] { filePath = path.join(projectPath, 'oh_modules'); } - const properties: string[] = ApiExtractor.parseThirdPartyLibs(filePath); - reservedProperties = [...reservedProperties, ...properties]; - const propertySet: Set = new Set(reservedProperties); - - return Array.from(propertySet); + return ApiExtractor.parseThirdPartyLibs(filePath); } diff --git a/arkguard/src/common/type.ts b/arkguard/src/common/type.ts index 960a83955a71cc3508a9f89110b34af54a0101ab..0f1f71b7e8bac0e41081d484b4e485aa7b184fb1 100644 --- a/arkguard/src/common/type.ts +++ b/arkguard/src/common/type.ts @@ -22,5 +22,12 @@ export const enum Extension { DETS = '.d.ets' } +export interface PathAndExtension { + path: string; + ext: string | undefined; +} + export const supportedRunningExtension: readonly string[] = [Extension.TS, Extension.JS]; -export const supportedDeclarationExtension: readonly string[] = [Extension.DTS, Extension.DETS]; \ No newline at end of file +export const supportedDeclarationExtension: readonly string[] = [Extension.DTS, Extension.DETS]; + +export const fileExtensions: string[] = [Extension.DETS, Extension.ETS, Extension.DTS, Extension.TS, Extension.JS, Extension.JSON]; \ No newline at end of file diff --git a/arkguard/src/configs/INameObfuscationOption.ts b/arkguard/src/configs/INameObfuscationOption.ts index 539b7a0994164add0e80a9358de1eeb2a4ed3a4f..d2e0423b6b432ad129d2935675137e3afaf9acc6 100644 --- a/arkguard/src/configs/INameObfuscationOption.ts +++ b/arkguard/src/configs/INameObfuscationOption.ts @@ -23,7 +23,7 @@ export interface INameObfuscationOption { readonly mRenameProperties: boolean; - readonly mReservedNames: string[]; + mReservedNames: string[]; mReservedProperties: string[]; diff --git a/arkguard/src/configs/IOptions.ts b/arkguard/src/configs/IOptions.ts index 3148979eff11f606bbdb34d2f0858b8fe53e25ef..0f49047619c41b3f3bd4c7d5bfde689c6d8de28d 100644 --- a/arkguard/src/configs/IOptions.ts +++ b/arkguard/src/configs/IOptions.ts @@ -49,4 +49,7 @@ export interface IOptions { readonly applyReservedNamePath?: string; readonly mRenameFileName?: IFileNameObfuscationOption; + + // Whether to obfuscate the names or properties of the exported content + readonly mExportObfuscation?: boolean; } diff --git a/arkguard/src/transformers/rename/RenameFileNameTransformer.ts b/arkguard/src/transformers/rename/RenameFileNameTransformer.ts index 7e69a42873dd645372e591ce8b6b0314cc3a2d6e..1510046451130783abf3d25a29cd58da8dcc267a 100644 --- a/arkguard/src/transformers/rename/RenameFileNameTransformer.ts +++ b/arkguard/src/transformers/rename/RenameFileNameTransformer.ts @@ -52,7 +52,9 @@ import type { IFileNameObfuscationOption } from '../../configs/INameObfuscationO import { NameGeneratorType, getNameGenerator } from '../../generator/NameFactory'; import type { INameGenerator, NameGeneratorOptions } from '../../generator/INameGenerator'; import { FileUtils } from '../../utils/FileUtils'; +import { NodeUtils } from '../../utils/NodeUtils'; import { orignalFilePathForSearching } from '../../ArkObfuscator'; +import type { PathAndExtension } from '../../common/type'; namespace secharmony { // global mangled file name table used by all files in a project @@ -91,7 +93,7 @@ namespace secharmony { const directories = FileUtils.splitFilePath(fileNameOrPath); directories.forEach(directory => { tempReservedFileName.push(directory); - const pathOrExtension: PathAndExtension = removeFileSuffix(directory); + const pathOrExtension: PathAndExtension = FileUtils.getFileSuffix(directory); if (pathOrExtension.ext) { tempReservedFileName.push(pathOrExtension.ext); tempReservedFileName.push(pathOrExtension.path); @@ -189,7 +191,7 @@ namespace secharmony { export function getMangleCompletePath(originalCompletePath: string): string { originalCompletePath = toUnixPath(originalCompletePath); - const { path: filePathWithoutSuffix, ext: extension } = removeFileSuffix(originalCompletePath); + const { path: filePathWithoutSuffix, ext: extension } = FileUtils.getFileSuffix(originalCompletePath); const mangleFilePath = manglFileName(filePathWithoutSuffix); return mangleFilePath + extension; } @@ -204,7 +206,7 @@ namespace secharmony { const mangleFilePath = manglFileName(pathAndExtension.path); return mangleFilePath; } else { - const { path: filePathWithoutSuffix, ext: extension } = removeFileSuffix(pathAndExtension.path); + const { path: filePathWithoutSuffix, ext: extension } = FileUtils.getFileSuffix(pathAndExtension.path); const mangleFilePath = manglFileName(filePathWithoutSuffix); return mangleFilePath + extension; } @@ -286,27 +288,10 @@ function tryValidateFileExisting(importPath: string): PathAndExtension | undefin return undefined; } -interface PathAndExtension { - path: string; - ext: string | undefined; -} - -const fileExtensions: string[] = ['.d.ets', '.ets', '.d.ts', '.ts', '.js', '.json']; - -function removeFileSuffix(filePath: string): PathAndExtension { - for (let ext of fileExtensions) { - if (filePath.endsWith(ext)) { - const filePathWithoutSuffix: string = filePath.replace(new RegExp(`${ext}$`), ''); - return { path: filePathWithoutSuffix, ext: ext }; - } - } - return { path: filePath, ext: undefined }; -} - function tryRemoveVirtualConstructor(node: StructDeclaration): StructDeclaration { - const sourceFile = getSourceFileOfNode(node); + const sourceFile = NodeUtils.getSourceFileOfNode(node); const tempStructMembers: ClassElement[] = []; - if (sourceFile && sourceFile.isDeclarationFile && isInETSFile(sourceFile)) { + if (sourceFile && sourceFile.isDeclarationFile && NodeUtils.isInETSFile(sourceFile)) { for (let member of node.members) { // @ts-ignore if (!isConstructorDeclaration(member) || !member.virtual) { @@ -319,17 +304,6 @@ function tryRemoveVirtualConstructor(node: StructDeclaration): StructDeclaration return node; } -function getSourceFileOfNode(node: Node): SourceFile { - while (node && node.kind !== SyntaxKind.SourceFile) { - node = node.parent; - } - return node; -} - -function isInETSFile(node: Node | undefined): boolean { - return !!node && getSourceFileOfNode(node).fileName.endsWith('.ets'); -} - function toUnixPath(data: string): string { if (/^win/.test(require('os').platform())) { const fileTmps: string[] = data.split(path.sep); diff --git a/arkguard/src/transformers/rename/RenameIdentifierTransformer.ts b/arkguard/src/transformers/rename/RenameIdentifierTransformer.ts index ab1542457f4d66ce392ae4fc6ebb6afe9ac7a62a..dcb507dd9e65cfde79fbae508a0860c4bc480441 100644 --- a/arkguard/src/transformers/rename/RenameIdentifierTransformer.ts +++ b/arkguard/src/transformers/rename/RenameIdentifierTransformer.ts @@ -17,17 +17,21 @@ import { factory, forEachChild, isBreakOrContinueStatement, + isConstructorDeclaration, isIdentifier, isLabeledStatement, isSourceFile, + isStructDeclaration, setParentRecursive, visitEachChild, } from 'typescript'; import type { + ClassElement, Identifier, Node, SourceFile, + StructDeclaration, Symbol, TransformationContext, Transformer, @@ -58,7 +62,7 @@ import type {TransformPlugin} from '../TransformPlugin'; import {TransformerOrder} from '../TransformPlugin'; import {getNameGenerator, NameGeneratorType} from '../../generator/NameFactory'; import {TypeUtils} from '../../utils/TypeUtils'; -import {collectIdentifiers} from '../../utils/TransformUtil'; +import {collectIdentifiersAndStructs} from '../../utils/TransformUtil'; import {NodeUtils} from '../../utils/NodeUtils'; namespace secharmony { @@ -82,6 +86,7 @@ namespace secharmony { } const openTopLevel: boolean = option?.mTopLevel; + const exportObfuscation: boolean = option?.mExportObfuscation; return renameIdentifierFactory; function renameIdentifierFactory(context: TransformationContext): Transformer { @@ -104,8 +109,10 @@ namespace secharmony { let checker: TypeChecker = undefined; let manager: ScopeManager = createScopeManager(); let shadowIdentifiers: Identifier[] = undefined; + let shadowStructs: StructDeclaration[] = undefined; let identifierIndex: number = 0; + let structIndex: number = 0; return renameTransformer; /** @@ -114,7 +121,7 @@ namespace secharmony { * @param node ast node of a file. */ function renameTransformer(node: Node): Node { - if (!isSourceFile(node) || NodeUtils.isDeclarationFile(node)) { + if (!isSourceFile(node)) { return node; } @@ -122,11 +129,16 @@ namespace secharmony { checker = TypeUtils.createChecker(shadowSourceAst); manager.analyze(shadowSourceAst, checker); - manager.getReservedNames().forEach((name) => { - reservedNames.push(name); - }); + // the reservedNames of manager contain the struct name. + if (!exportObfuscation) { + manager.getReservedNames().forEach((name) => { + reservedNames.push(name); + }); + } // collect all identifiers of shadow sourceFile - shadowIdentifiers = collectIdentifiers(shadowSourceAst, context); + const identifiersAndStructs = collectIdentifiersAndStructs(shadowSourceAst, context); + shadowIdentifiers = identifiersAndStructs.shadowIdentifiers; + shadowStructs = identifiersAndStructs.shadowStructs; if (nameCache === undefined) { nameCache = new Map(); @@ -134,7 +146,9 @@ namespace secharmony { let root: Scope = manager.getRootScope(); renameInScope(root); - return setParentRecursive(visit(node), true); + let ret: Node = visit(node); + ret = tryRemoveVirtualConstructor(ret); + return setParentRecursive(ret, true); } /** @@ -164,13 +178,14 @@ namespace secharmony { return; } - scope.defs.forEach((def) => { - if (scope.importNames.has(def.name)) { - scope.defs.delete(def); - } - }); + if (!exportObfuscation) { + scope.defs.forEach((def) => { + if (scope.importNames.has(def.name)) { + scope.defs.delete(def); + } + }); + } - generator.reset(); renames(scope, scope.defs, generator); } @@ -182,7 +197,7 @@ namespace secharmony { const original: string = def.name; let mangled: string = original; // No allow to rename reserved names. - if (reservedNames.includes(original) || scope.exportNames.has(def.name) || isSkippedGlobal(openTopLevel, scope)) { + if (reservedNames.includes(original) || (!exportObfuscation && scope.exportNames.has(def.name)) || isSkippedGlobal(openTopLevel, scope)) { mangledIdentifierNames.add(mangled); mangledSymbolNames.set(def, mangled); return; @@ -194,7 +209,9 @@ namespace secharmony { const path: string = scope.loc + '#' + original; const historyName: string = historyNameCache?.get(path); - const specifyName: string = historyName ? historyName : nameCache.get(path); + let specifyName: string = historyName ? historyName : nameCache.get(path); + specifyName = specifyName ? specifyName : globalNameCache.get(original); + if (specifyName) { mangled = specifyName; } else { @@ -204,6 +221,7 @@ namespace secharmony { // add new names to name cache nameCache.set(path, mangled); + globalNameCache.set(original, mangled); mangledIdentifierNames.add(mangled); mangledSymbolNames.set(def, mangled); localCache.set(original, mangled); @@ -321,6 +339,29 @@ namespace secharmony { return updateNameNode(node, shadowNode); } + function tryRemoveVirtualConstructor(node: Node): Node { + if (isStructDeclaration(node)) { + const shadowNode: StructDeclaration = shadowStructs[structIndex]; + structIndex++; + const sourceFile = NodeUtils.getSourceFileOfNode(shadowNode); + const tempStructMembers: ClassElement[] = []; + if (sourceFile && sourceFile.isDeclarationFile) { + for (let index = 0; index < node.members.length; index++) { + const member = node.members[index]; + // @ts-ignore + if (isConstructorDeclaration(member) && shadowNode.members[index].virtual) { + continue; + } + tempStructMembers.push(member); + } + const structMembersWithVirtualConstructor = factory.createNodeArray(tempStructMembers); + return factory.updateStructDeclaration(node, node.modifiers, node.name, node.typeParameters, node.heritageClauses, + structMembersWithVirtualConstructor); + } + } + return visitEachChild(node, tryRemoveVirtualConstructor, context); + } + function findNoSymbolIdentifiers(scope: Scope): void { const noSymbolVisit = (targetNode: Node): void => { if (!isIdentifier(targetNode)) { @@ -389,6 +430,7 @@ namespace secharmony { export let nameCache: Map = undefined; export let historyNameCache: Map = undefined; + export let globalNameCache: Map = new Map(); } export = secharmony; \ No newline at end of file diff --git a/arkguard/src/transformers/rename/RenamePropertiesTransformer.ts b/arkguard/src/transformers/rename/RenamePropertiesTransformer.ts index 778338075e8c311ccfc8067ee6cc3d4ea919f27b..4a37c1b513fb18790eec0e95709f573fe9124ec6 100644 --- a/arkguard/src/transformers/rename/RenamePropertiesTransformer.ts +++ b/arkguard/src/transformers/rename/RenamePropertiesTransformer.ts @@ -94,10 +94,6 @@ namespace secharmony { return renamePropertiesTransformer; function renamePropertiesTransformer(node: Node): Node { - if (isSourceFile(node) && NodeUtils.isDeclarationFile(node)) { - return node; - } - collectReservedNames(node); if (globalMangledTable === undefined) { globalMangledTable = new Map(); diff --git a/arkguard/src/transformers/rename/ShorthandPropertyTransformer.ts b/arkguard/src/transformers/rename/ShorthandPropertyTransformer.ts index 070ea5eb711153ad5e739307961e06e53c42b23a..66b57dc8def3751493fb33453e41a954f065143e 100644 --- a/arkguard/src/transformers/rename/ShorthandPropertyTransformer.ts +++ b/arkguard/src/transformers/rename/ShorthandPropertyTransformer.ts @@ -51,9 +51,6 @@ namespace secharmony { return shorthandPropertyTransformer; function shorthandPropertyTransformer(node: Node): Node { - if (isSourceFile(node) && NodeUtils.isDeclarationFile(node)) { - return node; - } return setParentRecursive(transformShortHandProperty(node), true); } diff --git a/arkguard/src/utils/FileUtils.ts b/arkguard/src/utils/FileUtils.ts index aebfc92c0166db4676a858100a034ef6ae023a6f..0f171102030646a6780881cb58a3a30ee2fd7bf5 100644 --- a/arkguard/src/utils/FileUtils.ts +++ b/arkguard/src/utils/FileUtils.ts @@ -13,9 +13,11 @@ * limitations under the License. */ -import {existsSync, readFileSync, writeFileSync} from 'fs'; -import {readJsonSync} from 'fs-extra'; -import type {IOptions} from '../configs/IOptions'; +import { existsSync, readFileSync, writeFileSync } from 'fs'; +import { readJsonSync } from 'fs-extra'; +import type { IOptions } from '../configs/IOptions'; +import { fileExtensions } from '../common/type'; +import type { PathAndExtension } from '../common/type'; export class FileUtils { /** @@ -142,4 +144,14 @@ export class FileUtils { } return false; } + + public static getFileSuffix(filePath: string): PathAndExtension { + for (let ext of fileExtensions) { + if (filePath.endsWith(ext)) { + const filePathWithoutSuffix: string = filePath.replace(new RegExp(`${ext}$`), ''); + return { path: filePathWithoutSuffix, ext: ext }; + } + } + return { path: filePath, ext: undefined }; + } } diff --git a/arkguard/src/utils/NodeUtils.ts b/arkguard/src/utils/NodeUtils.ts index ee63e1ca2d290c4e5621bd3f285211883c1267e0..d3911af8c5dc1330c30cbf912f3ea3fa2b15e5a3 100644 --- a/arkguard/src/utils/NodeUtils.ts +++ b/arkguard/src/utils/NodeUtils.ts @@ -13,9 +13,10 @@ * limitations under the License. */ -import type {Expression, Node, ObjectBindingPattern, SourceFile} from 'typescript'; +import type {ClassElement, Expression, Node, ObjectBindingPattern, SourceFile, StructDeclaration} from 'typescript'; import { SyntaxKind, + factory, getModifiers, isBinaryExpression, isBindingElement, @@ -199,4 +200,15 @@ export class NodeUtils { public static isDeclarationFile(node: SourceFile): boolean { return node.isDeclarationFile; } + + public static getSourceFileOfNode(node: Node): SourceFile { + while (node && node.kind !== SyntaxKind.SourceFile) { + node = node.parent; + } + return node; + } + + public static isInETSFile(node: Node | undefined): boolean { + return !!node && NodeUtils.getSourceFileOfNode(node).fileName.endsWith('.ets'); + } } diff --git a/arkguard/src/utils/ScopeAnalyzer.ts b/arkguard/src/utils/ScopeAnalyzer.ts index 5aec6b812e8aef9aa91bd547b3fd7e1e7a19adb5..c187da60ae58bfc6f0eb2249b1319c21f6ea7c17 100644 --- a/arkguard/src/utils/ScopeAnalyzer.ts +++ b/arkguard/src/utils/ScopeAnalyzer.ts @@ -18,6 +18,7 @@ import { getModifiers, isClassDeclaration, isConstructorDeclaration, + isExportSpecifier, isFunctionDeclaration, isFunctionLike, isIdentifier, @@ -364,15 +365,24 @@ namespace secharmony { // with export identification, special handling. if (def.exportSymbol) { current.exportNames.add(def.name); + current.addDefinition(def.exportSymbol); } current.addDefinition(def); }); } + function addExportSymbolInScope(node: Node): void { + let defSymbols: Symbol = node?.symbol; + + if (!defSymbols) { + return; + } + current.addDefinition(defSymbols); + } + /** * analyze chain of scopes - * * @param node */ function analyzeScope(node: Node): void { @@ -401,6 +411,7 @@ namespace secharmony { // class like case SyntaxKind.ClassExpression: case SyntaxKind.ClassDeclaration: + case SyntaxKind.StructDeclaration: analyzeClassLike(node as ClassLikeDeclaration); break; @@ -522,6 +533,7 @@ namespace secharmony { function analyzeExportNames(node: ExportSpecifier): void { // get export names. current.exportNames.add(node.name.text); + addExportSymbolInScope(node); forEachChild(node, analyzeScope); } @@ -724,13 +736,17 @@ namespace secharmony { addSymbolInScope(node); // Class members are seen as attribute names, and the reference of external symbols can be renamed as the same node.members?.forEach((elm: ClassElement) => { - if (elm?.symbol) { + // @ts-ignore + if (elm?.symbol && !elm.virtual) { current.addDefinition(elm.symbol); } }); node.members?.forEach((sub: Node) => { - analyzeScope(sub); + // @ts-ignore + if (!sub.virtual) { + analyzeScope(sub); + } }); } catch (e) { console.error(e); diff --git a/arkguard/src/utils/TransformUtil.ts b/arkguard/src/utils/TransformUtil.ts index c951f5f1f1aac7c48a30af73387874cf15f949f6..2698a770fc27d0e7bdcb79a44658a2654e9c4d49 100644 --- a/arkguard/src/utils/TransformUtil.ts +++ b/arkguard/src/utils/TransformUtil.ts @@ -19,6 +19,7 @@ import { isCallExpression, isExpressionStatement, isIdentifier, + isStructDeclaration, SyntaxKind, visitEachChild } from 'typescript'; @@ -28,6 +29,7 @@ import type { Identifier, Node, SourceFile, + StructDeclaration, TransformationContext } from 'typescript'; @@ -50,15 +52,25 @@ export function collectExistNames(sourceFile: SourceFile): Set { return identifiers; } +type IdentifiersAndStructs = {shadowIdentifiers: Identifier[], shadowStructs: StructDeclaration[]}; + /** * collect exist identifiers in current source file * @param sourceFile * @param context */ -export function collectIdentifiers(sourceFile: SourceFile, context: TransformationContext): Identifier[] { +export function collectIdentifiersAndStructs(sourceFile: SourceFile, context: TransformationContext): IdentifiersAndStructs { const identifiers: Identifier[] = []; + const structs: StructDeclaration[] = []; let visit = (node: Node): Node => { + if (isStructDeclaration(node)) { + structs.push(node); + } + // @ts-ignore + if (node.virtual) { + return node; + } if (!isIdentifier(node) || !node.parent) { return visitEachChild(node, visit, context); } @@ -68,7 +80,7 @@ export function collectIdentifiers(sourceFile: SourceFile, context: Transformati }; visit(sourceFile); - return identifiers; + return {shadowIdentifiers: identifiers, shadowStructs: structs}; } export enum OhPackType { diff --git a/arkguard/src/utils/TypeUtils.ts b/arkguard/src/utils/TypeUtils.ts index eb477729561c661174ddaecef2b70cf279d8d3b7..81b1fc8dfc64c9e6ab8825fc11366fd2b7b42269 100644 --- a/arkguard/src/utils/TypeUtils.ts +++ b/arkguard/src/utils/TypeUtils.ts @@ -31,6 +31,9 @@ import type { } from 'typescript'; import path from 'path'; +import { Extension } from '../common/type'; +import type { PathAndExtension } from '../common/type'; +import { FileUtils } from './FileUtils'; export class TypeUtils { /** @@ -42,7 +45,8 @@ export class TypeUtils { let printer: Printer = createPrinter(); let content: string = printer.printFile(oldAst); - const fileSuffix: string = '.ts'; + const pathOrExtension: PathAndExtension = FileUtils.getFileSuffix(oldAst.fileName); + const fileSuffix = pathOrExtension.ext === Extension.DETS ? Extension.DETS : Extension.TS; const { dir, name } = path.parse(oldAst.fileName); const targetName: string = path.join(dir, name) + '__tmp' + fileSuffix; return createSourceFile(targetName, content, ScriptTarget.ES2015, true); diff --git a/arkguard/test/grammar/compact/decoratorAndModifier-expected.txt b/arkguard/test/grammar/compact/decoratorAndModifier-expected.txt deleted file mode 100644 index 91837d05e586e1b967b5db52f51e0e33beab1aa9..0000000000000000000000000000000000000000 --- a/arkguard/test/grammar/compact/decoratorAndModifier-expected.txt +++ /dev/null @@ -1 +0,0 @@ -function a(f: Function) { console.log(`Class name: ${f.name}`); } function b(f: any, g: string) { console.log(`Property name: ${g}`); } function c(f: any, g: string) { console.log(`Property name: ${g}`); } @a class e { @b @c private g: string; @c @b public h: number; @b async i(): Promise { } } function d() { let f = 1; let g = 2; let h = 3; let i = 4; let j = 5; } \ No newline at end of file diff --git a/arkguard/test/grammar/compact/decoratorAndModifier_expected.txt b/arkguard/test/grammar/compact/decoratorAndModifier_expected.txt new file mode 100644 index 0000000000000000000000000000000000000000..c1e17c3db58b2179d6aca01a606f1070f118be09 --- /dev/null +++ b/arkguard/test/grammar/compact/decoratorAndModifier_expected.txt @@ -0,0 +1 @@ + function a(f: Function) { console.log(`Class name: ${f.name}`); } function b(g: any, h: string) { console.log(`Property name: ${h}`); } function c(g: any, h: string) { console.log(`Property name: ${h}`); } @a class e { @b @c private g: string; @c @b public h: number; @b async i(): Promise { } } function d() { let i = 1; let j = 2; let k = 3; let l = 4; let m = 5; } \ No newline at end of file diff --git a/arkguard/test/grammar/compact/numericLiteralsWithTrailingDecimalPoints-expected.txt b/arkguard/test/grammar/compact/numericLiteralsWithTrailingDecimalPoints-expected.txt deleted file mode 100644 index 917324371e451a1b987fe4feefed839c51f3f901..0000000000000000000000000000000000000000 --- a/arkguard/test/grammar/compact/numericLiteralsWithTrailingDecimalPoints-expected.txt +++ /dev/null @@ -1 +0,0 @@ -1..toString(); 1.0.toString(); 1. + 2.0 + 3.; var a: number = 1; var b = a.toString(); var c = 3..toString(); var d = 3..toString(); var e = 3..toString(); var f = 3.['toString'](); var g = 3 .toString(); var h = new Number(4).toString(); var i = 3. + 3.; var j = 0 .toString(); var k = 3. .toString(); var l = 3 .toString(); var m = 3 .toString(); var n = 3 .toString(); var o = 3. .toString(); var p = 3 .toString(); var q = 3. .toString(); var r = 3 .toString(); var s = 3. .toString(); \ No newline at end of file diff --git a/arkguard/test/grammar/compact/numericLiteralsWithTrailingDecimalPoints_expected.txt b/arkguard/test/grammar/compact/numericLiteralsWithTrailingDecimalPoints_expected.txt new file mode 100644 index 0000000000000000000000000000000000000000..711dbb2bd6fcb85b1b2d94c0e6824c13b073deb8 --- /dev/null +++ b/arkguard/test/grammar/compact/numericLiteralsWithTrailingDecimalPoints_expected.txt @@ -0,0 +1 @@ + 1..toString(); 1.0.toString(); 1. + 2.0 + 3.; var n: number = 1; var o = n.toString(); var p = 3..toString(); var q = 3..toString(); var r = 3..toString(); var s = 3.['toString'](); var t = 3 .toString(); var u = new Number(4).toString(); var v = 3. + 3.; var w = 0 .toString(); var x = 3. .toString(); var y = 3 .toString(); var z = 3 .toString(); var a1 = 3 .toString(); var b1 = 3. .toString(); var c1 = 3 .toString(); var d1 = 3. .toString(); var e1 = 3 .toString(); var f1 = 3. .toString(); \ No newline at end of file diff --git a/arkguard/test/grammar/export_obfuscation/export_obfuscation_1.ts b/arkguard/test/grammar/export_obfuscation/export_obfuscation_1.ts new file mode 100644 index 0000000000000000000000000000000000000000..3fa18df6a08e3c129b43cadbfa1ff8bc8c042d5f --- /dev/null +++ b/arkguard/test/grammar/export_obfuscation/export_obfuscation_1.ts @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * 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. + */ + +export class PersonClass01 { + name:string; + age:number; +} + +export function foo01(para01: number, para02: number) { + const v1 = 1; + const v2 = 2; + return para01 + para02 + v1 + v2; +} + +function foo02(para03: string, para04: number){ + const v1 = 4; + const v2 = 5; + return para03 + para04.toString(); +} \ No newline at end of file diff --git a/arkguard/test/grammar/export_obfuscation/export_obfuscation_1_expected.txt b/arkguard/test/grammar/export_obfuscation/export_obfuscation_1_expected.txt new file mode 100644 index 0000000000000000000000000000000000000000..4ea80a7e5f9938b02a4651464463ac2281603e4a --- /dev/null +++ b/arkguard/test/grammar/export_obfuscation/export_obfuscation_1_expected.txt @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * 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. + */ +export class c { + name: string; + g: number; +} +export function a(d: number, e: number) { + const f = 1; + const g = 2; + return d + e + f + g; +} +function b(h: string, i: number) { + const f = 4; + const g = 5; + return h + i.toString(); +} diff --git a/arkguard/test/grammar/export_obfuscation/export_obfuscation_2.ts b/arkguard/test/grammar/export_obfuscation/export_obfuscation_2.ts new file mode 100644 index 0000000000000000000000000000000000000000..6edf3b37220c7f18dbda5ae98bc5cdd197c57144 --- /dev/null +++ b/arkguard/test/grammar/export_obfuscation/export_obfuscation_2.ts @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * 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. + */ + +export interface Human01 { + gender01: string; + color01: string; + country01: string; +} + +export const value01: number = 100; + +interface Human02 { + gender02: string; + color02: string; + country02: string; +} + +const value02: number = 200; \ No newline at end of file diff --git a/arkguard/test/grammar/export_obfuscation/export_obfuscation_2_expected.txt b/arkguard/test/grammar/export_obfuscation/export_obfuscation_2_expected.txt new file mode 100644 index 0000000000000000000000000000000000000000..eb08f36dca35f4875d0cc8d812a05469d4d03145 --- /dev/null +++ b/arkguard/test/grammar/export_obfuscation/export_obfuscation_2_expected.txt @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * 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. + */ +export interface j { + h: string; + i: string; + j: string; +} +export const k: number = 100; +interface l { + k: string; + l: string; + m: string; +} +const m: number = 200; diff --git a/arkguard/test/grammar/export_obfuscation/export_obfuscation_3.js b/arkguard/test/grammar/export_obfuscation/export_obfuscation_3.js new file mode 100644 index 0000000000000000000000000000000000000000..dad8a2bf9ef2a90b7f3a8cd870a874bbf035260c --- /dev/null +++ b/arkguard/test/grammar/export_obfuscation/export_obfuscation_3.js @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * 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. + */ + +class SortMethod { + constructor() { + this.head = false; + } + compare(leftIndex, rightIndex) { + if (!this.head) { + throw new Error('List is empty'); + } + return leftIndex > rightIndex; + } + swap(leftIndex, rightIndex) { + const leftHand = rightIndex; + rightIndex = leftIndex; + } +} + +function plus01(n1, n2) { + return n1 + n2; +} \ No newline at end of file diff --git a/arkguard/test/grammar/export_obfuscation/export_obfuscation_3_expected.txt b/arkguard/test/grammar/export_obfuscation/export_obfuscation_3_expected.txt new file mode 100644 index 0000000000000000000000000000000000000000..200530a7a41942c149b4d2a91e6d12a6a3d613b0 --- /dev/null +++ b/arkguard/test/grammar/export_obfuscation/export_obfuscation_3_expected.txt @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * 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. + */ +class o { + constructor() { + this.head = false; + } + compare(p, q) { + if (!this.head) { + throw new Error('List is empty'); + } + return p > q; + } + o(p, q) { + const r = q; + q = p; + } +} +function n(s, t) { + return s + t; +} diff --git a/arkguard/test/grammar/export_obfuscation/export_obfuscation_declaration_1.d.ts b/arkguard/test/grammar/export_obfuscation/export_obfuscation_declaration_1.d.ts new file mode 100644 index 0000000000000000000000000000000000000000..641400322ba32a14d1a8dc0f21acf46c09a569b6 --- /dev/null +++ b/arkguard/test/grammar/export_obfuscation/export_obfuscation_declaration_1.d.ts @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * 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. + */ + +export declare class PersonClass01 { + name01: string | undefined; + age01: number; + addr01: string; + constructor(namePara?: PersonClass02); +} +export declare function foo01(para1: number, para2: number): number; +declare class PersonClass02 { + name02: string; + age02: number; + addr02: string; +} +export {}; \ No newline at end of file diff --git a/arkguard/test/grammar/export_obfuscation/export_obfuscation_declaration_1_expected.txt b/arkguard/test/grammar/export_obfuscation/export_obfuscation_declaration_1_expected.txt new file mode 100644 index 0000000000000000000000000000000000000000..0b4b1c76f7464a6a1d37c8e057e294e650225041 --- /dev/null +++ b/arkguard/test/grammar/export_obfuscation/export_obfuscation_declaration_1_expected.txt @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * 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. + */ +export declare class c { + p: string | undefined; + q: number; + t: string; + constructor(v?: u); +} +export declare function a(w: number, x: number): number; +declare class u { + u: string; + v: number; + a1: string; +} +export {}; diff --git a/arkguard/test/grammar/export_obfuscation/export_obfuscation_declaration_2.d.ets b/arkguard/test/grammar/export_obfuscation/export_obfuscation_declaration_2.d.ets new file mode 100644 index 0000000000000000000000000000000000000000..e1d350042ece7bdb41d7553329ccbb72228998f3 --- /dev/null +++ b/arkguard/test/grammar/export_obfuscation/export_obfuscation_declaration_2.d.ets @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * 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. + */ + +export declare struct IndexUI1 { + param1: string; + message1: string; + method1(): void; +} + +export declare function foo01(para3, para4); + +export declare const value04; + +export declare struct IndexUI2 { + param2: string; + message2: string; + method2(): void; +} \ No newline at end of file diff --git a/arkguard/test/grammar/export_obfuscation/export_obfuscation_declaration_2_expected.txt b/arkguard/test/grammar/export_obfuscation/export_obfuscation_declaration_2_expected.txt new file mode 100644 index 0000000000000000000000000000000000000000..0ca9d97f65cd26e228740a9be786a0c79afbcf84 --- /dev/null +++ b/arkguard/test/grammar/export_obfuscation/export_obfuscation_declaration_2_expected.txt @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * 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. + */ +export declare struct y { + b1: string; + c1: string; + d1(): void; +} +export declare function a(c1, d1); +export declare const z; +export declare struct a1 { + e1: string; + f1: string; + g1(): void; +} diff --git a/arkguard/test/grammar/export_obfuscation/export_struct_transform_class.ts b/arkguard/test/grammar/export_obfuscation/export_struct_transform_class.ts new file mode 100644 index 0000000000000000000000000000000000000000..69fe833f71012d9a2ed132aa243a70aab3b58b78 --- /dev/null +++ b/arkguard/test/grammar/export_obfuscation/export_struct_transform_class.ts @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * 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. + */ + +class ViewPU { + +} + +export class Retransmission1 extends ViewPU { + constructor() { + super(); + } + scroller1: string; + controller1: number; + callMethod1(): void {}; +} + +class Retransmission2 extends ViewPU { + constructor() { + super(); + } + scroller2: string; + controller2: number; + callMethod2(): void {}; +} \ No newline at end of file diff --git a/arkguard/test/grammar/export_obfuscation/export_struct_transform_class_expected.txt b/arkguard/test/grammar/export_obfuscation/export_struct_transform_class_expected.txt new file mode 100644 index 0000000000000000000000000000000000000000..6f1fb18f0159b7216960d9c3e2c2bcf3e22563d8 --- /dev/null +++ b/arkguard/test/grammar/export_obfuscation/export_struct_transform_class_expected.txt @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * 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. + */ +class e1 { +} +export class f1 extends e1 { + constructor() { + super(); + } + scroller1: string; + controller1: number; + callMethod1(): void { } + ; +} +class g1 extends e1 { + constructor() { + super(); + } + scroller2: string; + controller2: number; + callMethod2(): void { } + ; +} diff --git a/arkguard/test/grammar/export_obfuscation/import_obfuscation_1.ts b/arkguard/test/grammar/export_obfuscation/import_obfuscation_1.ts new file mode 100644 index 0000000000000000000000000000000000000000..af9907e2b1f12422d181003642486c4a819a4ccd --- /dev/null +++ b/arkguard/test/grammar/export_obfuscation/import_obfuscation_1.ts @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * 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. + */ + +import { PersonClass01, foo01 } from './export_obfuscation_1'; + +let instance01 = new PersonClass01(); +const getedName: string = instance01.name +foo01(1, 2); + +export function actionBarProp1(): void { + return; +} + +export function actionBarProp2():void { + return; +} \ No newline at end of file diff --git a/arkguard/test/grammar/export_obfuscation/import_obfuscation_1_expected.txt b/arkguard/test/grammar/export_obfuscation/import_obfuscation_1_expected.txt new file mode 100644 index 0000000000000000000000000000000000000000..28e450daa4ec08223f30c72489c811e818e46020 --- /dev/null +++ b/arkguard/test/grammar/export_obfuscation/import_obfuscation_1_expected.txt @@ -0,0 +1,24 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * 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. + */ +import { c, a } from './export_obfuscation_1'; +let j1 = new c(); +const k1: string = j1.name; +a(1, 2); +export function h1(): void { + return; +} +export function i1(): void { + return; +} diff --git a/arkguard/test/grammar/export_obfuscation/import_obfuscation_2.ts b/arkguard/test/grammar/export_obfuscation/import_obfuscation_2.ts new file mode 100644 index 0000000000000000000000000000000000000000..f9ddce93ee3ef209b32dd380412baaba5b599b47 --- /dev/null +++ b/arkguard/test/grammar/export_obfuscation/import_obfuscation_2.ts @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * 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. + */ + +import { Human01, value01} from './export_obfuscation_2'; + +type alis01 = Human01; +let newValue = value01 + 1; + + +export { actionBarProp1, actionBarProp2 } from './import_obfuscation_1'; + +function publicFoo1(): void{} +function publicFoo2(): void{} \ No newline at end of file diff --git a/arkguard/test/grammar/export_obfuscation/import_obfuscation_2_expected.txt b/arkguard/test/grammar/export_obfuscation/import_obfuscation_2_expected.txt new file mode 100644 index 0000000000000000000000000000000000000000..f69bdd1ed7bbf3c2d6affd37fbf0de416a564a11 --- /dev/null +++ b/arkguard/test/grammar/export_obfuscation/import_obfuscation_2_expected.txt @@ -0,0 +1,20 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * 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. + */ +import { j, k } from './export_obfuscation_2'; +type l1 = j; +let m1 = k + 1; +export { h1, i1 } from './import_obfuscation_1'; +function publicFoo1(): void { } +function publicFoo2(): void { } diff --git a/arkguard/test/grammar/export_obfuscation/obfConfig.json b/arkguard/test/grammar/export_obfuscation/obfConfig.json new file mode 100644 index 0000000000000000000000000000000000000000..12cc599e722ace0f4c32a6c67bea6af536e43130 --- /dev/null +++ b/arkguard/test/grammar/export_obfuscation/obfConfig.json @@ -0,0 +1,21 @@ +{ + "mCompact": false, + "mRemoveComments": false, + "mOutputDir": "../../local", + "mDisableHilog": false, + "mDisableConsole": false, + "mSimplify": false, + "mNameObfuscation": { + "mEnable": true, + "mNameGeneratorType": 1, + "mDictionaryList": [], + "mReservedNames": [], + "mRenameProperties": true, + "mReservedProperties": [], + "mKeepStringProperty": false + }, + "mEnableSourceMap": false, + "mEnableNameCache": true, + "mTopLevel": true, + "mExportObfuscation": true +} \ No newline at end of file diff --git a/arkguard/test/grammar/export_obfuscation/oh_modules/export_interface.ts b/arkguard/test/grammar/export_obfuscation/oh_modules/export_interface.ts new file mode 100644 index 0000000000000000000000000000000000000000..a07fdc98b542dda58d17968b5155ab74c22a98cf --- /dev/null +++ b/arkguard/test/grammar/export_obfuscation/oh_modules/export_interface.ts @@ -0,0 +1,24 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * 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. + */ + +export function publicFoo1(): void { + return; +} + +function publicFoo2(): void { + return; +} + +export {publicFoo2}; \ No newline at end of file