adb 备份
adb backup -f ~/Desktop/log/a.ab -apk com.package.activity下载 abe 包
ab 文件解包
java -jar ~/Downloads/abe/abe.jar unpack ~/Desktop/log/a.ab ~/Desktop/log/a.rarrar 软件解压 a.rar,即可
adb 备份
adb backup -f ~/Desktop/log/a.ab -apk com.package.activity
下载 abe 包
ab 文件解包
java -jar ~/Downloads/abe/abe.jar unpack ~/Desktop/log/a.ab ~/Desktop/log/a.rar
rar 软件解压 a.rar,即可
Android 中,格式化文件大小(Formatter.formatFileSize),Android8 之前用 1024 为单位,之后采用 1000 为单位。
查看 Android 28(Android P)源码
1 | public static BytesResult formatBytes(Resources res, long sizeBytes, int flags) { |
formatFileSize 方法源码如下:
1 | /* <p>As of O, the prefixes are used in their standard meanings in the SI system, so kB = 1000 |
意思就是在 Android 7 之后单位就变了,使用标准的单位制含义,即国际单位制,就像 1km = 1000 byte 一样;
在 Android 7 及更早的版本是 1024,即 1k = 1024B,这里就不贴代码了,感兴趣的同学可以去看源码。
有两个方案,一个是反射设置 FLAG_SI_UNITS 的值,使得与 FLAG_IEC_UNITS 相与不为 0 ,
另外一个方案重新封装一个类,如下,用法与 Android 提供的一样
1 | public class Formatter { |
通过 android 私有方法,快速解析 manifest,步骤如下:
1 | public class TestLoadApk { |
1 | public void testSftpListDir() { |
APP 在安卓端进入后台运行时,展示 toast 提示“已进入后台运行”
APP 安卓系统的 root 环境提示框,支持用户点击「我知道了」关闭弹窗,关闭弹窗后,APP 可正常使用。
文案:您的手机当前处于 root 环境下,您的个人隐私和****的使用可能存在安全隐患。
App 中使用 sdk 需要在隐私协议中,尽可能体现
1 | val rootPath = |
Let’s face it: we don’t think about SSH all that much. We SSH into a server and merrily type away our commands. Until we need to write an SSH server.
This document describes the high level concepts of SSH: how do you open a connection, what are channels, and how do requests work.
This is a very high level overview, but should contain everything you need to get started with ContainerSSH development.
Handshake¶
When the user connects an SSH server the SSH keys are verified. We won’t discuss this here as for ContainerSSH the Go SSH library takes care of that.
The first thing we are concerned with is authentication. Authentication is described by RFC 4252 and it states the following:
The server drives the authentication by telling the client which authentication methods can be used to continue the exchange at any given time. The client has the freedom to try the methods listed by the server in any order.
In other words, when the user connects the SSH server tells the client which authentication method it supports. The client picks one of them and performs the authentication. The server can then decide to reject, allow, or show the client another list of methods (e.g. to perform two factor authentication). The Go library vastly simplifies this process and only allows a single means of authentication for each connection.
Each authentication request contains a username. The username may change between authentication attempts to authenticate against different systems, but this is not customary.
Connection¶
Once the authentication is complete the connection is open and both the client and the server may now send two types of messages: global requests and channels.
Global requests describe requests in either direction that one party wants from the other. For example, the OpenSSH extensions describe the no-more-sessions@openssh.com to indicate that no more session channels should be opened on this connection.
The channels, on the other hand are means of transporting data. For example, the session channel is responsible for executing a program and then transporting the standard input, output, and error data streams to and from the program. They also give both ends the ability to send channel-specific requests (e.g. setting environment variables, resizing the window, etc.).
Session channels¶
While there are theoretically other types of channels possible, we currently only support session channels. The client can request channels to be opened at any time.
We currently support the following requests on the session channel. These are described in RFC 4254.
env
Sets an environment variable for the soon to be executed program.
pty
Requests an interactive terminal for user input.
shell
Requests the default shell to be executed.
exec
Requests a specific program to be executed.
subsystem
Requests a well-known subsystem (e.g. sftp) to be executed.
window-change
Informs the server that an interactive terminal window has changed size. This is only sent once the program has been started with the requests above.
signal
Requests the server to send a signal to the currently running process.
In addition, we also send an exit-status request to the client from the server when the program exits to inform the client of the exit code.
Interactive terminals¶
As you can see above, the user can request an interactive terminal using the pty request. This is done automatically by SSH clients if they detect that their input is an interactive terminal.
Using interactive terminals changes the operation mode of stdin, stdout, and stderr. While programs normally write their standard output to stdout and their error output to stderr, programs running in interactive mode send their combined output to stdout using a special framing. (TTY multiplexing)
Thankfully, we don’t need to know too much about TTY multiplexing for writing an SSH server since it is transparently passed through from the container engine to the SSH channel and we don’t interact with it.
RFCs¶
The SSH protocol is governed by the following RFCs:
RFC 913: Simple File Transfer Protocol
This document describes the SFTP protocol used over SSH.
RFC 4250: The Secure Shell (SSH) Protocol Assigned Numbers
This document describes the protocol numbers and standard constants used in SSH.
RFC 4251: The Secure Shell (SSH) Protocol Architecture
This document describes the design decisions taken to work with SSH.
RFC 4252: The Secure Shell (SSH) Authentication Protocol
This document describes how user authentication works in SSH.
RFC 4253: The Secure Shell (SSH) Transport Layer Protocol
This document describes the details of how data is transported over SSH.
RFC 4254: The Secure Shell (SSH) Connection Protocol
This document contains the parts most interesting to us: how channels, sessions, etc. work.
RFC 4255: Using DNS to Securely Publish Secure Shell (SSH) Key Fingerprints
This document describes how to publish SSH fingerprints using DNS. It has not seen wide adoption.
RFC 4256: Generic Message Exchange Authentication for the Secure Shell Protocol (SSH)
This document describes the keyboard-interactive authentication for SSH, which is often used for two factor authentication.
RFC 4335: The Secure Shell (SSH) Session Channel Break Extension
This document describes the telnet-compatible break request for use in SSH.
RFC 4344, RFC 4345, RFC 4419, RFC 4432
These documents describe various encryption-related topics.
RFC 4462: Generic Security Service Application Program Interface (GSS-API) Authentication and Key Exchange for the Secure Shell (SSH) Protocol
This document describes the GSS-API authentication method that can be used to authenticate with a Kerberos ticket.
RFC 4716: The Secure Shell (SSH) Public Key File Format
This document describes the PEM-like format to store SSH keys in.
RFC 4819: Secure Shell Public Key Subsystem
This document describes the SSH public key subsystem usable for adding, removing, and listing public keys.
RFC 5647, RFC 5656, RFC 6187, RFC 6239, RFC 6594, RFC 6668
These documents describe various cryptography and authentication related topics.
RFC 7479: Using Ed25519 in SSHFP Resource Records
This document describes publishing ED25519 host keys using DNS.
RFC 5592: Secure Shell Transport Model for the Simple Network Management Protocol (SNMP)
This protocol describes using SNMP over SSH.
RFC 6242: Using the NETCONF Protocol over Secure Shell (SSH)
This document describes transporting the RFC 6241 Network Configuration Protocol over SSH. This can be used to manage networking equipment.
In addition, OpenSSH defines the following extensions:
The OpenSSH Protocol
This document describes new cryptographic methods, tunnel forwarding, domain socket forwarding, and many more changes.
The CertKeys Document
This document describes the OpenSSH CA method.
SSH Agent Protocol
Describes the protocol used by the SSH agent holding the SSH keys in escrow.
Kotlin 有三种结构化跳转表达式:
return 默认从最直接包围它的函数或者匿名函数返回。
break 终止最直接包围它的循环。
continue 继续下一次最直接包围它的循环。
所有这些表达式都可以用作更大表达式的一部分:
val s = person.name ?: return
这些表达式的类型是 Nothing 类型。
Break 与 Continue 标签
在 Kotlin 中任何表达式都可以用标签来标记。 标签的格式为标识符后跟 @ 符号,例如:abc@、fooBar@。 要为一个表达式加标签,我们只要在其前加标签即可。
loop@ for (i in 1..100) {
// ……
}
现在,我们可以用标签限定 break 或者 continue:
loop@ for (i in 1..100) {
for (j in 1..100) {
if (……) break@loop
}
}
标签限定的 break 跳转到刚好位于该标签指定的循环后面的执行点。 continue 继续标签指定的循环的下一次迭代。
返回到标签
Kotlin 中函数可以使用函数字面量、局部函数与对象表达式实现嵌套。 标签限定的 return 允许我们从外层函数返回。 最重要的一个用途就是从 lambda 表达式中返回。回想一下我们这么写的时候, 这个 return 表达式从最直接包围它的函数——foo 中返回:
//sampleStart
fun foo() {
listOf(1, 2, 3, 4, 5).forEach {
if (it == 3) return // 非局部直接返回到 foo() 的调用者
print(it)
}
println(“this point is unreachable”)
}
//sampleEnd
fun main() {
foo()
}
注意,这种非局部的返回只支持传给内联函数的 lambda 表达式。 如需从 lambda 表达式中返回,可给它加标签并用以限定 return。
//sampleStart
fun foo() {
listOf(1, 2, 3, 4, 5).forEach lit@{
if (it == 3) return@lit // 局部返回到该 lambda 表达式的调用者——forEach 循环
print(it)
}
print(“ done with explicit label”)
}
//sampleEnd
fun main() {
foo()
}
现在,它只会从 lambda 表达式中返回。通常情况下使用隐式标签更方便,因为该标签与接受该 lambda 的函数同名。
//sampleStart
fun foo() {
listOf(1, 2, 3, 4, 5).forEach {
if (it == 3) return@forEach // 局部返回到该 lambda 表达式的调用者——forEach 循环
print(it)
}
print(“ done with implicit label”)
}
//sampleEnd
fun main() {
foo()
}
或者,我们用一个匿名函数替代 lambda 表达式。 匿名函数内部的 return 语句将从该匿名函数自身返回
//sampleStart
fun foo() {
listOf(1, 2, 3, 4, 5).forEach(fun(value: Int) {
if (value == 3) return // 局部返回到匿名函数的调用者——forEach 循环
print(value)
})
print(“ done with anonymous function”)
}
//sampleEnd
fun main() {
foo()
}
请注意,前文三个示例中使用的局部返回类似于在常规循环中使用 continue。
并没有 break 的直接等价形式,不过可以通过增加另一层嵌套 lambda 表达式并从其中非局部返回来模拟:
//sampleStart
fun foo() {
run loop@{
listOf(1, 2, 3, 4, 5).forEach {
if (it == 3) return@loop // 从传入 run 的 lambda 表达式非局部返回
print(it)
}
}
print(“ done with nested loop”)
}
//sampleEnd
fun main() {
foo()
}
当要返一个回值的时候,解析器优先选用标签限定的返回:
return@a 1
这意味着“返回 1 到 @a”,而不是“返回一个标签标注的表达式 (@a 1)”。