lamda 7.85__tar.gz → 8.0__tar.gz
Sign up to get free protection for your applications and to get access to all the features.
- {lamda-7.85 → lamda-8.0}/PKG-INFO +1 -1
- lamda-8.0/README.md +43 -0
- {lamda-7.85 → lamda-8.0}/lamda/__init__.py +1 -1
- {lamda-7.85 → lamda-8.0}/lamda/client.py +47 -57
- {lamda-7.85 → lamda-8.0}/lamda/exceptions.py +2 -0
- {lamda-7.85 → lamda-8.0}/lamda/rpc/application.proto +5 -0
- {lamda-7.85 → lamda-8.0}/lamda/rpc/services.proto +3 -3
- {lamda-7.85 → lamda-8.0}/lamda.egg-info/PKG-INFO +1 -1
- lamda-7.85/README.md +0 -52
- {lamda-7.85 → lamda-8.0}/lamda/bcast.proto +0 -0
- {lamda-7.85 → lamda-8.0}/lamda/const.py +0 -0
- {lamda-7.85 → lamda-8.0}/lamda/google/protobuf/any.proto +0 -0
- {lamda-7.85 → lamda-8.0}/lamda/google/protobuf/api.proto +0 -0
- {lamda-7.85 → lamda-8.0}/lamda/google/protobuf/compiler/plugin.proto +0 -0
- {lamda-7.85 → lamda-8.0}/lamda/google/protobuf/descriptor.proto +0 -0
- {lamda-7.85 → lamda-8.0}/lamda/google/protobuf/duration.proto +0 -0
- {lamda-7.85 → lamda-8.0}/lamda/google/protobuf/empty.proto +0 -0
- {lamda-7.85 → lamda-8.0}/lamda/google/protobuf/field_mask.proto +0 -0
- {lamda-7.85 → lamda-8.0}/lamda/google/protobuf/source_context.proto +0 -0
- {lamda-7.85 → lamda-8.0}/lamda/google/protobuf/struct.proto +0 -0
- {lamda-7.85 → lamda-8.0}/lamda/google/protobuf/timestamp.proto +0 -0
- {lamda-7.85 → lamda-8.0}/lamda/google/protobuf/type.proto +0 -0
- {lamda-7.85 → lamda-8.0}/lamda/google/protobuf/wrappers.proto +0 -0
- {lamda-7.85 → lamda-8.0}/lamda/rpc/debug.proto +0 -0
- {lamda-7.85 → lamda-8.0}/lamda/rpc/file.proto +0 -0
- {lamda-7.85 → lamda-8.0}/lamda/rpc/policy.proto +0 -0
- {lamda-7.85 → lamda-8.0}/lamda/rpc/proxy.proto +0 -0
- {lamda-7.85 → lamda-8.0}/lamda/rpc/settings.proto +0 -0
- {lamda-7.85 → lamda-8.0}/lamda/rpc/shell.proto +0 -0
- {lamda-7.85 → lamda-8.0}/lamda/rpc/status.proto +0 -0
- {lamda-7.85 → lamda-8.0}/lamda/rpc/storage.proto +0 -0
- {lamda-7.85 → lamda-8.0}/lamda/rpc/types.proto +0 -0
- {lamda-7.85 → lamda-8.0}/lamda/rpc/uiautomator.proto +0 -0
- {lamda-7.85 → lamda-8.0}/lamda/rpc/util.proto +0 -0
- {lamda-7.85 → lamda-8.0}/lamda/rpc/wifi.proto +0 -0
- {lamda-7.85 → lamda-8.0}/lamda/types.py +0 -0
- {lamda-7.85 → lamda-8.0}/lamda.egg-info/SOURCES.txt +0 -0
- {lamda-7.85 → lamda-8.0}/lamda.egg-info/dependency_links.txt +0 -0
- {lamda-7.85 → lamda-8.0}/lamda.egg-info/not-zip-safe +0 -0
- {lamda-7.85 → lamda-8.0}/lamda.egg-info/requires.txt +0 -0
- {lamda-7.85 → lamda-8.0}/lamda.egg-info/top_level.txt +0 -0
- {lamda-7.85 → lamda-8.0}/setup.cfg +0 -0
- {lamda-7.85 → lamda-8.0}/setup.py +0 -0
lamda-8.0/README.md
ADDED
@@ -0,0 +1,43 @@
|
|
1
|
+
<p align="center">
|
2
|
+
<img src="image/logo.svg" alt="LAMDA" width="345">
|
3
|
+
</p>
|
4
|
+
|
5
|
+
<p align="center">安卓 RPA 机器人框架,下一代移动端数据自动化机器人</p>
|
6
|
+
|
7
|
+
<p align="center">
|
8
|
+
<img src="https://img.shields.io/badge/python-3.6+-blue.svg?logo=python&labelColor=yellow" />
|
9
|
+
<img src="https://img.shields.io/badge/android-6.0+-blue.svg?logo=android&labelColor=white" />
|
10
|
+
<img src="https://img.shields.io/badge/root%20require-red.svg?logo=android&labelColor=black" />
|
11
|
+
<img src="https://img.shields.io/github/downloads/rev1si0n/lamda/total" />
|
12
|
+
<img src="https://img.shields.io/github/v/release/rev1si0n/lamda" />
|
13
|
+
</p>
|
14
|
+
|
15
|
+
<p align="center"><a href="https://device-farm.com/doc/index.html">使用文档</a> | <a href="https://t.me/lamda_dev">TELEGRAM</a> | <a href="https://lamda.run/join/qq">QQ 群组</a> | <a href="https://device-farm.com/doc/版本历史.html">更新历史</a></p>
|
16
|
+
|
17
|
+
智能机的崛起,传统网页端的普及度也开始显著减弱,数据与应用正加速向移动端转移。越来越多的人选择通过智能手机和平板等移动设备来获取信息和服务。随着移动设备的普及,用户享受到更便捷访问体验,传统的网页内容模式面临重新审视。与此同时,数据采集的技术也亟需适应这一趋势。过去,许多数据采集工具专注于网页内容,在移动端环境中,尤其是在移动端封闭的黑盒中,现今的常规采集技术也面临着新的挑战。LAMDA 的诞生,为这一切创造了可能。
|
18
|
+
|
19
|
+
LAMDA 是**安卓领域的集大成者**,设计为减少**安全分析**及**应用测试**或**自动化**工作的时间和琐碎问题,经过超 500 台设备的生产环境考验,稳定应用于多个大型系统,包括自动化取证,云平台,数据采集,合规分析等,具备商业级软件的质量和稳定性,仅需 root 权限即可正常运行。具备 ARM/X86 全架构,安卓 6.0-14 的广泛兼容性,支持 **模拟器**、**真机**、**云手机**、 **WSA**(Windows Subsystem for Android™️)、**RK开发板** (所有 ARM 架构)以及 **Redroid** 等大多数运行安卓系统的设备。为**移动端 RPA 数据采集**提供稳定的解决方案,以**编程化**的**接口**替代大量手动操作,**易部署**,没有那些复杂花哨不跨平台的安装流程,你所需要的能力他大概率能做到并且做的更好。他并不是一个单一功能的框架,他是集 Appium、uiautomator **自动化**的超集同时具备**逆向**领域如 **Hook** **抓包** **证书安装** **组网** **API跟踪** **手机自控** 等等各种能力的框架。当然,LAMDA 可以做到的远不止于此,你可以阅读使用文档尽情探索他的所有能力。
|
20
|
+
|
21
|
+
|
22
|
+
|
23
|
+
<h3><p align="center">丰富的设备编程接口</p></h3>
|
24
|
+
|
25
|
+
<p align="center">提供多达 160 条编程 API 接口,让你可以对安卓设备进行无微不至的管理和操作,提供了包括命令执行,系统设置,系统状态,应用相关,自动化相关,代理以及文件等十几个大类的接口。同时提供了封装完整的 Python 库让你可以快速上手使用。</p>
|
26
|
+
|
27
|
+
<h3><p align="center">简洁易用的远程桌面</p></h3>
|
28
|
+
|
29
|
+
<p align="center">
|
30
|
+
<img src="image/demo.gif" alt="动图演示" width="95%">
|
31
|
+
</p>
|
32
|
+
|
33
|
+
<h3><p align="center">一键中间人流量分析及更多其他功能</p></h3>
|
34
|
+
|
35
|
+
支持常规以及国际APP流量分析,DNS流量分析,得益于 [mitmproxy flow hook](https://docs.mitmproxy.org/stable/api/events.html),你可以对任何请求做到最大限度的掌控,mitmproxy 功能足够丰富,你可以使用 Python 脚本实时修改或者捕获应用的请求,也可以通过其 `Export` 选项导出特定请求的 `curl` 命令或者 `HTTPie` 命令,分析重放、拦截修改、功能组合足以替代你用过的任何此类商业/非商业软件。如果你仍不清楚 mitmproxy 是什么以及其具有的能力,请务必先查找相关文档,因为 LAMDA 将会使用 mitmproxy 为你展现应用请求。
|
36
|
+
|
37
|
+
<p align="center">
|
38
|
+
<img src="image/mitm.gif" alt="动图演示" width="95%">
|
39
|
+
</p>
|
40
|
+
|
41
|
+
<p align="center">
|
42
|
+
当然,LAMDA 提供的能力不止于这些,由于篇幅较长将不在此罗列,他是你强有力的设备控制及管理工具,如果你感兴趣,请转到 使用文档。
|
43
|
+
</p>
|
@@ -302,9 +302,6 @@ class CustomOcrBackend(object):
|
|
302
302
|
|
303
303
|
|
304
304
|
class BaseCryptor(object):
|
305
|
-
def __str__(self):
|
306
|
-
return "{}".format(self.__class__.__name__)
|
307
|
-
__repr__ = __str__
|
308
305
|
def encrypt(self, data):
|
309
306
|
return data
|
310
307
|
def decrypt(self, data):
|
@@ -312,9 +309,6 @@ class BaseCryptor(object):
|
|
312
309
|
|
313
310
|
|
314
311
|
class BaseServiceStub(object):
|
315
|
-
def __str__(self):
|
316
|
-
return "{}".format(self.__class__.__name__)
|
317
|
-
__repr__ = __str__
|
318
312
|
def __init__(self, stub):
|
319
313
|
self.stub = stub
|
320
314
|
|
@@ -408,7 +402,7 @@ class ObjectUiAutomatorOpStub:
|
|
408
402
|
s.setdefault("childOrSiblingSelector", [])
|
409
403
|
s["childOrSiblingSelector"].append(selector)
|
410
404
|
s["childOrSibling"].append(name)
|
411
|
-
return self.__class__(self.
|
405
|
+
return self.__class__(self.caller, s)
|
412
406
|
def child(self, **selector):
|
413
407
|
"""
|
414
408
|
匹配选择器里面的子节点
|
@@ -467,8 +461,6 @@ class ObjectUiAutomatorOpStub:
|
|
467
461
|
corner=corner)
|
468
462
|
r = self.stub.selectorClickExists(req)
|
469
463
|
return r.value
|
470
|
-
def click_exist(self, *args, **kwargs):
|
471
|
-
return self.click_exists(*args, **kwargs)
|
472
464
|
def long_click(self, corner=Corner.COR_CENTER):
|
473
465
|
"""
|
474
466
|
长按选择器选中的控件
|
@@ -484,26 +476,12 @@ class ObjectUiAutomatorOpStub:
|
|
484
476
|
req = protos.SelectorOnlyRequest(selector=self.selector)
|
485
477
|
r = self.stub.selectorExists(req)
|
486
478
|
return r.value
|
487
|
-
def exist(self, *args, **kwargs):
|
488
|
-
return self.exists(*args, **kwargs)
|
489
479
|
def info(self):
|
490
480
|
"""
|
491
481
|
获取选择器选中控件的信息
|
492
482
|
"""
|
493
483
|
req = protos.SelectorOnlyRequest(selector=self.selector)
|
494
484
|
return self.stub.selectorObjInfo(req)
|
495
|
-
def info_of_all_instances(self):
|
496
|
-
"""
|
497
|
-
获取选择器选中的所有控件的信息
|
498
|
-
"""
|
499
|
-
req = protos.SelectorOnlyRequest(selector=self.selector)
|
500
|
-
r = self.stub.selectorObjInfoOfAllInstances(req)
|
501
|
-
return r.objects
|
502
|
-
def all_instances(self):
|
503
|
-
"""
|
504
|
-
获取选择器选中的所有元素控件
|
505
|
-
"""
|
506
|
-
return list(self)
|
507
485
|
def _new_object(self, **kwargs):
|
508
486
|
selector = copy.deepcopy(self._selector)
|
509
487
|
selector.update(**kwargs)
|
@@ -559,6 +537,11 @@ class ObjectUiAutomatorOpStub:
|
|
559
537
|
return self._new_object(index=idx)
|
560
538
|
def instance(self, idx):
|
561
539
|
return self._new_object(instance=idx)
|
540
|
+
def get(self, idx):
|
541
|
+
"""
|
542
|
+
获取匹配的第 N 个索引的元素
|
543
|
+
"""
|
544
|
+
return self.instance(idx)
|
562
545
|
def __iter__(self):
|
563
546
|
"""
|
564
547
|
遍历所有符合选择器条件的元素实例
|
@@ -1042,16 +1025,21 @@ class AppScriptRpcInterface(object):
|
|
1042
1025
|
self.application = application
|
1043
1026
|
self.stub = stub
|
1044
1027
|
self.name = name
|
1028
|
+
def __str__(self):
|
1029
|
+
return "{}:Script:{}".format(self.application,
|
1030
|
+
self.name)
|
1031
|
+
__repr__ = __str__
|
1045
1032
|
def __call__(self, *args):
|
1046
1033
|
call_args = dict()
|
1047
1034
|
call_args["method"] = self.name
|
1048
1035
|
call_args["args"] = args
|
1049
1036
|
req = HookRpcRequest()
|
1050
1037
|
req.package = self.application.applicationId
|
1038
|
+
req.user = self.application.user
|
1051
1039
|
req.callinfo = json.dumps(call_args)
|
1052
1040
|
result = self.stub.callScript(req)
|
1053
|
-
|
1054
|
-
return
|
1041
|
+
data = json.loads(result.callresult)
|
1042
|
+
return data
|
1055
1043
|
|
1056
1044
|
|
1057
1045
|
class ApplicationOpStub:
|
@@ -1063,8 +1051,8 @@ class ApplicationOpStub:
|
|
1063
1051
|
self.applicationId = applicationId
|
1064
1052
|
self.stub = stub
|
1065
1053
|
def __str__(self):
|
1066
|
-
return "{}
|
1067
|
-
|
1054
|
+
return "Application:{}@{}".format(self.applicationId,
|
1055
|
+
self.user)
|
1068
1056
|
__repr__ = __str__
|
1069
1057
|
def is_foreground(self):
|
1070
1058
|
"""
|
@@ -1118,7 +1106,7 @@ class ApplicationOpStub:
|
|
1118
1106
|
req.user = self.user
|
1119
1107
|
r = self.stub.isPermissionGranted(req)
|
1120
1108
|
return r.value
|
1121
|
-
def
|
1109
|
+
def clear_cache(self):
|
1122
1110
|
"""
|
1123
1111
|
清空应用的缓存数据(非数据仅缓存)
|
1124
1112
|
"""
|
@@ -1126,7 +1114,7 @@ class ApplicationOpStub:
|
|
1126
1114
|
req.user = self.user
|
1127
1115
|
r = self.stub.deleteApplicationCache(req)
|
1128
1116
|
return r.value
|
1129
|
-
def
|
1117
|
+
def reset(self):
|
1130
1118
|
"""
|
1131
1119
|
清空应用的所有数据
|
1132
1120
|
"""
|
@@ -1134,8 +1122,6 @@ class ApplicationOpStub:
|
|
1134
1122
|
req.user = self.user
|
1135
1123
|
r = self.stub.resetApplicationData(req)
|
1136
1124
|
return r.value
|
1137
|
-
def reset(self):
|
1138
|
-
return self.reset_data()
|
1139
1125
|
def start(self):
|
1140
1126
|
"""
|
1141
1127
|
启动应用
|
@@ -1211,6 +1197,7 @@ class ApplicationOpStub:
|
|
1211
1197
|
def attach_script(self, script, runtime=ScriptRuntime.RUNTIME_QJS,
|
1212
1198
|
emit="",
|
1213
1199
|
encode=DataEncode.DATA_ENCODE_NONE,
|
1200
|
+
spawn=False,
|
1214
1201
|
standup=5):
|
1215
1202
|
"""
|
1216
1203
|
向应用注入持久化 Hook 脚本
|
@@ -1222,29 +1209,37 @@ class ApplicationOpStub:
|
|
1222
1209
|
req.script = script
|
1223
1210
|
req.runtime = runtime
|
1224
1211
|
req.standup = standup
|
1212
|
+
req.spawn = spawn
|
1225
1213
|
req.destination = emit
|
1226
1214
|
req.encode = encode
|
1215
|
+
req.user = self.user
|
1227
1216
|
r = self.stub.attachScript(req)
|
1228
1217
|
return r.value
|
1229
1218
|
def detach_script(self):
|
1230
1219
|
"""
|
1231
1220
|
移除注入应用的 Hook 脚本
|
1232
1221
|
"""
|
1233
|
-
req = protos.
|
1222
|
+
req = protos.HookRequest()
|
1223
|
+
req.package = self.applicationId
|
1224
|
+
req.user = self.user
|
1234
1225
|
r = self.stub.detachScript(req)
|
1235
1226
|
return r.value
|
1236
1227
|
def is_attached_script(self):
|
1237
1228
|
"""
|
1238
1229
|
检查使用在此应用注入了 Hook 脚本
|
1239
1230
|
"""
|
1240
|
-
req = protos.
|
1231
|
+
req = protos.HookRequest()
|
1232
|
+
req.package = self.applicationId
|
1233
|
+
req.user = self.user
|
1241
1234
|
r = self.stub.isScriptAttached(req)
|
1242
1235
|
return r.value
|
1243
1236
|
def is_script_alive(self):
|
1244
1237
|
"""
|
1245
1238
|
检查应用中的 Hook 脚本是否正常
|
1246
1239
|
"""
|
1247
|
-
req = protos.
|
1240
|
+
req = protos.HookRequest()
|
1241
|
+
req.package = self.applicationId
|
1242
|
+
req.user = self.user
|
1248
1243
|
r = self.stub.isScriptAlive(req)
|
1249
1244
|
return r.value
|
1250
1245
|
def __getattr__(self, name):
|
@@ -1261,7 +1256,7 @@ class ApplicationStub(BaseServiceStub):
|
|
1261
1256
|
获取当前处于前台的应用的信息
|
1262
1257
|
"""
|
1263
1258
|
top = self.stub.currentApplication(protos.Empty())
|
1264
|
-
app = self.__call__(top.packageName)
|
1259
|
+
app = self.__call__(top.packageName, user=top.user)
|
1265
1260
|
app.activity = top.activity
|
1266
1261
|
return app
|
1267
1262
|
def get_application_by_name(self, name, user=0):
|
@@ -1303,6 +1298,7 @@ class ApplicationStub(BaseServiceStub):
|
|
1303
1298
|
安装设备上的 apk 文件(注意此路径为设备上的 apk 路径)
|
1304
1299
|
"""
|
1305
1300
|
req = protos.ApplicationRequest(path=fpath)
|
1301
|
+
req.user = self.user
|
1306
1302
|
r = self.stub.installFromLocalFile(req)
|
1307
1303
|
return r
|
1308
1304
|
def __call__(self, applicationId, user=0):
|
@@ -1310,10 +1306,6 @@ class ApplicationStub(BaseServiceStub):
|
|
1310
1306
|
|
1311
1307
|
|
1312
1308
|
class StorageOpStub:
|
1313
|
-
def __str__(self):
|
1314
|
-
return "{}:{}".format(self.stub.__class__.__name__,
|
1315
|
-
self.name)
|
1316
|
-
__repr__ = __str__
|
1317
1309
|
# 用于容器值序列化的方法
|
1318
1310
|
def _decrypt(self, data):
|
1319
1311
|
return self.cryptor.decrypt(data)
|
@@ -1732,20 +1724,20 @@ class ProxyStub(BaseServiceStub):
|
|
1732
1724
|
|
1733
1725
|
|
1734
1726
|
class SelinuxPolicyStub(BaseServiceStub):
|
1735
|
-
def
|
1727
|
+
def allow(self, source, target, tclass, action):
|
1736
1728
|
"""
|
1737
1729
|
selinux allow
|
1738
1730
|
"""
|
1739
1731
|
req = protos.SelinuxPolicyRequest(source=source, target=target,
|
1740
|
-
|
1732
|
+
tclass=tclass, action=action)
|
1741
1733
|
r = self.stub.policySetAllow(req)
|
1742
1734
|
return r.value
|
1743
|
-
def
|
1735
|
+
def disallow(self, source, target, tclass, action):
|
1744
1736
|
"""
|
1745
1737
|
selinux disallow
|
1746
1738
|
"""
|
1747
1739
|
req = protos.SelinuxPolicyRequest(source=source, target=target,
|
1748
|
-
|
1740
|
+
tclass=tclass, action=action)
|
1749
1741
|
r = self.stub.policySetDisallow(req)
|
1750
1742
|
return r.value
|
1751
1743
|
def get_enforce(self):
|
@@ -1761,27 +1753,27 @@ class SelinuxPolicyStub(BaseServiceStub):
|
|
1761
1753
|
req = protos.Boolean(value=enforced)
|
1762
1754
|
r = self.stub.setEnforce(req)
|
1763
1755
|
return r.value
|
1764
|
-
def
|
1756
|
+
def enabled(self):
|
1765
1757
|
"""
|
1766
1758
|
获取设备上的 selinux 是否已经启用
|
1767
1759
|
"""
|
1768
1760
|
r = self.stub.isEnabled(protos.Empty())
|
1769
1761
|
return r.value
|
1770
|
-
def
|
1762
|
+
def enforce(self, name):
|
1771
1763
|
"""
|
1772
1764
|
设置一个域为 enforce
|
1773
1765
|
"""
|
1774
1766
|
req = protos.String(value=name)
|
1775
1767
|
r = self.stub.policySetEnforce(req)
|
1776
1768
|
return r.value
|
1777
|
-
def
|
1769
|
+
def permissive(self, name):
|
1778
1770
|
"""
|
1779
1771
|
设置一个域为 permissive
|
1780
1772
|
"""
|
1781
1773
|
req = protos.String(value=name)
|
1782
1774
|
r = self.stub.policySetPermissive(req)
|
1783
1775
|
return r.value
|
1784
|
-
def
|
1776
|
+
def create_domain(self, name):
|
1785
1777
|
"""
|
1786
1778
|
新建一个 selinux 域
|
1787
1779
|
"""
|
@@ -2020,11 +2012,6 @@ class OcrOperator(object):
|
|
2020
2012
|
OCR - 检查元素是否存在
|
2021
2013
|
"""
|
2022
2014
|
return bool(self.find_target_item())
|
2023
|
-
def exist(self):
|
2024
|
-
"""
|
2025
|
-
OCR - 检查元素是否存在
|
2026
|
-
"""
|
2027
|
-
return self.exists()
|
2028
2015
|
def click(self):
|
2029
2016
|
"""
|
2030
2017
|
OCR - 点击元素(不存在则报错)
|
@@ -2035,11 +2022,6 @@ class OcrOperator(object):
|
|
2035
2022
|
OCR - 点击元素(不存在将不会产生异常)
|
2036
2023
|
"""
|
2037
2024
|
return self.find_cb(self._click, False)
|
2038
|
-
def click_exist(self):
|
2039
|
-
"""
|
2040
|
-
OCR - 点击元素(不存在将不会产生异常)
|
2041
|
-
"""
|
2042
|
-
return self.click_exists()
|
2043
2025
|
def screenshot(self, quality=100):
|
2044
2026
|
"""
|
2045
2027
|
OCR - 对元素进行截图
|
@@ -2151,6 +2133,14 @@ class Device(object):
|
|
2151
2133
|
def frida(self):
|
2152
2134
|
if _frida_dma is None:
|
2153
2135
|
raise ModuleNotFoundError("frida")
|
2136
|
+
try:
|
2137
|
+
device = _frida_dma.get_device_matching(
|
2138
|
+
lambda d: d.name==self.server)
|
2139
|
+
# make a call to check server connectivity
|
2140
|
+
device.query_system_parameters()
|
2141
|
+
return device
|
2142
|
+
except:
|
2143
|
+
""" No-op """
|
2154
2144
|
kwargs = {}
|
2155
2145
|
if self.certificate is not None:
|
2156
2146
|
kwargs["certificate"] = self.certificate
|
@@ -22,6 +22,8 @@ class InvalidAndroidPackage(Exception):
|
|
22
22
|
""" Exception """
|
23
23
|
class InvalidArgumentError(Exception):
|
24
24
|
""" Exception """
|
25
|
+
class InvalidOperationError(Exception):
|
26
|
+
""" Exception """
|
25
27
|
class InvalidRootCertificate(Exception):
|
26
28
|
""" Exception """
|
27
29
|
class MethodNotFoundException(Exception):
|
@@ -54,6 +54,7 @@ message ApplicationActivityInfo {
|
|
54
54
|
int64 flags = 7;
|
55
55
|
bool debug = 8;
|
56
56
|
string data = 9;
|
57
|
+
uint32 user = 10;
|
57
58
|
}
|
58
59
|
|
59
60
|
message ApplicationActivityInfoList {
|
@@ -77,6 +78,7 @@ message ApplicationInfo {
|
|
77
78
|
uint32 versionCode = 10;
|
78
79
|
string versionName = 11;
|
79
80
|
string activity = 12;
|
81
|
+
uint32 user = 13;
|
80
82
|
}
|
81
83
|
|
82
84
|
message ApplicationProcess {
|
@@ -101,11 +103,14 @@ message HookRequest {
|
|
101
103
|
string destination = 4;
|
102
104
|
DataEncode encode = 5;
|
103
105
|
uint32 standup = 6;
|
106
|
+
bool spawn = 7;
|
107
|
+
uint32 user = 8;
|
104
108
|
}
|
105
109
|
|
106
110
|
message HookRpcRequest {
|
107
111
|
string package = 1;
|
108
112
|
string callinfo = 2;
|
113
|
+
uint32 user = 3;
|
109
114
|
}
|
110
115
|
|
111
116
|
message HookRpcResponse {
|
@@ -52,10 +52,10 @@ service Application {
|
|
52
52
|
rpc getIdentifierByLabel(String) returns (String) {}
|
53
53
|
|
54
54
|
rpc callScript(HookRpcRequest) returns (HookRpcResponse) {}
|
55
|
-
rpc isScriptAlive(
|
56
|
-
rpc isScriptAttached(
|
55
|
+
rpc isScriptAlive(HookRequest) returns (Boolean) {}
|
56
|
+
rpc isScriptAttached(HookRequest) returns (Boolean) {}
|
57
57
|
rpc attachScript(HookRequest) returns (Boolean) {}
|
58
|
-
rpc detachScript(
|
58
|
+
rpc detachScript(HookRequest) returns (Boolean) {}
|
59
59
|
}
|
60
60
|
|
61
61
|
service Debug {
|
lamda-7.85/README.md
DELETED
@@ -1,52 +0,0 @@
|
|
1
|
-
<p align="center">
|
2
|
-
<img src="image/logo.svg" alt="LAMDA" width="345">
|
3
|
-
</p>
|
4
|
-
|
5
|
-
<p align="center">安卓 RPA 机器人框架,下一代移动端数据自动化机器人</p>
|
6
|
-
|
7
|
-
<p align="center">
|
8
|
-
<img src="https://img.shields.io/badge/python-3.6+-blue.svg?logo=python&labelColor=yellow" />
|
9
|
-
<img src="https://img.shields.io/badge/android-6.0+-blue.svg?logo=android&labelColor=white" />
|
10
|
-
<img src="https://img.shields.io/badge/root%20require-red.svg?logo=android&labelColor=black" />
|
11
|
-
<img src="https://img.shields.io/github/downloads/rev1si0n/lamda/total" />
|
12
|
-
<img src="https://img.shields.io/github/v/release/rev1si0n/lamda" />
|
13
|
-
</p>
|
14
|
-
|
15
|
-
<p align="center"><a href="https://device-farm.com/doc/index.html">使用文档</a> | <a href="https://t.me/lamda_dev">TELEGRAM</a> | <a href="https://lamda.run/join/qq">QQ 群组</a> | <a href="https://github.com/rev1si0n/lamda/blob/HEAD/CHANGELOG.txt">更新历史</a></p>
|
16
|
-
|
17
|
-
智能机的崛起,传统网页端的普及度也开始显著减弱,数据与应用正加速向移动端转移。越来越多的人选择通过智能手机和平板等移动设备来获取信息和服务。随着移动设备的普及,用户享受到更便捷、更即时的访问体验,传统的网页内容消费模式面临重新审视。与此同时,数据采集的技术也亟需适应这一趋势。过去,许多数据采集工具专注于网页内容,但在移动端环境中,尤其是在移动端封闭的黑盒中,现今的常规采集技术也面临着新的挑战。LAMDA 的诞生,为这一切创造了可能。
|
18
|
-
|
19
|
-
LAMDA 是一个**安卓领域的集大成者**,设计为减少**安全分析**及**应用测试**工作的时间和琐碎问题,为**移动端RPA数据采集**提供稳定的解决方案,以**编程化**的**接口**替代大量手动操作,**易部署**,没有那些复杂花哨不跨平台的安装流程,你所需要的能力他大概率能做到并且做的更好。他并不是一个单一功能的框架,他是集 Appium、uiautomator **自动化**的超集同时具备**逆向**领域如 **Hook** **抓包** **证书安装** **组网** **API跟踪** **手机自控** 等等各种能力的框架。为了让你大概了解它的用处:你是否会在手机上安装各类代理、插件或者点来点去的设置来完成你的工作?你是否要在异地操作远在千里之外的手机?你是否有编程控制手机的需求?是否还在某些云手机厂商那里购买昂贵的 **IP切换**、**远程ADB调试**、**RPA自动化**甚至连 **logcat 日志** 都要付费的服务?如果有,那么对了,只需一个 LAMDA 即可解决所有问题。并且,他更注重**分布式**,事实上,你可以在一台公网服务器上管理散布在世界各地各种网络环境中的设备。当然,LAMDA 可以做到的远不止于此,你可以阅读使用文档尽情探索他的所有能力。
|
20
|
-
|
21
|
-
<p align="center"><b>长期维护及更新,质量稳定,安全可靠,生产环境可用<br>现稳定应用于多个外部大型系统,包括自动化取证,云平台,数据采集,涉诈应用分析系统等<br>本框架已稳定运行于各种数据生产环境五年以上</b></p>
|
22
|
-
|
23
|
-
<p align="center">
|
24
|
-
<img src="image/wx.png" alt="公众号" width="234">
|
25
|
-
</p>
|
26
|
-
<p align="center"><small>关注公众号查看视频教程以及更多使用方法</small><br><small><a href="https://space.bilibili.com/1964784386/video">B站教程视频同步发布</a></small>
|
27
|
-
</p>
|
28
|
-
|
29
|
-
经过超 500 台设备的稳定生产环境考验,具有**商业级软件**的**质量**和**稳定性**,仅需 root 权限即可正常运行。具备 ARM/X86 全架构,安卓 6.0-14 的广泛兼容性,支持 **模拟器**、**真机**、**云手机**、 **WSA**(Windows Subsystem for Android™️)、**无头开发板** (RK3399、3588 及任何 ARM 架构开发板)以及 **Redroid** 等大多数运行安卓系统的设备。提供大量可编程接口,支持界面布局检视、获取/重放系统中最近的 Activity、唤起应用的 Activity 等功能。除此之外,它支持大文件上传下载,远程桌面,以及UI自动化编程接口,点击、截图、获取界面元素、执行 shell 命令、设备状态、资源读取、系统配置、属性读写、一键中间人等,可通过 SSH 或内置 ADB 登录设备终端。具备 socks5、OpenVPN 代理并可通过接口轻松设置系统证书及中间人,同时支持定时任务、Magisk开机自启动,你可以在任何地方通过网络连接运行着 LAMDA 设备。
|
30
|
-
|
31
|
-
|
32
|
-
<h3><p align="center">丰富的设备编程接口</p></h3>
|
33
|
-
|
34
|
-
<p align="center">LAMDA 提供多达 160 条编程 API 接口,让你可以对安卓设备进行无微不至的管理和操作,提供了包括命令执行,系统设置,系统状态,应用相关,自动化相关,代理以及文件等十几个大类的接口。同时提供了封装完整的 Python 库让你可以快速上手使用。</p>
|
35
|
-
|
36
|
-
<h3><p align="center">简洁易用的远程桌面</p></h3>
|
37
|
-
|
38
|
-
<p align="center">
|
39
|
-
<img src="image/demo.gif" alt="动图演示" width="95%">
|
40
|
-
</p>
|
41
|
-
|
42
|
-
<h3><p align="center">一键中间人流量分析及更多其他功能</p></h3>
|
43
|
-
|
44
|
-
支持常规以及国际APP流量分析,DNS流量分析,得益于 [mitmproxy flow hook](https://docs.mitmproxy.org/stable/api/events.html),你可以对任何请求做到最大限度的掌控,mitmproxy 功能足够丰富,你可以使用 Python 脚本实时修改或者捕获应用的请求,也可以通过其 `Export` 选项导出特定请求的 `curl` 命令或者 `HTTPie` 命令,分析重放、拦截修改、功能组合足以替代你用过的任何此类商业/非商业软件。如果你仍不清楚 mitmproxy 是什么以及其具有的能力,请务必先查找相关文档,因为 LAMDA 将会使用 mitmproxy 为你展现应用请求。
|
45
|
-
|
46
|
-
<p align="center">
|
47
|
-
<img src="image/mitm.gif" alt="动图演示" width="95%">
|
48
|
-
</p>
|
49
|
-
|
50
|
-
<p align="center">
|
51
|
-
当然,LAMDA 提供的能力不止于这些,由于篇幅较长将不在此罗列,他是你强有力的设备控制及管理工具,如果你感兴趣,请转到 使用文档。
|
52
|
-
</p>
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|