Most powerful Android automation framework built for the mobile-first era.
20 |
面向移动优先时代的强大 Android 自动化框架。
21 |
22 | With the decline of traditional web interfaces and the rise of intelligent devices, automation and data technologies must adapt to the mobile shift. FIRERPA embraces this trend, offering a modern solution purpose-built for Android automation. Lightweight, with no external dependencies, and compatible with any version of the Android operating system. Low-latency remote desktop and audio transmission (under 80ms). Over 160 programming interfaces, covering automation, file I/O, script injection, proxy support, and more. Exceptionally stable, supports distributed deployment, and is easy to monitor and manage. 随着传统网页的式微与智能设备的崛起,自动化与数据技术迫切需要适应移动化转型。FIRERPA 正是顺应这一趋势而生,为 Android 自动化带来现代化解决方案。轻量,无任何外部依赖,可运行于任何版本的安卓系统。低延迟的远程桌面及远程音频传输(小于 80ms)。160+ 编程接口,涵盖自动化及文件读写、脚本注入、代理等等。极致稳定,支持分布式部署,易监控管理。
23 |
24 |
25 |
26 |
27 |
28 |
Reliable across Android 6.0 to 15, from emulators to cloud.
29 |
兼容 Android 6.0–15,适用于模拟器、真机与云平台。
30 |
31 | FIRERPA delivers commercial-grade automation capabilities across a wide range of Android versions and devices. It requires only root access, simplifies security analysis and testing, and is already widely used in scenarios such as digital forensics and compliance monitoring. FIRERPA 提供稳定且达到商用级的自动化能力,兼容众多 Android 系统与设备,仅需 Root 权限即可轻松完成安全分析与测试,广泛应用于数字取证与合规监测等场景。
32 |
33 |
Zero-Intrusion Design.
34 |
零侵入式设计。
35 |
36 | FIRERPA ensures complete non-intrusiveness during operation—it does not alter system settings or write to system files, preserving the original environment and ensuring device integrity.
37 | FIRERPA 保证运行过程完全无侵入,不修改系统设置、不改写系统文件,保留原始环境,设备完整性不受影响。
38 |
39 |
Designed from the ground up for flexible deployment.
40 |
从零设计,专为灵活性与大规模部署而生。
41 |
42 | FIRERPA was built from the ground up to run non-intrusively on most Android devices. It requires no third-party dependencies, no complex configuration, and is ready to use out of the box. Compared to other solutions, it avoids common issues like instability and poor compatibility, making it ideal for large-scale business applications. FIRERPA 从设计之初就面向多样化环境,几乎兼容所有 Android 设备,无侵入式运行,无需依赖与额外配置,即开即用。相较于其他方案常见的不稳定、兼容差、维护难等问题,FIRERPA 在大规模部署中的表现尤为出色。
43 |
44 |
160+ APIs and full Python SDK for rapid development.
45 |
160+ API 配套完整 Python SDK,助力高效开发。
46 |
47 | FIRERPA offers over 160 categorized, stable APIs that cover command execution, system configuration, automation flows, and app-level controls. It also provides a full-featured Python SDK for rapid development and seamless AI integration. Developers can easily build intelligent workflows with precise control over Android systems. FIRERPA 提供超 160 个分类清晰、稳定可靠的接口,涵盖命令执行、系统设置、自动化流程与应用控制等,并包含完整的 Python SDK,帮助开发者高效实现与 AI 的无缝集成,构建具备精细控制能力的智能化任务流。
48 |
49 |
50 |
51 |
52 |
53 |
Remote desktop and device control, made simple.
54 |
远程桌面与设备控制,简单直观。
55 |
56 | FIRERPA comes with a clean, intuitive remote desktop interface, allowing users to monitor and control Android devices visually and interactively. Whether for testing, automation validation, or system diagnostics, it provides a powerful control layer with minimal setup. FIRERPA 内置简洁直观的远程桌面功能,帮助用户以可视化方式监控和操作 Android 设备。无论用于测试、任务验证还是系统诊断,都能提供高效、轻量的控制体验。
57 |
58 |
59 |
60 |
61 |
62 |
Check out real usage examples and developer guides in the documentation.
63 |
欢迎查阅 FIRERPA 使用文档,了解更多实际案例与开发指南。
--------------------------------------------------------------------------------
/SECURITY.md:
--------------------------------------------------------------------------------
1 | # Security Policy
2 |
3 | ## Supported Versions
4 |
5 | | Version | Supported |
6 | | ------- | ------------------ |
7 | | 8.x | :white_check_mark: |
8 |
9 | ## Reporting a Vulnerability
10 |
11 | mailto:lamda.devel@gmail.com
12 |
--------------------------------------------------------------------------------
/examples/README.md:
--------------------------------------------------------------------------------
1 | We’re not targeting any specific application; we’re just using it as a convenient example for the demo.
2 |
3 | API Document: https://device-farm.com/doc/
--------------------------------------------------------------------------------
/examples/activity_jump.py:
--------------------------------------------------------------------------------
1 | # Copyright 2025 rev1si0n (lamda.devel@gmail.com). All rights reserved.
2 | #encoding=utf-8
3 | from lamda.client import *
4 | import time
5 |
6 | d = Device("localhost")
7 |
8 | app = d.application("com.taobao.taobao")
9 | app.start()
10 |
11 | while True:
12 | goodsid = input("Please input a taobao goods id (item_id) (eg. 123456): ")
13 | if goodsid.isdigit():
14 | intent["package"] = "com.taobao.taobao"
15 | intent["action"] = "android.intent.action.VIEW"
16 | intent["component"] = "com.taobao.taobao/com.taobao.android.detail.alittdetail.TTDetailActivity"
17 | intent["data"] = f"http://internal.tt.detail.taobao.com/detail/index.html?id={goodsid}"
18 | d.start_activity(**intent)
19 | time.sleep(2)
--------------------------------------------------------------------------------
/examples/search_in_taobao.py:
--------------------------------------------------------------------------------
1 | # Copyright 2025 rev1si0n (lamda.devel@gmail.com). All rights reserved.
2 | #encoding=utf-8
3 | from lamda.client import *
4 | import time
5 |
6 | """
7 | This is a simple demo for performing keyword searches on Taobao.
8 | """
9 |
10 | d = Device("localhost")
11 |
12 | app = d.application("com.taobao.taobao")
13 |
14 | if not app.is_installed():
15 | print ("taobao app is not installed")
16 | exit (1)
17 |
18 | if app.info().versionName != "10.48.0":
19 | print ("please intall taaobao 10.48.0")
20 | exit (1)
21 |
22 | # ensure the app is stopped
23 | app.stop()
24 | time.sleep(1.5)
25 |
26 | app.start()
27 | time.sleep(10) # wait for app fully started
28 |
29 | if not d(description="我的淘宝").exists():
30 | print ("is taobao home page?")
31 | exit (1)
32 |
33 | # click to activate input
34 | d(description="搜索栏").click()
35 |
36 | # wait for search input activated
37 | d(resourceId="com.taobao.taobao:id/searchbtn").wait_for_exists(15*1000)
38 |
39 | # input search keyword: 苹果手机
40 | d(resourceId="com.taobao.taobao:id/searchEdit").set_text("苹果手机")
41 |
42 | # click "Search"
43 | d(resourceId="com.taobao.taobao:id/searchbtn").click()
44 |
45 | # wait for goods showsup
46 | d(description="筛选").wait_for_exists(15*1000)
47 |
48 | # do a simple swipe
49 | d().swipe()
50 |
51 | # ...
--------------------------------------------------------------------------------
/extensions/README.md:
--------------------------------------------------------------------------------
1 | API Document: https://device-farm.com/doc/
--------------------------------------------------------------------------------
/extensions/example_http_extension.py:
--------------------------------------------------------------------------------
1 | # Copyright 2025 rev1si0n (lamda.devel@gmail.com). All rights reserved.
2 | #
3 | # Distributed under MIT license.
4 | # See file LICENSE for detail or copy at https://opensource.org/licenses/MIT
5 | from lamda.extensions import *
6 |
7 |
8 | class ExampleHttpExtension(BaseHttpExtension):
9 | route = "/api/v1/hello-world" # API route
10 | def http_get(self, *args, **kwargs):
11 | """ GET Method Handler """
12 | self.write("Hello World")
13 | def http_post(self, *args, **kwargs):
14 | """ POST Method Handler """
15 | self.write("Hello World")
16 | def http_put(self, *args, **kwargs):
17 | """ PUT Method Handler """
18 | self.write("Hello World")
19 | def http_delete(self, *args, **kwargs):
20 | """ DELETE Method Handler """
21 | self.write("Hello World")
22 | def http_patch(self, *args, **kwargs):
23 | """ PATCH Method Handler """
24 | self.write("Hello World")
--------------------------------------------------------------------------------
/extensions/example_mcp_extension.py:
--------------------------------------------------------------------------------
1 | # Copyright 2025 rev1si0n (lamda.devel@gmail.com). All rights reserved.
2 | #
3 | # Distributed under MIT license.
4 | # See file LICENSE for detail or copy at https://opensource.org/licenses/MIT
5 | import base64
6 |
7 | from lamda.mcp import *
8 | from lamda.utils import getprop
9 | from lamda.extensions import *
10 |
11 |
12 | class ExampleMcpExtension(BaseMcpExtension):
13 | route = "/model-context-protocol/sse/"
14 | name = "example-mcp-extension"
15 | version = "1.0.0"
16 | @mcp("tool", description="Send a greeting to others.")
17 | def greeting(self, ctx, msg: Annotated[str, "Greeting message"],
18 | to: Annotated[str, "Greeting to who"] = "John"):
19 | return TextContent(text=f"mcp greeting! {msg}, {to}!")
20 | @mcp("tool", description="Read android system property by name.")
21 | def getprop(self, ctx, name: Annotated[str, "Android system property name."]):
22 | return TextContent(text=getprop(name) or "")
23 | @mcp("resource", uri="file://{absolute_path}")
24 | def get_file(self, ctx, absolute_path: Annotated[str, "Absolute file path"]):
25 | """ Read file content on the device by full path """
26 | blob = base64.b64encode(open(absolute_path, "rb").read()).decode()
27 | return BlobResourceContents(blob=blob, uri=f"file://{absolute_path}",
28 | mimeType="text/plain")
--------------------------------------------------------------------------------
/image/claude.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/firerpa/lamda/fbd5e6e0ec602df622130c53abb4e87bd783e442/image/claude.gif
--------------------------------------------------------------------------------
/image/demo.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/firerpa/lamda/fbd5e6e0ec602df622130c53abb4e87bd783e442/image/demo.gif
--------------------------------------------------------------------------------
/image/inspect.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/firerpa/lamda/fbd5e6e0ec602df622130c53abb4e87bd783e442/image/inspect.png
--------------------------------------------------------------------------------
/image/logo.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/lamda/__init__.py:
--------------------------------------------------------------------------------
1 | # Copyright 2022 rev1si0n (lamda.devel@gmail.com). All rights reserved.
2 | #
3 | # Distributed under MIT license.
4 | # See file LICENSE for detail or copy at https://opensource.org/licenses/MIT
5 | __version__ = "8.35"
6 |
--------------------------------------------------------------------------------
/lamda/bcast.proto:
--------------------------------------------------------------------------------
1 | // Copyright 2022 rev1si0n (lamda.devel@gmail.com). All rights reserved.
2 | //
3 | // Distributed under MIT license.
4 | // See file LICENSE for detail or copy at https://opensource.org/licenses/MIT
5 | syntax = "proto3";
6 | package lamda;
7 |
8 | message BcastHeader {
9 | // magic always 0x54534143 ("CAST")
10 | uint32 magic = 1;
11 | // protocol version
12 | string version = 2;
13 | }
14 |
15 | message BcastDiscoverInfo {
16 | string ID = 1;
17 | uint64 uptime = 2;
18 | string device = 3;
19 | string abi = 4;
20 | uint32 sdk = 5;
21 | string version = 6;
22 | }
23 |
24 | message BcastResponse {
25 | BcastHeader header = 1;
26 | oneof body {
27 | BcastDiscoverInfo discoverinfo = 10;
28 | int32 errno = 11;
29 | bytes data = 12;
30 | }
31 | }
32 |
33 | message BcastRequest {
34 | BcastHeader header = 1;
35 | string method = 2;
36 | }
37 |
--------------------------------------------------------------------------------
/lamda/const.py:
--------------------------------------------------------------------------------
1 | # Copyright 2022 rev1si0n (https://github.com/rev1si0n). All rights reserved.
2 | #
3 | # Distributed under MIT license.
4 | # See file LICENSE for detail or copy at https://opensource.org/licenses/MIT
5 |
6 | # Android runtime permissions
7 | PERMISSION_READ_SMS = "android.permission.READ_SMS"
8 | PERMISSION_READ_CALENDAR = "android.permission.READ_CALENDAR"
9 | PERMISSION_READ_CALL_LOG = "android.permission.READ_CALL_LOG"
10 | PERMISSION_ACCESS_FINE_LOCATION = "android.permission.ACCESS_FINE_LOCATION"
11 | PERMISSION_ANSWER_PHONE_CALLS = "android.permission.ANSWER_PHONE_CALLS"
12 | PERMISSION_RECEIVE_WAP_PUSH = "android.permission.RECEIVE_WAP_PUSH"
13 | PERMISSION_BODY_SENSORS = "android.permission.BODY_SENSORS"
14 | PERMISSION_READ_PHONE_NUMBERS = "android.permission.READ_PHONE_NUMBERS"
15 | PERMISSION_RECEIVE_MMS = "android.permission.RECEIVE_MMS"
16 | PERMISSION_RECEIVE_SMS = "android.permission.RECEIVE_SMS"
17 | PERMISSION_READ_EXTERNAL_STORAGE = "android.permission.READ_EXTERNAL_STORAGE"
18 | PERMISSION_ACCESS_COARSE_LOCATION = "android.permission.ACCESS_COARSE_LOCATION"
19 | PERMISSION_READ_PHONE_STATE = "android.permission.READ_PHONE_STATE"
20 | PERMISSION_SEND_SMS = "android.permission.SEND_SMS"
21 | PERMISSION_CALL_PHONE = "android.permission.CALL_PHONE"
22 | PERMISSION_WRITE_CONTACTS = "android.permission.WRITE_CONTACTS"
23 | PERMISSION_ACCEPT_HANDOVER = "android.permission.ACCEPT_HANDOVER"
24 | PERMISSION_CAMERA = "android.permission.CAMERA"
25 | PERMISSION_WRITE_CALENDAR = "android.permission.WRITE_CALENDAR"
26 | PERMISSION_WRITE_CALL_LOG = "android.permission.WRITE_CALL_LOG"
27 | PERMISSION_USE_SIP = "android.permission.USE_SIP"
28 | PERMISSION_PROCESS_OUTGOING_CALLS = "android.permission.PROCESS_OUTGOING_CALLS"
29 | PERMISSION_READ_CELL_BROADCASTS = "android.permission.READ_CELL_BROADCASTS"
30 | PERMISSION_GET_ACCOUNTS = "android.permission.GET_ACCOUNTS"
31 | PERMISSION_WRITE_EXTERNAL_STORAGE = "android.permission.WRITE_EXTERNAL_STORAGE"
32 | PERMISSION_ACTIVITY_RECOGNITION = "android.permission.ACTIVITY_RECOGNITION"
33 | PERMISSION_RECORD_AUDIO = "android.permission.RECORD_AUDIO"
34 | PERMISSION_READ_CONTACTS = "android.permission.READ_CONTACTS"
35 | PERMISSION_ACCESS_BACKGROUND_LOCATION = "android.permission.ACCESS_BACKGROUND_LOCATION"
36 | PERMISSION_ACCESS_MEDIA_LOCATION = "android.permission.ACCESS_MEDIA_LOCATION"
37 |
38 | # Android activity flags
39 | FLAG_ACTIVITY_BROUGHT_TO_FRONT = 0x00400000
40 | FLAG_ACTIVITY_CLEAR_TASK = 0x00008000
41 | FLAG_ACTIVITY_CLEAR_TOP = 0x04000000
42 | FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS = 0x00800000
43 | FLAG_ACTIVITY_FORWARD_RESULT = 0x02000000
44 | FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY = 0x00100000
45 | FLAG_ACTIVITY_LAUNCH_ADJACENT = 0x00001000
46 | FLAG_ACTIVITY_MATCH_EXTERNAL = 0x00000800
47 |
48 | FLAG_ACTIVITY_MULTIPLE_TASK = 0x08000000
49 | FLAG_ACTIVITY_NEW_DOCUMENT = 0x00080000
50 | FLAG_ACTIVITY_NEW_TASK = 0x10000000
51 | FLAG_ACTIVITY_NO_ANIMATION = 0x00010000
52 | FLAG_ACTIVITY_NO_HISTORY = 0x40000000
53 | FLAG_ACTIVITY_NO_USER_ACTION = 0x00040000
54 |
55 | FLAG_ACTIVITY_PREVIOUS_IS_TOP = 0x01000000
56 | FLAG_ACTIVITY_REORDER_TO_FRONT = 0x00020000
57 | FLAG_ACTIVITY_REQUIRE_DEFAULT = 0x00000200
58 | FLAG_ACTIVITY_REQUIRE_NON_BROWSER = 0x00000400
59 |
60 | FLAG_ACTIVITY_RESET_TASK_IF_NEEDED = 0x00200000
61 | FLAG_ACTIVITY_RETAIN_IN_RECENTS = 0x00002000
62 | FLAG_ACTIVITY_SINGLE_TOP = 0x20000000
63 | FLAG_ACTIVITY_TASK_ON_HOME = 0x00004000
--------------------------------------------------------------------------------
/lamda/exceptions.py:
--------------------------------------------------------------------------------
1 | # Copyright 2022 rev1si0n (https://github.com/rev1si0n). All rights reserved.
2 | #
3 | # Distributed under MIT license.
4 | # See file LICENSE for detail or copy at https://opensource.org/licenses/MIT
5 | class CompatibilityException(Exception):
6 | """ Exception """
7 | class DeadSystemException(Exception):
8 | """ Exception """
9 | class DeviceUnavailable(Exception):
10 | """ Exception """
11 | class DuplicateEntryError(Exception):
12 | """ Exception """
13 | class IllegalArgumentException(Exception):
14 | """ Exception """
15 | class IllegalStateException(Exception):
16 | """ Exception """
17 | class InstallPackageFailed(Exception):
18 | """ Exception """
19 | class InternalRpcException(Exception):
20 | """ Exception """
21 | class InvalidAndroidPackage(Exception):
22 | """ Exception """
23 | class InvalidArgumentError(Exception):
24 | """ Exception """
25 | class InvalidOperationError(Exception):
26 | """ Exception """
27 | class InvalidRootCertificate(Exception):
28 | """ Exception """
29 | class MethodNotFoundException(Exception):
30 | """ Exception """
31 | class NameNotFoundException(Exception):
32 | """ Exception """
33 | class NotImplementedException(Exception):
34 | """ Exception """
35 | class NullPointerException(Exception):
36 | """ Exception """
37 | class SecurityException(Exception):
38 | """ Exception """
39 | class ServiceUnavailable(Exception):
40 | """ Exception """
41 | class StaleObjectException(Exception):
42 | """ Exception """
43 | class StartupActivityNotFound(Exception):
44 | """ Exception """
45 | class StorageOutOfMemory(Exception):
46 | """ Exception """
47 | class UiAutomatorException(Exception):
48 | """ Exception """
49 | class UiObjectNotFoundException(Exception):
50 | """ Exception """
51 | class UnHandledException(Exception):
52 | """ Exception """
--------------------------------------------------------------------------------
/lamda/google/protobuf/any.proto:
--------------------------------------------------------------------------------
1 | // Protocol Buffers - Google's data interchange format
2 | // Copyright 2008 Google Inc. All rights reserved.
3 | // https://developers.google.com/protocol-buffers/
4 | //
5 | // Redistribution and use in source and binary forms, with or without
6 | // modification, are permitted provided that the following conditions are
7 | // met:
8 | //
9 | // * Redistributions of source code must retain the above copyright
10 | // notice, this list of conditions and the following disclaimer.
11 | // * Redistributions in binary form must reproduce the above
12 | // copyright notice, this list of conditions and the following disclaimer
13 | // in the documentation and/or other materials provided with the
14 | // distribution.
15 | // * Neither the name of Google Inc. nor the names of its
16 | // contributors may be used to endorse or promote products derived from
17 | // this software without specific prior written permission.
18 | //
19 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 |
31 | syntax = "proto3";
32 |
33 | package google.protobuf;
34 |
35 | option csharp_namespace = "Google.Protobuf.WellKnownTypes";
36 | option go_package = "google.golang.org/protobuf/types/known/anypb";
37 | option java_package = "com.google.protobuf";
38 | option java_outer_classname = "AnyProto";
39 | option java_multiple_files = true;
40 | option objc_class_prefix = "GPB";
41 |
42 | // `Any` contains an arbitrary serialized protocol buffer message along with a
43 | // URL that describes the type of the serialized message.
44 | //
45 | // Protobuf library provides support to pack/unpack Any values in the form
46 | // of utility functions or additional generated methods of the Any type.
47 | //
48 | // Example 1: Pack and unpack a message in C++.
49 | //
50 | // Foo foo = ...;
51 | // Any any;
52 | // any.PackFrom(foo);
53 | // ...
54 | // if (any.UnpackTo(&foo)) {
55 | // ...
56 | // }
57 | //
58 | // Example 2: Pack and unpack a message in Java.
59 | //
60 | // Foo foo = ...;
61 | // Any any = Any.pack(foo);
62 | // ...
63 | // if (any.is(Foo.class)) {
64 | // foo = any.unpack(Foo.class);
65 | // }
66 | //
67 | // Example 3: Pack and unpack a message in Python.
68 | //
69 | // foo = Foo(...)
70 | // any = Any()
71 | // any.Pack(foo)
72 | // ...
73 | // if any.Is(Foo.DESCRIPTOR):
74 | // any.Unpack(foo)
75 | // ...
76 | //
77 | // Example 4: Pack and unpack a message in Go
78 | //
79 | // foo := &pb.Foo{...}
80 | // any, err := anypb.New(foo)
81 | // if err != nil {
82 | // ...
83 | // }
84 | // ...
85 | // foo := &pb.Foo{}
86 | // if err := any.UnmarshalTo(foo); err != nil {
87 | // ...
88 | // }
89 | //
90 | // The pack methods provided by protobuf library will by default use
91 | // 'type.googleapis.com/full.type.name' as the type URL and the unpack
92 | // methods only use the fully qualified type name after the last '/'
93 | // in the type URL, for example "foo.bar.com/x/y.z" will yield type
94 | // name "y.z".
95 | //
96 | //
97 | // JSON
98 | // ====
99 | // The JSON representation of an `Any` value uses the regular
100 | // representation of the deserialized, embedded message, with an
101 | // additional field `@type` which contains the type URL. Example:
102 | //
103 | // package google.profile;
104 | // message Person {
105 | // string first_name = 1;
106 | // string last_name = 2;
107 | // }
108 | //
109 | // {
110 | // "@type": "type.googleapis.com/google.profile.Person",
111 | // "firstName": ,
112 | // "lastName":
113 | // }
114 | //
115 | // If the embedded message type is well-known and has a custom JSON
116 | // representation, that representation will be embedded adding a field
117 | // `value` which holds the custom JSON in addition to the `@type`
118 | // field. Example (for message [google.protobuf.Duration][]):
119 | //
120 | // {
121 | // "@type": "type.googleapis.com/google.protobuf.Duration",
122 | // "value": "1.212s"
123 | // }
124 | //
125 | message Any {
126 | // A URL/resource name that uniquely identifies the type of the serialized
127 | // protocol buffer message. This string must contain at least
128 | // one "/" character. The last segment of the URL's path must represent
129 | // the fully qualified name of the type (as in
130 | // `path/google.protobuf.Duration`). The name should be in a canonical form
131 | // (e.g., leading "." is not accepted).
132 | //
133 | // In practice, teams usually precompile into the binary all types that they
134 | // expect it to use in the context of Any. However, for URLs which use the
135 | // scheme `http`, `https`, or no scheme, one can optionally set up a type
136 | // server that maps type URLs to message definitions as follows:
137 | //
138 | // * If no scheme is provided, `https` is assumed.
139 | // * An HTTP GET on the URL must yield a [google.protobuf.Type][]
140 | // value in binary format, or produce an error.
141 | // * Applications are allowed to cache lookup results based on the
142 | // URL, or have them precompiled into a binary to avoid any
143 | // lookup. Therefore, binary compatibility needs to be preserved
144 | // on changes to types. (Use versioned type names to manage
145 | // breaking changes.)
146 | //
147 | // Note: this functionality is not currently available in the official
148 | // protobuf release, and it is not used for type URLs beginning with
149 | // type.googleapis.com.
150 | //
151 | // Schemes other than `http`, `https` (or the empty scheme) might be
152 | // used with implementation specific semantics.
153 | //
154 | string type_url = 1;
155 |
156 | // Must be a valid serialized protocol buffer of the above specified type.
157 | bytes value = 2;
158 | }
159 |
--------------------------------------------------------------------------------
/lamda/google/protobuf/api.proto:
--------------------------------------------------------------------------------
1 | // Protocol Buffers - Google's data interchange format
2 | // Copyright 2008 Google Inc. All rights reserved.
3 | // https://developers.google.com/protocol-buffers/
4 | //
5 | // Redistribution and use in source and binary forms, with or without
6 | // modification, are permitted provided that the following conditions are
7 | // met:
8 | //
9 | // * Redistributions of source code must retain the above copyright
10 | // notice, this list of conditions and the following disclaimer.
11 | // * Redistributions in binary form must reproduce the above
12 | // copyright notice, this list of conditions and the following disclaimer
13 | // in the documentation and/or other materials provided with the
14 | // distribution.
15 | // * Neither the name of Google Inc. nor the names of its
16 | // contributors may be used to endorse or promote products derived from
17 | // this software without specific prior written permission.
18 | //
19 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 |
31 | syntax = "proto3";
32 |
33 | package google.protobuf;
34 |
35 | import "google/protobuf/source_context.proto";
36 | import "google/protobuf/type.proto";
37 |
38 | option csharp_namespace = "Google.Protobuf.WellKnownTypes";
39 | option java_package = "com.google.protobuf";
40 | option java_outer_classname = "ApiProto";
41 | option java_multiple_files = true;
42 | option objc_class_prefix = "GPB";
43 | option go_package = "google.golang.org/protobuf/types/known/apipb";
44 |
45 | // Api is a light-weight descriptor for an API Interface.
46 | //
47 | // Interfaces are also described as "protocol buffer services" in some contexts,
48 | // such as by the "service" keyword in a .proto file, but they are different
49 | // from API Services, which represent a concrete implementation of an interface
50 | // as opposed to simply a description of methods and bindings. They are also
51 | // sometimes simply referred to as "APIs" in other contexts, such as the name of
52 | // this message itself. See https://cloud.google.com/apis/design/glossary for
53 | // detailed terminology.
54 | message Api {
55 | // The fully qualified name of this interface, including package name
56 | // followed by the interface's simple name.
57 | string name = 1;
58 |
59 | // The methods of this interface, in unspecified order.
60 | repeated Method methods = 2;
61 |
62 | // Any metadata attached to the interface.
63 | repeated Option options = 3;
64 |
65 | // A version string for this interface. If specified, must have the form
66 | // `major-version.minor-version`, as in `1.10`. If the minor version is
67 | // omitted, it defaults to zero. If the entire version field is empty, the
68 | // major version is derived from the package name, as outlined below. If the
69 | // field is not empty, the version in the package name will be verified to be
70 | // consistent with what is provided here.
71 | //
72 | // The versioning schema uses [semantic
73 | // versioning](http://semver.org) where the major version number
74 | // indicates a breaking change and the minor version an additive,
75 | // non-breaking change. Both version numbers are signals to users
76 | // what to expect from different versions, and should be carefully
77 | // chosen based on the product plan.
78 | //
79 | // The major version is also reflected in the package name of the
80 | // interface, which must end in `v`, as in
81 | // `google.feature.v1`. For major versions 0 and 1, the suffix can
82 | // be omitted. Zero major versions must only be used for
83 | // experimental, non-GA interfaces.
84 | //
85 | //
86 | string version = 4;
87 |
88 | // Source context for the protocol buffer service represented by this
89 | // message.
90 | SourceContext source_context = 5;
91 |
92 | // Included interfaces. See [Mixin][].
93 | repeated Mixin mixins = 6;
94 |
95 | // The source syntax of the service.
96 | Syntax syntax = 7;
97 | }
98 |
99 | // Method represents a method of an API interface.
100 | message Method {
101 | // The simple name of this method.
102 | string name = 1;
103 |
104 | // A URL of the input message type.
105 | string request_type_url = 2;
106 |
107 | // If true, the request is streamed.
108 | bool request_streaming = 3;
109 |
110 | // The URL of the output message type.
111 | string response_type_url = 4;
112 |
113 | // If true, the response is streamed.
114 | bool response_streaming = 5;
115 |
116 | // Any metadata attached to the method.
117 | repeated Option options = 6;
118 |
119 | // The source syntax of this method.
120 | Syntax syntax = 7;
121 | }
122 |
123 | // Declares an API Interface to be included in this interface. The including
124 | // interface must redeclare all the methods from the included interface, but
125 | // documentation and options are inherited as follows:
126 | //
127 | // - If after comment and whitespace stripping, the documentation
128 | // string of the redeclared method is empty, it will be inherited
129 | // from the original method.
130 | //
131 | // - Each annotation belonging to the service config (http,
132 | // visibility) which is not set in the redeclared method will be
133 | // inherited.
134 | //
135 | // - If an http annotation is inherited, the path pattern will be
136 | // modified as follows. Any version prefix will be replaced by the
137 | // version of the including interface plus the [root][] path if
138 | // specified.
139 | //
140 | // Example of a simple mixin:
141 | //
142 | // package google.acl.v1;
143 | // service AccessControl {
144 | // // Get the underlying ACL object.
145 | // rpc GetAcl(GetAclRequest) returns (Acl) {
146 | // option (google.api.http).get = "/v1/{resource=**}:getAcl";
147 | // }
148 | // }
149 | //
150 | // package google.storage.v2;
151 | // service Storage {
152 | // rpc GetAcl(GetAclRequest) returns (Acl);
153 | //
154 | // // Get a data record.
155 | // rpc GetData(GetDataRequest) returns (Data) {
156 | // option (google.api.http).get = "/v2/{resource=**}";
157 | // }
158 | // }
159 | //
160 | // Example of a mixin configuration:
161 | //
162 | // apis:
163 | // - name: google.storage.v2.Storage
164 | // mixins:
165 | // - name: google.acl.v1.AccessControl
166 | //
167 | // The mixin construct implies that all methods in `AccessControl` are
168 | // also declared with same name and request/response types in
169 | // `Storage`. A documentation generator or annotation processor will
170 | // see the effective `Storage.GetAcl` method after inheriting
171 | // documentation and annotations as follows:
172 | //
173 | // service Storage {
174 | // // Get the underlying ACL object.
175 | // rpc GetAcl(GetAclRequest) returns (Acl) {
176 | // option (google.api.http).get = "/v2/{resource=**}:getAcl";
177 | // }
178 | // ...
179 | // }
180 | //
181 | // Note how the version in the path pattern changed from `v1` to `v2`.
182 | //
183 | // If the `root` field in the mixin is specified, it should be a
184 | // relative path under which inherited HTTP paths are placed. Example:
185 | //
186 | // apis:
187 | // - name: google.storage.v2.Storage
188 | // mixins:
189 | // - name: google.acl.v1.AccessControl
190 | // root: acls
191 | //
192 | // This implies the following inherited HTTP annotation:
193 | //
194 | // service Storage {
195 | // // Get the underlying ACL object.
196 | // rpc GetAcl(GetAclRequest) returns (Acl) {
197 | // option (google.api.http).get = "/v2/acls/{resource=**}:getAcl";
198 | // }
199 | // ...
200 | // }
201 | message Mixin {
202 | // The fully qualified name of the interface which is included.
203 | string name = 1;
204 |
205 | // If non-empty specifies a path under which inherited HTTP paths
206 | // are rooted.
207 | string root = 2;
208 | }
209 |
--------------------------------------------------------------------------------
/lamda/google/protobuf/compiler/plugin.proto:
--------------------------------------------------------------------------------
1 | // Protocol Buffers - Google's data interchange format
2 | // Copyright 2008 Google Inc. All rights reserved.
3 | // https://developers.google.com/protocol-buffers/
4 | //
5 | // Redistribution and use in source and binary forms, with or without
6 | // modification, are permitted provided that the following conditions are
7 | // met:
8 | //
9 | // * Redistributions of source code must retain the above copyright
10 | // notice, this list of conditions and the following disclaimer.
11 | // * Redistributions in binary form must reproduce the above
12 | // copyright notice, this list of conditions and the following disclaimer
13 | // in the documentation and/or other materials provided with the
14 | // distribution.
15 | // * Neither the name of Google Inc. nor the names of its
16 | // contributors may be used to endorse or promote products derived from
17 | // this software without specific prior written permission.
18 | //
19 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 |
31 | // Author: kenton@google.com (Kenton Varda)
32 | //
33 | // WARNING: The plugin interface is currently EXPERIMENTAL and is subject to
34 | // change.
35 | //
36 | // protoc (aka the Protocol Compiler) can be extended via plugins. A plugin is
37 | // just a program that reads a CodeGeneratorRequest from stdin and writes a
38 | // CodeGeneratorResponse to stdout.
39 | //
40 | // Plugins written using C++ can use google/protobuf/compiler/plugin.h instead
41 | // of dealing with the raw protocol defined here.
42 | //
43 | // A plugin executable needs only to be placed somewhere in the path. The
44 | // plugin should be named "protoc-gen-$NAME", and will then be used when the
45 | // flag "--${NAME}_out" is passed to protoc.
46 |
47 | syntax = "proto2";
48 |
49 | package google.protobuf.compiler;
50 | option java_package = "com.google.protobuf.compiler";
51 | option java_outer_classname = "PluginProtos";
52 |
53 | option go_package = "google.golang.org/protobuf/types/pluginpb";
54 |
55 | import "google/protobuf/descriptor.proto";
56 |
57 | // The version number of protocol compiler.
58 | message Version {
59 | optional int32 major = 1;
60 | optional int32 minor = 2;
61 | optional int32 patch = 3;
62 | // A suffix for alpha, beta or rc release, e.g., "alpha-1", "rc2". It should
63 | // be empty for mainline stable releases.
64 | optional string suffix = 4;
65 | }
66 |
67 | // An encoded CodeGeneratorRequest is written to the plugin's stdin.
68 | message CodeGeneratorRequest {
69 | // The .proto files that were explicitly listed on the command-line. The
70 | // code generator should generate code only for these files. Each file's
71 | // descriptor will be included in proto_file, below.
72 | repeated string file_to_generate = 1;
73 |
74 | // The generator parameter passed on the command-line.
75 | optional string parameter = 2;
76 |
77 | // FileDescriptorProtos for all files in files_to_generate and everything
78 | // they import. The files will appear in topological order, so each file
79 | // appears before any file that imports it.
80 | //
81 | // protoc guarantees that all proto_files will be written after
82 | // the fields above, even though this is not technically guaranteed by the
83 | // protobuf wire format. This theoretically could allow a plugin to stream
84 | // in the FileDescriptorProtos and handle them one by one rather than read
85 | // the entire set into memory at once. However, as of this writing, this
86 | // is not similarly optimized on protoc's end -- it will store all fields in
87 | // memory at once before sending them to the plugin.
88 | //
89 | // Type names of fields and extensions in the FileDescriptorProto are always
90 | // fully qualified.
91 | repeated FileDescriptorProto proto_file = 15;
92 |
93 | // The version number of protocol compiler.
94 | optional Version compiler_version = 3;
95 |
96 | }
97 |
98 | // The plugin writes an encoded CodeGeneratorResponse to stdout.
99 | message CodeGeneratorResponse {
100 | // Error message. If non-empty, code generation failed. The plugin process
101 | // should exit with status code zero even if it reports an error in this way.
102 | //
103 | // This should be used to indicate errors in .proto files which prevent the
104 | // code generator from generating correct code. Errors which indicate a
105 | // problem in protoc itself -- such as the input CodeGeneratorRequest being
106 | // unparseable -- should be reported by writing a message to stderr and
107 | // exiting with a non-zero status code.
108 | optional string error = 1;
109 |
110 | // A bitmask of supported features that the code generator supports.
111 | // This is a bitwise "or" of values from the Feature enum.
112 | optional uint64 supported_features = 2;
113 |
114 | // Sync with code_generator.h.
115 | enum Feature {
116 | FEATURE_NONE = 0;
117 | FEATURE_PROTO3_OPTIONAL = 1;
118 | }
119 |
120 | // Represents a single generated file.
121 | message File {
122 | // The file name, relative to the output directory. The name must not
123 | // contain "." or ".." components and must be relative, not be absolute (so,
124 | // the file cannot lie outside the output directory). "/" must be used as
125 | // the path separator, not "\".
126 | //
127 | // If the name is omitted, the content will be appended to the previous
128 | // file. This allows the generator to break large files into small chunks,
129 | // and allows the generated text to be streamed back to protoc so that large
130 | // files need not reside completely in memory at one time. Note that as of
131 | // this writing protoc does not optimize for this -- it will read the entire
132 | // CodeGeneratorResponse before writing files to disk.
133 | optional string name = 1;
134 |
135 | // If non-empty, indicates that the named file should already exist, and the
136 | // content here is to be inserted into that file at a defined insertion
137 | // point. This feature allows a code generator to extend the output
138 | // produced by another code generator. The original generator may provide
139 | // insertion points by placing special annotations in the file that look
140 | // like:
141 | // @@protoc_insertion_point(NAME)
142 | // The annotation can have arbitrary text before and after it on the line,
143 | // which allows it to be placed in a comment. NAME should be replaced with
144 | // an identifier naming the point -- this is what other generators will use
145 | // as the insertion_point. Code inserted at this point will be placed
146 | // immediately above the line containing the insertion point (thus multiple
147 | // insertions to the same point will come out in the order they were added).
148 | // The double-@ is intended to make it unlikely that the generated code
149 | // could contain things that look like insertion points by accident.
150 | //
151 | // For example, the C++ code generator places the following line in the
152 | // .pb.h files that it generates:
153 | // // @@protoc_insertion_point(namespace_scope)
154 | // This line appears within the scope of the file's package namespace, but
155 | // outside of any particular class. Another plugin can then specify the
156 | // insertion_point "namespace_scope" to generate additional classes or
157 | // other declarations that should be placed in this scope.
158 | //
159 | // Note that if the line containing the insertion point begins with
160 | // whitespace, the same whitespace will be added to every line of the
161 | // inserted text. This is useful for languages like Python, where
162 | // indentation matters. In these languages, the insertion point comment
163 | // should be indented the same amount as any inserted code will need to be
164 | // in order to work correctly in that context.
165 | //
166 | // The code generator that generates the initial file and the one which
167 | // inserts into it must both run as part of a single invocation of protoc.
168 | // Code generators are executed in the order in which they appear on the
169 | // command line.
170 | //
171 | // If |insertion_point| is present, |name| must also be present.
172 | optional string insertion_point = 2;
173 |
174 | // The file contents.
175 | optional string content = 15;
176 |
177 | // Information describing the file content being inserted. If an insertion
178 | // point is used, this information will be appropriately offset and inserted
179 | // into the code generation metadata for the generated files.
180 | optional GeneratedCodeInfo generated_code_info = 16;
181 | }
182 | repeated File file = 15;
183 | }
184 |
--------------------------------------------------------------------------------
/lamda/google/protobuf/duration.proto:
--------------------------------------------------------------------------------
1 | // Protocol Buffers - Google's data interchange format
2 | // Copyright 2008 Google Inc. All rights reserved.
3 | // https://developers.google.com/protocol-buffers/
4 | //
5 | // Redistribution and use in source and binary forms, with or without
6 | // modification, are permitted provided that the following conditions are
7 | // met:
8 | //
9 | // * Redistributions of source code must retain the above copyright
10 | // notice, this list of conditions and the following disclaimer.
11 | // * Redistributions in binary form must reproduce the above
12 | // copyright notice, this list of conditions and the following disclaimer
13 | // in the documentation and/or other materials provided with the
14 | // distribution.
15 | // * Neither the name of Google Inc. nor the names of its
16 | // contributors may be used to endorse or promote products derived from
17 | // this software without specific prior written permission.
18 | //
19 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 |
31 | syntax = "proto3";
32 |
33 | package google.protobuf;
34 |
35 | option csharp_namespace = "Google.Protobuf.WellKnownTypes";
36 | option cc_enable_arenas = true;
37 | option go_package = "google.golang.org/protobuf/types/known/durationpb";
38 | option java_package = "com.google.protobuf";
39 | option java_outer_classname = "DurationProto";
40 | option java_multiple_files = true;
41 | option objc_class_prefix = "GPB";
42 |
43 | // A Duration represents a signed, fixed-length span of time represented
44 | // as a count of seconds and fractions of seconds at nanosecond
45 | // resolution. It is independent of any calendar and concepts like "day"
46 | // or "month". It is related to Timestamp in that the difference between
47 | // two Timestamp values is a Duration and it can be added or subtracted
48 | // from a Timestamp. Range is approximately +-10,000 years.
49 | //
50 | // # Examples
51 | //
52 | // Example 1: Compute Duration from two Timestamps in pseudo code.
53 | //
54 | // Timestamp start = ...;
55 | // Timestamp end = ...;
56 | // Duration duration = ...;
57 | //
58 | // duration.seconds = end.seconds - start.seconds;
59 | // duration.nanos = end.nanos - start.nanos;
60 | //
61 | // if (duration.seconds < 0 && duration.nanos > 0) {
62 | // duration.seconds += 1;
63 | // duration.nanos -= 1000000000;
64 | // } else if (duration.seconds > 0 && duration.nanos < 0) {
65 | // duration.seconds -= 1;
66 | // duration.nanos += 1000000000;
67 | // }
68 | //
69 | // Example 2: Compute Timestamp from Timestamp + Duration in pseudo code.
70 | //
71 | // Timestamp start = ...;
72 | // Duration duration = ...;
73 | // Timestamp end = ...;
74 | //
75 | // end.seconds = start.seconds + duration.seconds;
76 | // end.nanos = start.nanos + duration.nanos;
77 | //
78 | // if (end.nanos < 0) {
79 | // end.seconds -= 1;
80 | // end.nanos += 1000000000;
81 | // } else if (end.nanos >= 1000000000) {
82 | // end.seconds += 1;
83 | // end.nanos -= 1000000000;
84 | // }
85 | //
86 | // Example 3: Compute Duration from datetime.timedelta in Python.
87 | //
88 | // td = datetime.timedelta(days=3, minutes=10)
89 | // duration = Duration()
90 | // duration.FromTimedelta(td)
91 | //
92 | // # JSON Mapping
93 | //
94 | // In JSON format, the Duration type is encoded as a string rather than an
95 | // object, where the string ends in the suffix "s" (indicating seconds) and
96 | // is preceded by the number of seconds, with nanoseconds expressed as
97 | // fractional seconds. For example, 3 seconds with 0 nanoseconds should be
98 | // encoded in JSON format as "3s", while 3 seconds and 1 nanosecond should
99 | // be expressed in JSON format as "3.000000001s", and 3 seconds and 1
100 | // microsecond should be expressed in JSON format as "3.000001s".
101 | //
102 | //
103 | message Duration {
104 | // Signed seconds of the span of time. Must be from -315,576,000,000
105 | // to +315,576,000,000 inclusive. Note: these bounds are computed from:
106 | // 60 sec/min * 60 min/hr * 24 hr/day * 365.25 days/year * 10000 years
107 | int64 seconds = 1;
108 |
109 | // Signed fractions of a second at nanosecond resolution of the span
110 | // of time. Durations less than one second are represented with a 0
111 | // `seconds` field and a positive or negative `nanos` field. For durations
112 | // of one second or more, a non-zero value for the `nanos` field must be
113 | // of the same sign as the `seconds` field. Must be from -999,999,999
114 | // to +999,999,999 inclusive.
115 | int32 nanos = 2;
116 | }
117 |
--------------------------------------------------------------------------------
/lamda/google/protobuf/empty.proto:
--------------------------------------------------------------------------------
1 | // Protocol Buffers - Google's data interchange format
2 | // Copyright 2008 Google Inc. All rights reserved.
3 | // https://developers.google.com/protocol-buffers/
4 | //
5 | // Redistribution and use in source and binary forms, with or without
6 | // modification, are permitted provided that the following conditions are
7 | // met:
8 | //
9 | // * Redistributions of source code must retain the above copyright
10 | // notice, this list of conditions and the following disclaimer.
11 | // * Redistributions in binary form must reproduce the above
12 | // copyright notice, this list of conditions and the following disclaimer
13 | // in the documentation and/or other materials provided with the
14 | // distribution.
15 | // * Neither the name of Google Inc. nor the names of its
16 | // contributors may be used to endorse or promote products derived from
17 | // this software without specific prior written permission.
18 | //
19 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 |
31 | syntax = "proto3";
32 |
33 | package google.protobuf;
34 |
35 | option csharp_namespace = "Google.Protobuf.WellKnownTypes";
36 | option go_package = "google.golang.org/protobuf/types/known/emptypb";
37 | option java_package = "com.google.protobuf";
38 | option java_outer_classname = "EmptyProto";
39 | option java_multiple_files = true;
40 | option objc_class_prefix = "GPB";
41 | option cc_enable_arenas = true;
42 |
43 | // A generic empty message that you can re-use to avoid defining duplicated
44 | // empty messages in your APIs. A typical example is to use it as the request
45 | // or the response type of an API method. For instance:
46 | //
47 | // service Foo {
48 | // rpc Bar(google.protobuf.Empty) returns (google.protobuf.Empty);
49 | // }
50 | //
51 | // The JSON representation for `Empty` is empty JSON object `{}`.
52 | message Empty {}
53 |
--------------------------------------------------------------------------------
/lamda/google/protobuf/field_mask.proto:
--------------------------------------------------------------------------------
1 | // Protocol Buffers - Google's data interchange format
2 | // Copyright 2008 Google Inc. All rights reserved.
3 | // https://developers.google.com/protocol-buffers/
4 | //
5 | // Redistribution and use in source and binary forms, with or without
6 | // modification, are permitted provided that the following conditions are
7 | // met:
8 | //
9 | // * Redistributions of source code must retain the above copyright
10 | // notice, this list of conditions and the following disclaimer.
11 | // * Redistributions in binary form must reproduce the above
12 | // copyright notice, this list of conditions and the following disclaimer
13 | // in the documentation and/or other materials provided with the
14 | // distribution.
15 | // * Neither the name of Google Inc. nor the names of its
16 | // contributors may be used to endorse or promote products derived from
17 | // this software without specific prior written permission.
18 | //
19 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 |
31 | syntax = "proto3";
32 |
33 | package google.protobuf;
34 |
35 | option csharp_namespace = "Google.Protobuf.WellKnownTypes";
36 | option java_package = "com.google.protobuf";
37 | option java_outer_classname = "FieldMaskProto";
38 | option java_multiple_files = true;
39 | option objc_class_prefix = "GPB";
40 | option go_package = "google.golang.org/protobuf/types/known/fieldmaskpb";
41 | option cc_enable_arenas = true;
42 |
43 | // `FieldMask` represents a set of symbolic field paths, for example:
44 | //
45 | // paths: "f.a"
46 | // paths: "f.b.d"
47 | //
48 | // Here `f` represents a field in some root message, `a` and `b`
49 | // fields in the message found in `f`, and `d` a field found in the
50 | // message in `f.b`.
51 | //
52 | // Field masks are used to specify a subset of fields that should be
53 | // returned by a get operation or modified by an update operation.
54 | // Field masks also have a custom JSON encoding (see below).
55 | //
56 | // # Field Masks in Projections
57 | //
58 | // When used in the context of a projection, a response message or
59 | // sub-message is filtered by the API to only contain those fields as
60 | // specified in the mask. For example, if the mask in the previous
61 | // example is applied to a response message as follows:
62 | //
63 | // f {
64 | // a : 22
65 | // b {
66 | // d : 1
67 | // x : 2
68 | // }
69 | // y : 13
70 | // }
71 | // z: 8
72 | //
73 | // The result will not contain specific values for fields x,y and z
74 | // (their value will be set to the default, and omitted in proto text
75 | // output):
76 | //
77 | //
78 | // f {
79 | // a : 22
80 | // b {
81 | // d : 1
82 | // }
83 | // }
84 | //
85 | // A repeated field is not allowed except at the last position of a
86 | // paths string.
87 | //
88 | // If a FieldMask object is not present in a get operation, the
89 | // operation applies to all fields (as if a FieldMask of all fields
90 | // had been specified).
91 | //
92 | // Note that a field mask does not necessarily apply to the
93 | // top-level response message. In case of a REST get operation, the
94 | // field mask applies directly to the response, but in case of a REST
95 | // list operation, the mask instead applies to each individual message
96 | // in the returned resource list. In case of a REST custom method,
97 | // other definitions may be used. Where the mask applies will be
98 | // clearly documented together with its declaration in the API. In
99 | // any case, the effect on the returned resource/resources is required
100 | // behavior for APIs.
101 | //
102 | // # Field Masks in Update Operations
103 | //
104 | // A field mask in update operations specifies which fields of the
105 | // targeted resource are going to be updated. The API is required
106 | // to only change the values of the fields as specified in the mask
107 | // and leave the others untouched. If a resource is passed in to
108 | // describe the updated values, the API ignores the values of all
109 | // fields not covered by the mask.
110 | //
111 | // If a repeated field is specified for an update operation, new values will
112 | // be appended to the existing repeated field in the target resource. Note that
113 | // a repeated field is only allowed in the last position of a `paths` string.
114 | //
115 | // If a sub-message is specified in the last position of the field mask for an
116 | // update operation, then new value will be merged into the existing sub-message
117 | // in the target resource.
118 | //
119 | // For example, given the target message:
120 | //
121 | // f {
122 | // b {
123 | // d: 1
124 | // x: 2
125 | // }
126 | // c: [1]
127 | // }
128 | //
129 | // And an update message:
130 | //
131 | // f {
132 | // b {
133 | // d: 10
134 | // }
135 | // c: [2]
136 | // }
137 | //
138 | // then if the field mask is:
139 | //
140 | // paths: ["f.b", "f.c"]
141 | //
142 | // then the result will be:
143 | //
144 | // f {
145 | // b {
146 | // d: 10
147 | // x: 2
148 | // }
149 | // c: [1, 2]
150 | // }
151 | //
152 | // An implementation may provide options to override this default behavior for
153 | // repeated and message fields.
154 | //
155 | // In order to reset a field's value to the default, the field must
156 | // be in the mask and set to the default value in the provided resource.
157 | // Hence, in order to reset all fields of a resource, provide a default
158 | // instance of the resource and set all fields in the mask, or do
159 | // not provide a mask as described below.
160 | //
161 | // If a field mask is not present on update, the operation applies to
162 | // all fields (as if a field mask of all fields has been specified).
163 | // Note that in the presence of schema evolution, this may mean that
164 | // fields the client does not know and has therefore not filled into
165 | // the request will be reset to their default. If this is unwanted
166 | // behavior, a specific service may require a client to always specify
167 | // a field mask, producing an error if not.
168 | //
169 | // As with get operations, the location of the resource which
170 | // describes the updated values in the request message depends on the
171 | // operation kind. In any case, the effect of the field mask is
172 | // required to be honored by the API.
173 | //
174 | // ## Considerations for HTTP REST
175 | //
176 | // The HTTP kind of an update operation which uses a field mask must
177 | // be set to PATCH instead of PUT in order to satisfy HTTP semantics
178 | // (PUT must only be used for full updates).
179 | //
180 | // # JSON Encoding of Field Masks
181 | //
182 | // In JSON, a field mask is encoded as a single string where paths are
183 | // separated by a comma. Fields name in each path are converted
184 | // to/from lower-camel naming conventions.
185 | //
186 | // As an example, consider the following message declarations:
187 | //
188 | // message Profile {
189 | // User user = 1;
190 | // Photo photo = 2;
191 | // }
192 | // message User {
193 | // string display_name = 1;
194 | // string address = 2;
195 | // }
196 | //
197 | // In proto a field mask for `Profile` may look as such:
198 | //
199 | // mask {
200 | // paths: "user.display_name"
201 | // paths: "photo"
202 | // }
203 | //
204 | // In JSON, the same mask is represented as below:
205 | //
206 | // {
207 | // mask: "user.displayName,photo"
208 | // }
209 | //
210 | // # Field Masks and Oneof Fields
211 | //
212 | // Field masks treat fields in oneofs just as regular fields. Consider the
213 | // following message:
214 | //
215 | // message SampleMessage {
216 | // oneof test_oneof {
217 | // string name = 4;
218 | // SubMessage sub_message = 9;
219 | // }
220 | // }
221 | //
222 | // The field mask can be:
223 | //
224 | // mask {
225 | // paths: "name"
226 | // }
227 | //
228 | // Or:
229 | //
230 | // mask {
231 | // paths: "sub_message"
232 | // }
233 | //
234 | // Note that oneof type names ("test_oneof" in this case) cannot be used in
235 | // paths.
236 | //
237 | // ## Field Mask Verification
238 | //
239 | // The implementation of any API method which has a FieldMask type field in the
240 | // request should verify the included field paths, and return an
241 | // `INVALID_ARGUMENT` error if any path is unmappable.
242 | message FieldMask {
243 | // The set of field mask paths.
244 | repeated string paths = 1;
245 | }
246 |
--------------------------------------------------------------------------------
/lamda/google/protobuf/source_context.proto:
--------------------------------------------------------------------------------
1 | // Protocol Buffers - Google's data interchange format
2 | // Copyright 2008 Google Inc. All rights reserved.
3 | // https://developers.google.com/protocol-buffers/
4 | //
5 | // Redistribution and use in source and binary forms, with or without
6 | // modification, are permitted provided that the following conditions are
7 | // met:
8 | //
9 | // * Redistributions of source code must retain the above copyright
10 | // notice, this list of conditions and the following disclaimer.
11 | // * Redistributions in binary form must reproduce the above
12 | // copyright notice, this list of conditions and the following disclaimer
13 | // in the documentation and/or other materials provided with the
14 | // distribution.
15 | // * Neither the name of Google Inc. nor the names of its
16 | // contributors may be used to endorse or promote products derived from
17 | // this software without specific prior written permission.
18 | //
19 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 |
31 | syntax = "proto3";
32 |
33 | package google.protobuf;
34 |
35 | option csharp_namespace = "Google.Protobuf.WellKnownTypes";
36 | option java_package = "com.google.protobuf";
37 | option java_outer_classname = "SourceContextProto";
38 | option java_multiple_files = true;
39 | option objc_class_prefix = "GPB";
40 | option go_package = "google.golang.org/protobuf/types/known/sourcecontextpb";
41 |
42 | // `SourceContext` represents information about the source of a
43 | // protobuf element, like the file in which it is defined.
44 | message SourceContext {
45 | // The path-qualified name of the .proto file that contained the associated
46 | // protobuf element. For example: `"google/protobuf/source_context.proto"`.
47 | string file_name = 1;
48 | }
49 |
--------------------------------------------------------------------------------
/lamda/google/protobuf/struct.proto:
--------------------------------------------------------------------------------
1 | // Protocol Buffers - Google's data interchange format
2 | // Copyright 2008 Google Inc. All rights reserved.
3 | // https://developers.google.com/protocol-buffers/
4 | //
5 | // Redistribution and use in source and binary forms, with or without
6 | // modification, are permitted provided that the following conditions are
7 | // met:
8 | //
9 | // * Redistributions of source code must retain the above copyright
10 | // notice, this list of conditions and the following disclaimer.
11 | // * Redistributions in binary form must reproduce the above
12 | // copyright notice, this list of conditions and the following disclaimer
13 | // in the documentation and/or other materials provided with the
14 | // distribution.
15 | // * Neither the name of Google Inc. nor the names of its
16 | // contributors may be used to endorse or promote products derived from
17 | // this software without specific prior written permission.
18 | //
19 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 |
31 | syntax = "proto3";
32 |
33 | package google.protobuf;
34 |
35 | option csharp_namespace = "Google.Protobuf.WellKnownTypes";
36 | option cc_enable_arenas = true;
37 | option go_package = "google.golang.org/protobuf/types/known/structpb";
38 | option java_package = "com.google.protobuf";
39 | option java_outer_classname = "StructProto";
40 | option java_multiple_files = true;
41 | option objc_class_prefix = "GPB";
42 |
43 | // `Struct` represents a structured data value, consisting of fields
44 | // which map to dynamically typed values. In some languages, `Struct`
45 | // might be supported by a native representation. For example, in
46 | // scripting languages like JS a struct is represented as an
47 | // object. The details of that representation are described together
48 | // with the proto support for the language.
49 | //
50 | // The JSON representation for `Struct` is JSON object.
51 | message Struct {
52 | // Unordered map of dynamically typed values.
53 | map fields = 1;
54 | }
55 |
56 | // `Value` represents a dynamically typed value which can be either
57 | // null, a number, a string, a boolean, a recursive struct value, or a
58 | // list of values. A producer of value is expected to set one of that
59 | // variants, absence of any variant indicates an error.
60 | //
61 | // The JSON representation for `Value` is JSON value.
62 | message Value {
63 | // The kind of value.
64 | oneof kind {
65 | // Represents a null value.
66 | NullValue null_value = 1;
67 | // Represents a double value.
68 | double number_value = 2;
69 | // Represents a string value.
70 | string string_value = 3;
71 | // Represents a boolean value.
72 | bool bool_value = 4;
73 | // Represents a structured value.
74 | Struct struct_value = 5;
75 | // Represents a repeated `Value`.
76 | ListValue list_value = 6;
77 | }
78 | }
79 |
80 | // `NullValue` is a singleton enumeration to represent the null value for the
81 | // `Value` type union.
82 | //
83 | // The JSON representation for `NullValue` is JSON `null`.
84 | enum NullValue {
85 | // Null value.
86 | NULL_VALUE = 0;
87 | }
88 |
89 | // `ListValue` is a wrapper around a repeated field of values.
90 | //
91 | // The JSON representation for `ListValue` is JSON array.
92 | message ListValue {
93 | // Repeated field of dynamically typed values.
94 | repeated Value values = 1;
95 | }
96 |
--------------------------------------------------------------------------------
/lamda/google/protobuf/timestamp.proto:
--------------------------------------------------------------------------------
1 | // Protocol Buffers - Google's data interchange format
2 | // Copyright 2008 Google Inc. All rights reserved.
3 | // https://developers.google.com/protocol-buffers/
4 | //
5 | // Redistribution and use in source and binary forms, with or without
6 | // modification, are permitted provided that the following conditions are
7 | // met:
8 | //
9 | // * Redistributions of source code must retain the above copyright
10 | // notice, this list of conditions and the following disclaimer.
11 | // * Redistributions in binary form must reproduce the above
12 | // copyright notice, this list of conditions and the following disclaimer
13 | // in the documentation and/or other materials provided with the
14 | // distribution.
15 | // * Neither the name of Google Inc. nor the names of its
16 | // contributors may be used to endorse or promote products derived from
17 | // this software without specific prior written permission.
18 | //
19 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 |
31 | syntax = "proto3";
32 |
33 | package google.protobuf;
34 |
35 | option csharp_namespace = "Google.Protobuf.WellKnownTypes";
36 | option cc_enable_arenas = true;
37 | option go_package = "google.golang.org/protobuf/types/known/timestamppb";
38 | option java_package = "com.google.protobuf";
39 | option java_outer_classname = "TimestampProto";
40 | option java_multiple_files = true;
41 | option objc_class_prefix = "GPB";
42 |
43 | // A Timestamp represents a point in time independent of any time zone or local
44 | // calendar, encoded as a count of seconds and fractions of seconds at
45 | // nanosecond resolution. The count is relative to an epoch at UTC midnight on
46 | // January 1, 1970, in the proleptic Gregorian calendar which extends the
47 | // Gregorian calendar backwards to year one.
48 | //
49 | // All minutes are 60 seconds long. Leap seconds are "smeared" so that no leap
50 | // second table is needed for interpretation, using a [24-hour linear
51 | // smear](https://developers.google.com/time/smear).
52 | //
53 | // The range is from 0001-01-01T00:00:00Z to 9999-12-31T23:59:59.999999999Z. By
54 | // restricting to that range, we ensure that we can convert to and from [RFC
55 | // 3339](https://www.ietf.org/rfc/rfc3339.txt) date strings.
56 | //
57 | // # Examples
58 | //
59 | // Example 1: Compute Timestamp from POSIX `time()`.
60 | //
61 | // Timestamp timestamp;
62 | // timestamp.set_seconds(time(NULL));
63 | // timestamp.set_nanos(0);
64 | //
65 | // Example 2: Compute Timestamp from POSIX `gettimeofday()`.
66 | //
67 | // struct timeval tv;
68 | // gettimeofday(&tv, NULL);
69 | //
70 | // Timestamp timestamp;
71 | // timestamp.set_seconds(tv.tv_sec);
72 | // timestamp.set_nanos(tv.tv_usec * 1000);
73 | //
74 | // Example 3: Compute Timestamp from Win32 `GetSystemTimeAsFileTime()`.
75 | //
76 | // FILETIME ft;
77 | // GetSystemTimeAsFileTime(&ft);
78 | // UINT64 ticks = (((UINT64)ft.dwHighDateTime) << 32) | ft.dwLowDateTime;
79 | //
80 | // // A Windows tick is 100 nanoseconds. Windows epoch 1601-01-01T00:00:00Z
81 | // // is 11644473600 seconds before Unix epoch 1970-01-01T00:00:00Z.
82 | // Timestamp timestamp;
83 | // timestamp.set_seconds((INT64) ((ticks / 10000000) - 11644473600LL));
84 | // timestamp.set_nanos((INT32) ((ticks % 10000000) * 100));
85 | //
86 | // Example 4: Compute Timestamp from Java `System.currentTimeMillis()`.
87 | //
88 | // long millis = System.currentTimeMillis();
89 | //
90 | // Timestamp timestamp = Timestamp.newBuilder().setSeconds(millis / 1000)
91 | // .setNanos((int) ((millis % 1000) * 1000000)).build();
92 | //
93 | //
94 | // Example 5: Compute Timestamp from Java `Instant.now()`.
95 | //
96 | // Instant now = Instant.now();
97 | //
98 | // Timestamp timestamp =
99 | // Timestamp.newBuilder().setSeconds(now.getEpochSecond())
100 | // .setNanos(now.getNano()).build();
101 | //
102 | //
103 | // Example 6: Compute Timestamp from current time in Python.
104 | //
105 | // timestamp = Timestamp()
106 | // timestamp.GetCurrentTime()
107 | //
108 | // # JSON Mapping
109 | //
110 | // In JSON format, the Timestamp type is encoded as a string in the
111 | // [RFC 3339](https://www.ietf.org/rfc/rfc3339.txt) format. That is, the
112 | // format is "{year}-{month}-{day}T{hour}:{min}:{sec}[.{frac_sec}]Z"
113 | // where {year} is always expressed using four digits while {month}, {day},
114 | // {hour}, {min}, and {sec} are zero-padded to two digits each. The fractional
115 | // seconds, which can go up to 9 digits (i.e. up to 1 nanosecond resolution),
116 | // are optional. The "Z" suffix indicates the timezone ("UTC"); the timezone
117 | // is required. A proto3 JSON serializer should always use UTC (as indicated by
118 | // "Z") when printing the Timestamp type and a proto3 JSON parser should be
119 | // able to accept both UTC and other timezones (as indicated by an offset).
120 | //
121 | // For example, "2017-01-15T01:30:15.01Z" encodes 15.01 seconds past
122 | // 01:30 UTC on January 15, 2017.
123 | //
124 | // In JavaScript, one can convert a Date object to this format using the
125 | // standard
126 | // [toISOString()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/toISOString)
127 | // method. In Python, a standard `datetime.datetime` object can be converted
128 | // to this format using
129 | // [`strftime`](https://docs.python.org/2/library/time.html#time.strftime) with
130 | // the time format spec '%Y-%m-%dT%H:%M:%S.%fZ'. Likewise, in Java, one can use
131 | // the Joda Time's [`ISODateTimeFormat.dateTime()`](
132 | // http://www.joda.org/joda-time/apidocs/org/joda/time/format/ISODateTimeFormat.html#dateTime%2D%2D
133 | // ) to obtain a formatter capable of generating timestamps in this format.
134 | //
135 | //
136 | message Timestamp {
137 | // Represents seconds of UTC time since Unix epoch
138 | // 1970-01-01T00:00:00Z. Must be from 0001-01-01T00:00:00Z to
139 | // 9999-12-31T23:59:59Z inclusive.
140 | int64 seconds = 1;
141 |
142 | // Non-negative fractions of a second at nanosecond resolution. Negative
143 | // second values with fractions must still have non-negative nanos values
144 | // that count forward in time. Must be from 0 to 999,999,999
145 | // inclusive.
146 | int32 nanos = 2;
147 | }
148 |
--------------------------------------------------------------------------------
/lamda/google/protobuf/type.proto:
--------------------------------------------------------------------------------
1 | // Protocol Buffers - Google's data interchange format
2 | // Copyright 2008 Google Inc. All rights reserved.
3 | // https://developers.google.com/protocol-buffers/
4 | //
5 | // Redistribution and use in source and binary forms, with or without
6 | // modification, are permitted provided that the following conditions are
7 | // met:
8 | //
9 | // * Redistributions of source code must retain the above copyright
10 | // notice, this list of conditions and the following disclaimer.
11 | // * Redistributions in binary form must reproduce the above
12 | // copyright notice, this list of conditions and the following disclaimer
13 | // in the documentation and/or other materials provided with the
14 | // distribution.
15 | // * Neither the name of Google Inc. nor the names of its
16 | // contributors may be used to endorse or promote products derived from
17 | // this software without specific prior written permission.
18 | //
19 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 |
31 | syntax = "proto3";
32 |
33 | package google.protobuf;
34 |
35 | import "google/protobuf/any.proto";
36 | import "google/protobuf/source_context.proto";
37 |
38 | option csharp_namespace = "Google.Protobuf.WellKnownTypes";
39 | option cc_enable_arenas = true;
40 | option java_package = "com.google.protobuf";
41 | option java_outer_classname = "TypeProto";
42 | option java_multiple_files = true;
43 | option objc_class_prefix = "GPB";
44 | option go_package = "google.golang.org/protobuf/types/known/typepb";
45 |
46 | // A protocol buffer message type.
47 | message Type {
48 | // The fully qualified message name.
49 | string name = 1;
50 | // The list of fields.
51 | repeated Field fields = 2;
52 | // The list of types appearing in `oneof` definitions in this type.
53 | repeated string oneofs = 3;
54 | // The protocol buffer options.
55 | repeated Option options = 4;
56 | // The source context.
57 | SourceContext source_context = 5;
58 | // The source syntax.
59 | Syntax syntax = 6;
60 | }
61 |
62 | // A single field of a message type.
63 | message Field {
64 | // Basic field types.
65 | enum Kind {
66 | // Field type unknown.
67 | TYPE_UNKNOWN = 0;
68 | // Field type double.
69 | TYPE_DOUBLE = 1;
70 | // Field type float.
71 | TYPE_FLOAT = 2;
72 | // Field type int64.
73 | TYPE_INT64 = 3;
74 | // Field type uint64.
75 | TYPE_UINT64 = 4;
76 | // Field type int32.
77 | TYPE_INT32 = 5;
78 | // Field type fixed64.
79 | TYPE_FIXED64 = 6;
80 | // Field type fixed32.
81 | TYPE_FIXED32 = 7;
82 | // Field type bool.
83 | TYPE_BOOL = 8;
84 | // Field type string.
85 | TYPE_STRING = 9;
86 | // Field type group. Proto2 syntax only, and deprecated.
87 | TYPE_GROUP = 10;
88 | // Field type message.
89 | TYPE_MESSAGE = 11;
90 | // Field type bytes.
91 | TYPE_BYTES = 12;
92 | // Field type uint32.
93 | TYPE_UINT32 = 13;
94 | // Field type enum.
95 | TYPE_ENUM = 14;
96 | // Field type sfixed32.
97 | TYPE_SFIXED32 = 15;
98 | // Field type sfixed64.
99 | TYPE_SFIXED64 = 16;
100 | // Field type sint32.
101 | TYPE_SINT32 = 17;
102 | // Field type sint64.
103 | TYPE_SINT64 = 18;
104 | }
105 |
106 | // Whether a field is optional, required, or repeated.
107 | enum Cardinality {
108 | // For fields with unknown cardinality.
109 | CARDINALITY_UNKNOWN = 0;
110 | // For optional fields.
111 | CARDINALITY_OPTIONAL = 1;
112 | // For required fields. Proto2 syntax only.
113 | CARDINALITY_REQUIRED = 2;
114 | // For repeated fields.
115 | CARDINALITY_REPEATED = 3;
116 | }
117 |
118 | // The field type.
119 | Kind kind = 1;
120 | // The field cardinality.
121 | Cardinality cardinality = 2;
122 | // The field number.
123 | int32 number = 3;
124 | // The field name.
125 | string name = 4;
126 | // The field type URL, without the scheme, for message or enumeration
127 | // types. Example: `"type.googleapis.com/google.protobuf.Timestamp"`.
128 | string type_url = 6;
129 | // The index of the field type in `Type.oneofs`, for message or enumeration
130 | // types. The first type has index 1; zero means the type is not in the list.
131 | int32 oneof_index = 7;
132 | // Whether to use alternative packed wire representation.
133 | bool packed = 8;
134 | // The protocol buffer options.
135 | repeated Option options = 9;
136 | // The field JSON name.
137 | string json_name = 10;
138 | // The string value of the default value of this field. Proto2 syntax only.
139 | string default_value = 11;
140 | }
141 |
142 | // Enum type definition.
143 | message Enum {
144 | // Enum type name.
145 | string name = 1;
146 | // Enum value definitions.
147 | repeated EnumValue enumvalue = 2;
148 | // Protocol buffer options.
149 | repeated Option options = 3;
150 | // The source context.
151 | SourceContext source_context = 4;
152 | // The source syntax.
153 | Syntax syntax = 5;
154 | }
155 |
156 | // Enum value definition.
157 | message EnumValue {
158 | // Enum value name.
159 | string name = 1;
160 | // Enum value number.
161 | int32 number = 2;
162 | // Protocol buffer options.
163 | repeated Option options = 3;
164 | }
165 |
166 | // A protocol buffer option, which can be attached to a message, field,
167 | // enumeration, etc.
168 | message Option {
169 | // The option's name. For protobuf built-in options (options defined in
170 | // descriptor.proto), this is the short name. For example, `"map_entry"`.
171 | // For custom options, it should be the fully-qualified name. For example,
172 | // `"google.api.http"`.
173 | string name = 1;
174 | // The option's value packed in an Any message. If the value is a primitive,
175 | // the corresponding wrapper type defined in google/protobuf/wrappers.proto
176 | // should be used. If the value is an enum, it should be stored as an int32
177 | // value using the google.protobuf.Int32Value type.
178 | Any value = 2;
179 | }
180 |
181 | // The syntax in which a protocol buffer element is defined.
182 | enum Syntax {
183 | // Syntax `proto2`.
184 | SYNTAX_PROTO2 = 0;
185 | // Syntax `proto3`.
186 | SYNTAX_PROTO3 = 1;
187 | }
188 |
--------------------------------------------------------------------------------
/lamda/google/protobuf/wrappers.proto:
--------------------------------------------------------------------------------
1 | // Protocol Buffers - Google's data interchange format
2 | // Copyright 2008 Google Inc. All rights reserved.
3 | // https://developers.google.com/protocol-buffers/
4 | //
5 | // Redistribution and use in source and binary forms, with or without
6 | // modification, are permitted provided that the following conditions are
7 | // met:
8 | //
9 | // * Redistributions of source code must retain the above copyright
10 | // notice, this list of conditions and the following disclaimer.
11 | // * Redistributions in binary form must reproduce the above
12 | // copyright notice, this list of conditions and the following disclaimer
13 | // in the documentation and/or other materials provided with the
14 | // distribution.
15 | // * Neither the name of Google Inc. nor the names of its
16 | // contributors may be used to endorse or promote products derived from
17 | // this software without specific prior written permission.
18 | //
19 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 |
31 | // Wrappers for primitive (non-message) types. These types are useful
32 | // for embedding primitives in the `google.protobuf.Any` type and for places
33 | // where we need to distinguish between the absence of a primitive
34 | // typed field and its default value.
35 | //
36 | // These wrappers have no meaningful use within repeated fields as they lack
37 | // the ability to detect presence on individual elements.
38 | // These wrappers have no meaningful use within a map or a oneof since
39 | // individual entries of a map or fields of a oneof can already detect presence.
40 |
41 | syntax = "proto3";
42 |
43 | package google.protobuf;
44 |
45 | option csharp_namespace = "Google.Protobuf.WellKnownTypes";
46 | option cc_enable_arenas = true;
47 | option go_package = "google.golang.org/protobuf/types/known/wrapperspb";
48 | option java_package = "com.google.protobuf";
49 | option java_outer_classname = "WrappersProto";
50 | option java_multiple_files = true;
51 | option objc_class_prefix = "GPB";
52 |
53 | // Wrapper message for `double`.
54 | //
55 | // The JSON representation for `DoubleValue` is JSON number.
56 | message DoubleValue {
57 | // The double value.
58 | double value = 1;
59 | }
60 |
61 | // Wrapper message for `float`.
62 | //
63 | // The JSON representation for `FloatValue` is JSON number.
64 | message FloatValue {
65 | // The float value.
66 | float value = 1;
67 | }
68 |
69 | // Wrapper message for `int64`.
70 | //
71 | // The JSON representation for `Int64Value` is JSON string.
72 | message Int64Value {
73 | // The int64 value.
74 | int64 value = 1;
75 | }
76 |
77 | // Wrapper message for `uint64`.
78 | //
79 | // The JSON representation for `UInt64Value` is JSON string.
80 | message UInt64Value {
81 | // The uint64 value.
82 | uint64 value = 1;
83 | }
84 |
85 | // Wrapper message for `int32`.
86 | //
87 | // The JSON representation for `Int32Value` is JSON number.
88 | message Int32Value {
89 | // The int32 value.
90 | int32 value = 1;
91 | }
92 |
93 | // Wrapper message for `uint32`.
94 | //
95 | // The JSON representation for `UInt32Value` is JSON number.
96 | message UInt32Value {
97 | // The uint32 value.
98 | uint32 value = 1;
99 | }
100 |
101 | // Wrapper message for `bool`.
102 | //
103 | // The JSON representation for `BoolValue` is JSON `true` and `false`.
104 | message BoolValue {
105 | // The bool value.
106 | bool value = 1;
107 | }
108 |
109 | // Wrapper message for `string`.
110 | //
111 | // The JSON representation for `StringValue` is JSON string.
112 | message StringValue {
113 | // The string value.
114 | string value = 1;
115 | }
116 |
117 | // Wrapper message for `bytes`.
118 | //
119 | // The JSON representation for `BytesValue` is JSON string.
120 | message BytesValue {
121 | // The bytes value.
122 | bytes value = 1;
123 | }
124 |
--------------------------------------------------------------------------------
/lamda/rpc/application.proto:
--------------------------------------------------------------------------------
1 | // Copyright 2022 rev1si0n (lamda.devel@gmail.com). All rights reserved.
2 | //
3 | // Distributed under MIT license.
4 | // See file LICENSE for detail or copy at https://opensource.org/licenses/MIT
5 | syntax = "proto3";
6 | package lamda.rpc;
7 |
8 | import "google/protobuf/struct.proto";
9 |
10 | enum GrantType {
11 | GRANT_ALLOW = 0;
12 | GRANT_DENY = 1;
13 | GRANT_IGNORE = 2;
14 | }
15 |
16 | enum DataEncode {
17 | DATA_ENCODE_NONE = 0;
18 | DATA_ENCODE_ZLIB = 1;
19 | }
20 |
21 | enum ScriptRuntime {
22 | RUNTIME_QJS = 0;
23 | RUNTIME_V8 = 1;
24 | }
25 |
26 | message ApplicationRequest {
27 | string name = 1;
28 | string permission = 2;
29 | GrantType mode = 3;
30 | string path = 4;
31 | uint32 user = 5;
32 | }
33 |
34 | message ApplicationActivityRequest {
35 | string package = 1;
36 | string action = 2;
37 | string category = 3;
38 | string component = 4;
39 | google.protobuf.Struct extras = 5;
40 | repeated string categories = 6;
41 | int64 flags = 7;
42 | bool debug = 8;
43 | string data = 9;
44 | uint32 user = 10;
45 | }
46 |
47 | message ApplicationActivityInfo {
48 | string package = 1;
49 | string action = 2;
50 | string category = 3;
51 | string component = 4;
52 | google.protobuf.Struct extras = 5;
53 | repeated string categories = 6;
54 | int64 flags = 7;
55 | bool debug = 8;
56 | string data = 9;
57 | uint32 user = 10;
58 | }
59 |
60 | message ApplicationActivityInfoList {
61 | repeated ApplicationActivityInfo activities = 1;
62 | }
63 |
64 | message ApplicationPermissions {
65 | repeated string permissions = 1;
66 | }
67 |
68 | message ApplicationInfo {
69 | string packageName = 1;
70 | uint32 uid = 2;
71 | bool enabled = 3;
72 | string processName = 4;
73 | string sourceDir = 5;
74 | string dataDir = 6;
75 | uint32 baseRevisionCode = 7;
76 | int64 firstInstallTime = 8;
77 | int64 lastUpdateTime = 9;
78 | uint32 versionCode = 10;
79 | string versionName = 11;
80 | string activity = 12;
81 | uint32 user = 13;
82 | }
83 |
84 | message ApplicationProcess {
85 | repeated string packages = 1;
86 | string processName = 2;
87 | int64 uid = 3;
88 | int64 pid = 4;
89 | }
90 |
91 | message ApplicationProcesses {
92 | repeated ApplicationProcess processes = 1;
93 | }
94 |
95 | message ApplicationPkgNames {
96 | repeated string names = 1;
97 | }
98 |
99 | message HookRequest {
100 | string package = 1;
101 | bytes script = 2;
102 | ScriptRuntime runtime = 3;
103 | string destination = 4;
104 | DataEncode encode = 5;
105 | uint32 standup = 6;
106 | bool spawn = 7;
107 | uint32 user = 8;
108 | }
109 |
110 | message HookRpcRequest {
111 | string package = 1;
112 | string callinfo = 2;
113 | uint32 user = 3;
114 | }
115 |
116 | message HookRpcResponse {
117 | string package = 1;
118 | string callresult = 2;
119 | }
--------------------------------------------------------------------------------
/lamda/rpc/debug.proto:
--------------------------------------------------------------------------------
1 | // Copyright 2022 rev1si0n (lamda.devel@gmail.com). All rights reserved.
2 | //
3 | // Distributed under MIT license.
4 | // See file LICENSE for detail or copy at https://opensource.org/licenses/MIT
5 | syntax = "proto3";
6 | package lamda.rpc;
7 |
8 | import "google/protobuf/struct.proto";
9 |
10 | message ADBDConfigRequest {
11 | string adb_pubkey = 1;
12 | }
--------------------------------------------------------------------------------
/lamda/rpc/file.proto:
--------------------------------------------------------------------------------
1 | // Copyright 2022 rev1si0n (lamda.devel@gmail.com). All rights reserved.
2 | //
3 | // Distributed under MIT license.
4 | // See file LICENSE for detail or copy at https://opensource.org/licenses/MIT
5 | syntax = "proto3";
6 | package lamda.rpc;
7 |
8 | message FileStat {
9 | string name = 1;
10 | string path = 2;
11 | bool directory = 3;
12 | int64 st_mode = 4;
13 | int64 st_atime = 5;
14 | int64 st_mtime = 6;
15 | int64 st_ctime = 7;
16 | int32 st_uid = 8;
17 | int32 st_gid = 9;
18 | int64 st_size = 10;
19 | }
20 |
21 | message FileRequest {
22 | string path = 1;
23 | uint64 mode = 2;
24 | bytes payload = 3;
25 | }
26 |
27 | message FileDataResponse {
28 | bytes payload = 1;
29 | }
30 |
--------------------------------------------------------------------------------
/lamda/rpc/policy.proto:
--------------------------------------------------------------------------------
1 | // Copyright 2022 rev1si0n (lamda.devel@gmail.com). All rights reserved.
2 | //
3 | // Distributed under MIT license.
4 | // See file LICENSE for detail or copy at https://opensource.org/licenses/MIT
5 | syntax = "proto3";
6 | package lamda.rpc;
7 |
8 | message SelinuxPolicyRequest {
9 | string source = 1;
10 | string target = 2;
11 | string tclass = 3;
12 | string action = 4;
13 | }
--------------------------------------------------------------------------------
/lamda/rpc/proxy.proto:
--------------------------------------------------------------------------------
1 | // Copyright 2022 rev1si0n (lamda.devel@gmail.com). All rights reserved.
2 | //
3 | // Distributed under MIT license.
4 | // See file LICENSE for detail or copy at https://opensource.org/licenses/MIT
5 | syntax = "proto3";
6 | package lamda.rpc;
7 |
8 | import "application.proto";
9 |
10 | enum GproxyType {
11 | SOCKS5 = 0;
12 | HTTP_CONNECT = 1;
13 | HTTP_RELAY = 2;
14 | }
15 |
16 | message GproxyConfigRequest {
17 | ApplicationInfo application = 1;
18 | GproxyType type = 2;
19 | string nameserver = 3;
20 | string login = 4;
21 | string password = 5;
22 | string host = 6;
23 | uint32 port = 7;
24 | bool bypass_local_subnet = 8;
25 | bool drop_udp = 9;
26 | bool udp_proxy = 10;
27 | bool dns_proxy = 11;
28 | }
29 |
30 | enum OpenVPNProto {
31 | TCP = 0;
32 | UDP = 1;
33 | }
34 |
35 | enum OpenVPNAuth {
36 | SHA1 = 0;
37 | SHA224 = 1;
38 | SHA256 = 2;
39 | SHA384 = 3;
40 | SHA512 = 4;
41 | RIPEMD160 = 5;
42 | RSA_SHA1 = 6;
43 | RSA_SHA224 = 7;
44 | RSA_SHA256 = 8;
45 | RSA_SHA384 = 9;
46 | RSA_SHA512 = 10;
47 | RSA_RIPEMD160 = 11;
48 | }
49 |
50 | enum OpenVPNCipher {
51 | AES_128_GCM = 0;
52 | AES_256_GCM = 1;
53 | CHACHA20_POLY1305= 2;
54 | AES_128_CBC = 3;
55 | AES_256_CBC = 4;
56 | }
57 |
58 | enum OpenVPNKeyDirection {
59 | // because 0 is a default value
60 | // so we use 1 as key-direction 0
61 | KEY_DIRECTION_NONE = 0;
62 | KEY_DIRECTION_0 = 1;
63 | KEY_DIRECTION_1 = 2;
64 | }
65 |
66 | enum OpenVPNEncryption {
67 | TLS_NONE = 0;
68 | TLS_AUTH = 1;
69 | TLS_CRYPT = 2;
70 | TLS_CRYPT_V2 = 3;
71 | }
72 |
73 | message OpenVPNConfigRequest {
74 | bool all_traffic = 1;
75 | OpenVPNProto proto = 2;
76 | string host = 3;
77 | uint32 port = 4;
78 | OpenVPNCipher cipher = 5;
79 | string ca = 6;
80 | string cert = 7;
81 | string key = 8;
82 | OpenVPNEncryption tls_encryption = 9;
83 | OpenVPNKeyDirection tls_key_direction = 10;
84 | string tls_key = 11;
85 | OpenVPNAuth auth = 12;
86 | string login = 13;
87 | string password = 14;
88 | }
89 |
--------------------------------------------------------------------------------
/lamda/rpc/services.proto:
--------------------------------------------------------------------------------
1 | // Copyright 2022 rev1si0n (lamda.devel@gmail.com). All rights reserved.
2 | //
3 | // Distributed under MIT license.
4 | // See file LICENSE for detail or copy at https://opensource.org/licenses/MIT
5 | syntax = "proto3";
6 | package lamda.rpc;
7 |
8 | import public "google/protobuf/empty.proto";
9 | import public "google/protobuf/any.proto";
10 |
11 | import public "types.proto";
12 |
13 | import public "util.proto";
14 | import public "shell.proto";
15 | import public "policy.proto";
16 | import public "debug.proto";
17 | import public "settings.proto";
18 | import public "status.proto";
19 | import public "application.proto";
20 | import public "uiautomator.proto";
21 | import public "storage.proto";
22 | import public "proxy.proto";
23 | import public "file.proto";
24 | import public "wifi.proto";
25 |
26 |
27 | service Application {
28 | rpc isForeground(ApplicationRequest) returns (Boolean) {}
29 | rpc currentApplication(google.protobuf.Empty) returns (ApplicationInfo) {}
30 | rpc enumerateAllPkgNames(google.protobuf.Empty) returns (ApplicationPkgNames) {}
31 | rpc enumerateRunningProcesses(google.protobuf.Empty) returns (ApplicationProcesses) {}
32 | rpc queryLaunchActivity(ApplicationRequest) returns (ApplicationActivityInfo) {}
33 | rpc getPermissions(ApplicationRequest) returns (ApplicationPermissions) {}
34 | rpc resetApplicationData(ApplicationRequest) returns (Boolean) {}
35 | rpc deleteApplicationCache(ApplicationRequest) returns (Boolean) {}
36 | rpc getLastActivities(Integer) returns (ApplicationActivityInfoList) {}
37 | rpc startActivity(ApplicationActivityRequest) returns (Boolean) {}
38 | rpc applicationInfo(ApplicationRequest) returns (ApplicationInfo) {}
39 | rpc startApplication(ApplicationRequest) returns (Boolean) {}
40 | rpc stopApplication(ApplicationRequest) returns (Boolean) {}
41 | rpc uninstallApplication(ApplicationRequest) returns (Boolean) {}
42 | rpc installFromLocalFile(ApplicationRequest) returns (ApplicationInfo) {}
43 | rpc enableApplication(ApplicationRequest) returns (Boolean) {}
44 | rpc disableApplication(ApplicationRequest) returns (Boolean) {}
45 | rpc grantPermission(ApplicationRequest) returns (Boolean) {}
46 | rpc revokePermission(ApplicationRequest) returns (Boolean) {}
47 | rpc isPermissionGranted(ApplicationRequest) returns (Boolean) {}
48 | rpc isInstalled(ApplicationRequest) returns (Boolean) {}
49 |
50 | rpc addToDozeModeWhiteList(ApplicationRequest) returns (Boolean) {}
51 | rpc removeFromDozeModeWhiteList(ApplicationRequest) returns (Boolean) {}
52 | rpc getIdentifierByLabel(String) returns (String) {}
53 |
54 | rpc callScript(HookRpcRequest) returns (HookRpcResponse) {}
55 | rpc isScriptAlive(HookRequest) returns (Boolean) {}
56 | rpc isScriptAttached(HookRequest) returns (Boolean) {}
57 | rpc attachScript(HookRequest) returns (Boolean) {}
58 | rpc detachScript(HookRequest) returns (Boolean) {}
59 | }
60 |
61 | service Debug {
62 | rpc isAndroidDebugBridgeRunning(google.protobuf.Empty) returns (Boolean) {}
63 |
64 | rpc installADBPubKey(ADBDConfigRequest) returns (Boolean) {}
65 | rpc uninstallADBPubKey(ADBDConfigRequest) returns (Boolean) {}
66 |
67 | rpc startAndroidDebugBridge(google.protobuf.Empty) returns (Boolean) {}
68 | rpc stopAndroidDebugBridge(google.protobuf.Empty) returns (Boolean) {}
69 | }
70 |
71 | service Proxy {
72 | rpc isOpenVPNRunning(google.protobuf.Empty) returns (Boolean) {}
73 | rpc isGproxyRunning(google.protobuf.Empty) returns (Boolean) {}
74 | rpc stopOpenVPN(google.protobuf.Empty) returns (Boolean) {}
75 | rpc stopGproxy(google.protobuf.Empty) returns (Boolean) {}
76 | rpc startOpenVPN(OpenVPNConfigRequest) returns (Boolean) {}
77 | rpc startGproxy(GproxyConfigRequest) returns (Boolean) {}
78 | }
79 |
80 | service SelinuxPolicy {
81 | rpc setEnforce(Boolean) returns (Integer) {}
82 | rpc getEnforce(google.protobuf.Empty) returns (Integer) {}
83 | rpc isEnabled(google.protobuf.Empty) returns (Boolean) {}
84 |
85 | rpc policySetEnforce(String) returns (Boolean) {}
86 | rpc policySetPermissive(String) returns (Boolean) {}
87 | rpc policySetAllow(SelinuxPolicyRequest) returns (Boolean) {}
88 | rpc policySetDisallow(SelinuxPolicyRequest) returns (Boolean) {}
89 | rpc policyCreateDomain(String) returns (Boolean) {}
90 | }
91 |
92 | service Settings {
93 | rpc putSettings(SettingsRequest) returns (Boolean) {}
94 | rpc getSettings(SettingsRequest) returns (String) {}
95 | }
96 |
97 | service Shell {
98 | rpc executeForeground(ShellRequest) returns (ShellResult) {}
99 | rpc executeBackground(ShellRequest) returns (ShellTask) {}
100 | rpc isBackgroundFinished(ShellTask) returns (Boolean) {}
101 | rpc killBackground(ShellTask) returns (Boolean) {}
102 | }
103 |
104 | service Status {
105 | rpc getBootTime(google.protobuf.Empty) returns (Integer) {}
106 | rpc getDiskUsage(String) returns (DiskUsage) {}
107 | rpc getBatteryInfo(google.protobuf.Empty) returns (BatteryInfo) {}
108 | rpc getCpuInfo(google.protobuf.Empty) returns (CpuInfo) {}
109 | rpc getOverallDiskIOInfo(google.protobuf.Empty) returns (DiskIOInfo) {}
110 | rpc getOverallNetIOInfo(google.protobuf.Empty) returns (NetIOInfo) {}
111 | rpc getMemInfo(google.protobuf.Empty) returns (MemInfo) {}
112 | rpc getUserDataDiskIOInfo(google.protobuf.Empty) returns (DiskIOInfo) {}
113 | rpc getNetIOInfo(String) returns (NetIOInfo) {}
114 | }
115 |
116 | service UiAutomator {
117 | rpc click(ClickPointRequest) returns (Boolean) {}
118 | rpc drag(DragPointRequest) returns (Boolean) {}
119 | rpc swipe(SwipePointRequest) returns (Boolean) {}
120 | rpc swipePoints(SwipePointsRequest) returns (Boolean) {}
121 | rpc openNotification(google.protobuf.Empty) returns (Boolean) {}
122 | rpc openQuickSettings(google.protobuf.Empty) returns (Boolean) {}
123 | rpc wakeUp(google.protobuf.Empty) returns (Boolean) {}
124 | rpc sleep(google.protobuf.Empty) returns (Boolean) {}
125 | rpc isScreenOn(google.protobuf.Empty) returns (Boolean) {}
126 | rpc isScreenLocked(google.protobuf.Empty) returns (Boolean) {}
127 | rpc setClipboard(ClipboardRequest) returns (Boolean) {}
128 | rpc getClipboard(google.protobuf.Empty) returns (String) {}
129 | rpc freezeRotation(Boolean) returns (Boolean) {}
130 | rpc setOrientation(OrientationRequest) returns (Boolean) {}
131 | rpc pressKey(PressKeyRequest) returns (Boolean) {}
132 | rpc pressKeyCode(PressKeyRequest) returns (Boolean) {}
133 |
134 | rpc deviceInfo(google.protobuf.Empty) returns (DeviceInfo) {}
135 |
136 | rpc takeScreenshot(TakeScreenshotRequest) returns (Bytes) {}
137 | rpc dumpWindowHierarchy(Boolean) returns (Bytes) {}
138 | rpc waitForIdle(Integer) returns (Boolean) {}
139 |
140 | rpc selectorTakeScreenshot(SelectorTakeScreenshotRequest) returns (Bytes) {}
141 |
142 | rpc selectorGetText(SelectorOnlyRequest) returns (String) {}
143 | rpc selectorClearTextField(SelectorOnlyRequest) returns (Boolean) {}
144 | rpc selectorSetText(SelectorSetTextRequest) returns (Boolean) {}
145 |
146 | rpc selectorClick(SelectorClickRequest) returns (Boolean) {}
147 | rpc selectorClickExists(SelectorClickRequest) returns (Boolean) {}
148 | rpc selectorLongClick(SelectorClickRequest) returns (Boolean) {}
149 |
150 | rpc selectorExists(SelectorOnlyRequest) returns (Boolean) {}
151 | rpc getLastToast(google.protobuf.Empty) returns (ToastInfo) {}
152 |
153 | rpc selectorObjInfo(SelectorOnlyRequest) returns (ObjInfo) {}
154 | rpc selectorObjInfoOfAllInstances(SelectorOnlyRequest) returns (ObjInfoList) {}
155 | rpc selectorCount(SelectorOnlyRequest) returns (Integer) {}
156 |
157 | rpc selectorDragTo(SelectorDragToRequest) returns (Boolean) {}
158 |
159 | rpc selectorWaitForExists(SelectorWaitRequest) returns (Boolean) {}
160 | rpc selectorWaitUntilGone(SelectorWaitRequest) returns (Boolean) {}
161 | rpc selectorSwipe(SelectorSwipeRequest) returns (Boolean) {}
162 |
163 | rpc selectorFlingToBeginning(SelectorFlingRequest) returns (Boolean) {}
164 | rpc selectorFlingToEnd(SelectorFlingRequest) returns (Boolean) {}
165 | rpc selectorFlingBackward(SelectorFlingRequest) returns (Boolean) {}
166 | rpc selectorFlingForward(SelectorFlingRequest) returns (Boolean) {}
167 |
168 | rpc selectorScrollToBeginning(SelectorScrollRequest) returns (Boolean) {}
169 | rpc selectorScrollToEnd(SelectorScrollRequest) returns (Boolean) {}
170 | rpc selectorScrollBackward(SelectorScrollRequest) returns (Boolean) {}
171 | rpc selectorScrollForward(SelectorScrollRequest) returns (Boolean) {}
172 | rpc selectorScrollTo(SelectorScrollRequest) returns (Boolean) {}
173 |
174 | rpc selectorPinchOut(SelectorPinchRequest) returns (Boolean) {}
175 | rpc selectorPinchIn(SelectorPinchRequest) returns (Boolean) {}
176 |
177 | rpc setWatcherLoopEnabled(Boolean) returns (Boolean) {}
178 | rpc getWatcherLoopEnabled(google.protobuf.Empty) returns (Boolean) {}
179 | rpc getWatcherTriggeredCount(String) returns (Integer) {}
180 | rpc resetWatcherTriggeredCount(String) returns (Boolean) {}
181 |
182 | rpc removeWatcher(String) returns (Boolean) {}
183 | rpc getAppliedWatchers(google.protobuf.Empty) returns (WatcherNameList) {}
184 |
185 | rpc registerClickUiObjectWatcher(WatcherRegistRequest) returns (Boolean) {}
186 | rpc registerPressKeysWatcher(WatcherRegistRequest) returns (Boolean) {}
187 | rpc registerNoneOpWatcher(WatcherRegistRequest) returns (Boolean) {}
188 | rpc findSimilarImage(FindImageRequest) returns (FindImageResponse) {}
189 | }
190 |
191 | service Wifi {
192 | rpc status(google.protobuf.Empty) returns (WifiStatus) {}
193 | rpc blacklistAdd(String) returns (Boolean) {}
194 | rpc blacklistClear(google.protobuf.Empty) returns (Boolean) {}
195 | rpc blacklistAll(google.protobuf.Empty) returns (WifiBlacklist) {}
196 | rpc scan(Boolean) returns (Boolean) {}
197 | rpc scanResults(google.protobuf.Empty) returns (ScanResult) {}
198 | rpc listNetworks(google.protobuf.Empty) returns (NetworkList) {}
199 | rpc selectNetwork(Network) returns (Boolean) {}
200 | rpc enableNetwork(Network) returns (Boolean) {}
201 | rpc disableNetwork(Network) returns (Boolean) {}
202 | rpc addNetwork(google.protobuf.Empty) returns (Network) {}
203 | rpc removeNetwork(Network) returns (Boolean) {}
204 | rpc setNetworkConfig(NetworkConfig) returns (Boolean) {}
205 | rpc getNetworkConfig(NetworkConfig) returns (NetworkConfig) {}
206 | rpc disconnect(google.protobuf.Empty) returns (Boolean) {}
207 | rpc reconnect(google.protobuf.Empty) returns (Boolean) {}
208 | rpc setConfig(WifiConfig) returns (Boolean) {}
209 | rpc setAutoConnect(Boolean) returns (Boolean) {}
210 | rpc saveConfig(google.protobuf.Empty) returns (Boolean) {}
211 | rpc getMacAddr(google.protobuf.Empty) returns (String) {}
212 | rpc signalPoll(google.protobuf.Empty) returns (SignalPoll) {}
213 | }
214 |
215 | service Util {
216 | rpc recordTouch(google.protobuf.Empty) returns (TouchSequence) {}
217 | rpc performTouch(PerformTouchRequest) returns (Boolean) {}
218 |
219 | rpc serverInfo(google.protobuf.Empty) returns (ServerInfoResponse) {}
220 |
221 | rpc reboot(google.protobuf.Empty) returns (Boolean) {}
222 | rpc beepBeep(google.protobuf.Empty) returns (Boolean) {}
223 | rpc isCACertificateInstalled(CertifiRequest) returns (Boolean) {}
224 | rpc installCACertificate(CertifiRequest) returns (Boolean) {}
225 | rpc uninstallCACertificate(CertifiRequest) returns (Boolean) {}
226 | rpc shutdown(google.protobuf.Empty) returns (Boolean) {}
227 | rpc showToast(ShowToastRequest) returns (Boolean) {}
228 | rpc reload(Boolean) returns (Boolean) {}
229 | rpc exit(google.protobuf.Empty) returns (Boolean) {}
230 | rpc setProp(SetPropRequest) returns (Boolean) {}
231 | rpc getProp(String) returns (String) {}
232 | rpc hexPatch(HexPatchRequest) returns (HexPatchResponse) {}
233 | }
234 |
235 | service File {
236 | rpc uploadFile(stream FileRequest) returns (FileStat) {}
237 | rpc downloadFile(FileRequest) returns (stream FileDataResponse) {}
238 | rpc deleteFile(FileRequest) returns (Boolean) {}
239 | rpc fileChmod(FileRequest) returns (FileStat) {}
240 | rpc fileStat(FileRequest) returns (FileStat) {}
241 | }
242 |
243 | service Lock {
244 | rpc releaseLock(google.protobuf.Empty) returns (Boolean) {}
245 | rpc getSessionToken(google.protobuf.Empty) returns (String) {}
246 | rpc acquireLock(Integer) returns (Boolean) {}
247 | rpc refreshLock(Integer) returns (Boolean) {}
248 | }
249 |
250 | service Storage {
251 | rpc clearAll(StorageRequest) returns (Boolean) {}
252 | rpc clearContainer(StorageRequest) returns (Boolean) {}
253 | rpc exists(StorageRequest) returns (Boolean) {}
254 | rpc delete(StorageRequest) returns (Boolean) {}
255 | rpc expire(StorageRequest) returns (Boolean) {}
256 | rpc ttl(StorageRequest) returns (Integer) {}
257 | rpc set(StorageRequest) returns (Boolean) {}
258 | rpc setnx(StorageRequest) returns (Boolean) {}
259 | rpc setex(StorageRequest) returns (Boolean) {}
260 | rpc get(StorageRequest) returns (Bytes) {}
261 | }
--------------------------------------------------------------------------------
/lamda/rpc/settings.proto:
--------------------------------------------------------------------------------
1 | // Copyright 2022 rev1si0n (lamda.devel@gmail.com). All rights reserved.
2 | //
3 | // Distributed under MIT license.
4 | // See file LICENSE for detail or copy at https://opensource.org/licenses/MIT
5 | syntax = "proto3";
6 | package lamda.rpc;
7 |
8 | enum Group {
9 | GROUP_SYSTEM = 0;
10 | GROUP_SECURE = 1;
11 | GROUP_GLOBAL = 2;
12 | }
13 |
14 | message SettingsRequest {
15 | Group group = 1;
16 | string name = 2;
17 | string value = 3;
18 | }
19 |
--------------------------------------------------------------------------------
/lamda/rpc/shell.proto:
--------------------------------------------------------------------------------
1 | // Copyright 2022 rev1si0n (lamda.devel@gmail.com). All rights reserved.
2 | //
3 | // Distributed under MIT license.
4 | // See file LICENSE for detail or copy at https://opensource.org/licenses/MIT
5 | syntax = "proto3";
6 | package lamda.rpc;
7 |
8 | message ShellRequest {
9 | string tid = 1;
10 | string name = 2;
11 | string script = 3;
12 | int32 timeout = 4;
13 | }
14 |
15 | message ShellResult {
16 | int32 exitstatus = 1;
17 | bytes stdout = 2;
18 | bytes stderr = 3;
19 | }
20 |
21 | message ShellTask {
22 | string tid = 1;
23 | string name = 2;
24 | int32 pid = 3;
25 | }
--------------------------------------------------------------------------------
/lamda/rpc/status.proto:
--------------------------------------------------------------------------------
1 | // Copyright 2022 rev1si0n (lamda.devel@gmail.com). All rights reserved.
2 | //
3 | // Distributed under MIT license.
4 | // See file LICENSE for detail or copy at https://opensource.org/licenses/MIT
5 | syntax = "proto3";
6 | package lamda.rpc;
7 |
8 | message BatteryInfo {
9 | bool batt_charging = 1;
10 | int32 batt_percent = 2;
11 | float batt_temperature = 3;
12 | }
13 |
14 | message CpuInfo {
15 | float cpu_percent = 1;
16 | int32 cpu_count = 2;
17 | float cpu_freq_current = 3;
18 | float cpu_freq_max = 4;
19 | float cpu_freq_min = 5;
20 | float cpu_times_user = 6;
21 | float cpu_times_system = 7;
22 | float cpu_times_idle = 8;
23 | }
24 |
25 | message DiskUsage {
26 | int64 disk_total = 1;
27 | int64 disk_used = 2;
28 | int64 disk_free = 3;
29 | float disk_percent = 4;
30 | }
31 |
32 | message DiskIOInfo {
33 | int64 disk_io_read_bytes = 1;
34 | int64 disk_io_read_count = 2;
35 | int64 disk_io_write_bytes = 3;
36 | int64 disk_io_write_count = 4;
37 | int64 disk_io_read_time = 5;
38 | int64 disk_io_write_time = 6;
39 | int64 disk_io_busy_time = 7;
40 | }
41 |
42 | message NetIOInfo {
43 | int64 net_io_bytes_sent = 1;
44 | int64 net_io_packets_sent = 2;
45 | int64 net_io_bytes_recv = 3;
46 | int64 net_io_packets_recv = 4;
47 | int64 net_io_dropin = 5;
48 | int64 net_io_dropout = 6;
49 | int64 net_io_errin = 7;
50 | int64 net_io_errout = 8;
51 | }
52 |
53 | message MemInfo {
54 | int64 mem_total = 1;
55 | int64 mem_available = 2;
56 | float mem_percent = 3;
57 | int64 mem_used = 4;
58 | int64 mem_free = 5;
59 | int64 mem_active = 6;
60 | int64 mem_inactive = 7;
61 | int64 mem_buffers = 8;
62 | int64 mem_cached = 9;
63 | int64 mem_shared = 10;
64 | int64 mem_slab = 11;
65 | }
66 |
--------------------------------------------------------------------------------
/lamda/rpc/storage.proto:
--------------------------------------------------------------------------------
1 | // Copyright 2022 rev1si0n (lamda.devel@gmail.com). All rights reserved.
2 | //
3 | // Distributed under MIT license.
4 | // See file LICENSE for detail or copy at https://opensource.org/licenses/MIT
5 | syntax = "proto3";
6 | package lamda.rpc;
7 |
8 | message StorageRequest {
9 | string container = 1;
10 | string key = 2;
11 | bytes value = 3;
12 | uint32 ttl = 4;
13 | }
--------------------------------------------------------------------------------
/lamda/rpc/types.proto:
--------------------------------------------------------------------------------
1 | // Copyright 2022 rev1si0n (lamda.devel@gmail.com). All rights reserved.
2 | //
3 | // Distributed under MIT license.
4 | // See file LICENSE for detail or copy at https://opensource.org/licenses/MIT
5 | syntax = "proto3";
6 | package lamda.rpc;
7 |
8 | message Boolean {
9 | bool value = 1;
10 | }
11 |
12 | message Integer {
13 | int64 value = 1;
14 | }
15 |
16 | message String {
17 | string value = 1;
18 | }
19 |
20 | message Bytes {
21 | bytes value = 1;
22 | }
23 |
24 | message Empty {
25 | }
26 |
--------------------------------------------------------------------------------
/lamda/rpc/util.proto:
--------------------------------------------------------------------------------
1 | // Copyright 2022 rev1si0n (lamda.devel@gmail.com). All rights reserved.
2 | //
3 | // Distributed under MIT license.
4 | // See file LICENSE for detail or copy at https://opensource.org/licenses/MIT
5 | syntax = "proto3";
6 | package lamda.rpc;
7 |
8 | enum ToastDuration {
9 | TD_SHORT = 0;
10 | TD_LONG = 1;
11 | }
12 |
13 | message TouchDown {
14 | int32 tid = 1;
15 | int32 x = 2;
16 | int32 y = 3;
17 | int32 pressure = 4;
18 | }
19 |
20 | message TouchUp {
21 | int32 tid = 1;
22 | }
23 |
24 | message TouchMove {
25 | int32 tid = 1;
26 | int32 x = 2;
27 | int32 y = 3;
28 | int32 pressure = 4;
29 | }
30 |
31 | message TouchWait {
32 | uint32 wait = 1;
33 | }
34 |
35 | message TouchAction {
36 | oneof action {
37 | TouchDown down = 1;
38 | TouchMove move = 2;
39 | TouchWait wait = 3;
40 | TouchUp up = 4;
41 | }
42 | }
43 |
44 | message TouchSequence {
45 | repeated TouchAction sequence = 1;
46 | }
47 |
48 | message PerformTouchRequest {
49 | TouchSequence sequence = 1;
50 | bool wait = 2;
51 | }
52 |
53 | message SetPropRequest {
54 | string name = 1;
55 | string value = 2;
56 | }
57 |
58 | message CertifiRequest {
59 | bytes cert = 1;
60 | }
61 |
62 | message ShowToastRequest {
63 | string text = 1;
64 | ToastDuration duration = 2;
65 | }
66 |
67 | message ServerInfoResponse {
68 | string uniqueId = 1;
69 | string version = 2;
70 | string architecture = 3;
71 | uint64 uptime = 4;
72 | bool secure = 5;
73 | }
74 |
75 | message HexPatchRequest {
76 | string pattern = 1;
77 | string replacement = 2;
78 | string path = 3;
79 | int32 maxreplace = 4;
80 | bool dryrun = 5;
81 | }
82 |
83 | message HexPatchItem {
84 | string path = 1;
85 | int32 index = 2;
86 | uint64 offset = 3;
87 | }
88 |
89 | message HexPatchResponse {
90 | int32 count = 1;
91 | repeated HexPatchItem replaces = 2;
92 | }
--------------------------------------------------------------------------------
/lamda/rpc/wifi.proto:
--------------------------------------------------------------------------------
1 | // Copyright 2022 rev1si0n (lamda.devel@gmail.com). All rights reserved.
2 | //
3 | // Distributed under MIT license.
4 | // See file LICENSE for detail or copy at https://opensource.org/licenses/MIT
5 | syntax = "proto3";
6 | package lamda.rpc;
7 |
8 | message WifiStatus {
9 | string id = 1;
10 | string address = 2;
11 | string bssid = 3;
12 | string freq = 4;
13 | string group_cipher = 5;
14 | string ip_address = 6;
15 | string key_mgmt = 7;
16 | string mode = 8;
17 | string pairwise_cipher = 9;
18 | string ssid = 10;
19 | string wifi_generation = 11;
20 | string wpa_state = 12;
21 | }
22 |
23 | message SignalPoll {
24 | string RSSI = 1;
25 | string LINKSPEED = 2;
26 | string NOISE = 3;
27 | string FREQUENCY = 4;
28 | string WIDTH = 5;
29 | string AVG_RSSI = 6;
30 | string AVG_BEACON_RSSI = 7;
31 | string CENTER_FRQ1 = 8;
32 | }
33 |
34 | message WifiInfo {
35 | string id = 1;
36 | string bssid = 2;
37 | string ssid = 3;
38 | string freq = 4;
39 | string noise = 5;
40 | string level = 6;
41 | string tsf = 7;
42 | string flags = 8;
43 | }
44 |
45 | message ScanResult {
46 | repeated WifiInfo stations = 1;
47 | }
48 |
49 | message Network {
50 | int32 nid = 1;
51 | string bssid = 2;
52 | string ssid = 3;
53 | string flags = 4;
54 | }
55 |
56 | message NetworkList {
57 | repeated Network networks = 1;
58 | }
59 |
60 | message NetworkConfig {
61 | Network network = 1;
62 | string name = 2;
63 | string value = 3;
64 | }
65 |
66 | message WifiConfig {
67 | string name = 1;
68 | string value = 2;
69 | }
70 |
71 | message WifiBlacklist {
72 | repeated string bssids = 1;
73 | }
--------------------------------------------------------------------------------
/lamda/types.py:
--------------------------------------------------------------------------------
1 | # Copyright 2022 rev1si0n (lamda.devel@gmail.com). All rights reserved.
2 | #
3 | # Distributed under MIT license.
4 | # See file LICENSE for detail or copy at https://opensource.org/licenses/MIT
5 | import io
6 | import codecs
7 |
8 | __all__ = ["AttributeDict", "BytesIO"]
9 |
10 |
11 | class AttributeDict(dict):
12 | def __getattr__(self, attr):
13 | return self[attr]
14 | def __setattr__(self, attr, value):
15 | self[attr] = value
16 | def remove(self, key):
17 | key in self and self.pop(key)
18 |
19 |
20 | class BytesIO(io.BytesIO):
21 | @classmethod
22 | def decode_from(cls, data, encoding):
23 | return cls(codecs.decode(data, encoding))
24 | def encode(self, encoding):
25 | return codecs.encode(self.getvalue(), encoding)
26 | def decode(self, encoding):
27 | return codecs.decode(self.getvalue(), encoding)
28 | def save(self, fpath):
29 | with open(fpath, "wb") as fd:
30 | return fd.write(self.getvalue())
31 | @classmethod
32 | def load(cls, fpath):
33 | with open(fpath, "rb") as fd:
34 | return cls(fd.read())
35 |
--------------------------------------------------------------------------------
/properties.local.example:
--------------------------------------------------------------------------------
1 | # properties.local configuration file
2 | #
3 | # DO NOT DIRECTLY COPY THIS FILE, PLEASE SELECT THE NECESSARY CONFIGURATION LINES TO CREATE A NEW FILE
4 | #
5 | # This file is the LAMDA service configuration file. You can use
6 | # it to automatically start some services when LAMDA starts.
7 | # The file should be located in /data or /data/usr (this directory
8 | # will not exist before the first startup, please create it if it does not exist).
9 | # Lines starting with # and ; are comment lines and will be ignored.
10 | # Please ensure that each line follows the format a=b and does not contain spaces.
11 | # If there are duplicate configuration items across multiple files,
12 | # the last duplicate will be used.
13 |
14 | # Set the default listening port for LAMDA.
15 | port=65000
16 |
17 | # You can change the name displayed on the remote desktop for
18 | # LAMDA to any name you prefer (up to 10 characters).
19 | brandname=FIRERPA
20 |
21 | # Set the LAMDA certificate. It will encrypt your remote desktop
22 | # and API traffic, and enable password authentication. You can obtain
23 | # the following configuration value by running 'base64 -w0 lamda.pem'.
24 | # It is the base64-encoded certificate.
25 | cert=TEFNREEgU1NMIENFUlRJRklDQVRFIChDTj10ZXN0LFBBU1NXRD1hMWMwZTNlYTcwN2E1NGRlN2EwZjk1KQotLS0tLUJFR0lOIFBSSVZBVEUgS0VZLS0tLS0KTUlJRXZnSUJBREFOQmdrcWhraUc5dzBCQVFFRkFBU0NCS2d3Z2dTa0FnRUFBb0lCQVFEVmNMWlA5b0xRWkRIRgp5V0pTa2U0Z0crSUpmSCtMWlk0cXUzdS9OckRwSHZCN2k5V01rMWxRL2FMSGI0V3ZqelBLK1RITm9rRzc2MENRClhBTUpWS0dmYXRwcmNLUXdvMGhvWDZ2NlhsTVlZUlNRbW9wN3pSaUtnN3ZxKzV2S09DQ2RKcDFlSVNiZXcyTEgKTmYxL3JZelpwa1Q1bHoxTGZkem00eXJBS3VNa0tyZ3pnTzJRcE9CQVdYdmdiWG9BMDdidDdOODZZOGdNZFUwdAp6Ui9EcmhLTi9JMVdYSk11MU4wQW5UbDJRdEhEb0dCN0UyS0xpdmwybDZJdnRrYWJ4RE55Y2lHbUxOUGlMRklrCllPSHlnMUg3MUJ2NU04NE5TWDc1c2xuOXVNUGUzOVNFVlJoU0ptNHcvT2tXZnA5dGpZRUx3dHphdFhoSWJoS3MKaC9OZU1lOWRBZ01CQUFFQ2dnRUFCYlFuWUdlcFdKYjAydURtSnhLNGx2OFNhL0o1dzJpSldMYjk0dW1SUExRKwpTa1E5c1Zpc0JiQU1JNHc2dWFyNEFBVTh3WGxaTndPekMvM2V6dWNHRXFreEFReXM0VDB4SXRPUkF2WExxVlowCkl1WnpxNW53Si9OeFFzeEtmaWhBZkRLYlRmZjdmcG5MWlV0dlpNbG5LWUhQVExtRlFua3drckwyRE5YdDVVOTYKYXJUUDVOY0x1aDQ2dU93alJUOWhaNytYQi9ubU9LeTV4V3hoNWVMQmJJUTJrS0UvdWViUlVYRGZNdG5tbTh2aApRSG9VM3N5dzlZcE1xRDlWQWppcGlqQXRwbUlwa2w1emRWSE52Q1dCSGk2NjZxKzF6cUpHeFVUODBseHo1N2R1ClRvRFFQc1l0OFFEL3ZjNGkxajd0bDZyRzNQWkJNM05LNVR5ZFYyRnlnUUtCZ1FEYUcycnV3aWxyYUdZRzZNQWwKNEF2WW1BY0hHQWUwQjR0ZmtkdS9QandlRWQyWUF2TjJIQWV1Z1ZUSWg1eFplUlIwNFE4ZVNGenBTaEpwREpkNAp1TEhHcXJ2cmpXL1greEVIc081NnNjNjRiem1weWJWQXBlQnA4NlFGSTk4V3FmZkFyN3FzbzhweFJjNmdTRU1uCk5TcXV1Z2psYU05TlJmcUo4ci82RklmQkxRS0JnUUQ2aGJ0Z2dIdVJoTHhHYWNNaERvOVppcXJlNi9HN1dvZnQKR2FGZmFQM2xZNTNmM0hPdSsyNTZMWDY1ZWFYRTdrbXlQOGRDM2VWL24xT3dvTHdBYm1BZ2pEWVd1N09KdGk4QQpPbG9VNmtnTkVwNWcwOHpVWlBaR3NSMkZMd2VpUkgrQ3ZOdFBZakJydmFIQUtVU2lLa3BKdEpWeFpIdUl6SlpGCjVUZkM2VjNrOFFLQmdEeWp0TlpPKzA4V2hvOVROT0VTNnBnOHBHK1BlY3pPOEN3UkZJU1dYQWFNTnd6bGZTVVEKWS81YmpPUDMrRHRVRTZEdlZkRzRrc1IxeUtxV1NxTFF6dlNLVVpjTEN0YUV3bFplRmQvZEFibDdpdyt1dWdzUQpVMVdCM005bENzaDFWeUdtZWdNM3dyZzlqVlk0NFJyTWlHSnQ3TDFEcDZjM1ZwSDJBUFFac3lpOUFvR0JBTk9pCmpmeWtEYitNNXBDRllEWlkybmpHVURzcUQzZzZyb0Y2R1gxRWNOaU1JeDZ1V1h3RkkvdEsyN2RNTU9JQWUzbDkKcjVPcGFPczdhYlBZMVhsM3hQVTUvYWVPd2NrZ2d1d3FYMWN6NDlKSFhFeG9JSzE4N1NBakY5RWZQYyt6RmhVWAovaDA5MGJIeTdPWXM5cklZRDlIY0lETStzNjJKUjVtY1hsTG1Xay9CQW9HQkFKRVhQV05IWEwra1l6My91R1c3CnRKd0hUQzFlbEJjclcvaHpJMWt4ZEhXem5VaXNTWlcyVnA5b0wwSWNrQXVWQkx6eGUvR1h6OGJRTjZkOWwyZDAKdGtmUmo1TmpDOTUzS2N1cTNSekRmVU40cTcyUlVWTWlFOHVvSTBkVVZpalczN0tVMEhLcm1pbDBocU01eW9iNQpVZlhPQ2Q5SlRRSWx5Y2dNWER6Tm00S3oKLS0tLS1FTkQgUFJJVkFURSBLRVktLS0tLQotLS0tLUJFR0lOIENFUlRJRklDQVRFLS0tLS0KTUlJQ3FEQ0NBWkNnQXdJQkFnSVJBUHNjMVBRNXBuSDNhNk1GZkdVTXA2WXdEUVlKS29aSWh2Y05BUUVMQlFBdwpFREVPTUF3R0ExVUVDZ3dGVEVGTlJFRXdIaGNOTWpBd01UQXhNREF3TURBeFdoY05Namt4TWpJNU1EQXdNREF4CldqQVBNUTB3Q3dZRFZRUUREQVIwWlhOME1JSUJJakFOQmdrcWhraUc5dzBCQVFFRkFBT0NBUThBTUlJQkNnS0MKQVFFQTFYQzJUL2FDMEdReHhjbGlVcEh1SUJ2aUNYeC9pMldPS3J0N3Z6YXc2Ujd3ZTR2VmpKTlpVUDJpeDIrRgpyNDh6eXZreHphSkJ1K3RBa0Z3RENWU2huMnJhYTNDa01LTklhRityK2w1VEdHRVVrSnFLZTgwWWlvTzc2dnViCnlqZ2duU2FkWGlFbTNzTml4elg5ZjYyTTJhWkUrWmM5UzMzYzV1TXF3Q3JqSkNxNE00RHRrS1RnUUZsNzRHMTYKQU5PMjdlemZPbVBJREhWTkxjMGZ3NjRTamZ5TlZseVRMdFRkQUowNWRrTFJ3NkJnZXhOaWk0cjVkcGVpTDdaRwptOFF6Y25JaHBpelQ0aXhTSkdEaDhvTlIrOVFiK1RQT0RVbCsrYkpaL2JqRDN0L1VoRlVZVWladU1QenBGbjZmCmJZMkJDOExjMnJWNFNHNFNySWZ6WGpIdlhRSURBUUFCTUEwR0NTcUdTSWIzRFFFQkN3VUFBNElCQVFBWEQ0L1cKQjBhSW1aWGpQbTRxUnBOazJmUnpjU1g4MGw2TlZaWWxJV3ZYalFxUXdXZnMvSGczZDVzYUpickFmcWVPa1lQdQpjeXJEWFZPdC9RTEVDOTFBSGtjRWJ1R0dPMGNFU2YyOHdUM1UzRnJJb2cxS1VyTURqWFFIb09vZEJpOGdNaVBmCmROcWhMSTdkNDJBTXJKU3dZUTlSUG9vWG9UZ2xDa0d3R291RDhuS0V5MmNHeVMxM3lQcDRseC9TWTR1QkRFU0sKRlErR0ZRTExGQktQZHZNc2x0cHYyQWFMWmR3clF4aFQ2aTU1U1puNStLb3c1TGxYL0RHdUw5UnRPdmZ2T0tzZQpRZ3pOQUg3QkYzbGdvQmJjYk9yZkVQazY1ZEZRN0NXYi91aDZjVmlmSjdxQzkvL0xhdElmb1VQVnJiRXdZL2dRCk5BRXFYclduMGZuYUc0cUEKLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQotLS0tLUJFR0lOIENFUlRJRklDQVRFLS0tLS0KTUlJQ2xEQ0NBWHdDQVFBd0RRWUpLb1pJaHZjTkFRRUxCUUF3RURFT01Bd0dBMVVFQ2d3RlRFRk5SRUV3SGhjTgpNakF3TVRBeE1EQXdNREF4V2hjTk1qa3hNakk1TURBd01EQXhXakFRTVE0d0RBWURWUVFLREFWTVFVMUVRVENDCkFTSXdEUVlKS29aSWh2Y05BUUVCQlFBRGdnRVBBRENDQVFvQ2dnRUJBTG5xZkJadnJHWmFxZ2s1bXNDUlJwUHoKcC8rNDY0akJrbmxtVEtldE9ja0RUVXE4VjZmSC8yR2ZiNkhqam9ENXBrQ3RENW1TS2thSE5odXhMWHNGZkVmYwpLbG1ubjNacGp5Tk9IRUEvaUFPMkR5RVlhMDh4U2V2TTdXb2piRjdjTmo1L0RZZzdlYjBpMCsvL2JCbGg4bmxPCmdoU1VoQ1RNNVBDb2ZMRFU4c1ZYdVlBaUdVNlV6QnJJQzB2SEVsdERraUpWTHBjQ3RzS2pFWk9za1BkQWM3dTYKL2FBMFA1R29uWjVVa1JEWXBhK2plSlVhYnFXWlFRRWd0bXZqbG1VVWlYd3UwalJuajFuMFQzZlBRRDNnQStMSQp2QUU5dmd2cFk1WFFqNm90cEJ2c1ozTUpKTktjVU1RdTF6T0FOVHpPMThUbEE4S29CTnNCeThaOURRWktYRjhDCkF3RUFBVEFOQmdrcWhraUc5dzBCQVFzRkFBT0NBUUVBZUduL055cUlSSS8wQUdxdkhQOTdLdFE3NlRqNmFjaGIKMzBMSVhXcCtZSFVhTWVBVmpkMlo3alNRcDVtWlpGbCtrMWZiMzM3SWVhR1hvZlZJMjFlSzUyUVgydGVOb0JrQQovVi9PMUh1MzUvK2FpejB4c2RENndXdndvNEZ5MWpsbWFlSmh3ZFFhY0JsREdGQTJqRkp4dUVwYWhmeFp2VXNiCjNqNXpVMFdLVFVDZkVEZ1hGd0J3MTJ4a3UvN1RNZENFYlJzWWFaM3pGVEMyMjZsUWJVRE43d2VxRndTRCt0QjYKUnVoSXhlOCtjRndBc0FXSENsZXJLZ1pucjN0NVFGMDc4cFcyR0h5OENzSjdWM01aVDVsWjQzbFM1TklCOUp6WgpTWXhaL2l6aFJ5aDVxUjczdUFnc0phTDU2QmorY1Fxbm9UcWhMWlZsN0orTTZXaFdLem9qc0E9PQotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCg==
26 |
27 | # Set the remote desktop login password for LAMDA, 6-32 characters.
28 | # This password will only take effect if a certificate (--certificate)
29 | # is used. It serves as a backup password to the one generated in
30 | # the certificate (for easier memorization).
31 | ssl-web-credential=password123
32 |
33 | # Set Access-Control-Allow-Origin header of firerpa webui
34 | # and it's apis to allow you embed firerpa's features
35 | # see https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Allow-Origin
36 | allow_origin=https://example.com
37 |
38 | # Setting this option will also disable the LAMDA Python client API.
39 | # This option should be set only if the device crashes after starting LAMDA,
40 | # or if you do not need to use the API. This option will also disable
41 | # any components that might impact system stability.
42 | disable-client-api=false
43 |
44 | # Enhanced stealth mode, designed to protect LAMDA and its associated
45 | # components from detection in cases where there is a risk of damaging
46 | # itself or third-party components.
47 | # Use only if necessary (introduced in version 7.65).
48 | enhanced-stealth-mode=false
49 |
50 | # Remote Desktop Touch Fix
51 | # If there is an offset or no response when you touch the screen on
52 | # the remote desktop, please set the following configuration:
53 | touch.backend=system
54 |
55 | # The switch for get_last_activities, default is false and does not intercept.
56 | # introduced in 8.20
57 | intercept-intent=false
58 |
59 | # Set the log file location (directory must exists)
60 | logfile=/data/local/tmp/server.log
61 |
62 | # ---------- OpenVPN Configuration ----------
63 | # Do not manually write the following configuration. You should use
64 | # our accompanying OpenVPN server setup solution to set it up and
65 | # generate this configuration using its built-in commands.
66 | openvpn.proto=udp
67 | openvpn.cipher=AES-256-GCM
68 | openvpn.host=123.123.123.123
69 | openvpn.port=1190
70 | openvpn.ca=LS0tLS1CRU...
71 | openvpn.cert=LS0tLS1CRU...
72 | openvpn.key=LS0tLS1CRU...
73 | openvpn.tls_encryption=
74 | openvpn.tls_key_direction=
75 | openvpn.tls_key=
76 | # ONLY THE FOLLOWING CONFIGURATION ITEMS CAN BE MANUALLY CONFIGURED.
77 | # Whether to enable global VPN.
78 | openvpn.global=false
79 | # Whether to enable the service true | false
80 | openvpn.enable=true
81 |
82 | # ---------- Proxy Configuration ----------
83 | # This configuration is used to make LAMDA automatically connect
84 | # to the proxy server at startup.
85 | #
86 | # Whether to enable the service true | false
87 | gproxy.enable=true
88 | # The proxy type can be either http-connect or socks5.
89 | gproxy.type=http-connect
90 | # Proxy server address
91 | gproxy.host=172.1.1.1
92 | # Proxy server port
93 | gproxy.port=8080
94 | # Proxy server login password (leave empty for no authentication)
95 | gproxy.password=
96 | # Proxy server login username (leave empty for no authentication)
97 | gproxy.login=
98 |
99 | # ---------- CRONTAB Scheduled Task Service ----------
100 | # If you do not need scheduled tasks, you can disable this service.
101 | # Whether to enable the service true | false
102 | cron.enable=true
103 |
104 | # ---------- SSHD Service ----------
105 | # If you do not need to connect to the device via SSH, you can disable this service.
106 | # Whether to enable the service true | false
107 | sshd.enable=true
108 |
109 | # ---------- Port Forwarding (frp) Service ----------
110 | # Whether to enable the service true | false
111 | fwd.enable=true
112 | # Port to forward to the remote (0 means randomly allocated)
113 | fwd.rport=0
114 | # FRP server address
115 | fwd.host=123.123.123.123
116 | # FRP server port
117 | fwd.port=9911
118 | # FRP protocol
119 | fwd.protocol=tcp
120 | # FRP login authentication
121 | fwd.token=abc123
122 |
123 | # ---------- ADB Service ----------
124 | # Whether to enable the service true | false
125 | adb.enable=true
126 | # Default working directory for built-in ADB (adb shell working directory)
127 | adb.directory=/data/local/tmp
128 | # If set to true, the ADB connection will have root privileges,
129 | # otherwise it will have shell privileges. When this option is set to false,
130 | # you will be using a native-like adb shell, and you will not be able to use
131 | # LAMDA's built-in commands. Please note that since ADB does not use TLS connections,
132 | # traffic may be monitored. For security reasons, when the LAMDA service is
133 | # started with a certificate, this value will be set to false by default.
134 | # However, if you specify it in the properties.local file, the configuration
135 | # in the file will take precedence.
136 | # You are responsible for ensuring security.
137 | adb.privileged=true
138 |
139 | # ---------- Bridge Proxy Service ----------
140 | # Whether to enable the service true | false
141 | tunnel2.enable=true
142 | # The bridge proxy will require login authentication only if both login and password
143 | # are set. If either one is left empty, no login authentication will be required.
144 | tunnel2.login=lamda
145 | # Login password for the bridge proxy
146 | tunnel2.password=1234
147 | # Outbound interface (rmnet|wlan)
148 | # When the outbound interface is rmnet, the proxy will attempt to forward your requests through mobile data.
149 | # When the outbound interface is wlan, requests will be forwarded through the wlan interface.
150 | # If the configuration is empty, the default network will be used to forward the requests.
151 | tunnel2.iface=rmnet
152 |
153 | # ---------- mDNS Broadcast Service ----------
154 | # Enable or disable true | false
155 | mdns.enable=true
156 | # Add TXT metadata for mDNS. When enabled, it will support querying device information
157 | # such as model, ABI, and device ID using tools like python-zeroconf. Disabled by default.
158 | mdns.meta=false
159 | # Set the broadcast domain name using a locally unique ID, default is {DEVICEID-UNIQUE}.lamda.
160 | # If the name duplicates in the local network, a suffix ID will be automatically added.
161 | mdns.name=DEVICEID-UNIQUE.lamda
162 | # Set the broadcast service name, default is lamda, i.e., _lamda._tcp.local.
163 | mdns.service=lamda
164 |
--------------------------------------------------------------------------------
/scripts/disable_flag_secure.yaml:
--------------------------------------------------------------------------------
1 | # EXAMPLE EXTENSION OF FIRERPA (https://github.com/firerpa/lamda)
2 | # This script is used to disable the android FLAG_SECURE flag.
3 | # Replace YOUR_APP_ID with the ID (eg. com.android.settings) of your target application.
4 | enable: true
5 | application: "YOUR_APP_ID"
6 | version: "N/A"
7 | script: !!binary "SmF2YS5wZXJmb3JtKGZ1bmN0aW9uICgpIHsKICAgICAgICB2YXIgRkxBR19TRUNVUkUgPSAweDIwMDA7CiAgICAgICAgdmFyIFdpbmRvdyA9IEphdmEudXNlKCJhbmRyb2lkLnZpZXcuV2luZG93Iik7CiAgICAgICAgdmFyIHNldEZsYWdzID0gV2luZG93LnNldEZsYWdzOwoKICAgICAgICBzZXRGbGFncy5pbXBsZW1lbnRhdGlvbiA9IGZ1bmN0aW9uIChmbGFncywgbWFzaykgewogICAgICAgICAgICBjb25zb2xlLmxvZygiRGlzYWJsaW5nIEZMQUdfU0VDVVJFLi4uIik7CiAgICAgICAgICAgIGZsYWdzICY9IH5GTEFHX1NFQ1VSRTsKICAgICAgICAgICAgc2V0RmxhZ3MuY2FsbCh0aGlzLCBmbGFncywgbWFzayk7CiAgICAgICAgfTsKfSk7Cg=="
8 | standup: 0
9 | spawn: false
--------------------------------------------------------------------------------
/scripts/disable_ssl_pinning_simple.yaml:
--------------------------------------------------------------------------------
1 | # EXAMPLE EXTENSION OF FIRERPA (https://github.com/firerpa/lamda)
2 | # This script is used to disable simple ssl pinning (checkServerTrusted).
3 | # Replace YOUR_APP_ID with the ID (eg. com.android.settings) of your target application.
4 | enable: true
5 | application: "YOUR_APP_ID"
6 | version: "N/A"
7 | script: !!binary "SmF2YS5wZXJmb3JtKGZ1bmN0aW9uKCkgewpKYXZhLnVzZSgiYW5kcm9pZC5zZWN1cml0eS5uZXQuY29uZmlnLlJvb3RUcnVzdE1hbmFnZXIiKS5jaGVja1NlcnZlclRydXN0ZWQub3ZlcmxvYWQoIltMamF2YS5zZWN1cml0eS5jZXJ0Llg1MDlDZXJ0aWZpY2F0ZTsiLCAiamF2YS5sYW5nLlN0cmluZyIsICJqYXZhLm5ldC5Tb2NrZXQiKS5pbXBsZW1lbnRhdGlvbiA9IGZ1bmN0aW9uIChhLCBiLCBjKSB7CiAgICAgICAgcmV0dXJuCn0KfSkK"
8 | standup: 0
9 | spawn: false
--------------------------------------------------------------------------------
/setup.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/python3
2 | # Copyright 2022 rev1si0n (lamda.devel@gmail.com). All rights reserved.
3 | import setuptools
4 |
5 | exec(open("lamda/__init__.py", "rt").read())
6 |
7 | setuptools.setup(
8 | name = "lamda",
9 | version = "{}".format(__version__),
10 | description = "Android reverse engineering & automation framework (Client API)",
11 | url = "https://github.com/firerpa/lamda",
12 | author = "rev1si0n",
13 | python_requires = ">=3.6,<3.13",
14 | zip_safe = False,
15 | extras_require = {
16 | "full": ["frida>=16.0.0,<17.0.0"],
17 | ":sys_platform == \"win32\"": [
18 | "pyreadline==2.1",
19 | ],
20 | },
21 | install_requires= [
22 | "grpcio-tools>=1.35.0,<=1.68.0",
23 | "grpc-interceptor>=0.13.0,<=0.15.4",
24 | "grpcio>=1.35.0,<=1.68.0",
25 | "cryptography>=35.0.0",
26 | "msgpack>=1.0.0",
27 | "asn1crypto>=1.0.0,<2",
28 | "pem==23.1.0",
29 | ],
30 | classifiers = [
31 | "Environment :: Console",
32 | "Intended Audience :: Developers",
33 | "Development Status :: 5 - Production/Stable",
34 | "Intended Audience :: Information Technology",
35 | "Intended Audience :: Science/Research",
36 | "Programming Language :: Python :: 3",
37 | "Operating System :: Android",
38 | "Topic :: Security",
39 | ],
40 | package_data = {
41 | "lamda": ["*.py", "*.proto"],
42 | "lamda.google.protobuf.compiler": ["*.proto"],
43 | "lamda.google.protobuf": ["*.proto"],
44 | "lamda.rpc": ["*.proto"],
45 | },
46 | packages = [
47 | "lamda.google.protobuf.compiler",
48 | "lamda.google.protobuf",
49 | "lamda.rpc",
50 | "lamda",
51 | ],
52 | )
53 |
--------------------------------------------------------------------------------
/tools/README.md:
--------------------------------------------------------------------------------
1 | Document: https://device-farm.com/doc/
--------------------------------------------------------------------------------
/tools/adb_pubkey.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python3
2 | #encoding=utf-8
3 | import os
4 | import argparse
5 |
6 | from os.path import isfile
7 | from lamda.client import *
8 |
9 | certfile = os.environ.get("CERTIFICATE", None)
10 | port = int(os.environ.get("PORT", 65000))
11 |
12 | android_path = os.path.join("~", ".android")
13 | abs_android_path = os.path.expanduser(android_path)
14 | f = "adbkey.pub"
15 |
16 | argp = argparse.ArgumentParser()
17 |
18 | argp.add_argument("action", nargs=1)
19 | argp.add_argument("device", nargs=1)
20 |
21 | args = argp.parse_args()
22 |
23 | d = Device(args.device[0], port=port,
24 | certificate=certfile)
25 | cmd = args.action[0]
26 |
27 | os.chdir(abs_android_path)
28 |
29 | # try generate pubkey
30 | pubkey = os.popen("adb pubkey adbkey").read()
31 | open("adbkey.lamda", "w").write(pubkey)
32 |
33 | f = ("adbkey.lamda", f)[isfile(f)]
34 |
35 | call = getattr(d, "%s_adb_pubkey" % cmd)
36 | exit(not call(f))
--------------------------------------------------------------------------------
/tools/cert.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python3
2 | import os
3 | import sys
4 | import random
5 | import datetime
6 |
7 | from hashlib import sha256
8 | from cryptography.hazmat.primitives.asymmetric import rsa
9 | from cryptography.hazmat.primitives import hashes, serialization
10 | from cryptography.hazmat.backends import default_backend
11 | from cryptography.x509 import (
12 | Name,
13 | NameAttribute,
14 | CertificateBuilder,
15 | CertificateSigningRequestBuilder,
16 | DNSName,
17 | SubjectAlternativeName,
18 | load_pem_x509_certificate,
19 | BasicConstraints,
20 | KeyUsage,
21 | )
22 | from cryptography.x509.oid import NameOID
23 |
24 | CN = "lamda"
25 | if len(sys.argv) == 2:
26 | CN = sys.argv[1]
27 |
28 | if os.path.isfile("root.key"):
29 | with open("root.key", "rb") as f:
30 | rk = serialization.load_pem_private_key(
31 | f.read(), password=None, backend=default_backend()
32 | )
33 | else:
34 | rk = rsa.generate_private_key(
35 | public_exponent=65537, key_size=2048, backend=default_backend()
36 | )
37 | with open("root.key", "wb") as f:
38 | f.write(
39 | rk.private_bytes(
40 | encoding=serialization.Encoding.PEM,
41 | format=serialization.PrivateFormat.TraditionalOpenSSL,
42 | encryption_algorithm=serialization.NoEncryption(),
43 | )
44 | )
45 |
46 | if os.path.isfile("root.crt"):
47 | with open("root.crt", "rb") as f:
48 | root = load_pem_x509_certificate(f.read(), default_backend())
49 | else:
50 | subject = issuer = Name(
51 | [
52 | NameAttribute(NameOID.ORGANIZATION_NAME, "LAMDA"),
53 | NameAttribute(NameOID.COMMON_NAME, "FireRPA LAMDA Root Trust"),
54 | ]
55 | )
56 | root = (
57 | CertificateBuilder()
58 | .subject_name(subject)
59 | .issuer_name(issuer)
60 | .not_valid_before(datetime.datetime.utcnow())
61 | .not_valid_after(datetime.datetime.utcnow() + datetime.timedelta(days=3650))
62 | .public_key(rk.public_key())
63 | .serial_number(random.randint(1, 2**128))
64 | .add_extension(BasicConstraints(ca=True, path_length=None), critical=True)
65 | .sign(rk, hashes.SHA256(), default_backend())
66 | )
67 | with open("root.crt", "wb") as f:
68 | f.write(root.public_bytes(serialization.Encoding.PEM))
69 |
70 |
71 | if not os.path.isfile(f"{CN}.pem"):
72 | pk = rsa.generate_private_key(
73 | public_exponent=65537, key_size=2048, backend=default_backend()
74 | )
75 | csr = (
76 | CertificateSigningRequestBuilder()
77 | .subject_name(Name([NameAttribute(NameOID.COMMON_NAME, CN)]))
78 | .sign(pk, hashes.SHA256(), default_backend())
79 | )
80 |
81 | cert = (
82 | CertificateBuilder()
83 | .subject_name(csr.subject)
84 | .issuer_name(root.subject)
85 | .not_valid_before(datetime.datetime.utcnow())
86 | .not_valid_after(datetime.datetime.utcnow() + datetime.timedelta(days=3650))
87 | .public_key(csr.public_key())
88 | .serial_number(random.randint(1, 2**128))
89 | .sign(rk, hashes.SHA256(), default_backend())
90 | )
91 |
92 | with open(f"{CN}.pem", "wb") as output:
93 | pem_private_key = pk.private_bytes(
94 | encoding=serialization.Encoding.PEM,
95 | format=serialization.PrivateFormat.TraditionalOpenSSL,
96 | encryption_algorithm=serialization.NoEncryption(),
97 | )
98 | pem_cert = cert.public_bytes(serialization.Encoding.PEM)
99 | pem_root = root.public_bytes(serialization.Encoding.PEM)
100 |
101 | d = pk.private_numbers().d
102 | pd = d.to_bytes((d.bit_length() + 7) // 8, "little")
103 | cred = sha256(pd).hexdigest()[::3]
104 |
105 | header = f"LAMDA SSL CERTIFICATE (CN={CN},PASSWD={cred})\n"
106 | output.write(header.encode())
107 | output.write(pem_private_key.strip())
108 | output.write(b"\n")
109 | output.write(pem_cert.strip())
110 | output.write(b"\n")
111 | output.write(pem_root.strip())
112 | output.write(b"\n")
113 |
--------------------------------------------------------------------------------
/tools/debugimage.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python3
2 | import os
3 | import argparse
4 |
5 | from PIL import Image, ImageDraw
6 | from lamda.client import *
7 |
8 | cert = os.environ.get("CERTIFICATE", None)
9 | port = int(os.environ.get("PORT", 65000))
10 |
11 | parser = argparse.ArgumentParser()
12 | parser.add_argument("-d", type=str, dest="device",
13 | help="service ip address", required=True)
14 | parser.add_argument("-p", "--port", type=str,
15 | default=port, help="service port")
16 | parser.add_argument("-f", "--method", type=str,
17 | help="find method", default="0")
18 | parser.add_argument("-i", "--image", type=argparse.FileType("rb"),
19 | help="find image path", required=True)
20 | parser.add_argument("-a", "--area", type=str,
21 | help="area", default="0")
22 | parser.add_argument("-s", "--scale", type=float,
23 | help="scale", default=1.0)
24 | parser.add_argument("-t", "--threshold", type=float,
25 | help="threshold", default=0)
26 | parser.add_argument("-m", "--distance", type=int,
27 | help="max distance", default=0)
28 | parser.add_argument("-cert", type=str, default=cert,
29 | help="ssl cert")
30 | args = parser.parse_args()
31 |
32 |
33 | d = Device(args.device, port=args.port,
34 | certificate=args.cert)
35 | image = Image.open(d.screenshot(95))
36 |
37 | draw = ImageDraw.Draw(image)
38 | for r in d.find_similar_image(args.image.read(),
39 | area=eval(args.area),
40 | method=eval(args.method),
41 | distance=args.distance,
42 | threshold=args.threshold,
43 | scale=args.scale):
44 | p1 = r.corner("top-left")
45 | p2 = r.corner("bottom-right")
46 | draw.rectangle(((p1.x, p1.y), (p2.x, p2.y)),
47 | outline="#00ff00", width=3)
48 | image.show()
--------------------------------------------------------------------------------
/tools/discover.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python3
2 | import os
3 | import struct
4 | from socket import *
5 |
6 | from lamda import __version__
7 | from lamda.client import load_proto
8 |
9 | protos, services = load_proto("bcast.proto")
10 |
11 | BcastHeader = protos.BcastHeader
12 | BcastDiscoverInfo = protos.BcastDiscoverInfo
13 | BcastResponse = protos.BcastResponse
14 | BcastRequest = protos.BcastRequest
15 |
16 | port = int(os.environ.get("PORT", 65000))
17 |
18 |
19 | def BcastCallMethod(method):
20 | req = BcastRequest(method=method)
21 | # ASTBCAST + length (body,4byte) + body + feeedeed
22 | hdr = BcastHeader(magic=0x54534143,
23 | version=__version__)
24 | req.header.CopyFrom(hdr)
25 | body = req.SerializeToString()
26 | buffer = []
27 | r = struct.pack("QH", 0x5453414342545341, len(body))
28 | buffer.append(r)
29 | r = struct.pack("{}s".format(len(body)), body)
30 | buffer.append(r)
31 | r = struct.pack("I", 0xeedeeefe)
32 | buffer.append(r)
33 | r = bytes().join(buffer)
34 | return r
35 |
36 |
37 | sock = socket(AF_INET, SOCK_DGRAM)
38 | sock.setsockopt(SOL_SOCKET, SO_BROADCAST, 1)
39 | message = BcastCallMethod("DISCOVER")
40 | sock.sendto(message, ("255.255.255.255", port))
41 | sock.settimeout(3.0)
42 |
43 | while True:
44 | try:
45 | data, remote = sock.recvfrom(4096)
46 | except timeout:
47 | break
48 | fmt = " ${BINDIR}/gost
16 |
17 | COPY startmitm.py ${BINDIR}
18 | COPY globalmitm/entry ${BINDIR}
19 | COPY globalmitm/DNS2SOCKS.c /tmp
20 | COPY requirements.txt /tmp
21 |
22 | RUN gcc -pthread DNS2SOCKS.c -o ${BINDIR}/DNS2SOCKS
23 | RUN pip3 install -i ${PYPIMIRROR} --no-cache-dir -r requirements.txt
24 |
25 | RUN chmod 755 ${BINDIR}/*
26 | ENV PATH=${BINDIR}:${PATH}
27 |
28 | WORKDIR /root
29 | EXPOSE 53/udp 8118/tcp 1234/tcp
30 | ENTRYPOINT [ "entry" ]
--------------------------------------------------------------------------------
/tools/globalmitm/entry:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | set -e
3 | export GRPC_DNS_RESOLVER=native
4 | export PROXYPORT=${PROXYPORT:-8118}
5 |
6 | die () {
7 | echo $@; exit 1
8 | }
9 |
10 | IP=${1:-}
11 | if [ -z "${IP}" ]; then
12 | die "no device provided"
13 | fi
14 |
15 | DNS=${DNS:-8.8.8.8}
16 | PDNS=$(((RANDOM % 10000) + 10000))
17 |
18 | if [ ! -z "${SOCKS5}" ] || [ ! -z "${HTTP}" ]; then
19 | PIDS=
20 |
21 | if [ ! -z "${SOCKS5}" ]; then
22 | PHTTP=$(((RANDOM % 10000) + 10000))
23 | UPSTREAM=http://127.0.0.1:${PHTTP}
24 | gost -L=${UPSTREAM} -F=socks5://${SOCKS5} >/dev/null 2>&1 &
25 | PIDS="$PIDS $!"
26 | DNS2SOCKS ${SOCKS5} ${DNS} 127.0.0.1:${PDNS} /q &
27 | PIDS="$PIDS $!"
28 |
29 | elif [ ! -z "${HTTP}" ]; then
30 | UPSTREAM=http://${HTTP}
31 | DNS2SOCKS ${HTTP} ${DNS} 127.0.0.1:${PDNS} /t /q &
32 | PIDS="$PIDS $!"
33 |
34 | else
35 | die
36 | fi
37 |
38 | trap "kill -9 ${PIDS} 2>/dev/null" SIGINT
39 | if ! dig +time=3 google.com @127.0.0.1 -p ${PDNS}; then
40 | die "BAD PROXY (CANNOT RESOLVE THROUGH PROXY)"
41 | fi
42 |
43 | set -- "$@" --dns 127.0.0.1:${PDNS}
44 | set -- "$@" --mode upstream:${UPSTREAM}
45 | fi
46 |
47 | # common arguments
48 | set -- "$@" --web-host=0.0.0.0
49 | set -- "$@" --web-port=${WEBPORT:-1234}
50 | set -- "$@" --set block_global=false
51 |
52 | startmitm.py $@
--------------------------------------------------------------------------------
/tools/id_rsa:
--------------------------------------------------------------------------------
1 | -----BEGIN RSA PRIVATE KEY-----
2 | MIIEogIBAAKCAQEA4QHmY32OT+F+maERMn1cvBRuIOIXH9yOALG+GMCngtjRJzSR
3 | n09dInmXE+PjiAqNRWvknVEjFywv0v1v/H2qSRJKR/togPgySjiABhigqDHdirNd
4 | Dh63oN2e+d0yythoLzsQrH5BSVtw05Atpkr7bW4KdfMveWuddvDACnQ3mvCXq50X
5 | IK3cOlmHXwcJrX55BhEXxgHIqw0upf0A7DC3Afz5xjOA6+K/O2EzZIIJ+sWw7/Ko
6 | 5+3m98Et0zwcxe20uNxzYf7JSMu3490YNckLiQcDrZVRUXNS70HO9HWCXKdjFJPi
7 | GgPtKUQNHjChwzSCQQGzqitXdwa60i9Sy1U09wIBIwKCAQAzbiYIHLLQbg5PAD5x
8 | 8MS9Rn+SfNIV6UUHeRWCACZJyyh9/WMdGXRfpsNyQreqEQpZArfpcaGe5YdGK0zL
9 | /3dhKMCFe0sWKhofl+K/kJnAC2XWj2W6FaZQp69PDfz7KiZxMhJwkeMJc/yIIPR9
10 | x/70cOxyuz4NH+l6Rag8510qujhxn6lGc1+ZNHGeAYmUD7wFz9/QYDZU9C0YcylA
11 | 2+Q5woU3L4b3y3JKqB6/dnsP9uF7R5KBR+qiqOwVm0nhvVU5uwbpQwTXeklopXyN
12 | rI/NeYcsDoEyb8NquVXX/GkOgY0FhqblGUR9kSdTLHq6VamelHc+dczZgMxcsq1c
13 | mnnLAoGBAP2FPssFpHJRhSr38Fq5A7mEjQeiPq2WgYV7kCpJT5F5OymcCCETIjEH
14 | 4pTk5zCWUuIBx5LlzSa0XnQSYb0100ZzvDgfm1NPmqdkpPwkkbh2xyoHYTTPJ3WG
15 | TDur8Qyi83NteveszO1TCAGBTe3zN+2ov9qzl5Y7QHF94GVFDo4NAoGBAOM1Q8eG
16 | 0KeqjutTz/UMtejoFpz0Hi1g32PfdQInHx8MDslYu3Fcpnos3xf59H7+mrRy0fUM
17 | hh27v7DiUvxUfhlojf0F3kDKeg9VZBslZF3vTCpFdKdFouZ2Cru3lCoaPSau69BC
18 | 6HQw4P+RABrgxc6CeE9FUGEEMss+wTcRItITAoGBAO8ImkpkZ9mAD9gOV6X+5kEz
19 | 1W2Y+USVOEqns9AZPGSW4AKpDvqdAvsHbzvtxAk9RtUXnumW118B1WYf9cEG3SUr
20 | SxBYUJ8B6ZaDdvxc/mwYOCBQGdK0sCz692t2OwvqGL1J95kQo/W0r8bnoT9wSqzg
21 | 72fN5rI33azVxPHExJSPAoGAGfd1deOFj4E057HOn6muY8LAwXr8InF4nbMjULQD
22 | joUJARF0gfv1xNHtnFcUoMyj912UVoUWpE/4poBD/5SgsnJZXr7XkmBIdsfuLvz1
23 | hxQItF+1j3WsN5h2QVbPGsErj2RyuLcwgk66oN1fGQO+1cXEm1hg9SUNHorUQM7C
24 | JqMCgYEAofxXJ8dOWUaFIHmKLE7Y+0+i3D1yXVIyu/puuaQGbNFHxjcJ9ZdubhLN
25 | IyzJvngtM7mC90FtUETxvErMGdTzFeKtSKBZsJ8BiLCszRCEuJf5RX6uNrFUQ2pT
26 | PEmns088Gs4KUDwjTG0zQtj3pNc5zDynDMpFKp96spefqLJqw3s=
27 | -----END RSA PRIVATE KEY-----
--------------------------------------------------------------------------------
/tools/ida.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python3
2 | #encoding=utf-8
3 | import os
4 | import sys
5 | import time
6 | import argparse
7 | import subprocess
8 |
9 | from shlex import split as s
10 | from lamda.client import *
11 |
12 | certfile = os.environ.get("CERTIFICATE", None)
13 | port = int(os.environ.get("PORT", 65000))
14 |
15 | argp = argparse.ArgumentParser()
16 | argp.add_argument("-d", type=str, required=True)
17 | argp.add_argument("-a", type=str, required=True)
18 | args = argp.parse_args()
19 |
20 | certfile = os.environ.get("CERTIFICATE", None)
21 | d = Device(args.d, certificate=certfile)
22 |
23 | app = d.application(args.a)
24 | d.start_activity(**app.query_launch_activity(), debug=True)
25 | print (time.ctime(), "{} is started as debuggable mode".format(args.a))
26 | print (time.ctime(), "Waitting for 'Waitting For Debugger' popup")
27 | if not d(textContains="Waiting").wait_for_exists(25*1000):
28 | print (time.ctime(), "No debugger prompt detected, please ensure "\
29 | "you already run 'setdebuggable' in firerpa terminal." )
30 | exit (1)
31 |
32 | pName = app.info().processName
33 | processes = d.enumerate_running_processes()
34 | p = list(filter(lambda p: p.processName == pName,
35 | processes))[0]
36 | print (time.ctime(), "Found pid: {}".format(p.pid))
37 | # Build forward cmd
38 | print (time.ctime(), "Forwarding jwdp pid")
39 | cmd = s("adb forward tcp:8700 jdwp:%s" % p.pid)
40 | forward = subprocess.Popen(cmd, stdout=subprocess.DEVNULL,
41 | stderr=subprocess.DEVNULL,
42 | shell=False)
43 | forward.wait()
44 |
45 | print (time.ctime(), "--------------------------------")
46 | print (time.ctime(), "Now please use your IDA to attach this target")
47 | print (time.ctime(), "name: {} pid: {}".format(pName, p.pid))
48 | print (time.ctime(), "and wait for IDA 'Downloading symbols' to finish")
49 | print (time.ctime(), "when all is finished, press ENTER to continue")
50 | print (time.ctime(), "--------------------------------")
51 |
52 | _ = input()
53 |
54 | cmd = s("jdb -connect com.sun.jdi.SocketAttach:hostname=localhost,port=8700")
55 | debug = subprocess.Popen(cmd, stdin=sys.stdin,
56 | stdout=sys.stdout,
57 | stderr=sys.stderr,
58 | bufsize=0,
59 | shell=False)
60 | debug.wait()
--------------------------------------------------------------------------------
/tools/magisk/META-INF/com/google/android/update-binary:
--------------------------------------------------------------------------------
1 | #!/sbin/sh
2 | source /data/adb/magisk/util_functions.sh
3 |
4 | if [ ${MAGISK_VER_CODE} -lt 20400 ]; then
5 | abort "Please install Magisk v20.4 +"
6 | exit 1
7 | fi
8 |
9 | if [ "${BOOTMODE}" != "true" ]; then
10 | abort "Must install from Magisk app"
11 | fi
12 |
13 | OUTFD=$2
14 | ZIPFILE=$3
15 | install_module
16 | exit 0
--------------------------------------------------------------------------------
/tools/magisk/META-INF/com/google/android/updater-script:
--------------------------------------------------------------------------------
1 | #MAGISK
2 |
--------------------------------------------------------------------------------
/tools/magisk/common/server/.keep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/firerpa/lamda/fbd5e6e0ec602df622130c53abb4e87bd783e442/tools/magisk/common/server/.keep
--------------------------------------------------------------------------------
/tools/magisk/common/service.sh:
--------------------------------------------------------------------------------
1 | #!/system/bin/sh
2 | base=${0%/*}
3 | cert=/data/usr/lamda.pem
4 | launch="sh ${base}/server/bin/launch.sh"
5 | port=65000
6 |
7 | sleep 25
8 | export ca_store_remount=true
9 | if [ -f "${cert}" ]; then
10 | $launch --port=${port} --certificate=${cert}
11 | else
12 | $launch --port=${port}
13 | fi
--------------------------------------------------------------------------------
/tools/magisk/install.sh:
--------------------------------------------------------------------------------
1 | #!/system/bin/sh
2 | ABI=$(getprop ro.product.cpu.abi)
3 | SERVER=$TMPDIR/lamda-server-$ABI.tar.gz
4 | BB="/data/adb/magisk/busybox"
5 | USRDIR=/data/usr
6 |
7 | if [ -d "/data/adb/ksu/" ]; then
8 | BB="/data/adb/ksu/bin/busybox"
9 | fi
10 |
11 | export LATESTARTSERVICE=true
12 |
13 | ui_print ".____ ________ _____ "
14 | ui_print "| | _____ _____ \______ \ / _ \ "
15 | ui_print "| | \__ \ / \ | | \ / /_\ \ "
16 | ui_print "| |___ / __ \_| Y Y \ | | \/ | \ "
17 | ui_print "|_______ \(____ /|__|_| / /_______ /\____|__ / "
18 | ui_print " \/ \/ \/ \/ \/ "
19 | ui_print " installer "
20 |
21 | pushd $(pwd)
22 | cd $MODPATH
23 | if [ ! -f $SERVER ]; then
24 | abort "lamda-server-${ABI}.tar.gz not in archive, please download and drop it to common/server."
25 | fi
26 |
27 | ui_print "- Extracting server files"
28 | $BB tar -xzf $SERVER
29 |
30 | ui_print "- Placing configs"
31 | mkdir -p ${USRDIR}
32 |
33 | cp -af $TMPDIR/adb_keys ${USRDIR}/.adb_keys
34 |
35 | cp -af $TMPDIR/properties.local ${USRDIR}
36 | cp -af $TMPDIR/lamda.pem ${USRDIR}
37 |
38 | ui_print "- Please reboot your device"
39 | popd
--------------------------------------------------------------------------------
/tools/magisk/module.prop:
--------------------------------------------------------------------------------
1 | id=lamda
2 | name=LAMDA
3 | version=VERSION
4 | versionCode=VERSIONCODE
5 | author=rev1si0n
6 | description=Android reverse engineering & automation framework
--------------------------------------------------------------------------------
/tools/magisk/uninstall.sh:
--------------------------------------------------------------------------------
1 | #!/system/bin/sh
2 | MODPATH=${0%/*}
3 |
4 | echo "/data/usr will not be removed, please remove it manually"
--------------------------------------------------------------------------------
/tools/objection-1.11.0-command-patch.diff:
--------------------------------------------------------------------------------
1 | diff --git a/console/cli.py b/console/cli.py
2 | index 1fc22fb..80e52dc 100644
3 | --- a/console/cli.py
4 | +++ b/console/cli.py
5 | @@ -31,8 +31,10 @@ from ..utils.helpers import normalize_gadget_name, print_frida_connection_help,
6 | @click.option('--serial', '-S', required=False, default=None, help='A device serial to connect to.')
7 | @click.option('--debug', '-d', required=False, default=False, is_flag=True,
8 | help='Enable debug mode with verbose output. (Includes agent source map in stack traces)')
9 | +@click.option('--certificate', '-c', required=False, default=None, help="Frida connection certificate")
10 | +@click.option('--token', '-t', required=False, default=None, help="Frida connection token")
11 | def cli(network: bool, host: str, port: int, api_host: str, api_port: int,
12 | - gadget: str, serial: str, debug: bool) -> None:
13 | + gadget: str, serial: str, debug: bool, certificate: str, token: str) -> None:
14 | """
15 | \b
16 | _ _ _ _
17 | @@ -56,6 +58,8 @@ def cli(network: bool, host: str, port: int, api_host: str, api_port: int,
18 | state_connection.use_network()
19 | state_connection.host = host
20 | state_connection.port = port
21 | + state_connection.certificate = certificate
22 | + state_connection.token = token
23 |
24 | if serial:
25 | state_connection.device_serial = serial
26 | diff --git a/utils/agent.py b/utils/agent.py
27 | index 6d88e3a..fbe9b40 100644
28 | --- a/utils/agent.py
29 | +++ b/utils/agent.py
30 | @@ -126,8 +126,13 @@ class Agent(object):
31 | return device
32 |
33 | if state_connection.get_comms_type() == state_connection.TYPE_REMOTE:
34 | + kwargs = {}
35 | + if state_connection.certificate:
36 | + kwargs["certificate"] = state_connection.certificate
37 | + if state_connection.token:
38 | + kwargs["token"] = state_connection.token
39 | device = frida.get_device_manager().add_remote_device('{host}:{port}'.format(
40 | - host=state_connection.host, port=state_connection.port))
41 | + host=state_connection.host, port=state_connection.port), **kwargs)
42 | click.secho('Using networked device @`{n}`'.format(n=device.name), bold=True)
43 |
44 | return device
45 |
--------------------------------------------------------------------------------
/tools/openvpn/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM alpine:3.15
2 |
3 | LABEL maintainer="rev1si0n "
4 |
5 | ENV VARS=/etc/openvpn/easy-rsa/vars
6 | ENV OVPNCONFIG=/etc/openvpn/config.ovpn
7 | ENV SOURCESMIRROR=mirrors.ustc.edu.cn
8 |
9 | RUN sed -i "s/dl-cdn.alpinelinux.org/${SOURCESMIRROR}/g" /etc/apk/repositories
10 |
11 | COPY entry /usr/bin/run
12 | COPY ovpn-server-new /usr/bin
13 | COPY ovpn-client-profile /usr/bin
14 | COPY ovpn-client-revoke /usr/bin
15 | COPY ovpn-client-new /usr/bin
16 |
17 | COPY config.ovpn /root
18 | COPY vars /root
19 |
20 | RUN apk add openvpn easy-rsa bash curl jq
21 |
22 | RUN ln -sf /usr/share/easy-rsa/easyrsa /usr/bin/easyrsa
23 | RUN ln -sf ${VARS} /usr/share/easy-rsa/vars
24 |
25 | WORKDIR /etc/openvpn
26 |
--------------------------------------------------------------------------------
/tools/openvpn/config.ovpn:
--------------------------------------------------------------------------------
1 | # openvpn Docker image config
2 | # https://github.com/rev1si0n/lamda/tree/master/tools/openvpn
3 | #
4 | topology subnet
5 | server 172.27.27.0 255.255.255.0
6 |
7 | proto udp
8 | port 1190
9 |
10 | dev tun
11 |
12 | # 不要编辑下面几行 easy-rsa/pki 配置
13 | ca /etc/openvpn/easy-rsa/pki/ca.crt
14 | dh /etc/openvpn/easy-rsa/pki/dh.pem
15 | cert /etc/openvpn/easy-rsa/pki/issued/lamda.crt
16 | key /etc/openvpn/easy-rsa/pki/private/lamda.key
17 | crl-verify /etc/openvpn/easy-rsa/pki/crl.pem
18 |
19 | # TLS crypt 配置二选一
20 | ;tls-auth /etc/openvpn/ta.key 0
21 | tls-crypt /etc/openvpn/ta.key
22 |
23 | cipher AES-256-GCM
24 | keepalive 15 120
25 |
26 | persist-tun
27 | persist-key
28 |
29 | ifconfig-pool-persist ipp.txt 10
30 | client-to-client
31 |
32 | client-config-dir ccd
33 | script-security 2
34 |
35 | compress lz4-v2
36 | push "compress lz4-v2"
37 |
38 | max-clients 254
39 |
40 | # 如果你想路由其他服务器上的网段到客户端
41 | ;push "route 192.168.1.0 255.255.255.0"
42 |
43 | # 如果你想要让每个客户端使用特定 DNS
44 | ;push "dhcp-option DNS 114.114.114.114"
45 |
46 | verb 4
--------------------------------------------------------------------------------
/tools/openvpn/entry:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | if [ -f "${OVPNCONFIG}" ] && [ -f "${VARS}" ]; then
3 | exec openvpn --config config.ovpn
4 | fi
5 |
--------------------------------------------------------------------------------
/tools/openvpn/ovpn-client-new:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | TC_CLIENT=/etc/openvpn/tls-crypt-v2-client/$1
3 | TC_SERVER=/etc/openvpn/tls-crypt-v2-server.key
4 | openvpn --genkey tls-crypt-v2-client ${TC_CLIENT} --tls-crypt-v2 ${TC_SERVER}
5 | easyrsa build-client-full "$1" nopass
--------------------------------------------------------------------------------
/tools/openvpn/ovpn-client-profile:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | export CLIENT=$2
3 |
4 | if [ -f "easy-rsa/pki/issued/${CLIENT}.crt" ]; then
5 |
6 | CRYPT_cfg_n="$(grep -Eo '^tls-(auth|crypt|crypt-v2)' config.ovpn | wc -l)"
7 | if [ 0"${CRYPT_cfg_n}" -gt 1 ]; then
8 | echo "Multiple tls-auth/crypt/crypt-v2 config detected"; exit 1
9 | fi
10 |
11 | TLS_ENCRYPTION=
12 | if [ 0"${CRYPT_cfg_n}" -eq 1 ]; then
13 | TLS_ENCRYPTION=$(grep -Eo '^tls-(auth|crypt|crypt-v2)' config.ovpn)
14 | TLS_CRYPT=$(echo ${TLS_ENCRYPTION}|tr '-' '_')
15 | else
16 | TLS_CRYPT=tls_none
17 | fi
18 |
19 | PROTO=$(sed -n -e 's/^proto *\(.\+\).*/\1/p' config.ovpn)
20 | CIPHER=$(sed -n -e 's/^cipher *\(.\+\).*/\1/p' config.ovpn)
21 | PORT=$(sed -n -e 's/^port *\([[:digit:]]\+\).*/\1/p' config.ovpn)
22 | WANIP=$(curl -s https://httpbin.org/ip | jq -r .origin)
23 |
24 | CA=$(cat easy-rsa/pki/ca.crt)
25 | CERT=$(openssl x509 -in easy-rsa/pki/issued/${CLIENT}.crt)
26 | KEY=$(cat easy-rsa/pki/private/${CLIENT}.key)
27 |
28 | SERVER_KEY_DIRECTION_n=$(sed -n -e 's/^tls-auth *.* \([[:digit:]]\).*/\1/p' config.ovpn)
29 | if [ x"${SERVER_KEY_DIRECTION_n}"x = xx ]; then
30 | SERVER_KEY_DIRECTION_n=$(sed -n -e 's/^key-direction *\(.\+\).*/\1/p' config.ovpn)
31 | fi
32 |
33 | CLIENT_KEY_DIRECTION_n=
34 | if [ x"${SERVER_KEY_DIRECTION_n}"x != xx ]; then
35 | CLIENT_KEY_DIRECTION_n=$((1^SERVER_KEY_DIRECTION_n))
36 | fi
37 |
38 | CLIENT_KEY_DIRECTION_inline=
39 | CLIENT_KEY_DIRECTION=KEY_DIRECTION_NONE
40 | if [ x"${CLIENT_KEY_DIRECTION_n}"x != xx ]; then
41 | CLIENT_KEY_DIRECTION_inline="key-direction ${CLIENT_KEY_DIRECTION_n}"
42 | CLIENT_KEY_DIRECTION=KEY_DIRECTION_${CLIENT_KEY_DIRECTION_n}
43 | fi
44 |
45 | if [ "${TLS_ENCRYPTION}" = "tls-crypt-v2" ]; then
46 | TA=$(cat /etc/openvpn/tls-crypt-v2-client/${CLIENT})
47 | elif [ ! -z "${TLS_ENCRYPTION}" ]; then
48 | TA=$(sed '/^#/d' ta.key)
49 | else
50 | TA=
51 | fi
52 | if [ "g$1" = govpn ]; then
53 | cat <&1
54 | client
55 | float
56 | nobind
57 |
58 | dev tun
59 | proto ${PROTO}
60 | remote ${WANIP} ${PORT}
61 | resolv-retry infinite
62 |
63 | cipher ${CIPHER}
64 | keepalive 15 60
65 |
66 | remote-cert-tls server
67 |
68 | ${CLIENT_KEY_DIRECTION_inline}
69 | <${TLS_ENCRYPTION}>
70 | ${TA}
71 | ${TLS_ENCRYPTION}>
72 |
73 |
74 | ${CA}
75 |
76 |
77 |
78 | ${CERT}
79 |
80 |
81 |
82 | ${KEY}
83 |
84 | EOL
85 | else
86 | cat <&1
87 | profile = OpenVPNProfile()
88 | profile.all_traffic = False
89 | profile.proto = OpenVPNProto.${PROTO^^}
90 | profile.host = "${WANIP}"
91 | profile.port = ${PORT}
92 | profile.cipher = OpenVPNCipher.$(echo ${CIPHER}|tr '-' '_')
93 |
94 | # auto-generated lamda OpenVPN profile, CN=${CLIENT}
95 | profile.tls_encryption = OpenVPNEncryption.${TLS_CRYPT^^}
96 | profile.tls_key_direction = OpenVPNKeyDirection.${CLIENT_KEY_DIRECTION}
97 | profile.tls_key = """
98 | ${TA}
99 | """
100 |
101 | profile.ca = """
102 | ${CA}
103 | """
104 |
105 | profile.cert = """
106 | ${CERT}
107 | """
108 |
109 | profile.key = """
110 | ${KEY}
111 | """
112 |
113 | """
114 | # auto-generated lamda OpenVPN prop, CN=${CLIENT}
115 | # copy lines below to properties.local to let openvpn
116 | # auto connect when lamda started
117 | openvpn.proto=${PROTO}
118 | openvpn.cipher=${CIPHER}
119 | openvpn.global=false
120 | openvpn.host=${WANIP}
121 | openvpn.port=${PORT}
122 | openvpn.ca=$(echo -n "${CA}" | base64 -w 0)
123 | openvpn.cert=$(echo -n "${CERT}" | base64 -w 0)
124 | openvpn.key=$(echo -n "${KEY}" | base64 -w 0)
125 | openvpn.tls_encryption=${TLS_ENCRYPTION}
126 | openvpn.tls_key_direction=${CLIENT_KEY_DIRECTION_n}
127 | openvpn.tls_key=$(echo -n "${TA}" | base64 -w 0)
128 | openvpn.enable=true
129 | """
130 | EOL
131 | fi
132 | fi
133 |
--------------------------------------------------------------------------------
/tools/openvpn/ovpn-client-renew:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | easyrsa renew "$1"
--------------------------------------------------------------------------------
/tools/openvpn/ovpn-client-revoke:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | easyrsa revoke "$1"
3 | easyrsa gen-crl
--------------------------------------------------------------------------------
/tools/openvpn/ovpn-server-new:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | mkdir -p /etc/openvpn/ccd
3 | mkdir -p /etc/openvpn/easy-rsa
4 |
5 | if [ ! -f ${OVPNCONFIG} ]; then
6 | cp /root/config.ovpn ${OVPNCONFIG}
7 | fi
8 |
9 | if [ ! -f ${VARS} ]; then
10 | cp /root/vars ${VARS}
11 | fi
12 |
13 | set -ex
14 | openvpn --genkey --secret /etc/openvpn/ta.key
15 | openvpn --genkey tls-crypt-v2-server /etc/openvpn/tls-crypt-v2-server.key
16 | mkdir -p /etc/openvpn/tls-crypt-v2-client
17 |
18 | easyrsa init-pki
19 | easyrsa build-ca nopass
20 | easyrsa gen-dh
21 | easyrsa build-server-full lamda nopass
22 | easyrsa gen-crl
23 |
--------------------------------------------------------------------------------
/tools/openvpn/vars:
--------------------------------------------------------------------------------
1 | # Easy-RSA 3 parameter settings
2 |
3 | # NOTE: If you installed Easy-RSA from your distro's package manager, don't edit
4 | # this file in place -- instead, you should copy the entire easy-rsa directory
5 | # to another location so future upgrades don't wipe out your changes.
6 |
7 | # HOW TO USE THIS FILE
8 | #
9 | # vars.example contains built-in examples to Easy-RSA settings. You MUST name
10 | # this file 'vars' if you want it to be used as a configuration file. If you do
11 | # not, it WILL NOT be automatically read when you call easyrsa commands.
12 | #
13 | # It is not necessary to use this config file unless you wish to change
14 | # operational defaults. These defaults should be fine for many uses without the
15 | # need to copy and edit the 'vars' file.
16 | #
17 | # All of the editable settings are shown commented and start with the command
18 | # 'set_var' -- this means any set_var command that is uncommented has been
19 | # modified by the user. If you're happy with a default, there is no need to
20 | # define the value to its default.
21 |
22 | # NOTES FOR WINDOWS USERS
23 | #
24 | # Paths for Windows *MUST* use forward slashes, or optionally double-escaped
25 | # backslashes (single forward slashes are recommended.) This means your path to
26 | # the openssl binary might look like this:
27 | # "C:/Program Files/OpenSSL-Win32/bin/openssl.exe"
28 |
29 | # DO YOUR EDITS BELOW THIS POINT
30 |
31 | # This variable is used as the base location of configuration files needed by
32 | # easyrsa. More specific variables for specific files (e.g., EASYRSA_SSL_CONF)
33 | # may override this default.
34 | #
35 | # The default value of this variable is the location of the easyrsa script
36 | # itself, which is also where the configuration files are located in the
37 | # easy-rsa tree.
38 |
39 | set_var EASYRSA "/etc/openvpn/easy-rsa"
40 |
41 | # If your OpenSSL command is not in the system PATH, you will need to define the
42 | # path to it here. Normally this means a full path to the executable, otherwise
43 | # you could have left it undefined here and the shown default would be used.
44 | #
45 | # Windows users, remember to use paths with forward-slashes (or escaped
46 | # back-slashes.) Windows users should declare the full path to the openssl
47 | # binary here if it is not in their system PATH.
48 |
49 | set_var EASYRSA_OPENSSL "openssl"
50 | #
51 | # This sample is in Windows syntax -- edit it for your path if not using PATH:
52 | #set_var EASYRSA_OPENSSL "C:/Program Files/OpenSSL-Win32/bin/openssl.exe"
53 |
54 | # Edit this variable to point to your soon-to-be-created key directory. By
55 | # default, this will be "$PWD/pki" (i.e. the "pki" subdirectory of the
56 | # directory you are currently in).
57 | #
58 | # WARNING: init-pki will do a rm -rf on this directory so make sure you define
59 | # it correctly! (Interactive mode will prompt before acting.)
60 |
61 | set_var EASYRSA_PKI "/etc/openvpn/easy-rsa/pki"
62 |
63 | # Define directory for temporary subdirectories.
64 |
65 | set_var EASYRSA_TEMP_DIR "$EASYRSA_PKI"
66 |
67 | # Define X509 DN mode.
68 | # This is used to adjust what elements are included in the Subject field as the DN
69 | # (this is the "Distinguished Name.")
70 | # Note that in cn_only mode the Organizational fields further below aren't used.
71 | #
72 | # Choices are:
73 | # cn_only - use just a CN value
74 | # org - use the "traditional" Country/Province/City/Org/OU/email/CN format
75 |
76 | set_var EASYRSA_DN "cn_only"
77 |
78 | # Organizational fields (used with 'org' mode and ignored in 'cn_only' mode.)
79 | # These are the default values for fields which will be placed in the
80 | # certificate. Don't leave any of these fields blank, although interactively
81 | # you may omit any specific field by typing the "." symbol (not valid for
82 | # email.)
83 |
84 | set_var EASYRSA_REQ_COUNTRY ""
85 | set_var EASYRSA_REQ_PROVINCE ""
86 | set_var EASYRSA_REQ_CITY ""
87 | set_var EASYRSA_REQ_ORG ""
88 | set_var EASYRSA_REQ_OU ""
89 | set_var EASYRSA_REQ_EMAIL ""
90 |
91 | # Choose a size in bits for your keypairs. The recommended value is 2048. Using
92 | # 2048-bit keys is considered more than sufficient for many years into the
93 | # future. Larger keysizes will slow down TLS negotiation and make key/DH param
94 | # generation take much longer. Values up to 4096 should be accepted by most
95 | # software. Only used when the crypto alg is rsa (see below.)
96 |
97 | set_var EASYRSA_KEY_SIZE 2048
98 |
99 | # The default crypto mode is rsa; ec can enable elliptic curve support.
100 | # Note that not all software supports ECC, so use care when enabling it.
101 | # Choices for crypto alg are: (each in lower-case)
102 | # * rsa
103 | # * ec
104 | # * ed
105 |
106 | #set_var EASYRSA_ALGO rsa
107 |
108 | # Define the named curve, used in ec & ed modes:
109 |
110 | #set_var EASYRSA_CURVE secp384r1
111 |
112 | # In how many days should the root CA key expire?
113 |
114 | # 50 years
115 | set_var EASYRSA_CA_EXPIRE 18250
116 |
117 | # In how many days should certificates expire?
118 |
119 | set_var EASYRSA_CERT_EXPIRE 3650
120 |
121 | # How many days until the next CRL publish date? Note that the CRL can still be
122 | # parsed after this timeframe passes. It is only used for an expected next
123 | # publication date.
124 | set_var EASYRSA_CRL_DAYS 3650
125 |
126 | # How many days before its expiration date a certificate is allowed to be
127 | # renewed?
128 | set_var EASYRSA_CERT_RENEW 30
129 |
130 | # Random serial numbers by default, set to no for the old incremental serial numbers
131 | #
132 | #set_var EASYRSA_RAND_SN "yes"
133 |
134 | # Support deprecated "Netscape" extensions? (choices "yes" or "no".) The default
135 | # is "no" to discourage use of deprecated extensions. If you require this
136 | # feature to use with --ns-cert-type, set this to "yes" here. This support
137 | # should be replaced with the more modern --remote-cert-tls feature. If you do
138 | # not use --ns-cert-type in your configs, it is safe (and recommended) to leave
139 | # this defined to "no". When set to "yes", server-signed certs get the
140 | # nsCertType=server attribute, and also get any NS_COMMENT defined below in the
141 | # nsComment field.
142 |
143 | #set_var EASYRSA_NS_SUPPORT "no"
144 |
145 | # When NS_SUPPORT is set to "yes", this field is added as the nsComment field.
146 | # Set this blank to omit it. With NS_SUPPORT set to "no" this field is ignored.
147 |
148 | #set_var EASYRSA_NS_COMMENT "Easy-RSA Generated Certificate"
149 |
150 | # A temp file used to stage cert extensions during signing. The default should
151 | # be fine for most users; however, some users might want an alternative under a
152 | # RAM-based FS, such as /dev/shm or /tmp on some systems.
153 |
154 | #set_var EASYRSA_TEMP_FILE "$EASYRSA_PKI/extensions.temp"
155 |
156 | # !!
157 | # NOTE: ADVANCED OPTIONS BELOW THIS POINT
158 | # PLAY WITH THEM AT YOUR OWN RISK
159 | # !!
160 |
161 | # Broken shell command aliases: If you have a largely broken shell that is
162 | # missing any of these POSIX-required commands used by Easy-RSA, you will need
163 | # to define an alias to the proper path for the command. The symptom will be
164 | # some form of a 'command not found' error from your shell. This means your
165 | # shell is BROKEN, but you can hack around it here if you really need. These
166 | # shown values are not defaults: it is up to you to know what you're doing if
167 | # you touch these.
168 | #
169 | #alias awk="/alt/bin/awk"
170 | #alias cat="/alt/bin/cat"
171 |
172 | # X509 extensions directory:
173 | # If you want to customize the X509 extensions used, set the directory to look
174 | # for extensions here. Each cert type you sign must have a matching filename,
175 | # and an optional file named 'COMMON' is included first when present. Note that
176 | # when undefined here, default behaviour is to look in $EASYRSA_PKI first, then
177 | # fallback to $EASYRSA for the 'x509-types' dir. You may override this
178 | # detection with an explicit dir here.
179 | #
180 | set_var EASYRSA_EXT_DIR "/usr/share/easy-rsa/x509-types"
181 |
182 | # If you want to generate KDC certificates, you need to set the realm here.
183 | #set_var EASYRSA_KDC_REALM "CHANGEME.EXAMPLE.COM"
184 |
185 | # OpenSSL config file:
186 | # If you need to use a specific openssl config file, you can reference it here.
187 | # Normally this file is auto-detected from a file named openssl-easyrsa.cnf from the
188 | # EASYRSA_PKI or EASYRSA dir (in that order.) NOTE that this file is Easy-RSA
189 | # specific and you cannot just use a standard config file, so this is an
190 | # advanced feature.
191 |
192 | set_var EASYRSA_SSL_CONF "/usr/share/easy-rsa/openssl-easyrsa.cnf"
193 |
194 | # Default CN:
195 | # This is best left alone. Interactively you will set this manually, and BATCH
196 | # callers are expected to set this themselves.
197 |
198 | set_var EASYRSA_REQ_CN "LAMDA"
199 |
200 | # Cryptographic digest to use.
201 | # Do not change this default unless you understand the security implications.
202 | # Valid choices include: md5, sha1, sha256, sha224, sha384, sha512
203 |
204 | #set_var EASYRSA_DIGEST "sha256"
205 |
206 | # Batch mode. Leave this disabled unless you intend to call Easy-RSA explicitly
207 | # in batch mode without any user input, confirmation on dangerous operations,
208 | # or most output. Setting this to any non-blank string enables batch mode.
209 |
210 | set_var EASYRSA_BATCH "yes"
211 |
--------------------------------------------------------------------------------
/tools/paddle_ocr_http_api.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python3
2 | # THIS IS EXAMPLE HTTP OCR BACKEND,
3 | # DO NOT USE IN PRODUCTION
4 | import uvicorn
5 | import asyncio
6 | import paddle as paddle
7 | from paddleocr import PaddleOCR
8 | from fastapi import FastAPI, Request
9 |
10 | app = FastAPI()
11 |
12 |
13 | @app.post("/ocr")
14 | async def ocr(request: Request):
15 | image = await request.body()
16 | r = await asyncio.to_thread(ocr.ocr, image)
17 | n = bool(r and r[0] and type(r[0][-1])==float)
18 | result = (r if n else r[0]) or []
19 | output = [[n[0], n[1][0], n[1][1]] for n in result]
20 | return output
21 |
22 |
23 | if __name__ == "__main__":
24 | ocr = PaddleOCR(use_gpu=False, drop_score=0.85,
25 | use_space_char=True)
26 | uvicorn.run(app, host="0.0.0.0", port=8000)
--------------------------------------------------------------------------------
/tools/requirements.txt:
--------------------------------------------------------------------------------
1 | mitmproxy>=9.0.0,<=10.2.0
2 | dnspython
3 | httpx[socks]<0.28.0
4 | packaging
5 | Pillow
--------------------------------------------------------------------------------
/tools/root.crt:
--------------------------------------------------------------------------------
1 | -----BEGIN CERTIFICATE-----
2 | MIIClDCCAXwCAQAwDQYJKoZIhvcNAQELBQAwEDEOMAwGA1UECgwFTEFNREEwHhcN
3 | MjAwMTAxMDAwMDAxWhcNMjkxMjI5MDAwMDAxWjAQMQ4wDAYDVQQKDAVMQU1EQTCC
4 | ASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALnqfBZvrGZaqgk5msCRRpPz
5 | p/+464jBknlmTKetOckDTUq8V6fH/2Gfb6HjjoD5pkCtD5mSKkaHNhuxLXsFfEfc
6 | Klmnn3ZpjyNOHEA/iAO2DyEYa08xSevM7WojbF7cNj5/DYg7eb0i0+//bBlh8nlO
7 | ghSUhCTM5PCofLDU8sVXuYAiGU6UzBrIC0vHEltDkiJVLpcCtsKjEZOskPdAc7u6
8 | /aA0P5GonZ5UkRDYpa+jeJUabqWZQQEgtmvjlmUUiXwu0jRnj1n0T3fPQD3gA+LI
9 | vAE9vgvpY5XQj6otpBvsZ3MJJNKcUMQu1zOANTzO18TlA8KoBNsBy8Z9DQZKXF8C
10 | AwEAATANBgkqhkiG9w0BAQsFAAOCAQEAeGn/NyqIRI/0AGqvHP97KtQ76Tj6achb
11 | 30LIXWp+YHUaMeAVjd2Z7jSQp5mZZFl+k1fb337IeaGXofVI21eK52QX2teNoBkA
12 | /V/O1Hu35/+aiz0xsdD6wWvwo4Fy1jlmaeJhwdQacBlDGFA2jFJxuEpahfxZvUsb
13 | 3j5zU0WKTUCfEDgXFwBw12xku/7TMdCEbRsYaZ3zFTC226lQbUDN7weqFwSD+tB6
14 | RuhIxe8+cFwAsAWHClerKgZnr3t5QF078pW2GHy8CsJ7V3MZT5lZ43lS5NIB9JzZ
15 | SYxZ/izhRyh5qR73uAgsJaL56Bj+cQqnoTqhLZVl7J+M6WhWKzojsA==
16 | -----END CERTIFICATE-----
17 |
--------------------------------------------------------------------------------
/tools/root.key:
--------------------------------------------------------------------------------
1 | -----BEGIN PRIVATE KEY-----
2 | MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQC56nwWb6xmWqoJ
3 | OZrAkUaT86f/uOuIwZJ5ZkynrTnJA01KvFenx/9hn2+h446A+aZArQ+ZkipGhzYb
4 | sS17BXxH3CpZp592aY8jThxAP4gDtg8hGGtPMUnrzO1qI2xe3DY+fw2IO3m9ItPv
5 | /2wZYfJ5ToIUlIQkzOTwqHyw1PLFV7mAIhlOlMwayAtLxxJbQ5IiVS6XArbCoxGT
6 | rJD3QHO7uv2gND+RqJ2eVJEQ2KWvo3iVGm6lmUEBILZr45ZlFIl8LtI0Z49Z9E93
7 | z0A94APiyLwBPb4L6WOV0I+qLaQb7GdzCSTSnFDELtczgDU8ztfE5QPCqATbAcvG
8 | fQ0GSlxfAgMBAAECggEAUVmJj3Ww7Z6JXXz/ung29kE9BxfetBnjYkyBiTMyoELa
9 | HLQZ9Nf95rURbzh3n/bdKNqxA0UiS3cZlXdrC7QERBtRyqYej/0zfULN+Mzz0o/k
10 | wdoCBoZuLogecH1si3t3HtSQUsaXh8uICjFtFxQ1OaBBKgksYz/mg2luGiAr1G5F
11 | yzCjKOpPo9rjgka0OMx5PnHjd9d6rf2ckB9VlLxxEVaYoGnXJTAe+FU0sWIFIfZY
12 | E1kknQ9F+MegGEZyE/r8kRUm4+81WWPChwWlXT8TpHp1HXtI0j9PY4vlWjDBB2cO
13 | 6w8nPiHT3Hy0BYpa3Vee7a9kHljLa3ZBgq2DMnoaqQKBgQDVGKAuRbQ7CXRinRou
14 | Lh/iDwzdWLVfIB/EpClZqhIQt+YcuqKixvBtlksRewJfC7lbSM5rcNYp+NFq2z1F
15 | ol6EezmVcylAfHf9jHJrY37uR7ilwJnl7FMqNAw6hwRUm2Zhj+PgWPCVO8VpRBFE
16 | j80fLhD1rrD3TqBBvQGTs6h2OQKBgQDfWPBgFTJsgmp6XLsgLiahAKVVtHQk4lXI
17 | 7WytdNgrf7U9rT9hGsRc5TJ/BagnUKRe3u/oIxnFw3QgFg1vPRWGxd8ckA3F4Z9V
18 | RgMUJcvnSDoLNctd19sXclC7KAIEAg5VZEEPPXFrmudlbO7AVDZ2/nqWsVxbJ4ie
19 | PolKMkOnVwKBgHhBRWPXgjYux7c+4R9eeC+iPqhK/0+HWWYnHg6zoy48GWftCwrB
20 | Kb0uK37Z5CSvARM6qwKG0tUszUF4J8O8NYqd34kvTABQPYagU5G2vFLLtrATWMYf
21 | 727JoH0G5LK6X7R+9yIMDviommclOnlujVsjK/75bnShsl5mwxUPNepBAoGBAIW0
22 | V4odhmchF58S3k7gce2WVmPdOF5QRGyZfaLFPRelRxmaGkQGYyD9cGJMP6LxisTk
23 | jxgX0zjpzh3bNcWu+rEIyYzuy9/3Now08mjgS5W0TlMhrBIMw7Lgk2XHCJXfqTcD
24 | YlM+RCTXwcidErx+bXCE3VxS5ugG3all5IhPWOLXAoGBAJ+qUklRlmmTds7RhpeH
25 | dX8UlAW8/AtJfTfWoA5EPLX8jZp2v8FSSKk4OME95jVS6G8mAevHjdpaw1iwrxDX
26 | szwh9hcWxT4i2HrAwYMI2HM0HqEIjgCx+1kzDrcdsU96rLDhbaRoN9JBMh3yHI05
27 | H0KRgTsIBx2u3aMQAe3AHZOd
28 | -----END PRIVATE KEY-----
29 |
--------------------------------------------------------------------------------
/tools/rsync.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | [ $# -lt 2 ] && exit 1
3 | DEFAULT_ID_RSA=$(mktemp)
4 | PORT=${PORT:-65000}
5 | case "$1" in
6 | *':'*)
7 | p1=root@$1
8 | p2=$2
9 | ;;
10 | *)
11 | p1=$1
12 | p2=root@$2
13 | ;;
14 | esac
15 | umask 077
16 | if [ ! -f "${CERTIFICATE}" ]; then
17 | # this is the default id_rsa for ssh service
18 | cat <$DEFAULT_ID_RSA
19 | -----BEGIN RSA PRIVATE KEY-----
20 | MIIEogIBAAKCAQEA4QHmY32OT+F+maERMn1cvBRuIOIXH9yOALG+GMCngtjRJzSR
21 | n09dInmXE+PjiAqNRWvknVEjFywv0v1v/H2qSRJKR/togPgySjiABhigqDHdirNd
22 | Dh63oN2e+d0yythoLzsQrH5BSVtw05Atpkr7bW4KdfMveWuddvDACnQ3mvCXq50X
23 | IK3cOlmHXwcJrX55BhEXxgHIqw0upf0A7DC3Afz5xjOA6+K/O2EzZIIJ+sWw7/Ko
24 | 5+3m98Et0zwcxe20uNxzYf7JSMu3490YNckLiQcDrZVRUXNS70HO9HWCXKdjFJPi
25 | GgPtKUQNHjChwzSCQQGzqitXdwa60i9Sy1U09wIBIwKCAQAzbiYIHLLQbg5PAD5x
26 | 8MS9Rn+SfNIV6UUHeRWCACZJyyh9/WMdGXRfpsNyQreqEQpZArfpcaGe5YdGK0zL
27 | /3dhKMCFe0sWKhofl+K/kJnAC2XWj2W6FaZQp69PDfz7KiZxMhJwkeMJc/yIIPR9
28 | x/70cOxyuz4NH+l6Rag8510qujhxn6lGc1+ZNHGeAYmUD7wFz9/QYDZU9C0YcylA
29 | 2+Q5woU3L4b3y3JKqB6/dnsP9uF7R5KBR+qiqOwVm0nhvVU5uwbpQwTXeklopXyN
30 | rI/NeYcsDoEyb8NquVXX/GkOgY0FhqblGUR9kSdTLHq6VamelHc+dczZgMxcsq1c
31 | mnnLAoGBAP2FPssFpHJRhSr38Fq5A7mEjQeiPq2WgYV7kCpJT5F5OymcCCETIjEH
32 | 4pTk5zCWUuIBx5LlzSa0XnQSYb0100ZzvDgfm1NPmqdkpPwkkbh2xyoHYTTPJ3WG
33 | TDur8Qyi83NteveszO1TCAGBTe3zN+2ov9qzl5Y7QHF94GVFDo4NAoGBAOM1Q8eG
34 | 0KeqjutTz/UMtejoFpz0Hi1g32PfdQInHx8MDslYu3Fcpnos3xf59H7+mrRy0fUM
35 | hh27v7DiUvxUfhlojf0F3kDKeg9VZBslZF3vTCpFdKdFouZ2Cru3lCoaPSau69BC
36 | 6HQw4P+RABrgxc6CeE9FUGEEMss+wTcRItITAoGBAO8ImkpkZ9mAD9gOV6X+5kEz
37 | 1W2Y+USVOEqns9AZPGSW4AKpDvqdAvsHbzvtxAk9RtUXnumW118B1WYf9cEG3SUr
38 | SxBYUJ8B6ZaDdvxc/mwYOCBQGdK0sCz692t2OwvqGL1J95kQo/W0r8bnoT9wSqzg
39 | 72fN5rI33azVxPHExJSPAoGAGfd1deOFj4E057HOn6muY8LAwXr8InF4nbMjULQD
40 | joUJARF0gfv1xNHtnFcUoMyj912UVoUWpE/4poBD/5SgsnJZXr7XkmBIdsfuLvz1
41 | hxQItF+1j3WsN5h2QVbPGsErj2RyuLcwgk66oN1fGQO+1cXEm1hg9SUNHorUQM7C
42 | JqMCgYEAofxXJ8dOWUaFIHmKLE7Y+0+i3D1yXVIyu/puuaQGbNFHxjcJ9ZdubhLN
43 | IyzJvngtM7mC90FtUETxvErMGdTzFeKtSKBZsJ8BiLCszRCEuJf5RX6uNrFUQ2pT
44 | PEmns088Gs4KUDwjTG0zQtj3pNc5zDynDMpFKp96spefqLJqw3s=
45 | -----END RSA PRIVATE KEY-----
46 | EOL
47 | else
48 | DEFAULT_ID_RSA=$CERTIFICATE
49 | fi
50 | exec rsync -avz ${@:3} -e "ssh -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -o LogLevel=ERROR -i $DEFAULT_ID_RSA -p $PORT" $p1 $p2
51 |
--------------------------------------------------------------------------------
/tools/scp.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | [ $# -lt 2 ] && exit 1
3 | DEFAULT_ID_RSA=$(mktemp)
4 | PORT=${PORT:-65000}
5 | case "$1" in
6 | *':'*)
7 | p1=root@$1
8 | p2=$2
9 | ;;
10 | *)
11 | p1=$1
12 | p2=root@$2
13 | ;;
14 | esac
15 | umask 077
16 | if [ ! -f "${CERTIFICATE}" ]; then
17 | # this is the default id_rsa for ssh service
18 | cat <$DEFAULT_ID_RSA
19 | -----BEGIN RSA PRIVATE KEY-----
20 | MIIEogIBAAKCAQEA4QHmY32OT+F+maERMn1cvBRuIOIXH9yOALG+GMCngtjRJzSR
21 | n09dInmXE+PjiAqNRWvknVEjFywv0v1v/H2qSRJKR/togPgySjiABhigqDHdirNd
22 | Dh63oN2e+d0yythoLzsQrH5BSVtw05Atpkr7bW4KdfMveWuddvDACnQ3mvCXq50X
23 | IK3cOlmHXwcJrX55BhEXxgHIqw0upf0A7DC3Afz5xjOA6+K/O2EzZIIJ+sWw7/Ko
24 | 5+3m98Et0zwcxe20uNxzYf7JSMu3490YNckLiQcDrZVRUXNS70HO9HWCXKdjFJPi
25 | GgPtKUQNHjChwzSCQQGzqitXdwa60i9Sy1U09wIBIwKCAQAzbiYIHLLQbg5PAD5x
26 | 8MS9Rn+SfNIV6UUHeRWCACZJyyh9/WMdGXRfpsNyQreqEQpZArfpcaGe5YdGK0zL
27 | /3dhKMCFe0sWKhofl+K/kJnAC2XWj2W6FaZQp69PDfz7KiZxMhJwkeMJc/yIIPR9
28 | x/70cOxyuz4NH+l6Rag8510qujhxn6lGc1+ZNHGeAYmUD7wFz9/QYDZU9C0YcylA
29 | 2+Q5woU3L4b3y3JKqB6/dnsP9uF7R5KBR+qiqOwVm0nhvVU5uwbpQwTXeklopXyN
30 | rI/NeYcsDoEyb8NquVXX/GkOgY0FhqblGUR9kSdTLHq6VamelHc+dczZgMxcsq1c
31 | mnnLAoGBAP2FPssFpHJRhSr38Fq5A7mEjQeiPq2WgYV7kCpJT5F5OymcCCETIjEH
32 | 4pTk5zCWUuIBx5LlzSa0XnQSYb0100ZzvDgfm1NPmqdkpPwkkbh2xyoHYTTPJ3WG
33 | TDur8Qyi83NteveszO1TCAGBTe3zN+2ov9qzl5Y7QHF94GVFDo4NAoGBAOM1Q8eG
34 | 0KeqjutTz/UMtejoFpz0Hi1g32PfdQInHx8MDslYu3Fcpnos3xf59H7+mrRy0fUM
35 | hh27v7DiUvxUfhlojf0F3kDKeg9VZBslZF3vTCpFdKdFouZ2Cru3lCoaPSau69BC
36 | 6HQw4P+RABrgxc6CeE9FUGEEMss+wTcRItITAoGBAO8ImkpkZ9mAD9gOV6X+5kEz
37 | 1W2Y+USVOEqns9AZPGSW4AKpDvqdAvsHbzvtxAk9RtUXnumW118B1WYf9cEG3SUr
38 | SxBYUJ8B6ZaDdvxc/mwYOCBQGdK0sCz692t2OwvqGL1J95kQo/W0r8bnoT9wSqzg
39 | 72fN5rI33azVxPHExJSPAoGAGfd1deOFj4E057HOn6muY8LAwXr8InF4nbMjULQD
40 | joUJARF0gfv1xNHtnFcUoMyj912UVoUWpE/4poBD/5SgsnJZXr7XkmBIdsfuLvz1
41 | hxQItF+1j3WsN5h2QVbPGsErj2RyuLcwgk66oN1fGQO+1cXEm1hg9SUNHorUQM7C
42 | JqMCgYEAofxXJ8dOWUaFIHmKLE7Y+0+i3D1yXVIyu/puuaQGbNFHxjcJ9ZdubhLN
43 | IyzJvngtM7mC90FtUETxvErMGdTzFeKtSKBZsJ8BiLCszRCEuJf5RX6uNrFUQ2pT
44 | PEmns088Gs4KUDwjTG0zQtj3pNc5zDynDMpFKp96spefqLJqw3s=
45 | -----END RSA PRIVATE KEY-----
46 | EOL
47 | else
48 | DEFAULT_ID_RSA=$CERTIFICATE
49 | fi
50 | ssh-add $DEFAULT_ID_RSA >/dev/null 2>&1 || true
51 | exec scp -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no \
52 | -o LogLevel=ERROR -i $DEFAULT_ID_RSA -P $PORT -pr $p1 $p2
53 |
--------------------------------------------------------------------------------
/tools/socks5/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM alpine:3.15
2 | # this will produce large image but IDC
3 | LABEL maintainer="rev1si0n "
4 |
5 | ENV SOURCESMIRROR=mirrors.ustc.edu.cn
6 | RUN sed -i "s/dl-cdn.alpinelinux.org/${SOURCESMIRROR}/g" /etc/apk/repositories
7 |
8 | COPY entry /usr/bin
9 |
10 | RUN apk add bash make g++ git
11 |
12 | RUN mkdir -p /tmp/workdir
13 | WORKDIR /tmp/workdir
14 |
15 | RUN wget https://www.inet.no/dante/files/dante-1.4.3.tar.gz -O - | tar -xz
16 | WORKDIR /tmp/workdir/dante-1.4.3
17 |
18 | ENV ac_cv_func_sched_setscheduler=no
19 | RUN ./configure --disable-client && make -j $(nproc)
20 | RUN cp sockd/sockd /usr/bin
21 |
22 | RUN rm -rf /tmp/workdir
23 |
24 | WORKDIR /
25 |
26 | EXPOSE 1080/tcp 1080/udp 50000:55000/udp
27 | ENTRYPOINT ["entry"]
28 |
--------------------------------------------------------------------------------
/tools/socks5/entry:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | LOGIN=${LOGIN:-lamda}
3 | PWD=${PASSWORD:-lamda}
4 | UDPRANGE=${UDPRANGE:-50000-55000}
5 | BIND=${BIND:-0.0.0.0}
6 | PORT=${PORT:-1080}
7 |
8 | # the default output interface
9 | DEFAULT_DEV=$(ip route | awk '/default/ { print $5 }')
10 | DEV=${DEV:-"${DEFAULT_DEV}"}
11 |
12 | deluser --remove-home ${LOGIN} 2>/dev/null
13 | adduser -D -H -s /bin/false ${LOGIN} 2>/dev/null
14 | echo "${LOGIN}:${PWD}" | chpasswd 2>/dev/null
15 |
16 | echo "SOCKS5 LOGIN: ${LOGIN}"
17 | echo "SOCKS5 PASSWORD: ${PWD}"
18 |
19 | cat </etc/danted.conf
20 | internal: ${BIND} port = ${PORT}
21 | external: ${DEV}
22 |
23 | clientmethod: none
24 | socksmethod: username
25 |
26 | user.privileged: root
27 | user.unprivileged: nobody
28 |
29 | timeout.tcp_fin_wait: 15
30 | timeout.negotiate: 15
31 | timeout.connect: 15
32 |
33 | logoutput: /proc/self/fd/2
34 |
35 | socks pass {
36 | from: 0.0.0.0/0 to: 0.0.0.0/0
37 | command: bind connect udpassociate
38 | udp.portrange: ${UDPRANGE}
39 | log: error connect
40 | }
41 |
42 | socks pass {
43 | from: 0.0.0.0/0 to: 0.0.0.0/0
44 | command: bindreply udpreply
45 | udp.portrange: ${UDPRANGE}
46 | log: error connect
47 | }
48 |
49 | client pass {
50 | from: 0.0.0.0/0 to: 0.0.0.0/0
51 | log: error
52 | }
53 | EOL
54 |
55 | exec sockd -f /etc/danted.conf
--------------------------------------------------------------------------------
/tools/ssh.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | TARGET=${1:-localhost}
3 | PORT=${PORT:-65000}
4 | DEFAULT_ID_RSA=$(mktemp)
5 |
6 | umask 077
7 | if [ ! -f "${CERTIFICATE}" ]; then
8 | # this is the default id_rsa for ssh service
9 | cat <$DEFAULT_ID_RSA
10 | -----BEGIN RSA PRIVATE KEY-----
11 | MIIEogIBAAKCAQEA4QHmY32OT+F+maERMn1cvBRuIOIXH9yOALG+GMCngtjRJzSR
12 | n09dInmXE+PjiAqNRWvknVEjFywv0v1v/H2qSRJKR/togPgySjiABhigqDHdirNd
13 | Dh63oN2e+d0yythoLzsQrH5BSVtw05Atpkr7bW4KdfMveWuddvDACnQ3mvCXq50X
14 | IK3cOlmHXwcJrX55BhEXxgHIqw0upf0A7DC3Afz5xjOA6+K/O2EzZIIJ+sWw7/Ko
15 | 5+3m98Et0zwcxe20uNxzYf7JSMu3490YNckLiQcDrZVRUXNS70HO9HWCXKdjFJPi
16 | GgPtKUQNHjChwzSCQQGzqitXdwa60i9Sy1U09wIBIwKCAQAzbiYIHLLQbg5PAD5x
17 | 8MS9Rn+SfNIV6UUHeRWCACZJyyh9/WMdGXRfpsNyQreqEQpZArfpcaGe5YdGK0zL
18 | /3dhKMCFe0sWKhofl+K/kJnAC2XWj2W6FaZQp69PDfz7KiZxMhJwkeMJc/yIIPR9
19 | x/70cOxyuz4NH+l6Rag8510qujhxn6lGc1+ZNHGeAYmUD7wFz9/QYDZU9C0YcylA
20 | 2+Q5woU3L4b3y3JKqB6/dnsP9uF7R5KBR+qiqOwVm0nhvVU5uwbpQwTXeklopXyN
21 | rI/NeYcsDoEyb8NquVXX/GkOgY0FhqblGUR9kSdTLHq6VamelHc+dczZgMxcsq1c
22 | mnnLAoGBAP2FPssFpHJRhSr38Fq5A7mEjQeiPq2WgYV7kCpJT5F5OymcCCETIjEH
23 | 4pTk5zCWUuIBx5LlzSa0XnQSYb0100ZzvDgfm1NPmqdkpPwkkbh2xyoHYTTPJ3WG
24 | TDur8Qyi83NteveszO1TCAGBTe3zN+2ov9qzl5Y7QHF94GVFDo4NAoGBAOM1Q8eG
25 | 0KeqjutTz/UMtejoFpz0Hi1g32PfdQInHx8MDslYu3Fcpnos3xf59H7+mrRy0fUM
26 | hh27v7DiUvxUfhlojf0F3kDKeg9VZBslZF3vTCpFdKdFouZ2Cru3lCoaPSau69BC
27 | 6HQw4P+RABrgxc6CeE9FUGEEMss+wTcRItITAoGBAO8ImkpkZ9mAD9gOV6X+5kEz
28 | 1W2Y+USVOEqns9AZPGSW4AKpDvqdAvsHbzvtxAk9RtUXnumW118B1WYf9cEG3SUr
29 | SxBYUJ8B6ZaDdvxc/mwYOCBQGdK0sCz692t2OwvqGL1J95kQo/W0r8bnoT9wSqzg
30 | 72fN5rI33azVxPHExJSPAoGAGfd1deOFj4E057HOn6muY8LAwXr8InF4nbMjULQD
31 | joUJARF0gfv1xNHtnFcUoMyj912UVoUWpE/4poBD/5SgsnJZXr7XkmBIdsfuLvz1
32 | hxQItF+1j3WsN5h2QVbPGsErj2RyuLcwgk66oN1fGQO+1cXEm1hg9SUNHorUQM7C
33 | JqMCgYEAofxXJ8dOWUaFIHmKLE7Y+0+i3D1yXVIyu/puuaQGbNFHxjcJ9ZdubhLN
34 | IyzJvngtM7mC90FtUETxvErMGdTzFeKtSKBZsJ8BiLCszRCEuJf5RX6uNrFUQ2pT
35 | PEmns088Gs4KUDwjTG0zQtj3pNc5zDynDMpFKp96spefqLJqw3s=
36 | -----END RSA PRIVATE KEY-----
37 | EOL
38 | else
39 | DEFAULT_ID_RSA=$CERTIFICATE
40 | fi
41 | ssh-add $DEFAULT_ID_RSA >/dev/null 2>&1 || true
42 | exec ssh -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no \
43 | -o LogLevel=ERROR -i $DEFAULT_ID_RSA -p $PORT root@$TARGET ${@:2}
44 |
--------------------------------------------------------------------------------
/tools/startmitm.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/firerpa/lamda/fbd5e6e0ec602df622130c53abb4e87bd783e442/tools/startmitm.ico
--------------------------------------------------------------------------------
/tools/startmitm.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python3
2 | # Copyright 2024 rev1si0n (lamda.devel@gmail.com). All rights reserved.
3 | #
4 | # Distributed under MIT license.
5 | # See file LICENSE for detail or copy at https://opensource.org/licenses/MIT
6 | #encoding=utf-8
7 | import os
8 | import re
9 | import sys
10 | import time
11 | import logging
12 | import subprocess
13 | import argparse
14 | import uuid
15 | import asyncio
16 | import threading
17 | import dns.message
18 | import dns.query
19 | import httpx
20 |
21 | from socket import *
22 | from random import randint
23 | from multiprocessing import Process
24 | from urllib.parse import urlparse
25 | from functools import partial
26 |
27 | from mitmproxy.certs import CertStore
28 | from mitmproxy.tools.main import mitmweb as web
29 | from mitmproxy.options import CONF_DIR, CONF_BASENAME, KEY_SIZE
30 | from mitmproxy.version import VERSION
31 |
32 | from packaging.version import parse as ver
33 |
34 | from lamda import __version__
35 | from lamda.client import *
36 |
37 |
38 | serial = None
39 | cleaning = False
40 | def cleanup(*args, **kwargs):
41 | global cleaning
42 | if cleaning is True:
43 | return
44 | cleaning = True
45 | log ("uninstall certificate")
46 | d.uninstall_ca_certificate(ca)
47 | log ("disable proxy")
48 | d.stop_gproxy()
49 | os._exit (0)
50 |
51 |
52 | def is_doh(server):
53 | u = urlparse(server)
54 | return u.scheme in ("http", "https")
55 |
56 |
57 | def fmt_rdns(dns, lport):
58 | return "reverse:dns://{}@{}".format(dns, lport)
59 |
60 |
61 | class DOHProxiedProtocol(asyncio.Protocol):
62 | def __init__(self, loop, server, proxy):
63 | self.server = server
64 | log ("using DOH: {}".format(server))
65 | self.client = httpx.Client(proxies=proxy)
66 | self.loop = loop
67 | def datagram_received(self, pkt, addr):
68 | self.loop.create_task(self.handle(pkt, addr))
69 | def connection_made(self, transport):
70 | self.transport = transport
71 | async def handle(self, pkt, addr):
72 | res = await self.loop.run_in_executor(None,
73 | self.dns_query, pkt)
74 | self.transport.sendto(res, addr)
75 | def dns_query(self, pkt):
76 | res = dns.message.from_wire(pkt)
77 | res = dns.query.https(res, self.server,
78 | session=self.client)
79 | return res.to_wire()
80 | @classmethod
81 | def start(cls, *args, **kwargs):
82 | dns = threading.Thread(target=cls._start,
83 | args=args, kwargs=kwargs)
84 | dns.daemon = True
85 | dns.start()
86 | @classmethod
87 | def _start(cls, bind, port, upstream, proxy=None):
88 | loop = asyncio.new_event_loop()
89 | factory = partial(cls, loop, upstream, proxy)
90 | coro = loop.create_datagram_endpoint(factory,
91 | local_addr=(bind, port))
92 | loop.run_until_complete(coro)
93 | loop.run_forever()
94 |
95 |
96 | def setup_dns_upstream(args):
97 | port = randint(28080, 58080)
98 | dns = "{}:{}".format("127.0.0.1", port)
99 | DOHProxiedProtocol.start(
100 | "127.0.0.1",
101 | port,
102 | args.dns,
103 | args.upstream)
104 | args.dns = fmt_rdns(dns, proxy)
105 |
106 |
107 | def add_server(command, spec):
108 | spec and command.append("--mode")
109 | spec and command.append(spec)
110 |
111 |
112 | def add_upstream(args, ext):
113 | u = urlparse(args.upstream)
114 | upstream = "upstream:{}://{}:{}".format(u.scheme,
115 | u.hostname,
116 | u.port)
117 | args.mode = upstream
118 | cred = "{}:{}".format(u.username, u.password)
119 | u.username and ext.append("--upstream-auth")
120 | u.username and ext.append(cred)
121 |
122 |
123 | def log(*args):
124 | print (time.ctime(), *args)
125 |
126 |
127 | def die(*args):
128 | print (time.ctime(), *args)
129 | sys.exit (1)
130 |
131 |
132 | def adb(*args):
133 | command = ["adb"]
134 | if serial is not None:
135 | command.extend(["-s", serial])
136 | command.extend(args)
137 | log (" ".join(command))
138 | proc = subprocess.Popen(command)
139 | return proc
140 |
141 |
142 | def adb_tcp(action, aport, bport):
143 | p = adb(action, "tcp:{}".format(aport),
144 | "tcp:{}".format(bport))
145 | return p
146 |
147 |
148 | def reverse(aport, bport):
149 | return adb_tcp("reverse", aport, bport)
150 |
151 |
152 | def forward(aport, bport):
153 | return adb_tcp("forward", aport, bport)
154 |
155 |
156 | def get_default_interface_ip_imp(target):
157 | s = socket(AF_INET, SOCK_DGRAM)
158 | s.connect(( target, lamda ))
159 | return s.getsockname()[0]
160 |
161 |
162 | def get_default_interface_ip(target):
163 | default = get_default_interface_ip_imp(target)
164 | ip = os.environ.get("LANIP", default)
165 | return ip
166 |
167 |
168 | print (r" __ __ .__ __ ")
169 | print (r" _______/ |______ ________/ |_ _____ |__|/ |_ _____ ")
170 | print (r" / ___/\ __\__ \\_ __ \ __\ / \| \ __\/ \ ")
171 | print (r" \___ \ | | / __ \| | \/| | | Y Y \ || | | Y Y \ ")
172 | print (r" /____ > |__| (____ /__| |__| |__|_| /__||__| |__|_| / ")
173 | print (r" \/ \/ \/ \/ ")
174 | print (r" Android HTTP Traffic Capture ")
175 | print (r"%60s" % ("lamda#v%s BY firerpa" % (__version__)))
176 |
177 |
178 | pkgName = None
179 | argp = argparse.ArgumentParser()
180 |
181 | login = "lamda"
182 | psw = uuid.uuid4().hex[::3]
183 | cert = os.environ.get("CERTIFICATE")
184 | proxy = int(os.environ.get("PROXYPORT",
185 | randint(28080, 58080)))
186 | webport = randint(28080, 58080)
187 | lamda = int(os.environ.get("PORT",
188 | 65000))
189 |
190 | argp.add_argument("device", nargs=1)
191 | mod = argp.add_mutually_exclusive_group(required=False)
192 | mod.add_argument("-m", "--mode", default="regular")
193 | mod.add_argument("--upstream", type=str, default=None)
194 | argp.add_argument("--serial", type=str, default=None)
195 | argp.add_argument("--dns", type=str, default=None)
196 | args, extras = argp.parse_known_args()
197 | serial = args.serial
198 | host = args.device[0]
199 |
200 | if ":" in host:
201 | host, pkgName = host.split(":")
202 | if args.dns and ver(VERSION) < ver("9.0.0"):
203 | log ("dns mitm needs mitmproxy>=9.0.0")
204 | sys.exit (1)
205 |
206 | server = get_default_interface_ip(host)
207 | usb = server in ("127.0.0.1", "::1")
208 |
209 | if cert:
210 | log ("ssl:", cert)
211 | if args.upstream:
212 | add_upstream(args, extras)
213 | if usb and args.dns:
214 | die ("dns mitm not available in USB mode")
215 | if usb and args.upstream:
216 | log ("dns will not sent via upstream in USB mode")
217 | if args.upstream and not args.dns:
218 | die ("dns must be set in upstream mode")
219 | if args.upstream and args.dns and not is_doh(args.dns):
220 | die ("dns must be DOH in upstream mode")
221 | if usb and forward(lamda, lamda).wait() != 0:
222 | die ("adb forward failed")
223 | if usb and reverse(proxy, proxy).wait() != 0:
224 | die ("adb forward failed")
225 | if not args.upstream and args.dns and not is_doh(args.dns):
226 | args.dns = fmt_rdns(args.dns, proxy)
227 | if args.dns and is_doh(args.dns):
228 | setup_dns_upstream(args)
229 |
230 |
231 | # 创建设备实例
232 | d = Device(host, port=lamda,
233 | certificate=cert)
234 | logger.setLevel(logging.WARN)
235 |
236 | # 拼接证书文件路径
237 | DIR = os.path.expanduser(CONF_DIR)
238 | CertStore.from_store(DIR, CONF_BASENAME, KEY_SIZE)
239 | ca = os.path.join(DIR, "mitmproxy-ca-cert.pem")
240 |
241 | log ("install cacert: %s" % ca)
242 | d.install_ca_certificate(ca)
243 |
244 | # 初始化 proxy 配置
245 | profile = GproxyProfile()
246 | profile.type = GproxyType.HTTP_CONNECT
247 | profile.nameserver = "1.1.1.1"
248 | if not usb and (args.upstream or args.dns):
249 | profile.nameserver = "{}:{}".format(server, proxy)
250 | profile.drop_udp = True
251 |
252 | profile.host = server
253 | profile.port = proxy
254 |
255 | profile.login = login
256 | profile.password = psw
257 | log ("set proxy: %s:%s@%s:%s/%s" % (
258 | login, psw,
259 | server, proxy,
260 | pkgName or "all"))
261 | if pkgName is not None:
262 | profile.application.set(d.application(pkgName))
263 | d.start_gproxy(profile)
264 |
265 | command = []
266 | # 设置 MITMPROXY 代理模式
267 | add_server(command, args.mode)
268 | add_server(command, args.dns)
269 | command.append("--ssl-insecure")
270 | # 代理认证,防止误绑定到公网被扫描
271 | command.append("--proxyauth")
272 | command.append("{}:{}".format(login, psw))
273 | # 随机 web-port
274 | command.append("--web-port")
275 | command.append(str(webport))
276 | command.append("--no-rawtcp")
277 | command.append("--listen-port")
278 | command.append(str(proxy))
279 | # 追加额外传递的参数
280 | command.extend(extras)
281 |
282 | log (" ".join(command))
283 |
284 | sys.exit = cleanup
285 | log ("press CONTROL + C to stop")
286 | proc = Process(target=web, name="mitmweb",
287 | args=(command,), daemon=True)
288 | proc.run()
289 | sys.exit(0)
--------------------------------------------------------------------------------
/tools/startmitm.spec:
--------------------------------------------------------------------------------
1 | # -*- mode: python ; coding: utf-8 -*-
2 | from PyInstaller.building.build_main import Analysis
3 | from PyInstaller.building.api import PYZ, EXE
4 |
5 | from PyInstaller.utils.hooks import collect_data_files
6 |
7 |
8 | a = Analysis(
9 | ["startmitm.py"],
10 | pathex=[],
11 | binaries=[],
12 | datas=collect_data_files("lamda"),
13 | hiddenimports=[],
14 | hookspath=[],
15 | hooksconfig={},
16 | excludes=["tcl", "tk", "tkinter"],
17 | win_no_prefer_redirects=False,
18 | win_private_assemblies=False,
19 | noarchive=False,
20 | )
21 |
22 | exe = EXE(
23 | PYZ(a.pure, a.zipped_data),
24 | a.scripts,
25 | a.binaries,
26 | a.zipfiles,
27 | a.datas,
28 | [],
29 | name="startmitm",
30 | icon=["startmitm.ico"],
31 | debug=False,
32 | bootloader_ignore_signals=False,
33 | console=True,
34 | disable_windowed_traceback=False,
35 | argv_emulation=False,
36 | target_arch=None,
37 | )
--------------------------------------------------------------------------------
/tools/test-fridarpc.js:
--------------------------------------------------------------------------------
1 | Java.perform(function() {
2 | var String = Java.use("java.lang.String")
3 | rpc.exports = {
4 | getMyString: function (paramA, paramB) {
5 | return performRpcJVMCall(function() {
6 | // 可以使用 Frida java 相关功能,Java.use 等
7 | var newParam = String.$new("helloWorld").toString()
8 | return newParam + ":" + paramA + paramB
9 | })
10 | },
11 | getMyString1: function (paramA, paramB) {
12 | return performRpcJVMCallOnMain(function() {
13 | // 可以使用 Frida java 相关功能,Java.use 等
14 | // 执行于应用的主进程,适用于涉及到 UI 主线程相关的功能
15 | var newParam = String.$new("helloWorld").toString()
16 | return newParam + ":" + paramA + paramB
17 | })
18 | },
19 | getMyString2: function (paramA, paramB) {
20 | return performRpcCall(function() {
21 | // 这里不能使用 Java 相关功能
22 | return paramA + paramB
23 | })
24 | },
25 | }
26 | });
27 |
--------------------------------------------------------------------------------
/tools/test.pem:
--------------------------------------------------------------------------------
1 | LAMDA SSL CERTIFICATE (CN=test,PASSWD=a1c0e3ea707a54de7a0f95)
2 | -----BEGIN PRIVATE KEY-----
3 | MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDVcLZP9oLQZDHF
4 | yWJSke4gG+IJfH+LZY4qu3u/NrDpHvB7i9WMk1lQ/aLHb4WvjzPK+THNokG760CQ
5 | XAMJVKGfatprcKQwo0hoX6v6XlMYYRSQmop7zRiKg7vq+5vKOCCdJp1eISbew2LH
6 | Nf1/rYzZpkT5lz1Lfdzm4yrAKuMkKrgzgO2QpOBAWXvgbXoA07bt7N86Y8gMdU0t
7 | zR/DrhKN/I1WXJMu1N0AnTl2QtHDoGB7E2KLivl2l6IvtkabxDNyciGmLNPiLFIk
8 | YOHyg1H71Bv5M84NSX75sln9uMPe39SEVRhSJm4w/OkWfp9tjYELwtzatXhIbhKs
9 | h/NeMe9dAgMBAAECggEABbQnYGepWJb02uDmJxK4lv8Sa/J5w2iJWLb94umRPLQ+
10 | SkQ9sVisBbAMI4w6uar4AAU8wXlZNwOzC/3ezucGEqkxAQys4T0xItORAvXLqVZ0
11 | IuZzq5nwJ/NxQsxKfihAfDKbTff7fpnLZUtvZMlnKYHPTLmFQnkwkrL2DNXt5U96
12 | arTP5NcLuh46uOwjRT9hZ7+XB/nmOKy5xWxh5eLBbIQ2kKE/uebRUXDfMtnmm8vh
13 | QHoU3syw9YpMqD9VAjipijAtpmIpkl5zdVHNvCWBHi666q+1zqJGxUT80lxz57du
14 | ToDQPsYt8QD/vc4i1j7tl6rG3PZBM3NK5TydV2FygQKBgQDaG2ruwilraGYG6MAl
15 | 4AvYmAcHGAe0B4tfkdu/PjweEd2YAvN2HAeugVTIh5xZeRR04Q8eSFzpShJpDJd4
16 | uLHGqrvrjW/X+xEHsO56sc64bzmpybVApeBp86QFI98WqffAr7qso8pxRc6gSEMn
17 | NSquugjlaM9NRfqJ8r/6FIfBLQKBgQD6hbtggHuRhLxGacMhDo9Ziqre6/G7Woft
18 | GaFfaP3lY53f3HOu+256LX65eaXE7kmyP8dC3eV/n1OwoLwAbmAgjDYWu7OJti8A
19 | OloU6kgNEp5g08zUZPZGsR2FLweiRH+CvNtPYjBrvaHAKUSiKkpJtJVxZHuIzJZF
20 | 5TfC6V3k8QKBgDyjtNZO+08Who9TNOES6pg8pG+PeczO8CwRFISWXAaMNwzlfSUQ
21 | Y/5bjOP3+DtUE6DvVdG4ksR1yKqWSqLQzvSKUZcLCtaEwlZeFd/dAbl7iw+uugsQ
22 | U1WB3M9lCsh1VyGmegM3wrg9jVY44RrMiGJt7L1Dp6c3VpH2APQZsyi9AoGBANOi
23 | jfykDb+M5pCFYDZY2njGUDsqD3g6roF6GX1EcNiMIx6uWXwFI/tK27dMMOIAe3l9
24 | r5OpaOs7abPY1Xl3xPU5/aeOwckgguwqX1cz49JHXExoIK187SAjF9EfPc+zFhUX
25 | /h090bHy7OYs9rIYD9HcIDM+s62JR5mcXlLmWk/BAoGBAJEXPWNHXL+kYz3/uGW7
26 | tJwHTC1elBcrW/hzI1kxdHWznUisSZW2Vp9oL0IckAuVBLzxe/GXz8bQN6d9l2d0
27 | tkfRj5NjC953Kcuq3RzDfUN4q72RUVMiE8uoI0dUVijW37KU0HKrmil0hqM5yob5
28 | UfXOCd9JTQIlycgMXDzNm4Kz
29 | -----END PRIVATE KEY-----
30 | -----BEGIN CERTIFICATE-----
31 | MIICqDCCAZCgAwIBAgIRAPsc1PQ5pnH3a6MFfGUMp6YwDQYJKoZIhvcNAQELBQAw
32 | EDEOMAwGA1UECgwFTEFNREEwHhcNMjAwMTAxMDAwMDAxWhcNMjkxMjI5MDAwMDAx
33 | WjAPMQ0wCwYDVQQDDAR0ZXN0MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC
34 | AQEA1XC2T/aC0GQxxcliUpHuIBviCXx/i2WOKrt7vzaw6R7we4vVjJNZUP2ix2+F
35 | r48zyvkxzaJBu+tAkFwDCVShn2raa3CkMKNIaF+r+l5TGGEUkJqKe80YioO76vub
36 | yjggnSadXiEm3sNixzX9f62M2aZE+Zc9S33c5uMqwCrjJCq4M4DtkKTgQFl74G16
37 | ANO27ezfOmPIDHVNLc0fw64SjfyNVlyTLtTdAJ05dkLRw6BgexNii4r5dpeiL7ZG
38 | m8QzcnIhpizT4ixSJGDh8oNR+9Qb+TPODUl++bJZ/bjD3t/UhFUYUiZuMPzpFn6f
39 | bY2BC8Lc2rV4SG4SrIfzXjHvXQIDAQABMA0GCSqGSIb3DQEBCwUAA4IBAQAXD4/W
40 | B0aImZXjPm4qRpNk2fRzcSX80l6NVZYlIWvXjQqQwWfs/Hg3d5saJbrAfqeOkYPu
41 | cyrDXVOt/QLEC91AHkcEbuGGO0cESf28wT3U3FrIog1KUrMDjXQHoOodBi8gMiPf
42 | dNqhLI7d42AMrJSwYQ9RPooXoTglCkGwGouD8nKEy2cGyS13yPp4lx/SY4uBDESK
43 | FQ+GFQLLFBKPdvMsltpv2AaLZdwrQxhT6i55SZn5+Kow5LlX/DGuL9RtOvfvOKse
44 | QgzNAH7BF3lgoBbcbOrfEPk65dFQ7CWb/uh6cVifJ7qC9//LatIfoUPVrbEwY/gQ
45 | NAEqXrWn0fnaG4qA
46 | -----END CERTIFICATE-----
47 | -----BEGIN CERTIFICATE-----
48 | MIIClDCCAXwCAQAwDQYJKoZIhvcNAQELBQAwEDEOMAwGA1UECgwFTEFNREEwHhcN
49 | MjAwMTAxMDAwMDAxWhcNMjkxMjI5MDAwMDAxWjAQMQ4wDAYDVQQKDAVMQU1EQTCC
50 | ASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALnqfBZvrGZaqgk5msCRRpPz
51 | p/+464jBknlmTKetOckDTUq8V6fH/2Gfb6HjjoD5pkCtD5mSKkaHNhuxLXsFfEfc
52 | Klmnn3ZpjyNOHEA/iAO2DyEYa08xSevM7WojbF7cNj5/DYg7eb0i0+//bBlh8nlO
53 | ghSUhCTM5PCofLDU8sVXuYAiGU6UzBrIC0vHEltDkiJVLpcCtsKjEZOskPdAc7u6
54 | /aA0P5GonZ5UkRDYpa+jeJUabqWZQQEgtmvjlmUUiXwu0jRnj1n0T3fPQD3gA+LI
55 | vAE9vgvpY5XQj6otpBvsZ3MJJNKcUMQu1zOANTzO18TlA8KoBNsBy8Z9DQZKXF8C
56 | AwEAATANBgkqhkiG9w0BAQsFAAOCAQEAeGn/NyqIRI/0AGqvHP97KtQ76Tj6achb
57 | 30LIXWp+YHUaMeAVjd2Z7jSQp5mZZFl+k1fb337IeaGXofVI21eK52QX2teNoBkA
58 | /V/O1Hu35/+aiz0xsdD6wWvwo4Fy1jlmaeJhwdQacBlDGFA2jFJxuEpahfxZvUsb
59 | 3j5zU0WKTUCfEDgXFwBw12xku/7TMdCEbRsYaZ3zFTC226lQbUDN7weqFwSD+tB6
60 | RuhIxe8+cFwAsAWHClerKgZnr3t5QF078pW2GHy8CsJ7V3MZT5lZ43lS5NIB9JzZ
61 | SYxZ/izhRyh5qR73uAgsJaL56Bj+cQqnoTqhLZVl7J+M6WhWKzojsA==
62 | -----END CERTIFICATE-----
63 |
--------------------------------------------------------------------------------