修复 打包后ui脚本无法运行的问题
修复 打包后模块无法运行的问题
This commit is contained in:
@@ -31,7 +31,7 @@
|
||||
android:name=".App"
|
||||
android:allowBackup="false"
|
||||
android:icon="@drawable/autojs_material"
|
||||
android:label="@string/_app_name"
|
||||
android:label="@string/app_name"
|
||||
android:largeHeap="true"
|
||||
android:supportsRtl="true"
|
||||
android:theme="@style/AppTheme"
|
||||
@@ -45,7 +45,7 @@
|
||||
<activity
|
||||
android:name=".ui.splash.SplashActivity"
|
||||
android:hardwareAccelerated="true"
|
||||
android:label="@string/_app_name"
|
||||
android:label="@string/app_name"
|
||||
android:theme="@style/AppTheme.Splash">
|
||||
<intent-filter>
|
||||
<category android:name="android.intent.category.LAUNCHER"/>
|
||||
@@ -56,7 +56,7 @@
|
||||
<activity
|
||||
android:name=".ui.main.MainActivity_"
|
||||
android:hardwareAccelerated="true"
|
||||
android:label="@string/_app_name"
|
||||
android:label="@string/app_name"
|
||||
android:launchMode="singleTask"
|
||||
android:theme="@style/AppTheme.FullScreen">
|
||||
</activity>
|
||||
@@ -164,7 +164,7 @@
|
||||
android:name=".external.tasker.PluginActivity"
|
||||
android:exported="true"
|
||||
android:icon="@drawable/ic_android_eat_js"
|
||||
android:label="@string/_app_name"
|
||||
android:label="@string/app_name"
|
||||
android:targetActivity=".external.tasker.TaskPrefEditActivity_"
|
||||
tools:ignore="ExportedActivity">
|
||||
<intent-filter>
|
||||
@@ -277,7 +277,7 @@
|
||||
</activity>
|
||||
<service
|
||||
android:name="com.stardust.notification.NotificationListenerService"
|
||||
android:label="@string/_app_name"
|
||||
android:label="@string/app_name"
|
||||
android:permission="android.permission.BIND_NOTIFICATION_LISTENER_SERVICE">
|
||||
<intent-filter>
|
||||
<action android:name="android.service.notification.NotificationListenerService"/>
|
||||
|
||||
@@ -9,6 +9,8 @@ import com.stardust.autojs.apkbuilder.ManifestEditor;
|
||||
import com.stardust.autojs.apkbuilder.util.StreamUtils;
|
||||
import com.stardust.autojs.project.BuildInfo;
|
||||
import com.stardust.autojs.project.ProjectConfig;
|
||||
import com.stardust.autojs.script.EncryptedScriptFileHeader;
|
||||
import com.stardust.autojs.script.JavaScriptFileSource;
|
||||
import com.stardust.pio.PFiles;
|
||||
import com.stardust.util.AdvancedEncryptionStandard;
|
||||
import com.stardust.util.MD5;
|
||||
@@ -198,12 +200,16 @@ public class ApkBuilder {
|
||||
}
|
||||
|
||||
private void encrypt(File toDir, File file) throws IOException {
|
||||
PFiles.writeBytes(new File(toDir, file.getName()).getPath(), encrypt(file));
|
||||
FileOutputStream fos = new FileOutputStream(new File(toDir, file.getName()));
|
||||
EncryptedScriptFileHeader.INSTANCE.writeHeader(fos, (short) new JavaScriptFileSource(file).getExecutionMode());
|
||||
encrypt(fos, file);
|
||||
}
|
||||
|
||||
private byte[] encrypt(File file) throws IOException {
|
||||
private void encrypt(FileOutputStream fos, File file) throws IOException {
|
||||
try {
|
||||
return new AdvancedEncryptionStandard(mKey.getBytes(), mInitVector).encrypt(PFiles.readBytes(file.getPath()));
|
||||
byte[] bytes = new AdvancedEncryptionStandard(mKey.getBytes(), mInitVector).encrypt(PFiles.readBytes(file.getPath()));
|
||||
fos.write(bytes);
|
||||
fos.close();
|
||||
} catch (Exception e) {
|
||||
throw new IOException(e);
|
||||
}
|
||||
@@ -212,7 +218,7 @@ public class ApkBuilder {
|
||||
|
||||
public ApkBuilder replaceFile(String relativePath, String newFilePath) throws IOException {
|
||||
if (newFilePath.endsWith(".js")) {
|
||||
PFiles.writeBytes(new File(mWorkspacePath, relativePath).getPath(), encrypt(new File(newFilePath)));
|
||||
encrypt(new FileOutputStream(new File(mWorkspacePath, relativePath)), new File(newFilePath));
|
||||
} else {
|
||||
StreamUtils.write(new FileInputStream(newFilePath), new FileOutputStream(new File(mWorkspacePath, relativePath)));
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@ import android.content.pm.PackageInfo;
|
||||
import android.content.pm.PackageManager;
|
||||
|
||||
import com.stardust.pio.UncheckedIOException;
|
||||
|
||||
import org.autojs.autojs.BuildConfig;
|
||||
|
||||
import com.stardust.util.DeveloperUtils;
|
||||
@@ -20,6 +21,7 @@ public class ApkBuilderPluginHelper {
|
||||
|
||||
private static final String PLUGIN_PACKAGE_NAME = "org.autojs.apkbuilderplugin";
|
||||
private static final String TEMPLATE_APK_PATH = "template.apk";
|
||||
private static final boolean DEBUG_APK_PLUGIN = false;
|
||||
|
||||
public static boolean isPluginAvailable(Context context) {
|
||||
return DeveloperUtils.checkSignature(context, PLUGIN_PACKAGE_NAME);
|
||||
@@ -27,9 +29,9 @@ public class ApkBuilderPluginHelper {
|
||||
|
||||
public static InputStream openTemplateApk(Context context) {
|
||||
try {
|
||||
//if (BuildConfig.DEBUG) {
|
||||
// return context.getAssets().open(TEMPLATE_APK_PATH);
|
||||
//}
|
||||
if (DEBUG_APK_PLUGIN && BuildConfig.DEBUG) {
|
||||
return context.getAssets().open(TEMPLATE_APK_PATH);
|
||||
}
|
||||
return context.getPackageManager().getResourcesForApplication(PLUGIN_PACKAGE_NAME)
|
||||
.getAssets().open(TEMPLATE_APK_PATH);
|
||||
} catch (IOException e) {
|
||||
|
||||
@@ -28,7 +28,6 @@ public class ScriptIntents {
|
||||
public static final String EXTRA_KEY_LOOP_INTERVAL = "interval";
|
||||
public static final String EXTRA_KEY_DELAY = "delay";
|
||||
|
||||
|
||||
public static boolean isTaskerBundleValid(Bundle bundle) {
|
||||
return bundle.containsKey(ScriptIntents.EXTRA_KEY_PATH) || bundle.containsKey(EXTRA_KEY_PRE_EXECUTE_SCRIPT);
|
||||
}
|
||||
|
||||
@@ -6,7 +6,6 @@ import android.text.TextUtils;
|
||||
|
||||
import com.stardust.app.GlobalAppContext;
|
||||
import org.autojs.autojs.Pref;
|
||||
import org.autojs.autojs.App;
|
||||
import org.autojs.autojs.R;
|
||||
|
||||
import com.stardust.autojs.core.accessibility.AccessibilityService;
|
||||
@@ -36,12 +35,12 @@ public class AccessibilityServiceTool {
|
||||
public static void goToAccessibilitySetting() {
|
||||
Context context = GlobalAppContext.get();
|
||||
if (Pref.isFirstGoToAccessibilitySetting()) {
|
||||
GlobalAppContext.toast(context.getString(R.string.text_please_choose) + context.getString(R.string._app_name));
|
||||
GlobalAppContext.toast(context.getString(R.string.text_please_choose) + context.getString(R.string.app_name));
|
||||
}
|
||||
try {
|
||||
AccessibilityServiceUtils.INSTANCE.goToAccessibilitySetting(context);
|
||||
} catch (ActivityNotFoundException e) {
|
||||
GlobalAppContext.toast(context.getString(R.string.go_to_accessibility_settings) + context.getString(R.string._app_name));
|
||||
GlobalAppContext.toast(context.getString(R.string.go_to_accessibility_settings) + context.getString(R.string.app_name));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -158,7 +158,7 @@ public class MainActivity extends BaseActivity implements OnActivityResultDelega
|
||||
private void setUpToolbar() {
|
||||
Toolbar toolbar = $(R.id.toolbar);
|
||||
setSupportActionBar(toolbar);
|
||||
toolbar.setTitle(R.string._app_name);
|
||||
toolbar.setTitle(R.string.app_name);
|
||||
ActionBarDrawerToggle drawerToggle = new ActionBarDrawerToggle(this, mDrawerLayout, toolbar, R.string.text_drawer_open,
|
||||
R.string.text_drawer_close);
|
||||
drawerToggle.syncState();
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="?attr/actionBarSize"
|
||||
android:theme="@style/ToolBarStyle"
|
||||
android:title="@string/_app_name"
|
||||
android:title="@string/app_name"
|
||||
app:layout_scrollFlags="scroll|enterAlways"
|
||||
app:popupTheme="@style/AppTheme.PopupOverlay"/>
|
||||
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="?attr/actionBarSize"
|
||||
app:popupTheme="@style/AppTheme.PopupOverlay"
|
||||
app:title="@string/_app_name">
|
||||
app:title="@string/app_name">
|
||||
|
||||
|
||||
</com.stardust.theme.widget.ThemeColorToolbar>
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
android:layout_width="match_parent"
|
||||
android:theme="@style/ToolBarStyle"
|
||||
android:layout_height="?attr/actionBarSize"
|
||||
android:title="@string/_app_name"
|
||||
android:title="@string/app_name"
|
||||
app:layout_scrollFlags="scroll|enterAlways"
|
||||
app:popupTheme="@style/AppTheme.PopupOverlay"/>
|
||||
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="?attr/actionBarSize"
|
||||
app:popupTheme="@style/AppTheme.PopupOverlay"
|
||||
app:title="@string/_app_name">
|
||||
app:title="@string/app_name">
|
||||
|
||||
|
||||
</com.stardust.theme.widget.ThemeColorToolbar>
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
android:theme="@style/ToolBarStyle"
|
||||
android:layout_height="?attr/actionBarSize"
|
||||
android:background="?attr/colorPrimary"
|
||||
android:title="@string/_app_name"
|
||||
android:title="@string/app_name"
|
||||
app:popupTheme="@style/AppTheme.PopupOverlay">
|
||||
|
||||
<LinearLayout
|
||||
|
||||
@@ -51,7 +51,7 @@
|
||||
android:layout_marginTop="8dp"
|
||||
android:gravity="center"
|
||||
android:minHeight="60dp"
|
||||
android:text="@string/_app_name"
|
||||
android:text="@string/app_name"
|
||||
android:textColor="@android:color/primary_text_light"/>
|
||||
|
||||
</LinearLayout>
|
||||
@@ -17,7 +17,7 @@
|
||||
android:layout_height="?attr/actionBarSize"
|
||||
android:theme="@style/ToolBarStyle"
|
||||
android:background="?attr/colorPrimary"
|
||||
android:title="@string/_app_name"
|
||||
android:title="@string/app_name"
|
||||
app:popupTheme="@style/AppTheme.PopupOverlay">
|
||||
|
||||
<FrameLayout
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<resources>
|
||||
<string name="_app_name">Auto.js</string>
|
||||
<string name="app_name">Auto.js</string>
|
||||
<string name="text_accessibility_service_description">Required by the script automatic operation (click, long press, slide, etc.).</string>
|
||||
<string name="text_new_file">New File</string>
|
||||
<string name="text_create_fail">Creation failed</string>
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
<resources>
|
||||
<string name="_app_name">Auto.js</string>
|
||||
<string name="app_name">Auto.js</string>
|
||||
<string name="text_new_file">新建文件</string>
|
||||
<string name="text_create_fail">创建失败</string>
|
||||
<string name="text_please_input_name">请输入名称</string>
|
||||
<string name="text_name">名称</string>
|
||||
<string name="text_go_to_setting">去设置</string>
|
||||
<string name="explain_accessibility_permission">软件需要打开\"无障碍服务\"才能运行,请在随后的设置中选择\"AutoJs\"并开启服务。\n您也可以稍后在侧拉菜单中设置。</string>
|
||||
<string name="explain_accessibility_permission">软件需要打开\"无障碍服务\"才能运行,请在随后的设置中选择\"Auto.js\"并开启服务。\n您也可以稍后在侧拉菜单中设置。</string>
|
||||
<string name="text_cancel">取消</string>
|
||||
<string name="text_path_is_empty">路径为空</string>
|
||||
<string name="text_file_not_exists">文件不存在</string>
|
||||
@@ -27,7 +27,7 @@
|
||||
<string name="text_about">关于</string>
|
||||
<string name="text_licenses">开放源代码许可</string>
|
||||
<string name="text_do_not_remind_again">不再提示</string>
|
||||
<string name="copyright">Copyright©2016 All right reserves.</string>
|
||||
<string name="copyright">Copyright©2018-2019 All right reserves.</string>
|
||||
<string name="developer">星尘幻影</string>
|
||||
<string name="qq" translatable="false">2732014414</string>
|
||||
<string name="email" translatable="false">hybbbb1996@gmail.com</string>
|
||||
@@ -35,7 +35,7 @@
|
||||
<string name="text_already_copy_to_clip">已复制到剪贴板</string>
|
||||
<string name="donate_developer">打赏作者</string>
|
||||
<string name="my_github">https://github.com/hyb1996/NoRootScriptDroid</string>
|
||||
<string name="share_app">[AutoJs]下载地址:http://www.coolapk.com/apk/org.autojs.autojs </string>
|
||||
<string name="share_app">[Auto.js]下载地址:http://www.coolapk.com/apk/org.autojs.autojs </string>
|
||||
<string name="text_floating_window">悬浮窗</string>
|
||||
<string name="text_error_report">错误报告</string>
|
||||
<string name="text_press_again_to_exit">再按一次退出程序</string>
|
||||
@@ -99,7 +99,7 @@
|
||||
<string name="text_import_succeed">导入成功</string>
|
||||
<string name="text_current_activity">当前活动:</string>
|
||||
<string name="text_current_package">当前应用包名:</string>
|
||||
<string name="go_to_accessibility_settings"><![CDATA[请打开设置->无障碍服务->AutoJs并开启]]></string>
|
||||
<string name="go_to_accessibility_settings"><![CDATA[请打开设置->无障碍服务->Auto.js并开启]]></string>
|
||||
<string name="text_script_running">脚本运行</string>
|
||||
<string name="key_use_volume_control_running">key_use_volume_control_running</string>
|
||||
<string name="text_use_volume_to_stop_running">音量上键停止所有脚本</string>
|
||||
|
||||
@@ -32,7 +32,7 @@
|
||||
|
||||
<service
|
||||
android:name="com.stardust.autojs.core.accessibility.AccessibilityService"
|
||||
android:label="@string/_app_name"
|
||||
android:label="@string/app_name"
|
||||
android:permission="android.permission.BIND_ACCESSIBILITY_SERVICE">
|
||||
<intent-filter>
|
||||
<action android:name="android.accessibilityservice.AccessibilityService"/>
|
||||
|
||||
@@ -5,15 +5,12 @@ import android.view.View;
|
||||
|
||||
import com.stardust.autojs.BuildConfig;
|
||||
import com.stardust.autojs.core.ui.ViewExtras;
|
||||
import com.stardust.autojs.rhino.NativeJavaObjectWithPrototype;
|
||||
import com.stardust.autojs.engine.module.AssetAndUrlModuleSourceProvider;
|
||||
import com.stardust.autojs.rhino.RhinoAndroidHelper;
|
||||
import com.stardust.autojs.rhino.TokenStream;
|
||||
import com.stardust.autojs.rhino.TopLevelScope;
|
||||
import com.stardust.autojs.runtime.ScriptRuntime;
|
||||
import com.stardust.autojs.script.JavaScriptSource;
|
||||
import com.stardust.autojs.script.StringScriptSource;
|
||||
import com.stardust.automator.UiObjectCollection;
|
||||
import com.stardust.pio.PFiles;
|
||||
import com.stardust.pio.UncheckedIOException;
|
||||
|
||||
import org.mozilla.javascript.Context;
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
package com.stardust.autojs.engine.encryption
|
||||
|
||||
import com.stardust.util.AdvancedEncryptionStandard
|
||||
|
||||
object ScriptEncryption {
|
||||
|
||||
private var mKey = ""
|
||||
private var mInitVector = ""
|
||||
|
||||
fun decrypt(bytes: ByteArray, start: Int = 0, end: Int = bytes.size): ByteArray {
|
||||
return AdvancedEncryptionStandard(mKey.toByteArray(), mInitVector).decrypt(bytes, start, end)
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,20 +1,21 @@
|
||||
package com.stardust.autojs.engine;
|
||||
package com.stardust.autojs.engine.module;
|
||||
|
||||
import android.content.res.AssetManager;
|
||||
import android.net.Uri;
|
||||
|
||||
import org.mozilla.javascript.Scriptable;
|
||||
import com.stardust.autojs.engine.encryption.ScriptEncryption;
|
||||
import com.stardust.autojs.script.EncryptedScriptFileHeader;
|
||||
|
||||
import org.mozilla.javascript.commonjs.module.provider.ModuleSource;
|
||||
import org.mozilla.javascript.commonjs.module.provider.UrlModuleSourceProvider;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.Reader;
|
||||
import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.net.URLConnection;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
@@ -49,4 +50,17 @@ public class AssetAndUrlModuleSourceProvider extends UrlModuleSourceProvider {
|
||||
return super.loadFromPrivilegedLocations(moduleId, validator);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Reader getReader(URLConnection urlConnection) throws IOException {
|
||||
InputStream stream = urlConnection.getInputStream();
|
||||
byte[] bytes = new byte[stream.available()];
|
||||
stream.read(bytes);
|
||||
stream.close();
|
||||
if (EncryptedScriptFileHeader.INSTANCE.isValidFile(bytes)) {
|
||||
byte[] clearText = ScriptEncryption.INSTANCE.decrypt(bytes, EncryptedScriptFileHeader.BLOCK_SIZE, bytes.length);
|
||||
return new InputStreamReader(new ByteArrayInputStream(clearText));
|
||||
}
|
||||
return new InputStreamReader(new ByteArrayInputStream(bytes));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,364 @@
|
||||
package com.stardust.autojs.engine.module;
|
||||
|
||||
import org.mozilla.javascript.commonjs.module.provider.DefaultUrlConnectionExpiryCalculator;
|
||||
import org.mozilla.javascript.commonjs.module.provider.ModuleSource;
|
||||
import org.mozilla.javascript.commonjs.module.provider.ModuleSourceProviderBase;
|
||||
import org.mozilla.javascript.commonjs.module.provider.ParsedContentType;
|
||||
import org.mozilla.javascript.commonjs.module.provider.UrlConnectionExpiryCalculator;
|
||||
import org.mozilla.javascript.commonjs.module.provider.UrlConnectionSecurityDomainProvider;
|
||||
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.Reader;
|
||||
import java.io.Serializable;
|
||||
import java.net.HttpURLConnection;
|
||||
import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
import java.net.URL;
|
||||
import java.net.URLConnection;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
|
||||
/**
|
||||
* A URL-based script provider that can load modules against a set of base
|
||||
* privileged and fallback URIs. It is deliberately not named "URI provider"
|
||||
* but a "URL provider" since it actually only works against those URIs that
|
||||
* are URLs (and the JRE has a protocol handler for them). It creates cache
|
||||
* validators that are suitable for use with both file: and http: URL
|
||||
* protocols. Specifically, it is able to use both last-modified timestamps and
|
||||
* ETags for cache revalidation, and follows the HTTP cache expiry calculation
|
||||
* model, and allows for fallback heuristic expiry calculation when no server
|
||||
* specified expiry is provided.
|
||||
*
|
||||
* @author Attila Szegedi
|
||||
* @version $Id: UrlModuleSourceProvider.java,v 1.4 2011/04/07 20:26:12 hannes%helma.at Exp $
|
||||
*/
|
||||
public class UrlModuleSourceProvider extends ModuleSourceProviderBase {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private final Iterable<URI> privilegedUris;
|
||||
private final Iterable<URI> fallbackUris;
|
||||
private final UrlConnectionSecurityDomainProvider
|
||||
urlConnectionSecurityDomainProvider;
|
||||
private final UrlConnectionExpiryCalculator urlConnectionExpiryCalculator;
|
||||
|
||||
/**
|
||||
* Creates a new module script provider that loads modules against a set of
|
||||
* privileged and fallback URIs. It will use a fixed default cache expiry
|
||||
* of 60 seconds, and provide no security domain objects for the resource.
|
||||
*
|
||||
* @param privilegedUris an iterable providing the privileged URIs. Can be
|
||||
* null if no privileged URIs are used.
|
||||
* @param fallbackUris an iterable providing the fallback URIs. Can be
|
||||
* null if no fallback URIs are used.
|
||||
*/
|
||||
public UrlModuleSourceProvider(Iterable<URI> privilegedUris,
|
||||
Iterable<URI> fallbackUris) {
|
||||
this(privilegedUris, fallbackUris,
|
||||
new DefaultUrlConnectionExpiryCalculator(), null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new module script provider that loads modules against a set of
|
||||
* privileged and fallback URIs. It will use the specified heuristic cache
|
||||
* expiry calculator and security domain provider.
|
||||
*
|
||||
* @param privilegedUris an iterable providing the privileged URIs. Can be
|
||||
* null if no privileged URIs are used.
|
||||
* @param fallbackUris an iterable providing the fallback URIs. Can be
|
||||
* null if no fallback URIs are used.
|
||||
* @param urlConnectionExpiryCalculator the calculator object for heuristic
|
||||
* calculation of the resource expiry, used when no expiry is provided by
|
||||
* the server of the resource. Can be null, in which case the maximum age
|
||||
* of cached entries without validation will be zero.
|
||||
* @param urlConnectionSecurityDomainProvider object that provides security
|
||||
* domain objects for the loaded sources. Can be null, in which case the
|
||||
* loaded sources will have no security domain associated with them.
|
||||
*/
|
||||
public UrlModuleSourceProvider(Iterable<URI> privilegedUris,
|
||||
Iterable<URI> fallbackUris,
|
||||
UrlConnectionExpiryCalculator urlConnectionExpiryCalculator,
|
||||
UrlConnectionSecurityDomainProvider urlConnectionSecurityDomainProvider) {
|
||||
this.privilegedUris = privilegedUris;
|
||||
this.fallbackUris = fallbackUris;
|
||||
this.urlConnectionExpiryCalculator = urlConnectionExpiryCalculator;
|
||||
this.urlConnectionSecurityDomainProvider =
|
||||
urlConnectionSecurityDomainProvider;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ModuleSource loadFromPrivilegedLocations(
|
||||
String moduleId, Object validator)
|
||||
throws IOException, URISyntaxException {
|
||||
return loadFromPathList(moduleId, validator, privilegedUris);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ModuleSource loadFromFallbackLocations(
|
||||
String moduleId, Object validator)
|
||||
throws IOException, URISyntaxException {
|
||||
return loadFromPathList(moduleId, validator, fallbackUris);
|
||||
}
|
||||
|
||||
private ModuleSource loadFromPathList(String moduleId,
|
||||
Object validator, Iterable<URI> paths)
|
||||
throws IOException, URISyntaxException {
|
||||
if (paths == null) {
|
||||
return null;
|
||||
}
|
||||
for (URI path : paths) {
|
||||
final ModuleSource moduleSource = loadFromUri(
|
||||
path.resolve(moduleId), path, validator);
|
||||
if (moduleSource != null) {
|
||||
return moduleSource;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ModuleSource loadFromUri(URI uri, URI base, Object validator)
|
||||
throws IOException, URISyntaxException {
|
||||
// We expect modules to have a ".js" file name extension ...
|
||||
URI fullUri = new URI(uri + ".js");
|
||||
ModuleSource source = loadFromActualUri(fullUri, base, validator);
|
||||
// ... but for compatibility we support modules without extension,
|
||||
// or ids with explicit extension.
|
||||
return source != null ?
|
||||
source : loadFromActualUri(uri, base, validator);
|
||||
}
|
||||
|
||||
protected ModuleSource loadFromActualUri(URI uri, URI base, Object validator)
|
||||
throws IOException {
|
||||
final URL url = new URL(base == null ? null : base.toURL(), uri.toString());
|
||||
final long request_time = System.currentTimeMillis();
|
||||
final URLConnection urlConnection = openUrlConnection(url);
|
||||
final URLValidator applicableValidator;
|
||||
if (validator instanceof URLValidator) {
|
||||
final URLValidator uriValidator = ((URLValidator) validator);
|
||||
applicableValidator = uriValidator.appliesTo(uri) ? uriValidator :
|
||||
null;
|
||||
} else {
|
||||
applicableValidator = null;
|
||||
}
|
||||
if (applicableValidator != null) {
|
||||
applicableValidator.applyConditionals(urlConnection);
|
||||
}
|
||||
try {
|
||||
urlConnection.connect();
|
||||
if (applicableValidator != null &&
|
||||
applicableValidator.updateValidator(urlConnection,
|
||||
request_time, urlConnectionExpiryCalculator)) {
|
||||
close(urlConnection);
|
||||
return NOT_MODIFIED;
|
||||
}
|
||||
|
||||
return new ModuleSource(getReader(urlConnection),
|
||||
getSecurityDomain(urlConnection), uri, base,
|
||||
new URLValidator(uri, urlConnection, request_time,
|
||||
urlConnectionExpiryCalculator));
|
||||
} catch (FileNotFoundException e) {
|
||||
return null;
|
||||
} catch (RuntimeException e) {
|
||||
close(urlConnection);
|
||||
throw e;
|
||||
} catch (IOException e) {
|
||||
close(urlConnection);
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
protected Reader getReader(URLConnection urlConnection)
|
||||
throws IOException {
|
||||
return new InputStreamReader(urlConnection.getInputStream(),
|
||||
getCharacterEncoding(urlConnection));
|
||||
}
|
||||
|
||||
protected String getCharacterEncoding(URLConnection urlConnection) {
|
||||
final ParsedContentType pct = new ParsedContentType(
|
||||
urlConnection.getContentType());
|
||||
final String encoding = pct.getEncoding();
|
||||
if (encoding != null) {
|
||||
return encoding;
|
||||
}
|
||||
final String contentType = pct.getContentType();
|
||||
if (contentType != null && contentType.startsWith("text/")) {
|
||||
return "8859_1";
|
||||
}
|
||||
return "utf-8";
|
||||
}
|
||||
|
||||
protected Object getSecurityDomain(URLConnection urlConnection) {
|
||||
return urlConnectionSecurityDomainProvider == null ? null :
|
||||
urlConnectionSecurityDomainProvider.getSecurityDomain(
|
||||
urlConnection);
|
||||
}
|
||||
|
||||
private void close(URLConnection urlConnection) {
|
||||
try {
|
||||
urlConnection.getInputStream().close();
|
||||
} catch (IOException e) {
|
||||
onFailedClosingUrlConnection(urlConnection, e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Override if you want to get notified if the URL connection fails to
|
||||
* close. Does nothing by default.
|
||||
*
|
||||
* @param urlConnection the connection
|
||||
* @param cause the cause it failed to close.
|
||||
*/
|
||||
protected void onFailedClosingUrlConnection(URLConnection urlConnection,
|
||||
IOException cause) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Can be overridden in subclasses to customize the URL connection opening
|
||||
* process. By default, just calls {@link URL#openConnection()}.
|
||||
*
|
||||
* @param url the URL
|
||||
* @return a connection to the URL.
|
||||
* @throws IOException if an I/O error occurs.
|
||||
*/
|
||||
protected URLConnection openUrlConnection(URL url) throws IOException {
|
||||
return url.openConnection();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean entityNeedsRevalidation(Object validator) {
|
||||
return !(validator instanceof URLValidator)
|
||||
|| ((URLValidator) validator).entityNeedsRevalidation();
|
||||
}
|
||||
|
||||
private static class URLValidator implements Serializable {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private final URI uri;
|
||||
private final long lastModified;
|
||||
private final String entityTags;
|
||||
private long expiry;
|
||||
|
||||
public URLValidator(URI uri, URLConnection urlConnection,
|
||||
long request_time, UrlConnectionExpiryCalculator
|
||||
urlConnectionExpiryCalculator) {
|
||||
this.uri = uri;
|
||||
this.lastModified = urlConnection.getLastModified();
|
||||
this.entityTags = getEntityTags(urlConnection);
|
||||
expiry = calculateExpiry(urlConnection, request_time,
|
||||
urlConnectionExpiryCalculator);
|
||||
}
|
||||
|
||||
boolean updateValidator(URLConnection urlConnection, long request_time,
|
||||
UrlConnectionExpiryCalculator urlConnectionExpiryCalculator)
|
||||
throws IOException {
|
||||
boolean isResourceChanged = isResourceChanged(urlConnection);
|
||||
if (!isResourceChanged) {
|
||||
expiry = calculateExpiry(urlConnection, request_time,
|
||||
urlConnectionExpiryCalculator);
|
||||
}
|
||||
return isResourceChanged;
|
||||
}
|
||||
|
||||
private boolean isResourceChanged(URLConnection urlConnection)
|
||||
throws IOException {
|
||||
if (urlConnection instanceof HttpURLConnection) {
|
||||
return ((HttpURLConnection) urlConnection).getResponseCode() ==
|
||||
HttpURLConnection.HTTP_NOT_MODIFIED;
|
||||
}
|
||||
return lastModified != urlConnection.getLastModified();
|
||||
}
|
||||
|
||||
private long calculateExpiry(URLConnection urlConnection,
|
||||
long request_time, UrlConnectionExpiryCalculator
|
||||
urlConnectionExpiryCalculator) {
|
||||
if ("no-cache".equals(urlConnection.getHeaderField("Pragma"))) {
|
||||
return 0L;
|
||||
}
|
||||
final String cacheControl = urlConnection.getHeaderField(
|
||||
"Cache-Control");
|
||||
if (cacheControl != null) {
|
||||
if (cacheControl.indexOf("no-cache") != -1) {
|
||||
return 0L;
|
||||
}
|
||||
final int max_age = getMaxAge(cacheControl);
|
||||
if (-1 != max_age) {
|
||||
final long response_time = System.currentTimeMillis();
|
||||
final long apparent_age = Math.max(0, response_time -
|
||||
urlConnection.getDate());
|
||||
final long corrected_received_age = Math.max(apparent_age,
|
||||
urlConnection.getHeaderFieldInt("Age", 0) * 1000L);
|
||||
final long response_delay = response_time - request_time;
|
||||
final long corrected_initial_age = corrected_received_age +
|
||||
response_delay;
|
||||
final long creation_time = response_time -
|
||||
corrected_initial_age;
|
||||
return max_age * 1000L + creation_time;
|
||||
}
|
||||
}
|
||||
final long explicitExpiry = urlConnection.getHeaderFieldDate(
|
||||
"Expires", -1L);
|
||||
if (explicitExpiry != -1L) {
|
||||
return explicitExpiry;
|
||||
}
|
||||
return urlConnectionExpiryCalculator == null ? 0L :
|
||||
urlConnectionExpiryCalculator.calculateExpiry(urlConnection);
|
||||
}
|
||||
|
||||
private int getMaxAge(String cacheControl) {
|
||||
final int maxAgeIndex = cacheControl.indexOf("max-age");
|
||||
if (maxAgeIndex == -1) {
|
||||
return -1;
|
||||
}
|
||||
final int eq = cacheControl.indexOf('=', maxAgeIndex + 7);
|
||||
if (eq == -1) {
|
||||
return -1;
|
||||
}
|
||||
final int comma = cacheControl.indexOf(',', eq + 1);
|
||||
final String strAge;
|
||||
if (comma == -1) {
|
||||
strAge = cacheControl.substring(eq + 1);
|
||||
} else {
|
||||
strAge = cacheControl.substring(eq + 1, comma);
|
||||
}
|
||||
try {
|
||||
return Integer.parseInt(strAge);
|
||||
} catch (NumberFormatException e) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
private String getEntityTags(URLConnection urlConnection) {
|
||||
final List<String> etags = urlConnection.getHeaderFields().get("ETag");
|
||||
if (etags == null || etags.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
final StringBuilder b = new StringBuilder();
|
||||
final Iterator<String> it = etags.iterator();
|
||||
b.append(it.next());
|
||||
while (it.hasNext()) {
|
||||
b.append(", ").append(it.next());
|
||||
}
|
||||
return b.toString();
|
||||
}
|
||||
|
||||
boolean appliesTo(URI uri) {
|
||||
return this.uri.equals(uri);
|
||||
}
|
||||
|
||||
void applyConditionals(URLConnection urlConnection) {
|
||||
if (lastModified != 0L) {
|
||||
urlConnection.setIfModifiedSince(lastModified);
|
||||
}
|
||||
if (entityTags != null && entityTags.length() > 0) {
|
||||
urlConnection.addRequestProperty("If-None-Match", entityTags);
|
||||
}
|
||||
}
|
||||
|
||||
boolean entityNeedsRevalidation() {
|
||||
return System.currentTimeMillis() > expiry;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -12,7 +12,9 @@ data class ExecutionConfig(var workingDirectory: String = "",
|
||||
var intentFlags: Int = 0,
|
||||
var delay: Long = 0,
|
||||
var interval: Long = 0,
|
||||
var loopTimes: Int = 1) : Parcelable {
|
||||
var loopTimes: Int = 1,
|
||||
var uiMode: Boolean = false,
|
||||
var features: Int = 0) : Parcelable {
|
||||
|
||||
|
||||
private val mArguments = HashMap<String, Any>()
|
||||
@@ -79,13 +81,16 @@ data class ExecutionConfig(var workingDirectory: String = "",
|
||||
|
||||
companion object CREATOR : Parcelable.Creator<ExecutionConfig> {
|
||||
|
||||
@JvmStatic
|
||||
val tag = "execution.config"
|
||||
@JvmStatic
|
||||
val tag = "execution.config"
|
||||
|
||||
@JvmStatic
|
||||
val default: ExecutionConfig
|
||||
get() = ExecutionConfig()
|
||||
|
||||
@JvmStatic
|
||||
val featureContinuation = 1
|
||||
|
||||
override fun createFromParcel(parcel: Parcel): ExecutionConfig {
|
||||
return ExecutionConfig(parcel)
|
||||
}
|
||||
|
||||
@@ -118,8 +118,8 @@ public class ScriptExecuteActivity extends AppCompatActivity {
|
||||
private void prepare() {
|
||||
mScriptEngine.put("activity", this);
|
||||
mScriptEngine.setTag("activity", this);
|
||||
mScriptEngine.setTag(ScriptEngine.TAG_ENV_PATH, mScriptExecution.getConfig().getWorkingDirectory());
|
||||
mScriptEngine.setTag(ScriptEngine.TAG_WORKING_DIRECTORY, mScriptExecution.getConfig().getPath());
|
||||
mScriptEngine.setTag(ScriptEngine.TAG_ENV_PATH, mScriptExecution.getConfig().getPath());
|
||||
mScriptEngine.setTag(ScriptEngine.TAG_WORKING_DIRECTORY, mScriptExecution.getConfig().getWorkingDirectory());
|
||||
mScriptEngine.init();
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,47 @@
|
||||
package com.stardust.autojs.script
|
||||
|
||||
import java.io.File
|
||||
import java.io.FileInputStream
|
||||
import java.io.OutputStream
|
||||
|
||||
object EncryptedScriptFileHeader {
|
||||
|
||||
const val FLAG_INVALID_FILE: Short = Short.MIN_VALUE
|
||||
|
||||
const val FLAG_EXECUTION_MODE_UI: Short = 0x0001
|
||||
const val FLAG_EXECUTION_MODE_AUTO: Short = 0x0002
|
||||
|
||||
const val BLOCK_SIZE = 8
|
||||
private val BLOCK = byteArrayOf(0x77, 0x01, 0x17, 0x7F, 0x12, 0x12)
|
||||
|
||||
fun getHeaderFlags(file: File): Short {
|
||||
val fis = FileInputStream(file)
|
||||
val bytes = ByteArray(BLOCK_SIZE)
|
||||
if (fis.read(bytes) < BLOCK_SIZE) {
|
||||
return FLAG_INVALID_FILE
|
||||
}
|
||||
if (!isValidFile(bytes)) {
|
||||
return FLAG_INVALID_FILE
|
||||
}
|
||||
return (bytes[BLOCK.size].toShort() * 256 + bytes[BLOCK.size + 1]).toShort()
|
||||
}
|
||||
|
||||
fun isValidFile(bytes: ByteArray): Boolean {
|
||||
for (i in 0 until BLOCK.size) {
|
||||
if (bytes[i] != BLOCK[i]) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
fun writeHeader(os: OutputStream, flags: Short = 0) {
|
||||
os.write(BLOCK)
|
||||
val byte6 = flags / 256
|
||||
val byte7 = flags % 256
|
||||
os.write(byte6)
|
||||
os.write(byte7)
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -43,6 +43,15 @@ public class JavaScriptFileSource extends JavaScriptSource {
|
||||
return mScript;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int parseExecutionMode() {
|
||||
short flags = EncryptedScriptFileHeader.INSTANCE.getHeaderFlags(mFile);
|
||||
if (flags == EncryptedScriptFileHeader.FLAG_INVALID_FILE) {
|
||||
return super.parseExecutionMode();
|
||||
}
|
||||
return flags;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Reader getScriptReader() {
|
||||
try {
|
||||
|
||||
@@ -1,10 +1,15 @@
|
||||
package com.stardust.autojs.script;
|
||||
|
||||
import android.util.Log;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import com.stardust.autojs.rhino.TokenStream;
|
||||
import com.stardust.util.MapBuilder;
|
||||
|
||||
import org.mozilla.javascript.Token;
|
||||
|
||||
import java.io.Reader;
|
||||
import java.io.StringReader;
|
||||
import java.util.Map;
|
||||
@@ -23,11 +28,13 @@ public abstract class JavaScriptSource extends ScriptSource {
|
||||
public static final int EXECUTION_MODE_UI = 0x00000001;
|
||||
public static final int EXECUTION_MODE_AUTO = 0x00000002;
|
||||
|
||||
private static final String LOG_TAG = "JavaScriptSource";
|
||||
|
||||
private static final Map<String, Integer> EXECUTION_MODES = new MapBuilder<String, Integer>()
|
||||
.put("ui", EXECUTION_MODE_UI)
|
||||
.put("auto", EXECUTION_MODE_AUTO)
|
||||
.build();
|
||||
private static final int EXECUTION_MODE_STRING_MAX_LENGTH = 7;
|
||||
private static final int PARSING_MAX_TOKEN = 300;
|
||||
|
||||
private int mExecutionMode = -1;
|
||||
|
||||
@@ -57,20 +64,35 @@ public abstract class JavaScriptSource extends ScriptSource {
|
||||
|
||||
public int getExecutionMode() {
|
||||
if (mExecutionMode == -1) {
|
||||
mExecutionMode = parseExecutionMode(getScript());
|
||||
mExecutionMode = parseExecutionMode();
|
||||
}
|
||||
return mExecutionMode;
|
||||
}
|
||||
|
||||
private int parseExecutionMode(String script) {
|
||||
if (script == null || script.length() == 0)
|
||||
return EXECUTION_MODE_NORMAL;
|
||||
if(script.charAt(0) == '"'){
|
||||
int i = script.lastIndexOf("\";", EXECUTION_MODE_STRING_MAX_LENGTH + 2);
|
||||
if (i >= 0){
|
||||
String modeString = script.substring(1, i);
|
||||
return parseExecutionMode(modeString.split(" "));
|
||||
protected int parseExecutionMode() {
|
||||
String script = getScript();
|
||||
TokenStream ts = new TokenStream(new StringReader(script), null, 1);
|
||||
int token;
|
||||
int count = 0;
|
||||
try {
|
||||
while (count <= PARSING_MAX_TOKEN && (token = ts.getToken()) != Token.EOF) {
|
||||
count++;
|
||||
if (token == Token.EOL || token == Token.COMMENT) {
|
||||
continue;
|
||||
}
|
||||
if (token == Token.STRING && ts.getTokenLength() > 2) {
|
||||
String tokenString = script.substring(ts.getTokenBeg() + 1, ts.getTokenEnd() - 1);
|
||||
if (ts.getToken() != Token.SEMI) {
|
||||
break;
|
||||
}
|
||||
Log.d(LOG_TAG, "string = " + tokenString);
|
||||
return parseExecutionMode(tokenString.split(" "));
|
||||
}
|
||||
break;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return EXECUTION_MODE_NORMAL;
|
||||
}
|
||||
return EXECUTION_MODE_NORMAL;
|
||||
|
||||
|
||||
@@ -1,10 +1,9 @@
|
||||
package com.stardust.autojs.script;
|
||||
|
||||
import android.content.Context;
|
||||
import android.util.Log;
|
||||
import android.view.View;
|
||||
|
||||
import com.stardust.autojs.engine.AssetAndUrlModuleSourceProvider;
|
||||
import com.stardust.autojs.engine.module.AssetAndUrlModuleSourceProvider;
|
||||
import com.stardust.pio.PFiles;
|
||||
import com.stardust.pio.UncheckedIOException;
|
||||
|
||||
@@ -18,7 +17,6 @@ import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.Collections;
|
||||
import java.util.concurrent.Executor;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<resources>
|
||||
<string name="app_name">AutoJs</string>
|
||||
<string name="app_name">Auto.js</string>
|
||||
<string name="text_error">Error:</string>
|
||||
<string name="text_start_running">Script Running</string>
|
||||
<string name="text_path_is_empty">Path is empty</string>
|
||||
@@ -13,7 +13,6 @@
|
||||
<string name="text_console">Console</string>
|
||||
<string name="text_no_floating_window_permission">No drawing overlay permission</string>
|
||||
<string name="text_accessibility_service_description">Auto.js</string>
|
||||
<string name="_app_name">AutoJs</string>
|
||||
<string name="text_should_enable_key_observing">Key observing is disabled, please enable in settings</string>
|
||||
<string name="no_write_settings_permissin">No writing settings permission</string>
|
||||
<string name="exception_notification_service_disabled">通知服务未运行,请重新启用通知权限</string>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<resources>
|
||||
<string name="app_name">AutoJs</string>
|
||||
<string name="app_name">Auto.js</string>
|
||||
<string name="text_error">错误:</string>
|
||||
<string name="text_start_running">开始运行</string>
|
||||
<string name="text_path_is_empty">路径为空</string>
|
||||
@@ -13,7 +13,6 @@
|
||||
<string name="text_console">控制台</string>
|
||||
<string name="text_no_floating_window_permission">没有悬浮窗权限</string>
|
||||
<string name="text_accessibility_service_description">使脚本自动操作(点击、长按、滑动等)所需,若关闭则只能执行不涉及自动操作的脚本。</string>
|
||||
<string name="_app_name">AutoJs</string>
|
||||
<string name="text_should_enable_key_observing">按键监听未启用,请在软件设置中开启</string>
|
||||
<string name="text_should_enable_gesture_observing">手势监听未启用,请在软件设置中开启</string>
|
||||
<string name="no_write_settings_permissin">沒有修改系統设置权限</string>
|
||||
|
||||
@@ -31,7 +31,7 @@ class AdvancedEncryptionStandard(private val key: ByteArray, private val initVec
|
||||
val ivParameterSpec = IvParameterSpec(initVector.toByteArray())
|
||||
val cipher = Cipher.getInstance(FULL_ALGORITHM)
|
||||
cipher.init(Cipher.DECRYPT_MODE, secretKey, ivParameterSpec)
|
||||
return cipher.doFinal(cipherText, start, end)
|
||||
return cipher.doFinal(cipherText, start, end - start)
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
||||
@@ -23,8 +23,6 @@ import java.lang.IllegalStateException
|
||||
*/
|
||||
|
||||
class AutoJs private constructor(application: Application) : com.stardust.autojs.AutoJs(application) {
|
||||
private var mKey = ""
|
||||
private var mInitVector = ""
|
||||
|
||||
init {
|
||||
scriptEngineService.registerGlobalScriptExecutionListener(ScriptExecutionGlobalListener())
|
||||
@@ -85,7 +83,6 @@ class AutoJs private constructor(application: Application) : com.stardust.autojs
|
||||
super.initScriptEngineManager()
|
||||
scriptEngineManager.registerEngine(JavaScriptSource.ENGINE) {
|
||||
val engine = XJavaScriptEngine(application)
|
||||
engine.setKey(mKey, mInitVector)
|
||||
engine.runtime = createRuntime()
|
||||
engine
|
||||
}
|
||||
@@ -98,11 +95,6 @@ class AutoJs private constructor(application: Application) : com.stardust.autojs
|
||||
return runtime
|
||||
}
|
||||
|
||||
fun setKey(key: String, vet: String) {
|
||||
mKey = key
|
||||
mInitVector = vet
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
||||
@SuppressLint("StaticFieldLeak")
|
||||
|
||||
@@ -20,7 +20,7 @@ class ScriptExecutionGlobalListener : ScriptExecutionListener {
|
||||
}
|
||||
|
||||
private fun onFinish(execution: ScriptExecution) {
|
||||
val millis = execution.engine.getTag(ENGINE_TAG_START_TIME) as Long ?: return
|
||||
val millis = execution.engine.getTag(ENGINE_TAG_START_TIME) as Long? ?: return
|
||||
val seconds = (System.currentTimeMillis() - millis) / 1000.0
|
||||
AutoJs.instance.scriptEngineService.globalConsole
|
||||
.verbose(GlobalAppContext.getString(R.string.text_execution_finished), execution.source.toString(), seconds)
|
||||
|
||||
@@ -2,20 +2,17 @@ package com.stardust.auojs.inrt.autojs
|
||||
|
||||
import android.content.Context
|
||||
import com.stardust.autojs.engine.LoopBasedJavaScriptEngine
|
||||
import com.stardust.autojs.engine.encryption.ScriptEncryption
|
||||
import com.stardust.autojs.script.EncryptedScriptFileHeader
|
||||
import com.stardust.autojs.script.JavaScriptFileSource
|
||||
import com.stardust.autojs.script.ScriptSource
|
||||
import com.stardust.autojs.script.StringScriptSource
|
||||
import com.stardust.pio.PFiles
|
||||
import com.stardust.util.AdvancedEncryptionStandard
|
||||
import java.io.File
|
||||
import java.lang.Exception
|
||||
import java.lang.IllegalStateException
|
||||
import java.security.GeneralSecurityException
|
||||
|
||||
class XJavaScriptEngine(context: Context) : LoopBasedJavaScriptEngine(context) {
|
||||
|
||||
private var mKey = ""
|
||||
private var mInitVector = ""
|
||||
|
||||
override fun execute(source: ScriptSource, callback: ExecuteCallback?) {
|
||||
if (source is JavaScriptFileSource) {
|
||||
@@ -32,17 +29,10 @@ class XJavaScriptEngine(context: Context) : LoopBasedJavaScriptEngine(context) {
|
||||
private fun execute(file: File) {
|
||||
val bytes = PFiles.readBytes(file.path)
|
||||
try {
|
||||
val source = AdvancedEncryptionStandard(mKey.toByteArray(), mInitVector).decrypt(bytes)
|
||||
super.execute(StringScriptSource(file.name, String(source)))
|
||||
super.execute(StringScriptSource(file.name, String(ScriptEncryption.decrypt(bytes, EncryptedScriptFileHeader.BLOCK_SIZE))))
|
||||
} catch (e: GeneralSecurityException) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
}
|
||||
|
||||
fun setKey(key: String, initVector: String) {
|
||||
mKey = key
|
||||
mInitVector = initVector
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -11,6 +11,7 @@ import com.stardust.auojs.inrt.BuildConfig
|
||||
import com.stardust.auojs.inrt.LogActivity
|
||||
import com.stardust.auojs.inrt.Pref
|
||||
import com.stardust.auojs.inrt.autojs.AutoJs
|
||||
import com.stardust.autojs.engine.encryption.ScriptEncryption
|
||||
import com.stardust.autojs.execution.ExecutionConfig
|
||||
import com.stardust.autojs.execution.ScriptExecution
|
||||
import com.stardust.autojs.project.ProjectConfig
|
||||
@@ -101,12 +102,12 @@ open class AssetsProjectLauncher(private val mAssetsProjectDir: String, private
|
||||
val key = MD5.md5(projectConfig.packageName + projectConfig.versionName + projectConfig.mainScriptFile)
|
||||
val vec = MD5.md5(projectConfig.buildInfo.buildId + projectConfig.name).substring(0, 16)
|
||||
try {
|
||||
val fieldKey = AutoJs::class.java.getDeclaredField("mKey")
|
||||
val fieldKey = ScriptEncryption::class.java.getDeclaredField("mKey")
|
||||
fieldKey.isAccessible = true
|
||||
fieldKey.set(AutoJs.instance, key)
|
||||
val fieldVector = AutoJs::class.java.getDeclaredField("mInitVector")
|
||||
fieldKey.set(null, key)
|
||||
val fieldVector = ScriptEncryption::class.java.getDeclaredField("mInitVector")
|
||||
fieldVector.isAccessible = true
|
||||
fieldVector.set(AutoJs.instance, vec)
|
||||
fieldVector.set(null, vec)
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user