Showing
104 changed files
with
2562 additions
and
0 deletions
obfuscator/.gitignore
0 → 100644
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
obfuscator/.gradle/5.2.1/gc.properties
0 → 100644
File mode changed
No preview for this file type
No preview for this file type
obfuscator/.gradle/vcs-1/gc.properties
0 → 100644
File mode changed
obfuscator/.idea/codeStyles/Project.xml
0 → 100644
1 | +<component name="ProjectCodeStyleConfiguration"> | ||
2 | + <code_scheme name="Project" version="173"> | ||
3 | + <JetCodeStyleSettings> | ||
4 | + <option name="CODE_STYLE_DEFAULTS" value="KOTLIN_OFFICIAL" /> | ||
5 | + </JetCodeStyleSettings> | ||
6 | + <codeStyleSettings language="kotlin"> | ||
7 | + <option name="CODE_STYLE_DEFAULTS" value="KOTLIN_OFFICIAL" /> | ||
8 | + </codeStyleSettings> | ||
9 | + </code_scheme> | ||
10 | +</component> | ||
... | \ No newline at end of file | ... | \ No newline at end of file |
obfuscator/.idea/gradle.xml
0 → 100644
1 | +<?xml version="1.0" encoding="UTF-8"?> | ||
2 | +<project version="4"> | ||
3 | + <component name="GradleMigrationSettings" migrationVersion="1" /> | ||
4 | + <component name="GradleSettings"> | ||
5 | + <option name="linkedExternalProjectsSettings"> | ||
6 | + <GradleProjectSettings> | ||
7 | + <option name="distributionType" value="DEFAULT_WRAPPED" /> | ||
8 | + <option name="externalProjectPath" value="$PROJECT_DIR$" /> | ||
9 | + <option name="gradleHome" value="/usr/local/Cellar/gradle/6.3/libexec" /> | ||
10 | + <option name="gradleJvm" value="11" /> | ||
11 | + <option name="modules"> | ||
12 | + <set> | ||
13 | + <option value="$PROJECT_DIR$" /> | ||
14 | + </set> | ||
15 | + </option> | ||
16 | + <option name="useQualifiedModuleNames" value="true" /> | ||
17 | + </GradleProjectSettings> | ||
18 | + </option> | ||
19 | + </component> | ||
20 | +</project> | ||
... | \ No newline at end of file | ... | \ No newline at end of file |
obfuscator/.idea/jarRepositories.xml
0 → 100644
1 | +<?xml version="1.0" encoding="UTF-8"?> | ||
2 | +<project version="4"> | ||
3 | + <component name="RemoteRepositoriesConfiguration"> | ||
4 | + <remote-repository> | ||
5 | + <option name="id" value="central" /> | ||
6 | + <option name="name" value="Maven Central repository" /> | ||
7 | + <option name="url" value="https://repo1.maven.org/maven2" /> | ||
8 | + </remote-repository> | ||
9 | + <remote-repository> | ||
10 | + <option name="id" value="jboss.community" /> | ||
11 | + <option name="name" value="JBoss Community repository" /> | ||
12 | + <option name="url" value="https://repository.jboss.org/nexus/content/repositories/public/" /> | ||
13 | + </remote-repository> | ||
14 | + <remote-repository> | ||
15 | + <option name="id" value="MavenRepo" /> | ||
16 | + <option name="name" value="MavenRepo" /> | ||
17 | + <option name="url" value="https://repo.maven.apache.org/maven2/" /> | ||
18 | + </remote-repository> | ||
19 | + </component> | ||
20 | +</project> | ||
... | \ No newline at end of file | ... | \ No newline at end of file |
obfuscator/.idea/misc.xml
0 → 100644
1 | +<?xml version="1.0" encoding="UTF-8"?> | ||
2 | +<project version="4"> | ||
3 | + <component name="ExternalStorageConfigurationManager" enabled="true" /> | ||
4 | + <component name="ProjectRootManager" version="2" languageLevel="JDK_13" project-jdk-name="13" project-jdk-type="JavaSDK"> | ||
5 | + <output url="file://$PROJECT_DIR$/out" /> | ||
6 | + </component> | ||
7 | +</project> | ||
... | \ No newline at end of file | ... | \ No newline at end of file |
obfuscator/.idea/vcs.xml
0 → 100644
obfuscator/.idea/workspace.xml
0 → 100644
1 | +<?xml version="1.0" encoding="UTF-8"?> | ||
2 | +<project version="4"> | ||
3 | + <component name="ChangeListManager"> | ||
4 | + <list default="true" id="3e580ba3-add3-4012-a557-2fe613477d9f" name="Default Changelist" comment=""> | ||
5 | + <change beforePath="$PROJECT_DIR$/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/workspace.xml" afterDir="false" /> | ||
6 | + <change beforePath="$PROJECT_DIR$/obfuscator/src/main/kotlin/cached/Code.kt" beforeDir="false" afterPath="$PROJECT_DIR$/obfuscator/src/main/kotlin/cached/Code.kt" afterDir="false" /> | ||
7 | + <change beforePath="$PROJECT_DIR$/obfuscator/src/main/kotlin/util/syntax/ClassUtil.kt" beforeDir="false" afterPath="$PROJECT_DIR$/obfuscator/src/main/kotlin/util/syntax/ClassUtil.kt" afterDir="false" /> | ||
8 | + <change beforePath="$PROJECT_DIR$/test_app_java/app/src/main/AndroidManifest.xml" beforeDir="false" afterPath="$PROJECT_DIR$/test_app_java/app/src/main/AndroidManifest.xml" afterDir="false" /> | ||
9 | + <change beforePath="$PROJECT_DIR$/test_app_java/app/src/main/java/com/ono/test_app/AndroidRsaCipherHelper.kt" beforeDir="false" afterPath="$PROJECT_DIR$/test_app_java/app/src/main/java/com/ono/test_app/cache/AndroidRsaCipherHelper.kt" afterDir="false" /> | ||
10 | + <change beforePath="$PROJECT_DIR$/test_app_java/app/src/main/java/com/ono/test_app/MainActivity.java" beforeDir="false" /> | ||
11 | + <change beforePath="$PROJECT_DIR$/test_app_java/app/src/main/java/com/ono/test_app/SecureSharedPreference.kt" beforeDir="false" afterPath="$PROJECT_DIR$/test_app_java/app/src/main/java/com/ono/test_app/cache/SecureSharedPreference.kt" afterDir="false" /> | ||
12 | + </list> | ||
13 | + <option name="SHOW_DIALOG" value="false" /> | ||
14 | + <option name="HIGHLIGHT_CONFLICTS" value="true" /> | ||
15 | + <option name="HIGHLIGHT_NON_ACTIVE_CHANGELIST" value="false" /> | ||
16 | + <option name="LAST_RESOLUTION" value="IGNORE" /> | ||
17 | + </component> | ||
18 | + <component name="ExternalProjectsData"> | ||
19 | + <projectState path="$PROJECT_DIR$"> | ||
20 | + <ProjectState /> | ||
21 | + </projectState> | ||
22 | + </component> | ||
23 | + <component name="FileTemplateManagerImpl"> | ||
24 | + <option name="RECENT_TEMPLATES"> | ||
25 | + <list> | ||
26 | + <option value="Kotlin Class" /> | ||
27 | + <option value="Kotlin File" /> | ||
28 | + <option value="Class" /> | ||
29 | + </list> | ||
30 | + </option> | ||
31 | + </component> | ||
32 | + <component name="Git.Settings"> | ||
33 | + <option name="RECENT_GIT_ROOT_PATH" value="$PROJECT_DIR$" /> | ||
34 | + </component> | ||
35 | + <component name="ProjectId" id="1aKhdS3cO6wtvAt8bFDZIe6HMz9" /> | ||
36 | + <component name="ProjectLevelVcsManager" settingsEditedManually="true" /> | ||
37 | + <component name="ProjectViewState"> | ||
38 | + <option name="hideEmptyMiddlePackages" value="true" /> | ||
39 | + <option name="showExcludedFiles" value="true" /> | ||
40 | + <option name="showLibraryContents" value="true" /> | ||
41 | + </component> | ||
42 | + <component name="PropertiesComponent"> | ||
43 | + <property name="RunOnceActivity.ShowReadmeOnStart" value="true" /> | ||
44 | + <property name="SHARE_PROJECT_CONFIGURATION_FILES" value="true" /> | ||
45 | + <property name="project.structure.last.edited" value="Modules" /> | ||
46 | + <property name="project.structure.proportion" value="0.15" /> | ||
47 | + <property name="project.structure.side.proportion" value="0.2" /> | ||
48 | + </component> | ||
49 | + <component name="RecentsManager"> | ||
50 | + <key name="MoveKotlinTopLevelDeclarationsDialog.RECENTS_KEY"> | ||
51 | + <recent name="util" /> | ||
52 | + </key> | ||
53 | + </component> | ||
54 | + <component name="RunManager"> | ||
55 | + <configuration name="MainKt" type="JetRunConfigurationType" temporary="true" nameIsGenerated="true"> | ||
56 | + <module name="obfuscator.main" /> | ||
57 | + <option name="VM_PARAMETERS" /> | ||
58 | + <option name="PROGRAM_PARAMETERS" /> | ||
59 | + <option name="ALTERNATIVE_JRE_PATH_ENABLED" value="false" /> | ||
60 | + <option name="ALTERNATIVE_JRE_PATH" /> | ||
61 | + <option name="PASS_PARENT_ENVS" value="true" /> | ||
62 | + <option name="MAIN_CLASS_NAME" value="MainKt" /> | ||
63 | + <option name="WORKING_DIRECTORY" /> | ||
64 | + <method v="2"> | ||
65 | + <option name="Make" enabled="true" /> | ||
66 | + </method> | ||
67 | + </configuration> | ||
68 | + <recent_temporary> | ||
69 | + <list> | ||
70 | + <item itemvalue="Kotlin.MainKt" /> | ||
71 | + </list> | ||
72 | + </recent_temporary> | ||
73 | + </component> | ||
74 | + <component name="SvnConfiguration"> | ||
75 | + <configuration /> | ||
76 | + </component> | ||
77 | + <component name="TaskManager"> | ||
78 | + <task active="true" id="Default" summary="Default task"> | ||
79 | + <changelist id="3e580ba3-add3-4012-a557-2fe613477d9f" name="Default Changelist" comment="" /> | ||
80 | + <created>1586490279278</created> | ||
81 | + <option name="number" value="Default" /> | ||
82 | + <option name="presentableId" value="Default" /> | ||
83 | + <updated>1586490279278</updated> | ||
84 | + </task> | ||
85 | + <servers /> | ||
86 | + </component> | ||
87 | + <component name="WindowStateProjectService"> | ||
88 | + <state x="440" y="159" key="#Project_Structure" timestamp="1586490643113"> | ||
89 | + <screen x="0" y="23" width="1680" height="942" /> | ||
90 | + </state> | ||
91 | + <state x="440" y="159" key="#Project_Structure/0.23.1680.942@0.23.1680.942" timestamp="1586490643113" /> | ||
92 | + <state x="304" y="155" key="#com.intellij.execution.impl.EditConfigurationsDialog" timestamp="1592124907973"> | ||
93 | + <screen x="0" y="23" width="1680" height="941" /> | ||
94 | + </state> | ||
95 | + <state x="304" y="155" key="#com.intellij.execution.impl.EditConfigurationsDialog/0.23.1680.941@0.23.1680.941" timestamp="1592124907973" /> | ||
96 | + <state x="622" y="217" key="#com.intellij.ide.util.MemberChooser" timestamp="1586596110190"> | ||
97 | + <screen x="0" y="23" width="1680" height="942" /> | ||
98 | + </state> | ||
99 | + <state x="622" y="217" key="#com.intellij.ide.util.MemberChooser/1680.23.2560.1057/0.23.1680.942@0.23.1680.942" timestamp="1586596110190" /> | ||
100 | + <state x="606" y="153" key="#org.jetbrains.kotlin.idea.refactoring.move.moveDeclarations.ui.MoveKotlinTopLevelDeclarationsDialog" timestamp="1586617500367"> | ||
101 | + <screen x="0" y="23" width="1680" height="942" /> | ||
102 | + </state> | ||
103 | + <state x="606" y="153" key="#org.jetbrains.kotlin.idea.refactoring.move.moveDeclarations.ui.MoveKotlinTopLevelDeclarationsDialog/0.23.1680.942@0.23.1680.942" timestamp="1586617500367" /> | ||
104 | + <state width="1638" height="150" key="GridCell.Tab.0.bottom" timestamp="1587297728312"> | ||
105 | + <screen x="0" y="23" width="1680" height="942" /> | ||
106 | + </state> | ||
107 | + <state width="1638" height="150" key="GridCell.Tab.0.bottom/0.23.1680.942@0.23.1680.942" timestamp="1587297728312" /> | ||
108 | + <state width="1638" height="150" key="GridCell.Tab.0.bottom/1680.23.2560.1057/0.23.1680.942@0.23.1680.942" timestamp="1587135448911" /> | ||
109 | + <state width="1638" height="150" key="GridCell.Tab.0.center" timestamp="1587297728312"> | ||
110 | + <screen x="0" y="23" width="1680" height="942" /> | ||
111 | + </state> | ||
112 | + <state width="1638" height="150" key="GridCell.Tab.0.center/0.23.1680.942@0.23.1680.942" timestamp="1587297728312" /> | ||
113 | + <state width="1638" height="150" key="GridCell.Tab.0.center/1680.23.2560.1057/0.23.1680.942@0.23.1680.942" timestamp="1587135448910" /> | ||
114 | + <state width="1638" height="150" key="GridCell.Tab.0.left" timestamp="1587297728311"> | ||
115 | + <screen x="0" y="23" width="1680" height="942" /> | ||
116 | + </state> | ||
117 | + <state width="1638" height="150" key="GridCell.Tab.0.left/0.23.1680.942@0.23.1680.942" timestamp="1587297728311" /> | ||
118 | + <state width="1638" height="150" key="GridCell.Tab.0.left/1680.23.2560.1057/0.23.1680.942@0.23.1680.942" timestamp="1587135448909" /> | ||
119 | + <state width="1638" height="150" key="GridCell.Tab.0.right" timestamp="1587297728312"> | ||
120 | + <screen x="0" y="23" width="1680" height="942" /> | ||
121 | + </state> | ||
122 | + <state width="1638" height="150" key="GridCell.Tab.0.right/0.23.1680.942@0.23.1680.942" timestamp="1587297728312" /> | ||
123 | + <state width="1638" height="150" key="GridCell.Tab.0.right/1680.23.2560.1057/0.23.1680.942@0.23.1680.942" timestamp="1587135448911" /> | ||
124 | + <state x="517" y="326" key="com.intellij.ide.util.TipDialog" timestamp="1592377934451"> | ||
125 | + <screen x="0" y="23" width="1680" height="941" /> | ||
126 | + </state> | ||
127 | + <state x="517" y="326" key="com.intellij.ide.util.TipDialog/0.23.1680.941@0.23.1680.941" timestamp="1592262533146" /> | ||
128 | + <state x="517" y="326" key="com.intellij.ide.util.TipDialog/0.23.1680.942@0.23.1680.942" timestamp="1587300634809" /> | ||
129 | + <state x="517" y="327" key="com.intellij.ide.util.TipDialog/0.23.1680.945@0.23.1680.945" timestamp="1589277203659" /> | ||
130 | + <state x="517" y="326" key="com.intellij.ide.util.TipDialog/1680.23.2560.1057/0.23.1680.941@0.23.1680.941" timestamp="1592377934451" /> | ||
131 | + <state x="517" y="326" key="com.intellij.ide.util.TipDialog/1680.23.2560.1057/0.23.1680.942@0.23.1680.942" timestamp="1587130133930" /> | ||
132 | + <state x="619" y="228" key="org.jetbrains.kotlin.idea.testIntegration.KotlinCreateTestDialog" timestamp="1586614244552"> | ||
133 | + <screen x="0" y="23" width="1680" height="942" /> | ||
134 | + </state> | ||
135 | + <state x="619" y="228" key="org.jetbrains.kotlin.idea.testIntegration.KotlinCreateTestDialog/0.23.1680.942@0.23.1680.942" timestamp="1586614244552" /> | ||
136 | + <state x="505" y="229" width="670" height="676" key="search.everywhere.popup" timestamp="1587134509023"> | ||
137 | + <screen x="0" y="23" width="1680" height="942" /> | ||
138 | + </state> | ||
139 | + <state x="505" y="229" width="670" height="676" key="search.everywhere.popup/1680.23.2560.1057/0.23.1680.942@0.23.1680.942" timestamp="1587134509023" /> | ||
140 | + </component> | ||
141 | + <component name="XDebuggerManager"> | ||
142 | + <breakpoint-manager> | ||
143 | + <breakpoints> | ||
144 | + <line-breakpoint enabled="true" type="java-line"> | ||
145 | + <url>jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/com.github.javaparser/javaparser-core/3.15.17/51e2e979c7d248c959f03a45c1862f248c8a4c6e/javaparser-core-3.15.17-sources.jar!/com/github/javaparser/ast/nodeTypes/NodeWithRange.java</url> | ||
146 | + <option name="timeStamp" value="5" /> | ||
147 | + </line-breakpoint> | ||
148 | + <line-breakpoint enabled="true" type="kotlin-line"> | ||
149 | + <url>file://$PROJECT_DIR$/obfuscator/src/main/kotlin/main.kt</url> | ||
150 | + <line>4</line> | ||
151 | + <option name="timeStamp" value="7" /> | ||
152 | + </line-breakpoint> | ||
153 | + </breakpoints> | ||
154 | + </breakpoint-manager> | ||
155 | + </component> | ||
156 | +</project> | ||
... | \ No newline at end of file | ... | \ No newline at end of file |
obfuscator/README.md
0 → 100644
obfuscator/obfuscator/.idea/.gitignore
0 → 100644
obfuscator/obfuscator/.idea/.name
0 → 100644
1 | +modifier.obfuscator | ||
... | \ No newline at end of file | ... | \ No newline at end of file |
1 | +<component name="ProjectCodeStyleConfiguration"> | ||
2 | + <code_scheme name="Project" version="173"> | ||
3 | + <JetCodeStyleSettings> | ||
4 | + <option name="CODE_STYLE_DEFAULTS" value="KOTLIN_OFFICIAL" /> | ||
5 | + </JetCodeStyleSettings> | ||
6 | + <codeStyleSettings language="kotlin"> | ||
7 | + <option name="CODE_STYLE_DEFAULTS" value="KOTLIN_OFFICIAL" /> | ||
8 | + </codeStyleSettings> | ||
9 | + </code_scheme> | ||
10 | +</component> | ||
... | \ No newline at end of file | ... | \ No newline at end of file |
obfuscator/obfuscator/.idea/gradle.xml
0 → 100644
1 | +<?xml version="1.0" encoding="UTF-8"?> | ||
2 | +<project version="4"> | ||
3 | + <component name="GradleMigrationSettings" migrationVersion="1" /> | ||
4 | + <component name="GradleSettings"> | ||
5 | + <option name="linkedExternalProjectsSettings"> | ||
6 | + <GradleProjectSettings> | ||
7 | + <option name="distributionType" value="DEFAULT_WRAPPED" /> | ||
8 | + <option name="externalProjectPath" value="$PROJECT_DIR$" /> | ||
9 | + <option name="gradleHome" value="/usr/local/Cellar/gradle/6.3/libexec" /> | ||
10 | + <option name="gradleJvm" value="11" /> | ||
11 | + <option name="modules"> | ||
12 | + <set> | ||
13 | + <option value="$PROJECT_DIR$" /> | ||
14 | + </set> | ||
15 | + </option> | ||
16 | + <option name="useQualifiedModuleNames" value="true" /> | ||
17 | + </GradleProjectSettings> | ||
18 | + </option> | ||
19 | + </component> | ||
20 | +</project> | ||
... | \ No newline at end of file | ... | \ No newline at end of file |
1 | +<?xml version="1.0" encoding="UTF-8"?> | ||
2 | +<project version="4"> | ||
3 | + <component name="RemoteRepositoriesConfiguration"> | ||
4 | + <remote-repository> | ||
5 | + <option name="id" value="central" /> | ||
6 | + <option name="name" value="Maven Central repository" /> | ||
7 | + <option name="url" value="https://repo1.maven.org/maven2" /> | ||
8 | + </remote-repository> | ||
9 | + <remote-repository> | ||
10 | + <option name="id" value="jboss.community" /> | ||
11 | + <option name="name" value="JBoss Community repository" /> | ||
12 | + <option name="url" value="https://repository.jboss.org/nexus/content/repositories/public/" /> | ||
13 | + </remote-repository> | ||
14 | + <remote-repository> | ||
15 | + <option name="id" value="MavenRepo" /> | ||
16 | + <option name="name" value="MavenRepo" /> | ||
17 | + <option name="url" value="https://repo.maven.apache.org/maven2/" /> | ||
18 | + </remote-repository> | ||
19 | + </component> | ||
20 | +</project> | ||
... | \ No newline at end of file | ... | \ No newline at end of file |
obfuscator/obfuscator/.idea/misc.xml
0 → 100644
1 | +<?xml version="1.0" encoding="UTF-8"?> | ||
2 | +<project version="4"> | ||
3 | + <component name="ExternalStorageConfigurationManager" enabled="true" /> | ||
4 | + <component name="ProjectRootManager" version="2" languageLevel="JDK_11" project-jdk-name="11" project-jdk-type="JavaSDK" /> | ||
5 | +</project> | ||
... | \ No newline at end of file | ... | \ No newline at end of file |
obfuscator/obfuscator/.idea/vcs.xml
0 → 100644
obfuscator/obfuscator/build.gradle
0 → 100644
1 | +plugins { | ||
2 | + id 'org.jetbrains.kotlin.jvm' version '1.3.61' | ||
3 | +} | ||
4 | + | ||
5 | +group 'org.example' | ||
6 | +version '1.0-SNAPSHOT' | ||
7 | + | ||
8 | +repositories { | ||
9 | + mavenCentral() | ||
10 | +} | ||
11 | + | ||
12 | +dependencies { | ||
13 | + implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8" | ||
14 | + implementation 'com.github.javaparser:javaparser-core:3.15.17' | ||
15 | + implementation 'com.googlecode.json-simple:json-simple:1.1.1' | ||
16 | + testImplementation 'junit:junit:4.13' | ||
17 | +} | ||
18 | + | ||
19 | +compileKotlin { | ||
20 | + kotlinOptions.jvmTarget = "1.8" | ||
21 | +} | ||
22 | +compileTestKotlin { | ||
23 | + kotlinOptions.jvmTarget = "1.8" | ||
24 | +} | ||
... | \ No newline at end of file | ... | \ No newline at end of file |
obfuscator/obfuscator/gradle.properties
0 → 100644
1 | +kotlin.code.style=official | ||
... | \ No newline at end of file | ... | \ No newline at end of file |
No preview for this file type
obfuscator/obfuscator/gradlew
0 → 100755
1 | +#!/usr/bin/env sh | ||
2 | + | ||
3 | +############################################################################## | ||
4 | +## | ||
5 | +## Gradle start up script for UN*X | ||
6 | +## | ||
7 | +############################################################################## | ||
8 | + | ||
9 | +# Attempt to set APP_HOME | ||
10 | +# Resolve links: $0 may be a link | ||
11 | +PRG="$0" | ||
12 | +# Need this for relative symlinks. | ||
13 | +while [ -h "$PRG" ] ; do | ||
14 | + ls=`ls -ld "$PRG"` | ||
15 | + link=`expr "$ls" : '.*-> \(.*\)$'` | ||
16 | + if expr "$link" : '/.*' > /dev/null; then | ||
17 | + PRG="$link" | ||
18 | + else | ||
19 | + PRG=`dirname "$PRG"`"/$link" | ||
20 | + fi | ||
21 | +done | ||
22 | +SAVED="`pwd`" | ||
23 | +cd "`dirname \"$PRG\"`/" >/dev/null | ||
24 | +APP_HOME="`pwd -P`" | ||
25 | +cd "$SAVED" >/dev/null | ||
26 | + | ||
27 | +APP_NAME="Gradle" | ||
28 | +APP_BASE_NAME=`basename "$0"` | ||
29 | + | ||
30 | +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. | ||
31 | +DEFAULT_JVM_OPTS='"-Xmx64m"' | ||
32 | + | ||
33 | +# Use the maximum available, or set MAX_FD != -1 to use that value. | ||
34 | +MAX_FD="maximum" | ||
35 | + | ||
36 | +warn () { | ||
37 | + echo "$*" | ||
38 | +} | ||
39 | + | ||
40 | +die () { | ||
41 | + echo | ||
42 | + echo "$*" | ||
43 | + echo | ||
44 | + exit 1 | ||
45 | +} | ||
46 | + | ||
47 | +# OS specific support (must be 'true' or 'false'). | ||
48 | +cygwin=false | ||
49 | +msys=false | ||
50 | +darwin=false | ||
51 | +nonstop=false | ||
52 | +case "`uname`" in | ||
53 | + CYGWIN* ) | ||
54 | + cygwin=true | ||
55 | + ;; | ||
56 | + Darwin* ) | ||
57 | + darwin=true | ||
58 | + ;; | ||
59 | + MINGW* ) | ||
60 | + msys=true | ||
61 | + ;; | ||
62 | + NONSTOP* ) | ||
63 | + nonstop=true | ||
64 | + ;; | ||
65 | +esac | ||
66 | + | ||
67 | +CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar | ||
68 | + | ||
69 | +# Determine the Java command to use to start the JVM. | ||
70 | +if [ -n "$JAVA_HOME" ] ; then | ||
71 | + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then | ||
72 | + # IBM's JDK on AIX uses strange locations for the executables | ||
73 | + JAVACMD="$JAVA_HOME/jre/sh/java" | ||
74 | + else | ||
75 | + JAVACMD="$JAVA_HOME/bin/java" | ||
76 | + fi | ||
77 | + if [ ! -x "$JAVACMD" ] ; then | ||
78 | + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME | ||
79 | + | ||
80 | +Please set the JAVA_HOME variable in your environment to match the | ||
81 | +location of your Java installation." | ||
82 | + fi | ||
83 | +else | ||
84 | + JAVACMD="java" | ||
85 | + which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. | ||
86 | + | ||
87 | +Please set the JAVA_HOME variable in your environment to match the | ||
88 | +location of your Java installation." | ||
89 | +fi | ||
90 | + | ||
91 | +# Increase the maximum file descriptors if we can. | ||
92 | +if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then | ||
93 | + MAX_FD_LIMIT=`ulimit -H -n` | ||
94 | + if [ $? -eq 0 ] ; then | ||
95 | + if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then | ||
96 | + MAX_FD="$MAX_FD_LIMIT" | ||
97 | + fi | ||
98 | + ulimit -n $MAX_FD | ||
99 | + if [ $? -ne 0 ] ; then | ||
100 | + warn "Could not set maximum file descriptor limit: $MAX_FD" | ||
101 | + fi | ||
102 | + else | ||
103 | + warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" | ||
104 | + fi | ||
105 | +fi | ||
106 | + | ||
107 | +# For Darwin, add options to specify how the application appears in the dock | ||
108 | +if $darwin; then | ||
109 | + GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" | ||
110 | +fi | ||
111 | + | ||
112 | +# For Cygwin, switch paths to Windows format before running java | ||
113 | +if $cygwin ; then | ||
114 | + APP_HOME=`cygpath --path --mixed "$APP_HOME"` | ||
115 | + CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` | ||
116 | + JAVACMD=`cygpath --unix "$JAVACMD"` | ||
117 | + | ||
118 | + # We build the pattern for arguments to be converted via cygpath | ||
119 | + ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` | ||
120 | + SEP="" | ||
121 | + for dir in $ROOTDIRSRAW ; do | ||
122 | + ROOTDIRS="$ROOTDIRS$SEP$dir" | ||
123 | + SEP="|" | ||
124 | + done | ||
125 | + OURCYGPATTERN="(^($ROOTDIRS))" | ||
126 | + # Add a user-defined pattern to the cygpath arguments | ||
127 | + if [ "$GRADLE_CYGPATTERN" != "" ] ; then | ||
128 | + OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" | ||
129 | + fi | ||
130 | + # Now convert the arguments - kludge to limit ourselves to /bin/sh | ||
131 | + i=0 | ||
132 | + for arg in "$@" ; do | ||
133 | + CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` | ||
134 | + CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option | ||
135 | + | ||
136 | + if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition | ||
137 | + eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` | ||
138 | + else | ||
139 | + eval `echo args$i`="\"$arg\"" | ||
140 | + fi | ||
141 | + i=$((i+1)) | ||
142 | + done | ||
143 | + case $i in | ||
144 | + (0) set -- ;; | ||
145 | + (1) set -- "$args0" ;; | ||
146 | + (2) set -- "$args0" "$args1" ;; | ||
147 | + (3) set -- "$args0" "$args1" "$args2" ;; | ||
148 | + (4) set -- "$args0" "$args1" "$args2" "$args3" ;; | ||
149 | + (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; | ||
150 | + (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; | ||
151 | + (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; | ||
152 | + (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; | ||
153 | + (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; | ||
154 | + esac | ||
155 | +fi | ||
156 | + | ||
157 | +# Escape application args | ||
158 | +save () { | ||
159 | + for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done | ||
160 | + echo " " | ||
161 | +} | ||
162 | +APP_ARGS=$(save "$@") | ||
163 | + | ||
164 | +# Collect all arguments for the java command, following the shell quoting and substitution rules | ||
165 | +eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" | ||
166 | + | ||
167 | +# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong | ||
168 | +if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then | ||
169 | + cd "$(dirname "$0")" | ||
170 | +fi | ||
171 | + | ||
172 | +exec "$JAVACMD" "$@" |
obfuscator/obfuscator/gradlew.bat
0 → 100644
1 | +@if "%DEBUG%" == "" @echo off | ||
2 | +@rem ########################################################################## | ||
3 | +@rem | ||
4 | +@rem Gradle startup script for Windows | ||
5 | +@rem | ||
6 | +@rem ########################################################################## | ||
7 | + | ||
8 | +@rem Set local scope for the variables with windows NT shell | ||
9 | +if "%OS%"=="Windows_NT" setlocal | ||
10 | + | ||
11 | +set DIRNAME=%~dp0 | ||
12 | +if "%DIRNAME%" == "" set DIRNAME=. | ||
13 | +set APP_BASE_NAME=%~n0 | ||
14 | +set APP_HOME=%DIRNAME% | ||
15 | + | ||
16 | +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. | ||
17 | +set DEFAULT_JVM_OPTS="-Xmx64m" | ||
18 | + | ||
19 | +@rem Find java.exe | ||
20 | +if defined JAVA_HOME goto findJavaFromJavaHome | ||
21 | + | ||
22 | +set JAVA_EXE=java.exe | ||
23 | +%JAVA_EXE% -version >NUL 2>&1 | ||
24 | +if "%ERRORLEVEL%" == "0" goto init | ||
25 | + | ||
26 | +echo. | ||
27 | +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. | ||
28 | +echo. | ||
29 | +echo Please set the JAVA_HOME variable in your environment to match the | ||
30 | +echo location of your Java installation. | ||
31 | + | ||
32 | +goto fail | ||
33 | + | ||
34 | +:findJavaFromJavaHome | ||
35 | +set JAVA_HOME=%JAVA_HOME:"=% | ||
36 | +set JAVA_EXE=%JAVA_HOME%/bin/java.exe | ||
37 | + | ||
38 | +if exist "%JAVA_EXE%" goto init | ||
39 | + | ||
40 | +echo. | ||
41 | +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% | ||
42 | +echo. | ||
43 | +echo Please set the JAVA_HOME variable in your environment to match the | ||
44 | +echo location of your Java installation. | ||
45 | + | ||
46 | +goto fail | ||
47 | + | ||
48 | +:init | ||
49 | +@rem Get command-line arguments, handling Windows variants | ||
50 | + | ||
51 | +if not "%OS%" == "Windows_NT" goto win9xME_args | ||
52 | + | ||
53 | +:win9xME_args | ||
54 | +@rem Slurp the command line arguments. | ||
55 | +set CMD_LINE_ARGS= | ||
56 | +set _SKIP=2 | ||
57 | + | ||
58 | +:win9xME_args_slurp | ||
59 | +if "x%~1" == "x" goto execute | ||
60 | + | ||
61 | +set CMD_LINE_ARGS=%* | ||
62 | + | ||
63 | +:execute | ||
64 | +@rem Setup the command line | ||
65 | + | ||
66 | +set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar | ||
67 | + | ||
68 | +@rem Execute Gradle | ||
69 | +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% | ||
70 | + | ||
71 | +:end | ||
72 | +@rem End local scope for the variables with windows NT shell | ||
73 | +if "%ERRORLEVEL%"=="0" goto mainEnd | ||
74 | + | ||
75 | +:fail | ||
76 | +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of | ||
77 | +rem the _cmd.exe /c_ return code! | ||
78 | +if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 | ||
79 | +exit /b 1 | ||
80 | + | ||
81 | +:mainEnd | ||
82 | +if "%OS%"=="Windows_NT" endlocal | ||
83 | + | ||
84 | +:omega |
obfuscator/obfuscator/settings.gradle
0 → 100644
1 | +package cached | ||
2 | + | ||
3 | +fun classify(method: String) = "class foo{$method}" | ||
4 | + | ||
5 | +val CACHED_APPLICATION = "" + | ||
6 | + "package com.ono.test_app;\n" + | ||
7 | + "\n" + | ||
8 | + "import android.app.Application;\n" + | ||
9 | + "import android.content.Context;\n" + | ||
10 | + "import com.ono.test_app.cache.SecureSharedPreferences;\n" + | ||
11 | + "import android.content.SharedPreferences;\n" + | ||
12 | + "import androidx.preference.PreferenceManager;\n" + | ||
13 | + "import org.json.JSONObject;\n" + | ||
14 | + "import java.io.InputStream;\n" + | ||
15 | + "import java.util.Iterator;\n" + | ||
16 | + "\n" + | ||
17 | + "public class MyApplication extends Application {\n" + | ||
18 | + "\n" + | ||
19 | + " static SecureSharedPreferences pref = null;\n" + | ||
20 | + "\n" + | ||
21 | + " @Override\n" + | ||
22 | + " public void onCreate() {\n" + | ||
23 | + " encryption();\n" + | ||
24 | + " super.onCreate();\n" + | ||
25 | + " }\n" + | ||
26 | + "\n" + | ||
27 | + " private void encryption() {\n" + | ||
28 | + " SharedPreferences p = PreferenceManager.getDefaultSharedPreferences(this);\n" + | ||
29 | + " pref = new SecureSharedPreferences(p);\n" + | ||
30 | + " loadJSONFromAsset(this);\n" + | ||
31 | + " try {\n" + | ||
32 | + " JSONObject jsonObject = new JSONObject(loadJSONFromAsset(this));\n" + | ||
33 | + " Iterator<String> keys = jsonObject.keys();\n" + | ||
34 | + " while (keys.hasNext()) {\n" + | ||
35 | + " String key = keys.next();\n" + | ||
36 | + " pref.put(key, jsonObject.get(key).toString());\n" + | ||
37 | + " }\n" + | ||
38 | + " } catch (Exception e) {\n" + | ||
39 | + " e.printStackTrace();\n" + | ||
40 | + " }\n" + | ||
41 | + " }\n" + | ||
42 | + "\n" + | ||
43 | + " public String loadJSONFromAsset(Context context) {\n" + | ||
44 | + " String json = null;\n" + | ||
45 | + " try {\n" + | ||
46 | + " InputStream is = context.getAssets().open(\"encryption.json\");\n" + | ||
47 | + " int size = is.available();\n" + | ||
48 | + " byte[] buffer = new byte[size];\n" + | ||
49 | + " is.read(buffer);\n" + | ||
50 | + " is.close();\n" + | ||
51 | + " json = new String(buffer, \"UTF-8\");\n" + | ||
52 | + " } catch (Exception e) {\n" + | ||
53 | + " e.printStackTrace();\n" + | ||
54 | + " }\n" + | ||
55 | + " return json;\n" + | ||
56 | + " }\n" + | ||
57 | + "}\n" | ||
58 | + | ||
59 | +val FUNCTION_ENCRPTION = " private void encryption() {\n" + | ||
60 | + " SharedPreferences p = PreferenceManager.getDefaultSharedPreferences(this);\n" + | ||
61 | + " pref = new SecureSharedPreferences(p);\n" + | ||
62 | + "\n" + | ||
63 | + " loadJSONFromAsset(this);\n" + | ||
64 | + " try {\n" + | ||
65 | + " JSONObject jsonObject = new JSONObject(loadJSONFromAsset(this));\n" + | ||
66 | + " Iterator<String> keys = jsonObject.keys();\n" + | ||
67 | + " while (keys.hasNext()) {\n" + | ||
68 | + " String key = keys.next();\n" + | ||
69 | + " pref.put(key, jsonObject.get(key).toString());\n" + | ||
70 | + " }\n" + | ||
71 | + " } catch (Exception e) {\n" + | ||
72 | + " e.printStackTrace();\n" + | ||
73 | + " }\n" + | ||
74 | + " }" | ||
75 | + | ||
76 | +val FUNCTION_LOAD_JSON = " public String loadJSONFromAsset(Context context) {\n" + | ||
77 | + " String json = null;\n" + | ||
78 | + " try {\n" + | ||
79 | + " InputStream is = context.getAssets().open(\"encryption.json\");\n" + | ||
80 | + " int size = is.available();\n" + | ||
81 | + " byte[] buffer = new byte[size];\n" + | ||
82 | + " is.read(buffer);\n" + | ||
83 | + " is.close();\n" + | ||
84 | + " json = new String(buffer, \"UTF-8\");\n" + | ||
85 | + " } catch (Exception e) {\n" + | ||
86 | + " e.printStackTrace();\n" + | ||
87 | + " }\n" + | ||
88 | + " return json;\n" + | ||
89 | + " }" | ||
90 | + | ||
91 | +val CLASS_APPLICATION = "import android.app.Application;\n" + | ||
92 | + "\n" + | ||
93 | + "public class MyApplication extends Application {\n" + | ||
94 | + " static SecureSharedPreferences pref = null;\n" + | ||
95 | + "}\n" | ||
96 | + |
1 | +import modifier.encryptor.Encryptor | ||
2 | +import modifier.obfuscator.Obfuscator | ||
3 | + | ||
4 | +fun main() { | ||
5 | + val TEST_APP_NAME = "test_app_java" | ||
6 | + | ||
7 | + /** | ||
8 | + * #순서 | ||
9 | + * #암호화 | ||
10 | + * | ||
11 | + * #난독화 | ||
12 | + * 변수 사용, 파라미터 사용 | ||
13 | + * 변수 선언, 파라미터 선언, 클래스 선언 | ||
14 | + **/ | ||
15 | + Encryptor.build(TEST_APP_NAME).run() | ||
16 | + Obfuscator.build(TEST_APP_NAME).run() | ||
17 | +} |
1 | +package modifier | ||
2 | + | ||
3 | +import com.github.javaparser.StaticJavaParser | ||
4 | +import com.github.javaparser.ast.CompilationUnit | ||
5 | +import util.file.FileUtil | ||
6 | +import java.io.File | ||
7 | + | ||
8 | +abstract class AbstractModifier : BaseModifier { | ||
9 | + protected lateinit var targetAppName: String | ||
10 | + protected val mainFolder by lazy { FileUtil.getMainFolder(targetAppName) } | ||
11 | + protected val codeFolder by lazy { File("${mainFolder}/java/${FileUtil.getPackageName(mainFolder)?.replace(".","/")}") } | ||
12 | + protected val javaFiles: List<File> by lazy { FileUtil.getJavaFiles(mainFolder) } | ||
13 | + | ||
14 | + protected fun parse(file : File) : CompilationUnit{ | ||
15 | + return StaticJavaParser.parse(file) | ||
16 | + } | ||
17 | + | ||
18 | + protected fun parse(code : String) : CompilationUnit{ | ||
19 | + return StaticJavaParser.parse(code) | ||
20 | + } | ||
21 | +} | ||
... | \ No newline at end of file | ... | \ No newline at end of file |
1 | +package modifier.encryptor | ||
2 | + | ||
3 | +import cached.CACHED_APPLICATION | ||
4 | +import cached.FUNCTION_ENCRPTION | ||
5 | +import cached.FUNCTION_LOAD_JSON | ||
6 | +import cached.classify | ||
7 | +import modifier.AbstractModifier | ||
8 | +import util.file.CompilationUtil.saveCompilationUnit | ||
9 | +import util.json.JsonFactory | ||
10 | +import util.syntax.ClassUtil | ||
11 | +import util.syntax.MethodDeclUtil | ||
12 | +import util.syntax.StringLiteralUtil | ||
13 | +import java.io.File | ||
14 | + | ||
15 | +class Encryptor private constructor() : AbstractModifier() { | ||
16 | + companion object { | ||
17 | + fun build(targetAppName: String): Encryptor { | ||
18 | + return Encryptor().apply { this.targetAppName = targetAppName } | ||
19 | + } | ||
20 | + } | ||
21 | + | ||
22 | + private class MakeJson(targetAppName: String) : AbstractModifier() { | ||
23 | + init { | ||
24 | + this.targetAppName = targetAppName | ||
25 | + } | ||
26 | + | ||
27 | + private fun makeJson(file: File) { | ||
28 | + val cu = parse(file) | ||
29 | + StringLiteralUtil(cu).also { util -> | ||
30 | + val jsonObject = JsonFactory.build(mainFolder) | ||
31 | + | ||
32 | + util.get().map { it.value.toString() }.forEach { | ||
33 | + jsonObject.add(it) | ||
34 | + } | ||
35 | + jsonObject.save() | ||
36 | + } | ||
37 | + } | ||
38 | + | ||
39 | + override fun run() { | ||
40 | + javaFiles.forEach { | ||
41 | + makeJson(it) | ||
42 | + } | ||
43 | + } | ||
44 | + } | ||
45 | + | ||
46 | + @Deprecated("Replaced by InjectApplication") | ||
47 | + private class InjectMethodDecl(targetAppName: String) : AbstractModifier() { | ||
48 | + init { | ||
49 | + this.targetAppName = targetAppName | ||
50 | + } | ||
51 | + | ||
52 | + private fun injectCode(file: File) { | ||
53 | + val cu = parse(file) | ||
54 | + ClassUtil(cu).also { util -> | ||
55 | + util.get().forEach { | ||
56 | + val name = it.name.toString() | ||
57 | + val condition = util.getExtends(name)?.contains("AppCompatActivity") ?: false | ||
58 | + if (condition) { | ||
59 | + util.addMethod(null, classify(FUNCTION_ENCRPTION)) | ||
60 | + util.addMethod(null, classify(FUNCTION_LOAD_JSON)) | ||
61 | + } | ||
62 | + } | ||
63 | + } | ||
64 | + saveCompilationUnit(file, cu) | ||
65 | + } | ||
66 | + | ||
67 | + override fun run() { | ||
68 | + javaFiles.forEach { | ||
69 | + injectCode(it) | ||
70 | + } | ||
71 | + } | ||
72 | + } | ||
73 | + | ||
74 | + @Deprecated("Replaced by InjectApplication") | ||
75 | + private class InjectMethodCall(targetAppName: String) : AbstractModifier() { | ||
76 | + init { | ||
77 | + this.targetAppName = targetAppName | ||
78 | + } | ||
79 | + | ||
80 | + private fun injectCode(file: File) { | ||
81 | + val cu = parse(file) | ||
82 | + ClassUtil(cu).also { util -> | ||
83 | + util.get().forEach { | ||
84 | + val name = it.name.toString() | ||
85 | + val condition = util.getExtends(name)?.contains("Application") ?: false | ||
86 | + if (condition) { | ||
87 | + MethodDeclUtil(cu).also { util -> | ||
88 | + util.get("onCreate").also { | ||
89 | + util.injectMethod("onCreate", "encryption") | ||
90 | + } | ||
91 | + } | ||
92 | + } | ||
93 | + } | ||
94 | + } | ||
95 | + saveCompilationUnit(file, cu) | ||
96 | + } | ||
97 | + | ||
98 | + override fun run() { | ||
99 | + javaFiles.forEach { | ||
100 | + injectCode(it) | ||
101 | + } | ||
102 | + } | ||
103 | + } | ||
104 | + | ||
105 | + private class ReplaceLiteral(targetAppName: String) : AbstractModifier() { | ||
106 | + init { | ||
107 | + this.targetAppName = targetAppName | ||
108 | + } | ||
109 | + | ||
110 | + private fun replace(file: File) { | ||
111 | + val cu = parse(file) | ||
112 | + StringLiteralUtil(cu).replace("MyApplication.pref.get") | ||
113 | + saveCompilationUnit(file, cu) | ||
114 | + } | ||
115 | + override fun run() { | ||
116 | + javaFiles.forEach { | ||
117 | + replace(it) | ||
118 | + } | ||
119 | + } | ||
120 | + } | ||
121 | + | ||
122 | + private class InjectApplication(targetAppName: String) : AbstractModifier() { | ||
123 | + init { | ||
124 | + this.targetAppName = targetAppName | ||
125 | + } | ||
126 | + | ||
127 | + private fun inject() { | ||
128 | + val cu = parse(CACHED_APPLICATION) | ||
129 | + saveCompilationUnit("$codeFolder/MyApplication.java", cu) | ||
130 | + } | ||
131 | + | ||
132 | + override fun run() { | ||
133 | + inject() | ||
134 | + } | ||
135 | + } | ||
136 | + | ||
137 | + override fun run() { | ||
138 | + /** | ||
139 | + * string literal json 생성 | ||
140 | + * string literal -> securePref.get() 치환 | ||
141 | + * application class 생성 | ||
142 | + */ | ||
143 | + MakeJson(targetAppName).run() | ||
144 | + ReplaceLiteral(targetAppName).run() | ||
145 | + InjectApplication(targetAppName).run() | ||
146 | + } | ||
147 | +} | ||
... | \ No newline at end of file | ... | \ No newline at end of file |
1 | +package modifier.obfuscator | ||
2 | + | ||
3 | +import com.github.javaparser.ast.expr.FieldAccessExpr | ||
4 | +import com.github.javaparser.ast.expr.Name | ||
5 | +import modifier.AbstractModifier | ||
6 | +import util.cipher.CipherHelper.SHA256 | ||
7 | +import util.file.CompilationUtil.saveCompilationUnit | ||
8 | +import util.file.FileUtil | ||
9 | +import util.file.FileUtil.changeFileName | ||
10 | +import util.file.XMLUtil | ||
11 | +import util.syntax.* | ||
12 | +import java.io.File | ||
13 | + | ||
14 | +class Obfuscator private constructor() : AbstractModifier() { | ||
15 | + companion object { | ||
16 | + fun build(targetAppName: String): Obfuscator { | ||
17 | + return Obfuscator().apply { this.targetAppName = targetAppName } | ||
18 | + } | ||
19 | + } | ||
20 | + | ||
21 | + private class XMLObfuscator(targetAppName: String) : AbstractModifier() { | ||
22 | + val XMLFile by lazy { FileUtil.getManifestXML(mainFolder) } | ||
23 | + | ||
24 | + init { | ||
25 | + this.targetAppName = targetAppName | ||
26 | + } | ||
27 | + | ||
28 | + override fun run() { | ||
29 | + applyToActivity() | ||
30 | + applyToApplication() | ||
31 | + } | ||
32 | + | ||
33 | + private fun applyToActivity() { | ||
34 | + XMLUtil.obfuscateActivityName(XMLFile) | ||
35 | + } | ||
36 | + | ||
37 | + private fun applyToApplication() { | ||
38 | + XMLUtil.obfuscateApplicationName(XMLFile) | ||
39 | + } | ||
40 | + } | ||
41 | + | ||
42 | + private class DeclarationObfuscator(targetAppName: String) : AbstractModifier() { | ||
43 | + init { | ||
44 | + this.targetAppName = targetAppName | ||
45 | + } | ||
46 | + | ||
47 | + override fun run() { | ||
48 | + javaFiles.forEach { | ||
49 | + applyToVariable(it) | ||
50 | + applyToParameter(it) | ||
51 | + applyToMethod(it) | ||
52 | + applyToClass(it) | ||
53 | + } | ||
54 | + } | ||
55 | + | ||
56 | + private fun applyToClass(file: File) { | ||
57 | + val cu = parse(file) | ||
58 | + val util = ClassUtil(cu) | ||
59 | + val classNameList = mutableListOf<String>() | ||
60 | + val obfuscatedClassNameList = mutableListOf<String>() | ||
61 | + | ||
62 | + util.get().forEach { | ||
63 | + classNameList.add(it.name.toString()) | ||
64 | + } | ||
65 | + | ||
66 | + classNameList.forEach { default -> | ||
67 | + SHA256(default)?.let { | ||
68 | + obfuscatedClassNameList.add(it) | ||
69 | + util.setName(default, it) | ||
70 | + } | ||
71 | + } | ||
72 | + | ||
73 | + saveCompilationUnit(file, cu) | ||
74 | + | ||
75 | + changeFileName(file, obfuscatedClassNameList[0]) | ||
76 | + } | ||
77 | + | ||
78 | + private fun applyToVariable(file: File) { | ||
79 | + println("----$file----") | ||
80 | + val cu = parse(file) | ||
81 | + VariableDeclUtil(cu).also { util -> | ||
82 | + util.get().forEach { | ||
83 | + val name = it.name.toString() | ||
84 | + println(name) | ||
85 | + with(SHA256(name), { | ||
86 | + util.setName(name, this!!) | ||
87 | + }) | ||
88 | + } | ||
89 | + } | ||
90 | + | ||
91 | + saveCompilationUnit(file, cu) | ||
92 | + } | ||
93 | + | ||
94 | + private fun applyToParameter(file: File) { | ||
95 | + val cu = parse(file) | ||
96 | + ParameterUtil(cu).also { util -> | ||
97 | + util.get().forEach { | ||
98 | + val name = it.name.toString() | ||
99 | + if (name[0].isLowerCase()) { | ||
100 | + println(name) | ||
101 | + with(SHA256(name), { | ||
102 | + util.setName(name, this!!) | ||
103 | + }) | ||
104 | + } | ||
105 | + } | ||
106 | + } | ||
107 | + saveCompilationUnit(file, cu) | ||
108 | + } | ||
109 | + | ||
110 | + private fun applyToMethod(file: File) { | ||
111 | + val cu = parse(file) | ||
112 | + MethodDeclUtil(cu).also { util -> | ||
113 | + util.get().filter { it.annotations.size == 0 }.forEach { | ||
114 | + val name = it.name.toString() | ||
115 | + with(SHA256(name), { | ||
116 | + util.setName(name, this!!) | ||
117 | + }) | ||
118 | + } | ||
119 | + } | ||
120 | + saveCompilationUnit(file, cu) | ||
121 | + } | ||
122 | + } | ||
123 | + | ||
124 | + private class CallingObfuscator(targetAppName: String, private val userDefCode: List<String>) : AbstractModifier() { | ||
125 | + init { | ||
126 | + this.targetAppName = targetAppName | ||
127 | + } | ||
128 | + | ||
129 | + override fun run() { | ||
130 | + javaFiles.forEach { | ||
131 | + applyToInstanceVariable(it) | ||
132 | + applyToVariable(it) | ||
133 | + applyToMethodCall(it) | ||
134 | + } | ||
135 | + } | ||
136 | + | ||
137 | + private fun applyToVariable(file: File) { | ||
138 | + val cu = parse(file) | ||
139 | + NameUtil(cu).also { util -> | ||
140 | + util.get().forEach { | ||
141 | + val name = it.name.toString() | ||
142 | + if (userDefCode.contains(name) || name[0].isLowerCase()) { | ||
143 | + with(SHA256(name), { | ||
144 | + util.setName(name, this!!) | ||
145 | + }) | ||
146 | + } | ||
147 | + } | ||
148 | + } | ||
149 | + | ||
150 | + saveCompilationUnit(file, cu) | ||
151 | + } | ||
152 | + | ||
153 | + private fun applyToInstanceVariable(file: File){ | ||
154 | + val cu = parse(file) | ||
155 | + FieldAccessUtil(cu).also{ util -> | ||
156 | + util.get().filter{"R" !in it.toString()}.forEach { | ||
157 | + val name = it.name.toString() | ||
158 | + with(SHA256(name), { | ||
159 | + util.setName(name, this!!) | ||
160 | + }) | ||
161 | + } | ||
162 | + } | ||
163 | + | ||
164 | + saveCompilationUnit(file, cu) | ||
165 | + } | ||
166 | + | ||
167 | + private fun applyToMethodCall(file: File){ | ||
168 | + val cu = parse(file) | ||
169 | + | ||
170 | + MethodCallUtil(cu).also{ util -> | ||
171 | + util.get().forEach { | ||
172 | + val name = it.name.toString() | ||
173 | + if (userDefCode.contains(name)) { | ||
174 | + with(SHA256(name), { | ||
175 | + util.setName(name, this!!) | ||
176 | + }) | ||
177 | + } | ||
178 | + } | ||
179 | + } | ||
180 | + | ||
181 | + saveCompilationUnit(file, cu) | ||
182 | + } | ||
183 | + } | ||
184 | + | ||
185 | + private fun getUserDefCode(): List<String> { | ||
186 | + val userDefine = mutableListOf<String>() | ||
187 | + | ||
188 | + javaFiles.forEach { | ||
189 | + val cu = parse(it) | ||
190 | + ClassUtil(cu).get().forEach { | ||
191 | + userDefine.add(it.name.toString()) | ||
192 | + } | ||
193 | + | ||
194 | + MethodDeclUtil(cu).get().filter { it.annotations.size == 0 }.forEach { | ||
195 | + userDefine.add(it.name.toString()) | ||
196 | + } | ||
197 | + } | ||
198 | + return userDefine | ||
199 | + } | ||
200 | + | ||
201 | + override fun run() { | ||
202 | + val userDefCode = getUserDefCode() | ||
203 | + XMLObfuscator(targetAppName).run() | ||
204 | + CallingObfuscator(targetAppName, userDefCode).run() | ||
205 | + DeclarationObfuscator(targetAppName).run() | ||
206 | + } | ||
207 | +} | ||
208 | + | ||
209 | +/** | ||
210 | + * FieldAccess -> 클래스 인스턴스 변수 접근 난독화 | ||
211 | + * Name -> 변수 사용 난독화 | ||
212 | + * Parameter -> 파라미터 선언 난독화 | ||
213 | + * Class -> 클래스 선언 난독화 | ||
214 | + * VariableDecl -> 변수 선언 난독화 | ||
215 | + * MethodDecl -> 메소드 선언 난독화 | ||
216 | + * MethodCall -> 메소드 사용 난독화 | ||
217 | + **/ | ||
... | \ No newline at end of file | ... | \ No newline at end of file |
1 | +package util.cipher | ||
2 | + | ||
3 | +import java.math.BigInteger | ||
4 | +import java.security.MessageDigest | ||
5 | + | ||
6 | +object CipherHelper{ | ||
7 | + //WITH_DROP_INT_PREFIX | ||
8 | + fun SHA256(input: String): String? { | ||
9 | + var toReturn: String? = null | ||
10 | + try { | ||
11 | + val digest = MessageDigest.getInstance("SHA-256") | ||
12 | + digest.reset() | ||
13 | + digest.update(input.toByteArray(charset("utf8"))) | ||
14 | + toReturn = String.format("%064x", BigInteger(1, digest.digest())) | ||
15 | + } catch (e: Exception) { | ||
16 | + e.printStackTrace() | ||
17 | + } | ||
18 | + | ||
19 | + for(i in toReturn?.indices!!){ | ||
20 | + if(!toReturn[i].isDigit()){ | ||
21 | + toReturn = toReturn.substring(i) + toReturn.substring(0,i) | ||
22 | + break | ||
23 | + } | ||
24 | + } | ||
25 | + return toReturn | ||
26 | + } | ||
27 | +} |
1 | +package util.file | ||
2 | + | ||
3 | +import com.github.javaparser.ast.CompilationUnit | ||
4 | +import java.io.File | ||
5 | +import java.nio.file.Files | ||
6 | +import java.nio.file.Path | ||
7 | +import java.nio.file.Paths | ||
8 | + | ||
9 | +object CompilationUtil { | ||
10 | + fun saveCompilationUnit(path: Path, cu: CompilationUnit) { | ||
11 | + Files.write(path, cu.toString().toByteArray()) | ||
12 | + } | ||
13 | + | ||
14 | + fun saveCompilationUnit(uri: String, cu: CompilationUnit) { | ||
15 | + saveCompilationUnit(Paths.get(uri), cu) | ||
16 | + } | ||
17 | + | ||
18 | + fun saveCompilationUnit(file: File, cu: CompilationUnit) { | ||
19 | + saveCompilationUnit(Paths.get(file.absolutePath), cu) | ||
20 | + } | ||
21 | +} | ||
... | \ No newline at end of file | ... | \ No newline at end of file |
1 | +package util.file | ||
2 | + | ||
3 | +import java.io.File | ||
4 | +import java.nio.file.Files | ||
5 | +import java.nio.file.Path | ||
6 | + | ||
7 | +object FileUtil { | ||
8 | + private val filterFiles = listOf( | ||
9 | + "ExampleInstrumentedTest.java", | ||
10 | + "ExampleUnitTest.java", | ||
11 | + "BuildConfig.java", | ||
12 | + "R.java" | ||
13 | + ) | ||
14 | + | ||
15 | + fun getMainFolder(name: String): File { | ||
16 | + return File(getAppPath(name)) | ||
17 | + } | ||
18 | + | ||
19 | + fun getPackageName(folder: File) : String?{ | ||
20 | + return XMLUtil.getPackageName(getManifestXML(folder)) | ||
21 | + } | ||
22 | + | ||
23 | + fun getAppPath(name: String): String { | ||
24 | + return joinDir(getRoot(), "$name/app/src/main") | ||
25 | + } | ||
26 | + | ||
27 | + fun getRoot(): String { | ||
28 | + return getForwardDir(getCurrentDir()) | ||
29 | + } | ||
30 | + | ||
31 | + fun getJavaFiles(folder: File): List<File> { | ||
32 | + return getFilesByCondition(folder) { it.name.endsWith(".java") && !filterFiles.contains(it.name) } | ||
33 | + } | ||
34 | + | ||
35 | + fun getManifestXML(folder: File): File{ | ||
36 | + return getFilesByCondition(folder) { it.name == "AndroidManifest.xml" }[0] | ||
37 | + } | ||
38 | + | ||
39 | + private fun getFilesByCondition(folder: File, condition: ((File) -> Boolean)): List<File> { | ||
40 | + val files = mutableListOf<File>() | ||
41 | + for (fileEntry in folder.listFiles()) { | ||
42 | + if (fileEntry.isDirectory) { | ||
43 | + files += getFilesByCondition(fileEntry, condition) | ||
44 | + } else { | ||
45 | + if (condition(fileEntry)) { | ||
46 | + files.add(fileEntry) | ||
47 | + } | ||
48 | + } | ||
49 | + } | ||
50 | + return files | ||
51 | + } | ||
52 | + | ||
53 | + fun getCurrentDir(): String { | ||
54 | + return System.getProperty("user.dir") | ||
55 | + } | ||
56 | + | ||
57 | + fun getForwardDir(dir: String): String { | ||
58 | + return dir.split('/').dropLast(1).joinToString("/") | ||
59 | + } | ||
60 | + | ||
61 | + fun joinDir(main: String, sub: String): String { | ||
62 | + return if (main.last() == '/' && sub.first() == '/') main.dropLast(1) + sub | ||
63 | + else if (main.last() == '/' || sub.first() == '/') main + sub | ||
64 | + else "$main/$sub" | ||
65 | + } | ||
66 | + | ||
67 | + fun changeFileName(target : File, change : String){ | ||
68 | + changeFileName(target.toPath(), change) | ||
69 | + } | ||
70 | + | ||
71 | + fun changeFileName(target : Path, change : String){ | ||
72 | + Files.move(target,target.resolveSibling("$change.java")) | ||
73 | + } | ||
74 | +} | ||
... | \ No newline at end of file | ... | \ No newline at end of file |
1 | +package util.file | ||
2 | + | ||
3 | +import org.w3c.dom.Attr | ||
4 | +import org.w3c.dom.NamedNodeMap | ||
5 | +import org.w3c.dom.Node | ||
6 | +import util.cipher.CipherHelper | ||
7 | +import java.io.File | ||
8 | +import javax.xml.parsers.DocumentBuilderFactory | ||
9 | +import javax.xml.transform.TransformerFactory | ||
10 | +import javax.xml.transform.dom.DOMSource | ||
11 | +import javax.xml.transform.stream.StreamResult | ||
12 | + | ||
13 | + | ||
14 | +object XMLUtil { | ||
15 | + fun obfuscateActivityName(xml: File) { | ||
16 | + val documentBuilder = DocumentBuilderFactory.newDefaultInstance().newDocumentBuilder() | ||
17 | + val document = documentBuilder.parse(xml) | ||
18 | + val activityList = document.getElementsByTagName("activity") | ||
19 | + | ||
20 | + for(i in 0 until activityList.length){ | ||
21 | + val activity = activityList.item(i) | ||
22 | + var nameTag = activity.attributes.getNamedItem("android:name") | ||
23 | + nameTag.textContent = CipherHelper.SHA256(nameTag.textContent) | ||
24 | + } | ||
25 | + | ||
26 | + val transformer = TransformerFactory.newInstance().newTransformer() | ||
27 | + val domSource = DOMSource(document) | ||
28 | + val streamResult = StreamResult(File(xml.absolutePath)); | ||
29 | + transformer.transform(domSource, streamResult); | ||
30 | + } | ||
31 | + | ||
32 | + fun obfuscateApplicationName(xml: File) { | ||
33 | + injectApplicationName(xml) | ||
34 | + | ||
35 | + val documentBuilder = DocumentBuilderFactory.newDefaultInstance().newDocumentBuilder() | ||
36 | + val document = documentBuilder.parse(xml) | ||
37 | + val activityList = document.getElementsByTagName("application") | ||
38 | + | ||
39 | + for(i in 0 until activityList.length){ | ||
40 | + val activity = activityList.item(i) | ||
41 | + var nameTag = activity.attributes.getNamedItem("android:name") | ||
42 | + nameTag.textContent = CipherHelper.SHA256(nameTag.textContent) | ||
43 | + } | ||
44 | + | ||
45 | + val transformer = TransformerFactory.newInstance().newTransformer() | ||
46 | + val domSource = DOMSource(document) | ||
47 | + val streamResult = StreamResult(File(xml.absolutePath)); | ||
48 | + transformer.transform(domSource, streamResult); | ||
49 | + } | ||
50 | + | ||
51 | + fun injectApplicationName(xml: File) { | ||
52 | + val documentBuilder = DocumentBuilderFactory.newDefaultInstance().newDocumentBuilder() | ||
53 | + val document = documentBuilder.parse(xml) | ||
54 | + val activityList = document.getElementsByTagName("application") | ||
55 | + | ||
56 | + for(i in 0 until activityList.length){ | ||
57 | + val activity = activityList.item(i) | ||
58 | + var nameTag = activity.attributes.getNamedItem("android:name") | ||
59 | + if(nameTag == null){ | ||
60 | + val attr: Attr = document.createAttribute("android:name") | ||
61 | + attr.nodeValue = "MyApplication" | ||
62 | + activity.attributes.setNamedItem(attr) | ||
63 | + }else{ | ||
64 | + nameTag.textContent = "MyApplication" | ||
65 | + } | ||
66 | + } | ||
67 | + | ||
68 | + val transformer = TransformerFactory.newInstance().newTransformer() | ||
69 | + val domSource = DOMSource(document) | ||
70 | + val streamResult = StreamResult(File(xml.absolutePath)); | ||
71 | + transformer.transform(domSource, streamResult); | ||
72 | + } | ||
73 | + | ||
74 | + fun getPackageName(xml: File) : String?{ | ||
75 | + val documentBuilder = DocumentBuilderFactory.newDefaultInstance().newDocumentBuilder() | ||
76 | + val document = documentBuilder.parse(xml) | ||
77 | + val manifestList = document.getElementsByTagName("manifest") | ||
78 | + | ||
79 | + var packageName : String? = null | ||
80 | + for(i in 0 until manifestList.length){ | ||
81 | + val activity = manifestList.item(i) | ||
82 | + packageName = activity.attributes.getNamedItem("package").nodeValue.toString() | ||
83 | + } | ||
84 | + return packageName | ||
85 | + } | ||
86 | +} | ||
... | \ No newline at end of file | ... | \ No newline at end of file |
1 | +package util.json | ||
2 | + | ||
3 | +import org.json.simple.JSONObject | ||
4 | +import java.io.File | ||
5 | +import java.io.FileWriter | ||
6 | +import java.io.IOException | ||
7 | + | ||
8 | +class JsonFactory private constructor() { | ||
9 | + companion object { | ||
10 | + private val jsonObject = JSONObject() | ||
11 | + private var count = 0 | ||
12 | + private val assetPath by lazy { "$folder/assets/" } | ||
13 | + private val assetFile by lazy { File(assetPath) } | ||
14 | + private val jsonPath by lazy{ "${assetPath}/encryption.json"} | ||
15 | + private lateinit var folder: File | ||
16 | + | ||
17 | + fun build(f: File): JsonFactory { | ||
18 | + this.folder = f | ||
19 | + return JsonFactory() | ||
20 | + } | ||
21 | + } | ||
22 | + | ||
23 | + fun add(value: String) { | ||
24 | + jsonObject[count.toString()] = value | ||
25 | + count++ | ||
26 | + } | ||
27 | + | ||
28 | + fun save() { | ||
29 | + if (!assetFile.exists()) { | ||
30 | + assetFile.mkdir() | ||
31 | + } | ||
32 | + println(jsonObject.toJSONString()) | ||
33 | + | ||
34 | + try { | ||
35 | + FileWriter(jsonPath).use { file -> | ||
36 | + file.write(jsonObject.toJSONString()) | ||
37 | + file.flush() | ||
38 | + } | ||
39 | + } catch (e: IOException) { | ||
40 | + e.printStackTrace() | ||
41 | + } | ||
42 | + } | ||
43 | +} | ||
... | \ No newline at end of file | ... | \ No newline at end of file |
1 | +package util.syntax | ||
2 | + | ||
3 | +import com.github.javaparser.StaticJavaParser | ||
4 | +import com.github.javaparser.ast.CompilationUnit | ||
5 | +import com.github.javaparser.ast.expr.AssignExpr | ||
6 | +import com.github.javaparser.ast.expr.Expression | ||
7 | + | ||
8 | +class AssignUtil(override var cu: CompilationUnit) : BaseUtil<AssignExpr>(AssignExpr::class.java) { | ||
9 | + | ||
10 | + fun setName(name: String?, value: String) { | ||
11 | + val t = StaticJavaParser.parseExpression<Expression>(value) | ||
12 | + looper(name) { it.target = t } | ||
13 | + } | ||
14 | + | ||
15 | + fun setValue(name: String?, value: String) { | ||
16 | + val t = StaticJavaParser.parseExpression<Expression>(value) | ||
17 | + looper(name) { it.value = t } | ||
18 | + } | ||
19 | + | ||
20 | + override fun isNameSame(node: AssignExpr, comp: String): Boolean { | ||
21 | + return node.target.toString() == comp | ||
22 | + } | ||
23 | +} | ||
... | \ No newline at end of file | ... | \ No newline at end of file |
1 | +package util.syntax | ||
2 | + | ||
3 | +import com.github.javaparser.ast.CompilationUnit | ||
4 | +import com.github.javaparser.ast.Node | ||
5 | +import com.github.javaparser.ast.body.MethodDeclaration | ||
6 | +import com.github.javaparser.ast.expr.AssignExpr | ||
7 | +import java.lang.Exception | ||
8 | + | ||
9 | +abstract class BaseUtil<T : Node>(private val clazz : Class<T>) { | ||
10 | + abstract var cu: CompilationUnit | ||
11 | + | ||
12 | + fun get(): List<T> { | ||
13 | + val list = mutableListOf<T>() | ||
14 | + looper(null) { list.add(it) } | ||
15 | + return list.toSet().toList() | ||
16 | + } | ||
17 | + | ||
18 | + fun get(name: String): T? { | ||
19 | + return try{ | ||
20 | + get().filter { isNameSame(it, name) }[0] | ||
21 | + }catch (except: Exception){ | ||
22 | + null | ||
23 | + } | ||
24 | + } | ||
25 | + | ||
26 | + abstract fun isNameSame(node: T, comp:String): Boolean | ||
27 | + | ||
28 | + protected fun looper(name: String?, block: (T) -> Unit) { | ||
29 | + cu.findAll(clazz).filter { | ||
30 | + if (name.isNullOrEmpty()) { | ||
31 | + true | ||
32 | + } else { | ||
33 | + isNameSame(it, name) | ||
34 | + } | ||
35 | + }.forEach { | ||
36 | + block(it) | ||
37 | + } | ||
38 | + } | ||
39 | +} | ||
... | \ No newline at end of file | ... | \ No newline at end of file |
1 | +package util.syntax | ||
2 | + | ||
3 | +import com.github.javaparser.StaticJavaParser | ||
4 | +import com.github.javaparser.ast.CompilationUnit | ||
5 | +import com.github.javaparser.ast.NodeList | ||
6 | +import com.github.javaparser.ast.body.ClassOrInterfaceDeclaration | ||
7 | +import com.github.javaparser.ast.body.MethodDeclaration | ||
8 | +import com.github.javaparser.ast.expr.MethodCallExpr | ||
9 | +import com.github.javaparser.ast.stmt.BlockStmt | ||
10 | +import com.github.javaparser.ast.type.ClassOrInterfaceType | ||
11 | +import java.lang.Exception | ||
12 | + | ||
13 | +class ClassUtil(override var cu: CompilationUnit) : | ||
14 | + BaseUtil<ClassOrInterfaceDeclaration>(ClassOrInterfaceDeclaration::class.java) { | ||
15 | + | ||
16 | + fun setName(name: String?, value: String) { | ||
17 | + looper(name) { it.setName(value) } | ||
18 | + } | ||
19 | + | ||
20 | + fun addMethod(name: String?, code: String) { | ||
21 | + val cu = StaticJavaParser.parse(code) | ||
22 | + val method = cu.findAll(MethodDeclaration::class.java)[0] | ||
23 | + val blockStmt = BlockStmt() | ||
24 | + looper(name) { it.addMember(method) } | ||
25 | + } | ||
26 | + | ||
27 | + fun getExtends(name: String): List<String>? { | ||
28 | + return try{ | ||
29 | + cu.findAll(ClassOrInterfaceDeclaration::class.java) | ||
30 | + .filter {isNameSame(it,name)}[0].extendedTypes.map{it.name.toString()} | ||
31 | + }catch(except : Exception) { | ||
32 | + null | ||
33 | + } | ||
34 | + } | ||
35 | + | ||
36 | + override fun isNameSame(node: ClassOrInterfaceDeclaration, comp: String): Boolean { | ||
37 | + return node.name.toString() == comp | ||
38 | + } | ||
39 | +} | ||
... | \ No newline at end of file | ... | \ No newline at end of file |
1 | +package util.syntax | ||
2 | + | ||
3 | +import com.github.javaparser.ast.CompilationUnit | ||
4 | +import com.github.javaparser.ast.body.ClassOrInterfaceDeclaration | ||
5 | +import com.github.javaparser.ast.expr.FieldAccessExpr | ||
6 | + | ||
7 | +class FieldAccessUtil(override var cu: CompilationUnit) : BaseUtil<FieldAccessExpr>(FieldAccessExpr::class.java) { | ||
8 | + fun setName(name: String?, value: String) { | ||
9 | + looper(name) { it.setName(value) } | ||
10 | + } | ||
11 | + | ||
12 | + override fun isNameSame(node: FieldAccessExpr, comp: String): Boolean { | ||
13 | + return node.name.toString() == comp | ||
14 | + } | ||
15 | +} | ||
... | \ No newline at end of file | ... | \ No newline at end of file |
1 | +package util.syntax | ||
2 | + | ||
3 | +import com.github.javaparser.ast.CompilationUnit | ||
4 | +import com.github.javaparser.ast.body.MethodDeclaration | ||
5 | +import com.github.javaparser.ast.expr.MethodCallExpr | ||
6 | +import com.github.javaparser.ast.stmt.BlockStmt | ||
7 | + | ||
8 | +class MethodCallUtil(override var cu: CompilationUnit) : BaseUtil<MethodCallExpr>(MethodCallExpr::class.java) { | ||
9 | + fun setName(name: String?, value: String) { | ||
10 | + looper(name) { it.setName(value) } | ||
11 | + } | ||
12 | + | ||
13 | + override fun isNameSame(node: MethodCallExpr, comp: String): Boolean { | ||
14 | + return node.name.toString() == comp | ||
15 | + } | ||
16 | +} | ||
... | \ No newline at end of file | ... | \ No newline at end of file |
1 | +package util.syntax | ||
2 | + | ||
3 | +import com.github.javaparser.ast.CompilationUnit | ||
4 | +import com.github.javaparser.ast.body.MethodDeclaration | ||
5 | +import com.github.javaparser.ast.expr.MethodCallExpr | ||
6 | +import com.github.javaparser.ast.stmt.BlockStmt | ||
7 | +import java.lang.Exception | ||
8 | +import java.lang.reflect.Method | ||
9 | + | ||
10 | +class MethodDeclUtil(override var cu: CompilationUnit) : BaseUtil<MethodDeclaration>(MethodDeclaration::class.java) { | ||
11 | + fun setType(name: String?, value: String) { | ||
12 | + looper(name) { it.setType(value) } | ||
13 | + } | ||
14 | + | ||
15 | + fun setName(name: String?, value: String) { | ||
16 | + looper(name) { it.setName(value) } | ||
17 | + } | ||
18 | + | ||
19 | + fun setBody(name: String?, blockStmt: BlockStmt) { | ||
20 | + looper(name) { it.setBody(blockStmt) } | ||
21 | + } | ||
22 | + | ||
23 | + fun injectMethod(name: String, method: String, parameter: List<String>? = null, index: Int = 0) { | ||
24 | + val method = MethodCallExpr(method) | ||
25 | + parameter?.forEach { | ||
26 | + method.addArgument(it) | ||
27 | + } | ||
28 | + | ||
29 | + looper(name) { | ||
30 | + it.findFirst(BlockStmt::class.java).get().apply { | ||
31 | + this.addStatement(index, method) | ||
32 | + } | ||
33 | + } | ||
34 | + } | ||
35 | + | ||
36 | + override fun isNameSame(node: MethodDeclaration, comp: String): Boolean { | ||
37 | + return node.name.toString() == comp | ||
38 | + } | ||
39 | +} | ||
... | \ No newline at end of file | ... | \ No newline at end of file |
1 | +package util.syntax | ||
2 | + | ||
3 | +import com.github.javaparser.ast.CompilationUnit | ||
4 | +import com.github.javaparser.ast.expr.NameExpr | ||
5 | + | ||
6 | +class NameUtil(override var cu: CompilationUnit) : BaseUtil<NameExpr>(NameExpr::class.java){ | ||
7 | + | ||
8 | + fun setName(name: String?, value: String){ | ||
9 | + looper(name) {it.setName(value)} | ||
10 | + } | ||
11 | + | ||
12 | + override fun isNameSame(node: NameExpr, comp: String): Boolean { | ||
13 | + return node.name.toString() == comp | ||
14 | + } | ||
15 | +} | ||
... | \ No newline at end of file | ... | \ No newline at end of file |
1 | +package util.syntax | ||
2 | + | ||
3 | +import com.github.javaparser.ast.CompilationUnit | ||
4 | +import com.github.javaparser.ast.body.Parameter | ||
5 | + | ||
6 | +class ParameterUtil(override var cu: CompilationUnit) : BaseUtil<Parameter>(Parameter::class.java) { | ||
7 | + | ||
8 | + fun setName(name: String?, value: String) { | ||
9 | + looper(name) { it.setName(value) } | ||
10 | + } | ||
11 | + | ||
12 | + override fun isNameSame(node: Parameter, comp: String): Boolean { | ||
13 | + return node.name.toString() == comp | ||
14 | + } | ||
15 | +} | ||
... | \ No newline at end of file | ... | \ No newline at end of file |
1 | +package util.syntax | ||
2 | + | ||
3 | +import com.github.javaparser.ast.CompilationUnit | ||
4 | +import com.github.javaparser.ast.expr.* | ||
5 | +import com.github.javaparser.ast.stmt.BlockStmt | ||
6 | +import com.github.javaparser.ast.stmt.ExpressionStmt | ||
7 | + | ||
8 | +class StringLiteralUtil(override var cu: CompilationUnit) : BaseUtil<StringLiteralExpr>(StringLiteralExpr::class.java) { | ||
9 | + fun replace(method: String) { | ||
10 | + get().forEachIndexed { i, it -> | ||
11 | + val method = MethodCallExpr(method).apply { | ||
12 | + addArgument(stringify(i.toString())) | ||
13 | + addArgument(stringify("")) | ||
14 | + } | ||
15 | + it.replace(method) | ||
16 | + } | ||
17 | + } | ||
18 | + | ||
19 | + private fun stringify(value: String): String = "\"$value\"" | ||
20 | + | ||
21 | + override fun isNameSame(node: StringLiteralExpr, comp: String): Boolean { | ||
22 | + return node.value.toString() == comp | ||
23 | + } | ||
24 | +} | ||
... | \ No newline at end of file | ... | \ No newline at end of file |
1 | +package util.syntax | ||
2 | + | ||
3 | +import com.github.javaparser.ast.CompilationUnit | ||
4 | +import com.github.javaparser.ast.body.VariableDeclarator | ||
5 | +import com.github.javaparser.ast.expr.AssignExpr | ||
6 | + | ||
7 | +class VariableDeclUtil(override var cu: CompilationUnit) : BaseUtil<VariableDeclarator>(VariableDeclarator::class.java){ | ||
8 | + | ||
9 | + fun setValue(name: String?, value: String) { | ||
10 | + looper(name) { it.setInitializer(value) } | ||
11 | + } | ||
12 | + | ||
13 | + fun setName(name: String?, value: String) { | ||
14 | + looper(name) { it.setName(value) } | ||
15 | + } | ||
16 | + | ||
17 | + override fun isNameSame(node: VariableDeclarator, comp: String): Boolean { | ||
18 | + return node.name.toString() == comp | ||
19 | + } | ||
20 | +} | ||
... | \ No newline at end of file | ... | \ No newline at end of file |
obfuscator/test_app_java/.gitignore
0 → 100644
obfuscator/test_app_java/.idea/.name
0 → 100644
1 | +test_app | ||
... | \ No newline at end of file | ... | \ No newline at end of file |
1 | +<component name="ProjectCodeStyleConfiguration"> | ||
2 | + <code_scheme name="Project" version="173"> | ||
3 | + <codeStyleSettings language="XML"> | ||
4 | + <indentOptions> | ||
5 | + <option name="CONTINUATION_INDENT_SIZE" value="4" /> | ||
6 | + </indentOptions> | ||
7 | + <arrangement> | ||
8 | + <rules> | ||
9 | + <section> | ||
10 | + <rule> | ||
11 | + <match> | ||
12 | + <AND> | ||
13 | + <NAME>xmlns:android</NAME> | ||
14 | + <XML_ATTRIBUTE /> | ||
15 | + <XML_NAMESPACE>^$</XML_NAMESPACE> | ||
16 | + </AND> | ||
17 | + </match> | ||
18 | + </rule> | ||
19 | + </section> | ||
20 | + <section> | ||
21 | + <rule> | ||
22 | + <match> | ||
23 | + <AND> | ||
24 | + <NAME>xmlns:.*</NAME> | ||
25 | + <XML_ATTRIBUTE /> | ||
26 | + <XML_NAMESPACE>^$</XML_NAMESPACE> | ||
27 | + </AND> | ||
28 | + </match> | ||
29 | + <order>BY_NAME</order> | ||
30 | + </rule> | ||
31 | + </section> | ||
32 | + <section> | ||
33 | + <rule> | ||
34 | + <match> | ||
35 | + <AND> | ||
36 | + <NAME>.*:id</NAME> | ||
37 | + <XML_ATTRIBUTE /> | ||
38 | + <XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE> | ||
39 | + </AND> | ||
40 | + </match> | ||
41 | + </rule> | ||
42 | + </section> | ||
43 | + <section> | ||
44 | + <rule> | ||
45 | + <match> | ||
46 | + <AND> | ||
47 | + <NAME>.*:name</NAME> | ||
48 | + <XML_ATTRIBUTE /> | ||
49 | + <XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE> | ||
50 | + </AND> | ||
51 | + </match> | ||
52 | + </rule> | ||
53 | + </section> | ||
54 | + <section> | ||
55 | + <rule> | ||
56 | + <match> | ||
57 | + <AND> | ||
58 | + <NAME>name</NAME> | ||
59 | + <XML_ATTRIBUTE /> | ||
60 | + <XML_NAMESPACE>^$</XML_NAMESPACE> | ||
61 | + </AND> | ||
62 | + </match> | ||
63 | + </rule> | ||
64 | + </section> | ||
65 | + <section> | ||
66 | + <rule> | ||
67 | + <match> | ||
68 | + <AND> | ||
69 | + <NAME>style</NAME> | ||
70 | + <XML_ATTRIBUTE /> | ||
71 | + <XML_NAMESPACE>^$</XML_NAMESPACE> | ||
72 | + </AND> | ||
73 | + </match> | ||
74 | + </rule> | ||
75 | + </section> | ||
76 | + <section> | ||
77 | + <rule> | ||
78 | + <match> | ||
79 | + <AND> | ||
80 | + <NAME>.*</NAME> | ||
81 | + <XML_ATTRIBUTE /> | ||
82 | + <XML_NAMESPACE>^$</XML_NAMESPACE> | ||
83 | + </AND> | ||
84 | + </match> | ||
85 | + <order>BY_NAME</order> | ||
86 | + </rule> | ||
87 | + </section> | ||
88 | + <section> | ||
89 | + <rule> | ||
90 | + <match> | ||
91 | + <AND> | ||
92 | + <NAME>.*</NAME> | ||
93 | + <XML_ATTRIBUTE /> | ||
94 | + <XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE> | ||
95 | + </AND> | ||
96 | + </match> | ||
97 | + <order>ANDROID_ATTRIBUTE_ORDER</order> | ||
98 | + </rule> | ||
99 | + </section> | ||
100 | + <section> | ||
101 | + <rule> | ||
102 | + <match> | ||
103 | + <AND> | ||
104 | + <NAME>.*</NAME> | ||
105 | + <XML_ATTRIBUTE /> | ||
106 | + <XML_NAMESPACE>.*</XML_NAMESPACE> | ||
107 | + </AND> | ||
108 | + </match> | ||
109 | + <order>BY_NAME</order> | ||
110 | + </rule> | ||
111 | + </section> | ||
112 | + </rules> | ||
113 | + </arrangement> | ||
114 | + </codeStyleSettings> | ||
115 | + </code_scheme> | ||
116 | +</component> | ||
... | \ No newline at end of file | ... | \ No newline at end of file |
obfuscator/test_app_java/.idea/gradle.xml
0 → 100644
1 | +<?xml version="1.0" encoding="UTF-8"?> | ||
2 | +<project version="4"> | ||
3 | + <component name="GradleSettings"> | ||
4 | + <option name="linkedExternalProjectsSettings"> | ||
5 | + <GradleProjectSettings> | ||
6 | + <option name="distributionType" value="DEFAULT_WRAPPED" /> | ||
7 | + <option name="externalProjectPath" value="$PROJECT_DIR$" /> | ||
8 | + <option name="modules"> | ||
9 | + <set> | ||
10 | + <option value="$PROJECT_DIR$" /> | ||
11 | + <option value="$PROJECT_DIR$/app" /> | ||
12 | + </set> | ||
13 | + </option> | ||
14 | + <option name="resolveModulePerSourceSet" value="false" /> | ||
15 | + <option name="testRunner" value="PLATFORM" /> | ||
16 | + </GradleProjectSettings> | ||
17 | + </option> | ||
18 | + </component> | ||
19 | +</project> | ||
... | \ No newline at end of file | ... | \ No newline at end of file |
obfuscator/test_app_java/.idea/misc.xml
0 → 100644
1 | +<?xml version="1.0" encoding="UTF-8"?> | ||
2 | +<project version="4"> | ||
3 | + <component name="ProjectRootManager" version="2" languageLevel="JDK_1_7" project-jdk-name="1.8" project-jdk-type="JavaSDK"> | ||
4 | + <output url="file://$PROJECT_DIR$/build/classes" /> | ||
5 | + </component> | ||
6 | + <component name="ProjectType"> | ||
7 | + <option name="id" value="Android" /> | ||
8 | + </component> | ||
9 | +</project> | ||
... | \ No newline at end of file | ... | \ No newline at end of file |
1 | +<?xml version="1.0" encoding="UTF-8"?> | ||
2 | +<project version="4"> | ||
3 | + <component name="RunConfigurationProducerService"> | ||
4 | + <option name="ignoredProducers"> | ||
5 | + <set> | ||
6 | + <option value="org.jetbrains.plugins.gradle.execution.test.runner.AllInPackageGradleConfigurationProducer" /> | ||
7 | + <option value="org.jetbrains.plugins.gradle.execution.test.runner.TestClassGradleConfigurationProducer" /> | ||
8 | + <option value="org.jetbrains.plugins.gradle.execution.test.runner.TestMethodGradleConfigurationProducer" /> | ||
9 | + </set> | ||
10 | + </option> | ||
11 | + </component> | ||
12 | +</project> | ||
... | \ No newline at end of file | ... | \ No newline at end of file |
obfuscator/test_app_java/.idea/vcs.xml
0 → 100644
obfuscator/test_app_java/app/.gitignore
0 → 100644
1 | +/build |
obfuscator/test_app_java/app/build.gradle
0 → 100644
1 | +apply plugin: 'com.android.application' | ||
2 | +apply plugin: 'kotlin-android-extensions' | ||
3 | +apply plugin: 'kotlin-android' | ||
4 | + | ||
5 | +android { | ||
6 | + compileSdkVersion 29 | ||
7 | + buildToolsVersion "29.0.2" | ||
8 | + defaultConfig { | ||
9 | + applicationId "com.ono.test_app" | ||
10 | + minSdkVersion 21 | ||
11 | + targetSdkVersion 29 | ||
12 | + versionCode 1 | ||
13 | + versionName "1.0" | ||
14 | + testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" | ||
15 | + } | ||
16 | + buildTypes { | ||
17 | + release { | ||
18 | + minifyEnabled true | ||
19 | + proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' | ||
20 | + } | ||
21 | + } | ||
22 | +} | ||
23 | + | ||
24 | +dependencies { | ||
25 | + implementation fileTree(dir: 'libs', include: ['*.jar']) | ||
26 | + implementation 'androidx.appcompat:appcompat:1.1.0' | ||
27 | + implementation 'androidx.constraintlayout:constraintlayout:1.1.3' | ||
28 | + implementation 'com.jakewharton.timber:timber:4.7.1' | ||
29 | + | ||
30 | + testImplementation 'junit:junit:4.13' | ||
31 | + androidTestImplementation 'androidx.test:runner:1.2.0' | ||
32 | + androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0' | ||
33 | + implementation "androidx.preference:preference:1.1.1" | ||
34 | + implementation 'androidx.core:core-ktx:1.2.0' | ||
35 | + implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" | ||
36 | +} | ||
37 | +repositories { | ||
38 | + mavenCentral() | ||
39 | +} |
1 | +# Add project specific ProGuard rules here. | ||
2 | +# You can control the set of applied configuration files using the | ||
3 | +# proguardFiles setting in build.gradle. | ||
4 | +# | ||
5 | +# For more details, see | ||
6 | +# http://developer.android.com/guide/developing/tools/proguard.html | ||
7 | + | ||
8 | +# If your project uses WebView with JS, uncomment the following | ||
9 | +# and specify the fully qualified class name to the JavaScript interface | ||
10 | +# class: | ||
11 | +#-keepclassmembers class fqcn.of.javascript.interface.for.webview { | ||
12 | +# public *; | ||
13 | +#} | ||
14 | + | ||
15 | +# Uncomment this to preserve the line number information for | ||
16 | +# debugging stack traces. | ||
17 | +#-keepattributes SourceFile,LineNumberTable | ||
18 | + | ||
19 | +# If you keep the line number information, uncomment this to | ||
20 | +# hide the original source file name. | ||
21 | +#-renamesourcefileattribute SourceFile |
1 | +[{"outputType":{"type":"APK"},"apkData":{"type":"MAIN","splits":[],"versionCode":1,"versionName":"1.0","enabled":true,"outputFile":"app-release.apk","fullName":"release","baseName":"release"},"path":"app-release.apk","properties":{}}] | ||
... | \ No newline at end of file | ... | \ No newline at end of file |
obfuscator/test_app_java/app/src/androidTest/java/com/ono/test_app/ExampleInstrumentedTest.java
0 → 100644
1 | +package com.ono.test_app; | ||
2 | + | ||
3 | +import android.content.Context; | ||
4 | + | ||
5 | +import androidx.test.platform.app.InstrumentationRegistry; | ||
6 | +import androidx.test.ext.junit.runners.AndroidJUnit4; | ||
7 | + | ||
8 | +import org.junit.Test; | ||
9 | +import org.junit.runner.RunWith; | ||
10 | + | ||
11 | +import static org.junit.Assert.*; | ||
12 | + | ||
13 | +/** | ||
14 | + * Instrumented test, which will execute on an Android device. | ||
15 | + * | ||
16 | + * @see <a href="http://d.android.com/tools/testing">Testing documentation</a> | ||
17 | + */ | ||
18 | +@RunWith(AndroidJUnit4.class) | ||
19 | +public class ExampleInstrumentedTest { | ||
20 | + @Test | ||
21 | + public void useAppContext() { | ||
22 | + // Context of the app under test. | ||
23 | + Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext(); | ||
24 | + | ||
25 | + assertEquals("com.ono.test_app", appContext.getPackageName()); | ||
26 | + } | ||
27 | +} |
1 | +<?xml version="1.0" encoding="utf-8" standalone="no"?><manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.ono.test_app"> | ||
2 | + | ||
3 | + <application android:allowBackup="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:name="bbf24e1ea6e9832bbb2a745f80bf9e637e97df2603837aeb1d8e65385f554123" android:roundIcon="@mipmap/ic_launcher_round" android:supportsRtl="true" android:theme="@style/AppTheme"> | ||
4 | + <activity android:name="fde94312239df6837d838778b655f7f215a16570150d6bd72a1c6ae5f28a5c53"> | ||
5 | + <intent-filter> | ||
6 | + <action android:name="android.intent.action.MAIN"/> | ||
7 | + | ||
8 | + <category android:name="android.intent.category.LAUNCHER"/> | ||
9 | + </intent-filter> | ||
10 | + </activity> | ||
11 | + </application> | ||
12 | + | ||
13 | +</manifest> | ||
... | \ No newline at end of file | ... | \ No newline at end of file |
1 | +{"0":"test","1":"테스트1","2":"테스트2","3":"테스트3"} | ||
... | \ No newline at end of file | ... | \ No newline at end of file |
1 | +package com.ono.test_app; | ||
2 | + | ||
3 | +import androidx.appcompat.app.AppCompatActivity; | ||
4 | + | ||
5 | +import android.content.Context; | ||
6 | +import android.content.SharedPreferences; | ||
7 | +import android.os.Bundle; | ||
8 | +import android.widget.TextView; | ||
9 | + | ||
10 | +import org.json.JSONArray; | ||
11 | +import org.json.JSONException; | ||
12 | +import org.json.JSONObject; | ||
13 | + | ||
14 | +import java.io.IOException; | ||
15 | +import java.io.InputStream; | ||
16 | +import java.io.UnsupportedEncodingException; | ||
17 | +import java.util.Iterator; | ||
18 | + | ||
19 | +public class MainActivity extends AppCompatActivity { | ||
20 | + | ||
21 | + private String test = "test"; | ||
22 | + | ||
23 | + @Override | ||
24 | + protected void onCreate(Bundle bundle) { | ||
25 | + super.onCreate(bundle); | ||
26 | + this.setContentView(R.layout.activity_main); | ||
27 | + TextView textView = findViewById(R.id.textView); | ||
28 | + textView.setText(test); | ||
29 | + fTest("테스트1"); | ||
30 | + } | ||
31 | + | ||
32 | + void fTest(String test) { | ||
33 | + test = "테스트2"; | ||
34 | + String t = "테스트3"; | ||
35 | + } | ||
36 | +} | ||
... | \ No newline at end of file | ... | \ No newline at end of file |
1 | +package com.ono.test_app; | ||
2 | + | ||
3 | +import android.app.Application; | ||
4 | +import android.content.Context; | ||
5 | +import com.ono.test_app.cache.SecureSharedPreferences; | ||
6 | +import android.content.SharedPreferences; | ||
7 | +import androidx.preference.PreferenceManager; | ||
8 | +import org.json.JSONObject; | ||
9 | +import java.io.InputStream; | ||
10 | +import java.util.Iterator; | ||
11 | + | ||
12 | +public class bbf24e1ea6e9832bbb2a745f80bf9e637e97df2603837aeb1d8e65385f554123 extends Application { | ||
13 | + | ||
14 | + static SecureSharedPreferences a46a15e810034f80d4bef61772990ec9895e961d767fe9635485ace95826b266 = null; | ||
15 | + | ||
16 | + @Override | ||
17 | + public void onCreate() { | ||
18 | + bf86075ceab2af34c4bf04695936f6522b383cee6b0d377a410b470499ab5485(); | ||
19 | + super.onCreate(); | ||
20 | + } | ||
21 | + | ||
22 | + private void bf86075ceab2af34c4bf04695936f6522b383cee6b0d377a410b470499ab5485() { | ||
23 | + SharedPreferences de9c5a7a44d19e56cd9ae1a554bf67847afb0c58f6e12fa29ac7ddfca9940148 = PreferenceManager.getDefaultSharedPreferences(this); | ||
24 | + a46a15e810034f80d4bef61772990ec9895e961d767fe9635485ace95826b266 = new SecureSharedPreferences(de9c5a7a44d19e56cd9ae1a554bf67847afb0c58f6e12fa29ac7ddfca9940148); | ||
25 | + b7f8fa0aa628d3ab67838133ac702fb1dfc8d712d7cc9672311ff78b8a73dc76(this); | ||
26 | + try { | ||
27 | + JSONObject cbf2b2ea5e035f9d878ad9d2001f041da2b92217fd1e91abea0c4c8383743025 = new JSONObject(b7f8fa0aa628d3ab67838133ac702fb1dfc8d712d7cc9672311ff78b8a73dc76(this)); | ||
28 | + Iterator<String> a53f0774c8ceff574a1fdcb0d470dbd382b3db273cff4344b6d39d5379c92348 = cbf2b2ea5e035f9d878ad9d2001f041da2b92217fd1e91abea0c4c8383743025.keys(); | ||
29 | + while (a53f0774c8ceff574a1fdcb0d470dbd382b3db273cff4344b6d39d5379c92348.hasNext()) { | ||
30 | + String c70e12b7a0646f92279f427c7b38e7334d8e5389cff167a1dc30e73f826b6832 = a53f0774c8ceff574a1fdcb0d470dbd382b3db273cff4344b6d39d5379c92348.next(); | ||
31 | + a46a15e810034f80d4bef61772990ec9895e961d767fe9635485ace95826b266.put(c70e12b7a0646f92279f427c7b38e7334d8e5389cff167a1dc30e73f826b6832, cbf2b2ea5e035f9d878ad9d2001f041da2b92217fd1e91abea0c4c8383743025.get(c70e12b7a0646f92279f427c7b38e7334d8e5389cff167a1dc30e73f826b6832).toString()); | ||
32 | + } | ||
33 | + } catch (Exception f79bb7b435b05321651daefd374cdc681dc06faa65e374e38337b88ca046dea3) { | ||
34 | + f79bb7b435b05321651daefd374cdc681dc06faa65e374e38337b88ca046dea3.printStackTrace(); | ||
35 | + } | ||
36 | + } | ||
37 | + | ||
38 | + public String b7f8fa0aa628d3ab67838133ac702fb1dfc8d712d7cc9672311ff78b8a73dc76(Context ea7792a26f405e2ae9c6f49ca93bbe6076ceac0a1fc53d83426c7d7f2d9377e4) { | ||
39 | + String bd175f329720378ce83dd56a1b6b1f5291a60182d6c54b5e0d1e8d248a267a02 = null; | ||
40 | + try { | ||
41 | + InputStream fa51fd49abf67705d6a35d18218c115ff5633aec1f9ebfdc9d5d4956416f57f6 = ea7792a26f405e2ae9c6f49ca93bbe6076ceac0a1fc53d83426c7d7f2d9377e4.getAssets().open("encryption.json"); | ||
42 | + int ccdcbe846f3da4eb044fbdf64bf6b57902388ab72fb0c852ba72280f8d478b40 = fa51fd49abf67705d6a35d18218c115ff5633aec1f9ebfdc9d5d4956416f57f6.available(); | ||
43 | + byte[] d0ca8c2ac0dab879bf27bfb58227b301db17f5ca716d065e7c884253d3ab99e4 = new byte[ccdcbe846f3da4eb044fbdf64bf6b57902388ab72fb0c852ba72280f8d478b40]; | ||
44 | + fa51fd49abf67705d6a35d18218c115ff5633aec1f9ebfdc9d5d4956416f57f6.read(d0ca8c2ac0dab879bf27bfb58227b301db17f5ca716d065e7c884253d3ab99e4); | ||
45 | + fa51fd49abf67705d6a35d18218c115ff5633aec1f9ebfdc9d5d4956416f57f6.close(); | ||
46 | + bd175f329720378ce83dd56a1b6b1f5291a60182d6c54b5e0d1e8d248a267a02 = new String(d0ca8c2ac0dab879bf27bfb58227b301db17f5ca716d065e7c884253d3ab99e4, "UTF-8"); | ||
47 | + } catch (Exception f79bb7b435b05321651daefd374cdc681dc06faa65e374e38337b88ca046dea3) { | ||
48 | + f79bb7b435b05321651daefd374cdc681dc06faa65e374e38337b88ca046dea3.printStackTrace(); | ||
49 | + } | ||
50 | + return bd175f329720378ce83dd56a1b6b1f5291a60182d6c54b5e0d1e8d248a267a02; | ||
51 | + } | ||
52 | +} |
obfuscator/test_app_java/app/src/main/java/com/ono/test_app/cache/AndroidRsaCipherHelper.kt
0 → 100644
1 | +package com.ono.test_app.cache | ||
2 | + | ||
3 | +import android.annotation.TargetApi | ||
4 | +import android.content.Context | ||
5 | +import android.os.Build | ||
6 | +import android.security.KeyPairGeneratorSpec | ||
7 | +import android.security.keystore.KeyGenParameterSpec | ||
8 | +import android.security.keystore.KeyProperties | ||
9 | +import android.util.Base64 | ||
10 | +import timber.log.Timber | ||
11 | +import java.math.BigInteger | ||
12 | +import java.security.GeneralSecurityException | ||
13 | +import java.security.KeyPairGenerator | ||
14 | +import java.security.KeyStore | ||
15 | +import java.security.spec.RSAKeyGenParameterSpec | ||
16 | +import java.security.spec.RSAKeyGenParameterSpec.F4 | ||
17 | +import java.util.* | ||
18 | +import javax.crypto.Cipher | ||
19 | +import javax.security.auth.x500.X500Principal | ||
20 | + | ||
21 | +object AndroidRsaCipherHelper { | ||
22 | + private const val KEY_LENGTH_BIT = 2048 | ||
23 | + private const val VALIDITY_YEARS = 25 | ||
24 | + private const val KEY_PROVIDER_NAME = "AndroidKeyStore" | ||
25 | + private const val CIPHER_ALGORITHM = | ||
26 | + "${KeyProperties.KEY_ALGORITHM_RSA}/" + | ||
27 | + "${KeyProperties.BLOCK_MODE_ECB}/" + | ||
28 | + KeyProperties.ENCRYPTION_PADDING_RSA_PKCS1 | ||
29 | + | ||
30 | + private lateinit var keyEntry: KeyStore.Entry | ||
31 | + | ||
32 | + @Suppress("ObjectPropertyName") | ||
33 | + private var _isSupported = false | ||
34 | + | ||
35 | + val isSupported: Boolean | ||
36 | + get() = _isSupported | ||
37 | + | ||
38 | + private lateinit var appContext: Context | ||
39 | + | ||
40 | + internal fun init(applicationContext: Context) { | ||
41 | + if (isSupported) { | ||
42 | + Timber.w("Already initialised - Do not attempt to initialise this twice") | ||
43 | + return | ||
44 | + } | ||
45 | + | ||
46 | + appContext = applicationContext | ||
47 | + val alias = "${appContext.packageName}.rsakeypairs" | ||
48 | + val keyStore = KeyStore.getInstance("AndroidKeyStore").apply { | ||
49 | + load(null) | ||
50 | + } | ||
51 | + | ||
52 | + val result: Boolean = if (keyStore.containsAlias(alias)) { | ||
53 | + true | ||
54 | + } else { | ||
55 | + Timber.v("No keypair for %s, creating a new one", alias) | ||
56 | + | ||
57 | + if (Build.VERSION.SDK_INT > Build.VERSION_CODES.LOLLIPOP_MR1 && initAndroidM(alias)) { | ||
58 | + true | ||
59 | + } else { | ||
60 | + initAndroidL(alias) | ||
61 | + } | ||
62 | + } | ||
63 | + | ||
64 | + keyEntry = keyStore.getEntry(alias, null) | ||
65 | + _isSupported = result | ||
66 | + } | ||
67 | + | ||
68 | + @TargetApi(Build.VERSION_CODES.M) | ||
69 | + private fun initAndroidM(alias: String): Boolean { | ||
70 | + try { | ||
71 | + with(KeyPairGenerator.getInstance(KeyProperties.KEY_ALGORITHM_RSA, KEY_PROVIDER_NAME), { | ||
72 | + val spec = KeyGenParameterSpec.Builder(alias, | ||
73 | + KeyProperties.PURPOSE_ENCRYPT or KeyProperties.PURPOSE_DECRYPT) | ||
74 | + .setAlgorithmParameterSpec(RSAKeyGenParameterSpec(KEY_LENGTH_BIT, F4)) | ||
75 | + .setBlockModes(KeyProperties.BLOCK_MODE_CBC) | ||
76 | + .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_RSA_PKCS1) | ||
77 | + .setDigests(KeyProperties.DIGEST_SHA512, | ||
78 | + KeyProperties.DIGEST_SHA384, | ||
79 | + KeyProperties.DIGEST_SHA256) | ||
80 | + /* | ||
81 | + * Setting true only permit the private key to be used if the user authenticated | ||
82 | + * within the last five minutes. | ||
83 | + */ | ||
84 | + .setUserAuthenticationRequired(false) | ||
85 | + .build() | ||
86 | + initialize(spec) | ||
87 | + generateKeyPair() | ||
88 | + }) | ||
89 | + Timber.i("Random keypair with %s/%s/%s is created.", KeyProperties.KEY_ALGORITHM_RSA, | ||
90 | + KeyProperties.BLOCK_MODE_CBC, KeyProperties.ENCRYPTION_PADDING_RSA_PKCS1) | ||
91 | + | ||
92 | + return true | ||
93 | + } catch (e: GeneralSecurityException) { | ||
94 | + /* | ||
95 | + * Nonsense, but some devices manufactured by developing countries have actual problem | ||
96 | + * Consider using JCE substitutes like Spongy castle(Bouncy castle for android) | ||
97 | + */ | ||
98 | + Timber.w(e, "It seems that this device does not support RSA algorithm!!") | ||
99 | + return false | ||
100 | + } | ||
101 | + } | ||
102 | + | ||
103 | + private fun initAndroidL(alias: String): Boolean { | ||
104 | + try { | ||
105 | + with(KeyPairGenerator.getInstance("RSA", KEY_PROVIDER_NAME), { | ||
106 | + val start = Calendar.getInstance(Locale.ENGLISH) | ||
107 | + val end = Calendar.getInstance(Locale.ENGLISH).apply { add(Calendar.YEAR, VALIDITY_YEARS) } | ||
108 | + val spec = KeyPairGeneratorSpec.Builder(appContext) | ||
109 | + .setKeySize(KEY_LENGTH_BIT) | ||
110 | + .setAlias(alias) | ||
111 | + .setSubject(X500Principal("CN=francescojo.github.com, OU=Android dev, O=Francesco Jo, L=Chiyoda, ST=Tokyo, C=JP")) | ||
112 | + .setSerialNumber(BigInteger.ONE) | ||
113 | + .setStartDate(start.time) | ||
114 | + .setEndDate(end.time) | ||
115 | + .build() | ||
116 | + initialize(spec) | ||
117 | + generateKeyPair() | ||
118 | + }) | ||
119 | + Timber.i("Random RSA algorithm keypair is created.") | ||
120 | + | ||
121 | + return true | ||
122 | + } catch (e: GeneralSecurityException) { | ||
123 | + Timber.w(e, "It seems that this device does not support encryption!!") | ||
124 | + | ||
125 | + return false | ||
126 | + } | ||
127 | + } | ||
128 | + | ||
129 | + fun encrypt(plainText: String): String { | ||
130 | + if (!_isSupported) { | ||
131 | + return plainText | ||
132 | + } | ||
133 | + | ||
134 | + val cipher = Cipher.getInstance(CIPHER_ALGORITHM).apply({ | ||
135 | + init(Cipher.ENCRYPT_MODE, (keyEntry as KeyStore.PrivateKeyEntry).certificate.publicKey) | ||
136 | + }) | ||
137 | + val bytes = plainText.toByteArray(Charsets.UTF_8) | ||
138 | + val encryptedBytes = cipher.doFinal(bytes) | ||
139 | + val base64EncryptedBytes = Base64.encode(encryptedBytes, Base64.DEFAULT) | ||
140 | + | ||
141 | + return String(base64EncryptedBytes) | ||
142 | + } | ||
143 | + | ||
144 | + fun decrypt(base64EncryptedCipherText: String): String { | ||
145 | + if (!_isSupported) { | ||
146 | + return base64EncryptedCipherText | ||
147 | + } | ||
148 | + | ||
149 | + val cipher = Cipher.getInstance(CIPHER_ALGORITHM).apply({ | ||
150 | + init(Cipher.DECRYPT_MODE, (keyEntry as KeyStore.PrivateKeyEntry).privateKey) | ||
151 | + }) | ||
152 | + val base64EncryptedBytes = base64EncryptedCipherText.toByteArray(Charsets.UTF_8) | ||
153 | + val encryptedBytes = Base64.decode(base64EncryptedBytes, Base64.DEFAULT) | ||
154 | + val decryptedBytes = cipher.doFinal(encryptedBytes) | ||
155 | + | ||
156 | + return String(decryptedBytes) | ||
157 | + } | ||
158 | +} | ||
... | \ No newline at end of file | ... | \ No newline at end of file |
obfuscator/test_app_java/app/src/main/java/com/ono/test_app/cache/SecureSharedPreference.kt
0 → 100644
1 | +package com.ono.test_app.cache | ||
2 | + | ||
3 | +import android.content.SharedPreferences | ||
4 | + | ||
5 | +class SecureSharedPreferences(private val sharedPref: SharedPreferences) { | ||
6 | + fun contains(key: String) = sharedPref.contains(key) | ||
7 | + | ||
8 | + fun get(key: String, defaultValue: Boolean): Boolean = getInternal(key, defaultValue) | ||
9 | + | ||
10 | + fun get(key: String, defaultValue: Int): Int = getInternal(key, defaultValue) | ||
11 | + | ||
12 | + fun get(key: String, defaultValue: Long): Long = getInternal(key, defaultValue) | ||
13 | + | ||
14 | + fun get(key: String, defaultValue: String): String = getInternal(key, defaultValue) | ||
15 | + | ||
16 | + private fun <T : Any> getInternal(key: String, defaultValue: T): T { | ||
17 | + val str = sharedPref.getString(key, "") | ||
18 | + if (str.isNullOrEmpty()) { | ||
19 | + return defaultValue | ||
20 | + } | ||
21 | + val value = AndroidRsaCipherHelper.decrypt(str) | ||
22 | + | ||
23 | + @Suppress("PlatformExtensionReceiverOfInline", "UNCHECKED_CAST", "IMPLICIT_CAST_TO_ANY") | ||
24 | + return when(defaultValue) { | ||
25 | + is Boolean -> value.toBoolean() | ||
26 | + is Int -> value.toInt() | ||
27 | + is Long -> value.toLong() | ||
28 | + is String -> value | ||
29 | + else -> throw IllegalArgumentException("defaultValue only could be one of these types: Boolean, Int, Long, String") | ||
30 | + } as T | ||
31 | + } | ||
32 | + | ||
33 | + fun put(key: String, value: Boolean) = putInternal(key, value) | ||
34 | + | ||
35 | + fun put(key: String, value: Int) = putInternal(key, value) | ||
36 | + | ||
37 | + fun put(key: String, value: Long) = putInternal(key, value) | ||
38 | + | ||
39 | + fun put(key: String, value: String) = putInternal(key, value) | ||
40 | + | ||
41 | + private fun putInternal(key: String, value: Any?) { | ||
42 | + try { | ||
43 | + sharedPref.edit().run { | ||
44 | + if (value == null) { | ||
45 | + remove(key) | ||
46 | + } else { | ||
47 | + putString(key, AndroidRsaCipherHelper.encrypt(value.toString())) | ||
48 | + } | ||
49 | + | ||
50 | + apply() | ||
51 | + } | ||
52 | + } catch (e: Throwable) { | ||
53 | + e.printStackTrace() | ||
54 | + } | ||
55 | + } | ||
56 | + | ||
57 | + companion object { | ||
58 | + fun wrap(sharedPref: SharedPreferences) = SecureSharedPreferences(sharedPref) | ||
59 | + } | ||
60 | +} | ||
... | \ No newline at end of file | ... | \ No newline at end of file |
1 | +package com.ono.test_app; | ||
2 | + | ||
3 | +import androidx.appcompat.app.AppCompatActivity; | ||
4 | +import android.content.Context; | ||
5 | +import android.content.SharedPreferences; | ||
6 | +import android.os.Bundle; | ||
7 | +import android.widget.TextView; | ||
8 | +import org.json.JSONArray; | ||
9 | +import org.json.JSONException; | ||
10 | +import org.json.JSONObject; | ||
11 | +import java.io.IOException; | ||
12 | +import java.io.InputStream; | ||
13 | +import java.io.UnsupportedEncodingException; | ||
14 | +import java.util.Iterator; | ||
15 | + | ||
16 | +public class fde94312239df6837d838778b655f7f215a16570150d6bd72a1c6ae5f28a5c53 extends AppCompatActivity { | ||
17 | + | ||
18 | + private String f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a089 | ||
19 | + = bbf24e1ea6e9832bbb2a745f80bf9e637e97df2603837aeb1d8e65385f554123 | ||
20 | + .a46a15e810034f80d4bef61772990ec9895e961d767fe9635485ace95826b266 | ||
21 | + .get("0", ""); | ||
22 | + | ||
23 | + @Override | ||
24 | + protected void onCreate(Bundle e6ed65d77d6364eeaed5a745ba5c4985ae2b700dd85d7cf7f027bdf294a33fc1) { | ||
25 | + super.onCreate(e6ed65d77d6364eeaed5a745ba5c4985ae2b700dd85d7cf7f027bdf294a33fc1); | ||
26 | + this.setContentView(R.layout.activity_main); | ||
27 | + TextView b27a6a0d519ce361947681b6887f6eb0e9b4bb620d22ad404b23aa1e0e465d47 = findViewById(R.id.textView); | ||
28 | + b27a6a0d519ce361947681b6887f6eb0e9b4bb620d22ad404b23aa1e0e465d47 | ||
29 | + .setText(f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a089); | ||
30 | + | ||
31 | + d131faf9dc50392ca68b2a3cde6ab848e98771849dcfce95b9401f6ebee26c2c( | ||
32 | + bbf24e1ea6e9832bbb2a745f80bf9e637e97df2603837aeb1d8e65385f554123 | ||
33 | + .a46a15e810034f80d4bef61772990ec9895e961d767fe9635485ace95826b266 | ||
34 | + .get("1", "")); | ||
35 | + } | ||
36 | + | ||
37 | + void d131faf9dc50392ca68b2a3cde6ab848e98771849dcfce95b9401f6ebee26c2c(String f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a089) { | ||
38 | + f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a089 | ||
39 | + = bbf24e1ea6e9832bbb2a745f80bf9e637e97df2603837aeb1d8e65385f554123 | ||
40 | + .a46a15e810034f80d4bef61772990ec9895e961d767fe9635485ace95826b266 | ||
41 | + .get("2", ""); | ||
42 | + | ||
43 | + String e3b98a4da31a127d4bde6e43033f66ba274cab0eb7eb1c70ec41402bf6273dd8 | ||
44 | + = bbf24e1ea6e9832bbb2a745f80bf9e637e97df2603837aeb1d8e65385f554123 | ||
45 | + .a46a15e810034f80d4bef61772990ec9895e961d767fe9635485ace95826b266 | ||
46 | + .get("3", ""); | ||
47 | + } | ||
48 | +} |
1 | +<vector xmlns:android="http://schemas.android.com/apk/res/android" | ||
2 | + xmlns:aapt="http://schemas.android.com/aapt" | ||
3 | + android:width="108dp" | ||
4 | + android:height="108dp" | ||
5 | + android:viewportWidth="108" | ||
6 | + android:viewportHeight="108"> | ||
7 | + <path | ||
8 | + android:fillType="evenOdd" | ||
9 | + android:pathData="M32,64C32,64 38.39,52.99 44.13,50.95C51.37,48.37 70.14,49.57 70.14,49.57L108.26,87.69L108,109.01L75.97,107.97L32,64Z" | ||
10 | + android:strokeWidth="1" | ||
11 | + android:strokeColor="#00000000"> | ||
12 | + <aapt:attr name="android:fillColor"> | ||
13 | + <gradient | ||
14 | + android:endX="78.5885" | ||
15 | + android:endY="90.9159" | ||
16 | + android:startX="48.7653" | ||
17 | + android:startY="61.0927" | ||
18 | + android:type="linear"> | ||
19 | + <item | ||
20 | + android:color="#44000000" | ||
21 | + android:offset="0.0" /> | ||
22 | + <item | ||
23 | + android:color="#00000000" | ||
24 | + android:offset="1.0" /> | ||
25 | + </gradient> | ||
26 | + </aapt:attr> | ||
27 | + </path> | ||
28 | + <path | ||
29 | + android:fillColor="#FFFFFF" | ||
30 | + android:fillType="nonZero" | ||
31 | + android:pathData="M66.94,46.02L66.94,46.02C72.44,50.07 76,56.61 76,64L32,64C32,56.61 35.56,50.11 40.98,46.06L36.18,41.19C35.45,40.45 35.45,39.3 36.18,38.56C36.91,37.81 38.05,37.81 38.78,38.56L44.25,44.05C47.18,42.57 50.48,41.71 54,41.71C57.48,41.71 60.78,42.57 63.68,44.05L69.11,38.56C69.84,37.81 70.98,37.81 71.71,38.56C72.44,39.3 72.44,40.45 71.71,41.19L66.94,46.02ZM62.94,56.92C64.08,56.92 65,56.01 65,54.88C65,53.76 64.08,52.85 62.94,52.85C61.8,52.85 60.88,53.76 60.88,54.88C60.88,56.01 61.8,56.92 62.94,56.92ZM45.06,56.92C46.2,56.92 47.13,56.01 47.13,54.88C47.13,53.76 46.2,52.85 45.06,52.85C43.92,52.85 43,53.76 43,54.88C43,56.01 43.92,56.92 45.06,56.92Z" | ||
32 | + android:strokeWidth="1" | ||
33 | + android:strokeColor="#00000000" /> | ||
34 | +</vector> |
1 | +<?xml version="1.0" encoding="utf-8"?> | ||
2 | +<vector xmlns:android="http://schemas.android.com/apk/res/android" | ||
3 | + android:width="108dp" | ||
4 | + android:height="108dp" | ||
5 | + android:viewportWidth="108" | ||
6 | + android:viewportHeight="108"> | ||
7 | + <path | ||
8 | + android:fillColor="#008577" | ||
9 | + android:pathData="M0,0h108v108h-108z" /> | ||
10 | + <path | ||
11 | + android:fillColor="#00000000" | ||
12 | + android:pathData="M9,0L9,108" | ||
13 | + android:strokeWidth="0.8" | ||
14 | + android:strokeColor="#33FFFFFF" /> | ||
15 | + <path | ||
16 | + android:fillColor="#00000000" | ||
17 | + android:pathData="M19,0L19,108" | ||
18 | + android:strokeWidth="0.8" | ||
19 | + android:strokeColor="#33FFFFFF" /> | ||
20 | + <path | ||
21 | + android:fillColor="#00000000" | ||
22 | + android:pathData="M29,0L29,108" | ||
23 | + android:strokeWidth="0.8" | ||
24 | + android:strokeColor="#33FFFFFF" /> | ||
25 | + <path | ||
26 | + android:fillColor="#00000000" | ||
27 | + android:pathData="M39,0L39,108" | ||
28 | + android:strokeWidth="0.8" | ||
29 | + android:strokeColor="#33FFFFFF" /> | ||
30 | + <path | ||
31 | + android:fillColor="#00000000" | ||
32 | + android:pathData="M49,0L49,108" | ||
33 | + android:strokeWidth="0.8" | ||
34 | + android:strokeColor="#33FFFFFF" /> | ||
35 | + <path | ||
36 | + android:fillColor="#00000000" | ||
37 | + android:pathData="M59,0L59,108" | ||
38 | + android:strokeWidth="0.8" | ||
39 | + android:strokeColor="#33FFFFFF" /> | ||
40 | + <path | ||
41 | + android:fillColor="#00000000" | ||
42 | + android:pathData="M69,0L69,108" | ||
43 | + android:strokeWidth="0.8" | ||
44 | + android:strokeColor="#33FFFFFF" /> | ||
45 | + <path | ||
46 | + android:fillColor="#00000000" | ||
47 | + android:pathData="M79,0L79,108" | ||
48 | + android:strokeWidth="0.8" | ||
49 | + android:strokeColor="#33FFFFFF" /> | ||
50 | + <path | ||
51 | + android:fillColor="#00000000" | ||
52 | + android:pathData="M89,0L89,108" | ||
53 | + android:strokeWidth="0.8" | ||
54 | + android:strokeColor="#33FFFFFF" /> | ||
55 | + <path | ||
56 | + android:fillColor="#00000000" | ||
57 | + android:pathData="M99,0L99,108" | ||
58 | + android:strokeWidth="0.8" | ||
59 | + android:strokeColor="#33FFFFFF" /> | ||
60 | + <path | ||
61 | + android:fillColor="#00000000" | ||
62 | + android:pathData="M0,9L108,9" | ||
63 | + android:strokeWidth="0.8" | ||
64 | + android:strokeColor="#33FFFFFF" /> | ||
65 | + <path | ||
66 | + android:fillColor="#00000000" | ||
67 | + android:pathData="M0,19L108,19" | ||
68 | + android:strokeWidth="0.8" | ||
69 | + android:strokeColor="#33FFFFFF" /> | ||
70 | + <path | ||
71 | + android:fillColor="#00000000" | ||
72 | + android:pathData="M0,29L108,29" | ||
73 | + android:strokeWidth="0.8" | ||
74 | + android:strokeColor="#33FFFFFF" /> | ||
75 | + <path | ||
76 | + android:fillColor="#00000000" | ||
77 | + android:pathData="M0,39L108,39" | ||
78 | + android:strokeWidth="0.8" | ||
79 | + android:strokeColor="#33FFFFFF" /> | ||
80 | + <path | ||
81 | + android:fillColor="#00000000" | ||
82 | + android:pathData="M0,49L108,49" | ||
83 | + android:strokeWidth="0.8" | ||
84 | + android:strokeColor="#33FFFFFF" /> | ||
85 | + <path | ||
86 | + android:fillColor="#00000000" | ||
87 | + android:pathData="M0,59L108,59" | ||
88 | + android:strokeWidth="0.8" | ||
89 | + android:strokeColor="#33FFFFFF" /> | ||
90 | + <path | ||
91 | + android:fillColor="#00000000" | ||
92 | + android:pathData="M0,69L108,69" | ||
93 | + android:strokeWidth="0.8" | ||
94 | + android:strokeColor="#33FFFFFF" /> | ||
95 | + <path | ||
96 | + android:fillColor="#00000000" | ||
97 | + android:pathData="M0,79L108,79" | ||
98 | + android:strokeWidth="0.8" | ||
99 | + android:strokeColor="#33FFFFFF" /> | ||
100 | + <path | ||
101 | + android:fillColor="#00000000" | ||
102 | + android:pathData="M0,89L108,89" | ||
103 | + android:strokeWidth="0.8" | ||
104 | + android:strokeColor="#33FFFFFF" /> | ||
105 | + <path | ||
106 | + android:fillColor="#00000000" | ||
107 | + android:pathData="M0,99L108,99" | ||
108 | + android:strokeWidth="0.8" | ||
109 | + android:strokeColor="#33FFFFFF" /> | ||
110 | + <path | ||
111 | + android:fillColor="#00000000" | ||
112 | + android:pathData="M19,29L89,29" | ||
113 | + android:strokeWidth="0.8" | ||
114 | + android:strokeColor="#33FFFFFF" /> | ||
115 | + <path | ||
116 | + android:fillColor="#00000000" | ||
117 | + android:pathData="M19,39L89,39" | ||
118 | + android:strokeWidth="0.8" | ||
119 | + android:strokeColor="#33FFFFFF" /> | ||
120 | + <path | ||
121 | + android:fillColor="#00000000" | ||
122 | + android:pathData="M19,49L89,49" | ||
123 | + android:strokeWidth="0.8" | ||
124 | + android:strokeColor="#33FFFFFF" /> | ||
125 | + <path | ||
126 | + android:fillColor="#00000000" | ||
127 | + android:pathData="M19,59L89,59" | ||
128 | + android:strokeWidth="0.8" | ||
129 | + android:strokeColor="#33FFFFFF" /> | ||
130 | + <path | ||
131 | + android:fillColor="#00000000" | ||
132 | + android:pathData="M19,69L89,69" | ||
133 | + android:strokeWidth="0.8" | ||
134 | + android:strokeColor="#33FFFFFF" /> | ||
135 | + <path | ||
136 | + android:fillColor="#00000000" | ||
137 | + android:pathData="M19,79L89,79" | ||
138 | + android:strokeWidth="0.8" | ||
139 | + android:strokeColor="#33FFFFFF" /> | ||
140 | + <path | ||
141 | + android:fillColor="#00000000" | ||
142 | + android:pathData="M29,19L29,89" | ||
143 | + android:strokeWidth="0.8" | ||
144 | + android:strokeColor="#33FFFFFF" /> | ||
145 | + <path | ||
146 | + android:fillColor="#00000000" | ||
147 | + android:pathData="M39,19L39,89" | ||
148 | + android:strokeWidth="0.8" | ||
149 | + android:strokeColor="#33FFFFFF" /> | ||
150 | + <path | ||
151 | + android:fillColor="#00000000" | ||
152 | + android:pathData="M49,19L49,89" | ||
153 | + android:strokeWidth="0.8" | ||
154 | + android:strokeColor="#33FFFFFF" /> | ||
155 | + <path | ||
156 | + android:fillColor="#00000000" | ||
157 | + android:pathData="M59,19L59,89" | ||
158 | + android:strokeWidth="0.8" | ||
159 | + android:strokeColor="#33FFFFFF" /> | ||
160 | + <path | ||
161 | + android:fillColor="#00000000" | ||
162 | + android:pathData="M69,19L69,89" | ||
163 | + android:strokeWidth="0.8" | ||
164 | + android:strokeColor="#33FFFFFF" /> | ||
165 | + <path | ||
166 | + android:fillColor="#00000000" | ||
167 | + android:pathData="M79,19L79,89" | ||
168 | + android:strokeWidth="0.8" | ||
169 | + android:strokeColor="#33FFFFFF" /> | ||
170 | +</vector> |
2.4 KB
1 | +<?xml version="1.0" encoding="utf-8"?> | ||
2 | +<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" | ||
3 | + xmlns:app="http://schemas.android.com/apk/res-auto" | ||
4 | + android:layout_width="match_parent" | ||
5 | + android:layout_height="match_parent"> | ||
6 | + | ||
7 | + <TextView | ||
8 | + android:id="@+id/textView" | ||
9 | + android:layout_width="wrap_content" | ||
10 | + android:layout_height="wrap_content" | ||
11 | + android:text="Hello World!" | ||
12 | + android:textSize="25sp" | ||
13 | + app:layout_constraintBottom_toBottomOf="parent" | ||
14 | + app:layout_constraintHorizontal_bias="0.498" | ||
15 | + app:layout_constraintLeft_toLeftOf="parent" | ||
16 | + app:layout_constraintRight_toRightOf="parent" | ||
17 | + app:layout_constraintTop_toTopOf="parent" | ||
18 | + app:layout_constraintVertical_bias="0.387" /> | ||
19 | + | ||
20 | + <ImageView | ||
21 | + android:id="@+id/imageView" | ||
22 | + app:layout_constraintStart_toStartOf="parent" | ||
23 | + app:layout_constraintEnd_toEndOf="parent" | ||
24 | + app:layout_constraintTop_toBottomOf="@id/textView" | ||
25 | + android:layout_width="wrap_content" | ||
26 | + android:layout_height="wrap_content" | ||
27 | + android:background="@drawable/test" | ||
28 | + /> | ||
29 | + | ||
30 | + | ||
31 | +</androidx.constraintlayout.widget.ConstraintLayout> | ||
... | \ No newline at end of file | ... | \ No newline at end of file |
1 | +<?xml version="1.0" encoding="utf-8"?> | ||
2 | +<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android"> | ||
3 | + <background android:drawable="@drawable/ic_launcher_background" /> | ||
4 | + <foreground android:drawable="@drawable/ic_launcher_foreground" /> | ||
5 | +</adaptive-icon> | ||
... | \ No newline at end of file | ... | \ No newline at end of file |
1 | +<?xml version="1.0" encoding="utf-8"?> | ||
2 | +<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android"> | ||
3 | + <background android:drawable="@drawable/ic_launcher_background" /> | ||
4 | + <foreground android:drawable="@drawable/ic_launcher_foreground" /> | ||
5 | +</adaptive-icon> | ||
... | \ No newline at end of file | ... | \ No newline at end of file |
2.89 KB
4.79 KB
2.01 KB
2.72 KB
4.38 KB
6.73 KB
6.24 KB
8.91 KB
1 | +<resources> | ||
2 | + | ||
3 | + <!-- Base application theme. --> | ||
4 | + <style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar"> | ||
5 | + <!-- Customize your theme here. --> | ||
6 | + <item name="colorPrimary">@color/colorPrimary</item> | ||
7 | + <item name="colorPrimaryDark">@color/colorPrimaryDark</item> | ||
8 | + <item name="colorAccent">@color/colorAccent</item> | ||
9 | + </style> | ||
10 | + | ||
11 | +</resources> |
1 | +package com.ono.test_app; | ||
2 | + | ||
3 | +import org.junit.Test; | ||
4 | + | ||
5 | +import static org.junit.Assert.*; | ||
6 | + | ||
7 | +/** | ||
8 | + * Example local unit test, which will execute on the development machine (host). | ||
9 | + * | ||
10 | + * @see <a href="http://d.android.com/tools/testing">Testing documentation</a> | ||
11 | + */ | ||
12 | +public class ExampleUnitTest { | ||
13 | + @Test | ||
14 | + public void addition_isCorrect() { | ||
15 | + assertEquals(4, 2 + 2); | ||
16 | + } | ||
17 | +} | ||
... | \ No newline at end of file | ... | \ No newline at end of file |
obfuscator/test_app_java/build.gradle
0 → 100644
1 | +// Top-level build file where you can add configuration options common to all sub-projects/modules. | ||
2 | + | ||
3 | +buildscript { | ||
4 | + ext.kotlin_version = '1.3.72' | ||
5 | + repositories { | ||
6 | + google() | ||
7 | + jcenter() | ||
8 | + | ||
9 | + } | ||
10 | + dependencies { | ||
11 | + classpath 'com.android.tools.build:gradle:3.5.0' | ||
12 | + classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" | ||
13 | + | ||
14 | + // NOTE: Do not place your application dependencies here; they belong | ||
15 | + // in the individual module build.gradle files | ||
16 | + } | ||
17 | +} | ||
18 | + | ||
19 | +allprojects { | ||
20 | + repositories { | ||
21 | + google() | ||
22 | + jcenter() | ||
23 | + | ||
24 | + } | ||
25 | +} | ||
26 | + | ||
27 | +task clean(type: Delete) { | ||
28 | + delete rootProject.buildDir | ||
29 | +} |
obfuscator/test_app_java/gradle.properties
0 → 100644
1 | +# Project-wide Gradle settings. | ||
2 | +# IDE (e.g. Android Studio) users: | ||
3 | +# Gradle settings configured through the IDE *will override* | ||
4 | +# any settings specified in this file. | ||
5 | +# For more details on how to configure your build environment visit | ||
6 | +# http://www.gradle.org/docs/current/userguide/build_environment.html | ||
7 | +# Specifies the JVM arguments used for the daemon process. | ||
8 | +# The setting is particularly useful for tweaking memory settings. | ||
9 | +org.gradle.jvmargs=-Xmx1536m | ||
10 | +# When configured, Gradle will run in incubating parallel mode. | ||
11 | +# This option should only be used with decoupled projects. More details, visit | ||
12 | +# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects | ||
13 | +# org.gradle.parallel=true | ||
14 | +# AndroidX package structure to make it clearer which packages are bundled with the | ||
15 | +# Android operating system, and which are packaged with your app's APK | ||
16 | +# https://developer.android.com/topic/libraries/support-library/androidx-rn | ||
17 | +android.useAndroidX=true | ||
18 | +# Automatically convert third-party libraries to use AndroidX | ||
19 | +android.enableJetifier=true | ||
20 | + |
No preview for this file type
obfuscator/test_app_java/gradlew
0 → 100755
This diff is collapsed. Click to expand it.
obfuscator/test_app_java/gradlew.bat
0 → 100644
This diff is collapsed. Click to expand it.
obfuscator/test_app_java/settings.gradle
0 → 100644
This diff is collapsed. Click to expand it.
obfuscator/test_app_java/test_app.zip
0 → 100644
No preview for this file type
-
Please register or login to post a comment