retrowave3/emulite
GitHub: retrowave3/emulite
Emulite 是一个用 Python 编写的 Android native 库模拟框架,支持在不依赖真机的情况下加载并执行 ELF 动态库中的函数。
Stars: 1 | Forks: 0
# 关于
Emulite 是一个用于 Android native 库的模拟框架,灵感来自 [Unidbg](https://github.com/zhkl0228/unidbg)。iOS 支持已在计划中。
## 环境要求
- Python 3.10+
- Unicorn 2.1.4+
- Capstone 5+
- LIEF 0.14+
- Cryptography 42+
## 项目状态
### 支持的平台
| 平台 | ARM32 | ARM64 |
|----------|:-----:|:-----:|
| Android | ✅ AndroidEmulator32 | ✅ AndroidEmulator64 |
| iOS | — | ⏳ |
### 支持的引擎
| 后端引擎 | 状态 |
|----------|:-----:|
| Unicorn | ✅ |
| Dynarmic | — |
| Apple Silicon Hypervisor | — |
| Linux KVM Hypervisor | — |
✅ 支持 · ⏳ 计划中 · — 不在计划内
## 示例
请参阅 [examples](./examples) 目录。
## Android 用法
根据目标架构使用 `AndroidEmulator32` 或 `AndroidEmulator64`。
```
from emulite import AndroidEmulator64, HookStatus, LogCategory, JniHandler
class CustomJniHandler(JniHandler):
# Unhandled methods raise `NotImplementedError`.
def call_static_method(self, method, args):
if method.java_class.name == "com/example/Device" and method.name == "getValue":
return "value"
return super().call_static_method(method, args)
def before_malloc(emu):
print("malloc size:", emu.arg(0))
def after_malloc(emu):
print("malloc returned:", hex(emu.ret))
def before_time(emu):
replacement_value = 150000
# emu.set_arg(0, replacement_value) # Store result in r0/x0
emu.finish(replacement_value)
return HookStatus.SKIP_ORIGINAL # Skip the original call
def on_instruction(emu, info):
print(info.format())
with AndroidEmulator64("path/to/rootfs/android", jni_handler=CustomJniHandler(), log=LogCategory.NONE) as emu:
# Load the target ELF and its dependencies
module = emu.load("path/to/libnative.so")
# Hook malloc import
malloc_hook = emu.hook_symbol(
"malloc",
before_malloc,
after_malloc,
module_name=module.name, # Module name is optional
)
# Replace time() result
time_hook = emu.hook_symbol(
"time",
before_time,
module_name=module.name, # Module name is optional
)
# Run JNI_OnLoad
emu.call_jni_onload(module)
# Call JNI function
native = emu.java_class("com/example/Native")
result = native.call("getValue", "(I)I", 123)
# Trace executed instructions within the target module
trace = emu.trace_module(on_instruction, module.name)
result = native.call("getValue", "(I)I", 123)
trace.close()
malloc_hook.close()
time_hook.close()
# Allocate memory
buffer = emu.malloc(32)
buffer.write_cstr("testing")
print(buffer.read_cstr())
emu.free(buffer)
# Call a regular ELF export by name
result = module.call_symbol("exported_symbol", 123)
```
## 贡献
欢迎提交 Bug 报告和 pull request。
## 相关资源
- [Unidbg](https://github.com/zhkl0228/unidbg)
- [Unicorn](https://github.com/unicorn-engine/unicorn)
- [LIEF](https://github.com/lief-project/LIEF)
- [Capstone](https://github.com/capstone-engine/capstone)
标签:Android, DSL, iOS, Python, 云资产清单, 代码模拟, 无后门, 移动开发, 逆向工具, 逆向工程