This commit is contained in:
Yutousama 2022-08-24 21:12:13 +08:00
parent 887c7681dc
commit 54eb1365c6
5 changed files with 347 additions and 44 deletions

20
.vscode/settings.json vendored Normal file
View File

@ -0,0 +1,20 @@
{
"MicroPython.executeButton": [
{
"text": "▶",
"tooltip": "运行",
"alignment": "left",
"command": "extension.executeFile",
"priority": 3.5
}
],
"MicroPython.syncButton": [
{
"text": "$(sync)",
"tooltip": "同步",
"alignment": "left",
"command": "extension.execute",
"priority": 4
}
]
}

View File

@ -18,8 +18,8 @@
</select>
<input id="btn" name="btn" type="button" value="执行" class="layui-btn layui-btn-normal" />
<button type="button" class="layui-btn" id="upload">
<i class="layui-icon">&#xe67c;</i>上传APK
<button type="button" class="layui-btn" id="setSignFile">
<i class="layui-icon">&#xe67c;</i>设置签名
</button>
<input id="flush" name="flush" type="button" value="刷新设备列表" class="layui-btn" />
<input id="showPack" name="showPack" type="button" value="已安装列表" class="layui-btn" />
@ -36,6 +36,28 @@
</body>
<script>
function showWindows() {
utools.showMainWindow()
}
function uploadSign(alias, aliasPassword, password, sign) {
utools.db.put({
_id: "alias",
data: alias
})
utools.db.put({
_id: "aliasPassword",
data: aliasPassword
})
utools.db.put({
_id: "password",
data: password
})
utools.db.put({
_id: "sign",
data: sign
})
}
function log(data) {
console.log("日志输出:" + data)
$('#log').val($('#log').val() + "\n" + data)
@ -84,6 +106,9 @@
$('#flush').click(function () {
reload()
})
$('#setSignFile').click(function () {
setSign()
})
reload()
utools.onPluginEnter(({
@ -91,22 +116,64 @@
type,
payload
}) => {
if (type == 'files') {
console.log(code)
if (type != 'window')
path = payload[0].path;
if (code == 'install') {
console.log("检测到文件:" + path)
log("准备安装:" + path)
}
reload()
})
} else if (code == 'unapk') {
log("准备反编译:" + path)
window.unapk(payload[0].path, (stdout, error) => {
log(stdout)
utools.shellBeep()
})
} else if (code == 'apkinfo') {
window.apkinfo(path, (stdout, error) => {
log(stdout)
})
} else if (code == 'packapk') {
utools.readCurrentFolderPath().then((dir) => {
log("正在回编译")
window.packapk(dir, (stdout, error) => {
log(stdout)
})
})
} else if (code == 'signapk') {
let isUseSign = utools.db.get('sign')
if (isUseSign == null) {
setSign()
} else {
log("正在签名:" + path)
window.signapk(payload[0].path, (stdout, error) => {
log(stdout)
utools.shellBeep()
log('签名完成')
})
}
}
})
function setSign() {
layer.open({
type: 2,
title: '设置签名'
, area: ['350px', '300px']
, content: ['sign_dialog.html', 'no']
, cancel: function (index, layero) {
layer.close(index)
return false;
}
});
}
function reload() {
chinese = [];
$('#device').empty();
$('#log').val('');
window.adb('adb devices', (stdout,error) => {
if(error==true){
window.adb('adb devices', (stdout, error) => {
if (error == true) {
log(stdout)
return;
}
@ -149,31 +216,34 @@
log("没有连接设备");
}
})
}
$('#showPack').click(function () {
window.adb("adb shell pm list package", (stdout,error) => {
if(error==true){
var dv = devices[0].split(/\s+/);
window.adb("adb -s "+dv[0]+" shell pm list package", (stdout, error) => {
if (error == true) {
log(stdout)
return;
}
log(stdout)
})
})
$('#show').click(function(){
console.log("aapt dump badging \""+path+"\"")
window.adb("aapt dump badging \""+path+"\"",(stdout,error) => {
if(error==true){
$('#show').click(function () {
console.log("aapt dump badging \"" + path + "\"")
window.adb("aapt dump badging \"" + path + "\"", (stdout, error) => {
if (error == true) {
log(stdout)
return;
}
log(stdout)
window.adb("aapt dump xmltree \""+path+"\" AndroidManifest.xml",(stdout,error)=>{
window.adb("aapt dump xmltree \"" + path + "\" AndroidManifest.xml", (stdout, error) => {
log(stdout)
})
})
})
$('#showTopActivity').click(function(){
window.adb("adb shell dumpsys window | findstr mCurrentFocus",(data,error)=>{
$('#showTopActivity').click(function () {
var dv = devices[0].split(/\s+/);
window.adb("adb -s "+dv[0]+" shell dumpsys window | findstr mCurrentFocus", (data, error) => {
log(data)
})
})

View File

@ -4,22 +4,80 @@
"main": "index.html",
"version": "0.0.3",
"author": "Yutou",
"logo": "logo.png",
"preload":"preload.js",
"pluginSetting":{
"single": true
},
"logo": "logo.png",
"preload": "preload.js",
"pluginSetting": {
"single": true
},
"features": [
{
"code": "adb",
"cmds":["adb",{
"label":"adb install apk",
"type":"files",
"fileType": "file",
"minNum": 1,
"maxNum": 1
}]
}
{
"code":"text",
"cmds": [ "adb", "android" ]
},
{
"code": "install",
"cmds": [
{
"label": "安装apk到手机",
"type": "files",
"fileType": "file",
"match":"/.*?\\.apk$/i",
"minNum": 1,
"maxNum": 1
}
]
},
{
"code": "unapk",
"cmds": [
{
"label": "反编译",
"type": "files",
"fileType": "file",
"match":"/.*?\\.apk$/i",
"minNum": 1,
"maxNum": 1
}
]
},
{
"code": "packapk",
"cmds": [
{
"label": "回编apk",
"type": "window",
"match":{
"title":"*"
}
}
]
},
{
"code": "signapk",
"cmds": [
{
"label": "签名apk",
"type": "files",
"fileType": "file",
"match":"/.*?\\.apk$/i",
"minNum": 1,
"maxNum": 1
}
]
}
,
{
"code": "apkinfo",
"cmds": [
{
"label": "查看apk信息",
"type": "files",
"fileType": "file",
"match":"/.*?\\.apk$/i",
"minNum": 1,
"maxNum": 1
}
]
}
]
}

View File

@ -1,19 +1,98 @@
const exec = require('child_process');
const path = require('path')
const fs = require('fs')
const { POINT_CONVERSION_HYBRID } = require('constants');
const iconv = require('iconv-lite')
var encoding = 'GBK';
var binaryEncoding = 'binary';
window.adb = function (ext,fun) {
exec.exec(ext,{ encoding: 'binary' }, (err, stdout, stderr)=>{
if(stderr!=''){
fun(iconv.decode(new Buffer(stderr, binaryEncoding), encoding),true)
}else if(stdout!=''){
fun(iconv.decode(new Buffer(stdout, binaryEncoding), encoding),false)
}else if(err!=''){
fun(iconv.decode(new Buffer(err, binaryEncoding), encoding),true)
}else{
window.exec_ = function (ext, fun) {
exec.exec(ext, { encoding: 'binary' }, (err, stdout, stderr) => {
if (stderr != '') {
fun(iconv.decode(new Buffer(stderr, binaryEncoding), encoding), true)
} else if (stdout != '') {
fun(iconv.decode(new Buffer(stdout, binaryEncoding), encoding), false)
} else if (err != '') {
try {
fun(iconv.decode(new Buffer(err, binaryEncoding), encoding), true)
} catch (error) {
fun(err)
}
} else {
fun("异常错误")
}
})
}
window.adb = function (ext, fun) {
let adb = getAdb()
let _exec = ext.replace('adb', adb)
//ext="dir"
console.log(_exec)
exec.exec(_exec, { encoding: 'binary' }, (err, stdout, stderr) => {
if (stderr != '') {
fun(iconv.decode(new Buffer(stderr, binaryEncoding), encoding), true)
} else if (stdout != '') {
fun(iconv.decode(new Buffer(stdout, binaryEncoding), encoding), false)
} else if (err != '') {
fun(iconv.decode(new Buffer(err, binaryEncoding), encoding), true)
} else {
fun("异常错误")
}
})
}
window.unapk = function (file, fun) {
let apktool = getApkTools();
let _exec = getJavaRuntimer()+"java -jar \"" + apktool + "\" d -f \"" + file + "\" --only-main-classes -out=\"" + getFilePath(file) + path.sep + getFileNotExtName(file) + "\""
exec_(_exec, fun)
}
window.apkinfo = function (file, fun) {
let aapt = getAapt()
let _exec = aapt + " dump badging " + file
exec_(_exec, fun)
}
window.packapk = function (dir, fun) {
let apktool = getApkTools();
let _exec = getJavaRuntimer()+"java -jar " + apktool + " -r b -f " + dir + " -o " + dir + path.sep + "game.apk"
exec_(_exec, fun)
}
window.signapk = function (file, fun) {
let sign = getSign()
let _exec =getJavaRuntimer()+ sign + " -verbose -keystore " + utools.db.get('sign').data + ' -keypass ' + utools.db.get('password').data
+ ' -storepass ' + utools.db.get('aliasPassword').data + ' -signedjar \"' + file + '_sign.apk\" \"'
+ file + '\" ' + utools.db.get('alias').data
console.log(_exec)
exec_(_exec, fun)
}
window.readSignDialog = function (fun) {
console.log('read file')
let data = fs.readFileSync('sign_dialog.txt');
console.log(data)
fun(data)
}
function getApkTools() {
return utools.getPath('documents') + path.sep + 'utools_adb_libs' + path.sep + 'apktool.jar'
}
function getAdb() {
return utools.getPath('documents') + path.sep + 'utools_adb_libs' + path.sep + 'adb.exe';
}
function getAapt() {
return utools.getPath('documents') + path.sep + 'utools_adb_libs' + path.sep + 'aapt.exe';
}
function getSign() {
return 'jarsigner.exe';
}
function getSignTools() {
return utools.getPath('documents') + path.sep + 'utools_adb_libs' + path.sep + 'sign'+path.sep+'bin';
}
function getJavaRuntimer(){
return "path="+getSignTools()+"&"
}
function getFilePath(file) {
return path.dirname(file)
}
function getFileNotExtName(file) {
return path.basename(file, path.extname(file))
}

76
sign_dialog.html Normal file
View File

@ -0,0 +1,76 @@
<!DOCTYPE html>
<html>
<head>
<script src="js/jquery-3.2.1.js"></script>
<script src="layui/layui.all.js"></script>
<link rel="stylesheet" href="layui/css/layui.css">
<link rel="stylesheet" href="layui/css/modules/layer/default/layer.css">
<link rel="stylesheet" href="layui/css/layui.css" media="all">
</head>
<body>
<form class="layui-form" style="height: 300px;width: 330px;">
<div class="layui-form-item">
<label class="layui-form-label">别名</label>
<div class="layui-input-block">
<input type="text" id="alias" required lay-verify="required" placeholder="请输入别名(Alias)" autocomplete="off"
class="layui-input">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">别名密码</label>
<div class="layui-input-block">
<input type="text" id="aliasPassword" required lay-verify="required" placeholder="请输入别名密码(AliasPassword)"
autocomplete="off" class="layui-input">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">签名密码</label>
<div class="layui-input-block">
<input type="text" id="password" required lay-verify="required" placeholder="请输入签名密码(Password)"
autocomplete="off" class="layui-input">
</div>
</div>
<div class="layui-form-item" style="margin-left: 10px;">
<button id="select" type="button" class="layui-btn">选择签名</button>
<button id="sub" type="button" class="layui-btn">保存</button>
</div>
</form>
</body>
<script>
layui.use('upload', function () {
let upload = layui.upload;
let signFile
let uploadInst = upload.render({
elem: '#select' //绑定元素
, url: '/' //上传接口
, accept: 'file'
, auto: false
, choose: function (res) {
//上传完毕回调
let files = res.pushFile();
res.preview(function (index, file, result) {
path = file.path;
signFile=path
window.parent.showWindows()
});
}
, error: function () {
//请求异常回调
}
});
$('#sub').click(function(){
let alias=$('#alias').val()
let aliasPassword=$('#aliasPassword').val()
let password=$('#password').val()
window.parent.uploadSign(alias,aliasPassword,password,signFile)
layer.msg('保存成功,正常关闭对话框即可')
})
})
</script>
</html>