emulite 0.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- emulite-0.1.0/.gitignore +32 -0
- emulite-0.1.0/PKG-INFO +147 -0
- emulite-0.1.0/README.md +131 -0
- emulite-0.1.0/pyproject.toml +40 -0
- emulite-0.1.0/rootfs/android/system/build.prop +451 -0
- emulite-0.1.0/rootfs/android/system/lib/libc.so +0 -0
- emulite-0.1.0/rootfs/android/system/lib/libcpp.so +0 -0
- emulite-0.1.0/rootfs/android/system/lib/libcrypto.so +0 -0
- emulite-0.1.0/rootfs/android/system/lib/libdl.so +0 -0
- emulite-0.1.0/rootfs/android/system/lib/liblog.so +0 -0
- emulite-0.1.0/rootfs/android/system/lib/libm.so +0 -0
- emulite-0.1.0/rootfs/android/system/lib/libssl.so +0 -0
- emulite-0.1.0/rootfs/android/system/lib/libstdcpp.so +0 -0
- emulite-0.1.0/rootfs/android/system/lib/libz.so +0 -0
- emulite-0.1.0/rootfs/android/system/lib64/libc.so +0 -0
- emulite-0.1.0/rootfs/android/system/lib64/libcpp.so +0 -0
- emulite-0.1.0/rootfs/android/system/lib64/libcrypto.so +0 -0
- emulite-0.1.0/rootfs/android/system/lib64/libdl.so +0 -0
- emulite-0.1.0/rootfs/android/system/lib64/liblog.so +0 -0
- emulite-0.1.0/rootfs/android/system/lib64/libm.so +0 -0
- emulite-0.1.0/rootfs/android/system/lib64/libssl.so +0 -0
- emulite-0.1.0/rootfs/android/system/lib64/libstdcpp.so +0 -0
- emulite-0.1.0/rootfs/android/system/lib64/libz.so +0 -0
- emulite-0.1.0/rootfs/android/system/usr/share/zoneinfo/tzdata +0 -0
- emulite-0.1.0/src/emulite/__init__.py +56 -0
- emulite-0.1.0/src/emulite/_rootfs.py +19 -0
- emulite-0.1.0/src/emulite/android/__init__.py +1 -0
- emulite-0.1.0/src/emulite/android/android_file_system.py +906 -0
- emulite-0.1.0/src/emulite/android/arm32/__init__.py +1 -0
- emulite-0.1.0/src/emulite/android/arm32/android_libc_hooks32.py +556 -0
- emulite-0.1.0/src/emulite/android/arm32/android_syscall_handler32.py +2885 -0
- emulite-0.1.0/src/emulite/android/arm64/__init__.py +1 -0
- emulite-0.1.0/src/emulite/android/arm64/android_libc_hooks64.py +541 -0
- emulite-0.1.0/src/emulite/android/arm64/android_syscall_handler64.py +2367 -0
- emulite-0.1.0/src/emulite/android/art_method_area.py +37 -0
- emulite-0.1.0/src/emulite/android/bionic_property_area.py +100 -0
- emulite-0.1.0/src/emulite/android/cformat/__init__.py +7 -0
- emulite-0.1.0/src/emulite/android/cformat/register_args.py +27 -0
- emulite-0.1.0/src/emulite/android/cformat/register_args32.py +46 -0
- emulite-0.1.0/src/emulite/android/cformat/valist_args.py +38 -0
- emulite-0.1.0/src/emulite/android/cformat/valist_args32.py +31 -0
- emulite-0.1.0/src/emulite/android/cformat/var_args.py +73 -0
- emulite-0.1.0/src/emulite/android/dalvik_vm.py +219 -0
- emulite-0.1.0/src/emulite/android/enums/auxv.py +22 -0
- emulite-0.1.0/src/emulite/android/enums/errno.py +23 -0
- emulite-0.1.0/src/emulite/android/enums/sockopt.py +13 -0
- emulite-0.1.0/src/emulite/android/flags/clone_flag.py +10 -0
- emulite-0.1.0/src/emulite/android/flags/mmap_flag.py +8 -0
- emulite-0.1.0/src/emulite/android/flags/pf_flag.py +9 -0
- emulite-0.1.0/src/emulite/android/io/ashmem_io.py +32 -0
- emulite-0.1.0/src/emulite/android/io/binder.py +122 -0
- emulite-0.1.0/src/emulite/android/io/buffer_backed_io.py +38 -0
- emulite-0.1.0/src/emulite/android/io/device_io.py +44 -0
- emulite-0.1.0/src/emulite/android/io/directory_io.py +16 -0
- emulite-0.1.0/src/emulite/android/io/epoll_io.py +31 -0
- emulite-0.1.0/src/emulite/android/io/event_fd_io.py +34 -0
- emulite-0.1.0/src/emulite/android/io/pipe_io.py +32 -0
- emulite-0.1.0/src/emulite/android/io/regular_file_io.py +54 -0
- emulite-0.1.0/src/emulite/android/io/socket_io.py +56 -0
- emulite-0.1.0/src/emulite/android/io/stdio_io.py +36 -0
- emulite-0.1.0/src/emulite/android/io/tty_io.py +31 -0
- emulite-0.1.0/src/emulite/android/java/__init__.py +0 -0
- emulite-0.1.0/src/emulite/android/java/crypto/java_cipher.py +109 -0
- emulite-0.1.0/src/emulite/android/java/crypto/java_mac.py +71 -0
- emulite-0.1.0/src/emulite/android/java/crypto/spec/java_iv_parameter_spec.py +29 -0
- emulite-0.1.0/src/emulite/android/java/crypto/spec/java_secret_key_spec.py +36 -0
- emulite-0.1.0/src/emulite/android/java/io/java_byte_array_input_stream.py +52 -0
- emulite-0.1.0/src/emulite/android/java/io/java_byte_array_output_stream.py +48 -0
- emulite-0.1.0/src/emulite/android/java/io/java_file.py +53 -0
- emulite-0.1.0/src/emulite/android/java/jvalue.py +5 -0
- emulite-0.1.0/src/emulite/android/java/lang/_java_boxed_integer.py +37 -0
- emulite-0.1.0/src/emulite/android/java/lang/java_boolean.py +39 -0
- emulite-0.1.0/src/emulite/android/java/lang/java_byte.py +23 -0
- emulite-0.1.0/src/emulite/android/java/lang/java_character.py +72 -0
- emulite-0.1.0/src/emulite/android/java/lang/java_class.py +166 -0
- emulite-0.1.0/src/emulite/android/java/lang/java_class_loader.py +60 -0
- emulite-0.1.0/src/emulite/android/java/lang/java_double.py +73 -0
- emulite-0.1.0/src/emulite/android/java/lang/java_error.py +13 -0
- emulite-0.1.0/src/emulite/android/java/lang/java_exception.py +13 -0
- emulite-0.1.0/src/emulite/android/java/lang/java_float.py +73 -0
- emulite-0.1.0/src/emulite/android/java/lang/java_integer.py +20 -0
- emulite-0.1.0/src/emulite/android/java/lang/java_linkage_error.py +13 -0
- emulite-0.1.0/src/emulite/android/java/lang/java_long.py +27 -0
- emulite-0.1.0/src/emulite/android/java/lang/java_math.py +108 -0
- emulite-0.1.0/src/emulite/android/java/lang/java_no_class_def_found_error.py +13 -0
- emulite-0.1.0/src/emulite/android/java/lang/java_number.py +61 -0
- emulite-0.1.0/src/emulite/android/java/lang/java_object.py +65 -0
- emulite-0.1.0/src/emulite/android/java/lang/java_runtime_exception.py +13 -0
- emulite-0.1.0/src/emulite/android/java/lang/java_short.py +23 -0
- emulite-0.1.0/src/emulite/android/java/lang/java_string.py +234 -0
- emulite-0.1.0/src/emulite/android/java/lang/java_string_buffer.py +13 -0
- emulite-0.1.0/src/emulite/android/java/lang/java_string_builder.py +102 -0
- emulite-0.1.0/src/emulite/android/java/lang/java_system.py +54 -0
- emulite-0.1.0/src/emulite/android/java/lang/java_throwable.py +56 -0
- emulite-0.1.0/src/emulite/android/java/lang/reflect/java_accessible_object.py +45 -0
- emulite-0.1.0/src/emulite/android/java/lang/reflect/java_constructor.py +26 -0
- emulite-0.1.0/src/emulite/android/java/lang/reflect/java_executable.py +40 -0
- emulite-0.1.0/src/emulite/android/java/lang/reflect/java_field.py +41 -0
- emulite-0.1.0/src/emulite/android/java/lang/reflect/java_method.py +32 -0
- emulite-0.1.0/src/emulite/android/java/lang/reflect/modifier.py +8 -0
- emulite-0.1.0/src/emulite/android/java/math/java_big_integer.py +134 -0
- emulite-0.1.0/src/emulite/android/java/models.py +118 -0
- emulite-0.1.0/src/emulite/android/java/nio/java_byte_buffer.py +172 -0
- emulite-0.1.0/src/emulite/android/java/nio/java_byte_order.py +35 -0
- emulite-0.1.0/src/emulite/android/java/security/java_message_digest.py +65 -0
- emulite-0.1.0/src/emulite/android/java/security/java_secure_random.py +55 -0
- emulite-0.1.0/src/emulite/android/java/util/_java_list.py +76 -0
- emulite-0.1.0/src/emulite/android/java/util/_support.py +38 -0
- emulite-0.1.0/src/emulite/android/java/util/concurrent/atomic/_java_atomic_number.py +65 -0
- emulite-0.1.0/src/emulite/android/java/util/concurrent/atomic/java_atomic_integer.py +14 -0
- emulite-0.1.0/src/emulite/android/java/util/concurrent/atomic/java_atomic_long.py +14 -0
- emulite-0.1.0/src/emulite/android/java/util/java_array_list.py +17 -0
- emulite-0.1.0/src/emulite/android/java/util/java_arrays.py +161 -0
- emulite-0.1.0/src/emulite/android/java/util/java_base64.py +89 -0
- emulite-0.1.0/src/emulite/android/java/util/java_collections.py +84 -0
- emulite-0.1.0/src/emulite/android/java/util/java_hash_map.py +112 -0
- emulite-0.1.0/src/emulite/android/java/util/java_hash_set.py +71 -0
- emulite-0.1.0/src/emulite/android/java/util/java_iterator.py +28 -0
- emulite-0.1.0/src/emulite/android/java/util/java_linked_hash_map.py +13 -0
- emulite-0.1.0/src/emulite/android/java/util/java_linked_list.py +61 -0
- emulite-0.1.0/src/emulite/android/java/util/java_locale.py +38 -0
- emulite-0.1.0/src/emulite/android/java/util/java_objects.py +44 -0
- emulite-0.1.0/src/emulite/android/java/util/java_optional.py +59 -0
- emulite-0.1.0/src/emulite/android/java/util/java_string_tokenizer.py +48 -0
- emulite-0.1.0/src/emulite/android/java/util/java_uuid.py +66 -0
- emulite-0.1.0/src/emulite/android/java_vm.py +47 -0
- emulite-0.1.0/src/emulite/android/jni/enums/java_vm_function.py +11 -0
- emulite-0.1.0/src/emulite/android/jni/enums/jni_function.py +242 -0
- emulite-0.1.0/src/emulite/android/jni/enums/jni_return_code.py +17 -0
- emulite-0.1.0/src/emulite/android/jni/enums/jni_version.py +21 -0
- emulite-0.1.0/src/emulite/android/jni/jni_env.py +1499 -0
- emulite-0.1.0/src/emulite/android/jni/jni_handler.py +54 -0
- emulite-0.1.0/src/emulite/android/jni/jni_mangler.py +30 -0
- emulite-0.1.0/src/emulite/android/jni/mutf8.py +63 -0
- emulite-0.1.0/src/emulite/android/linker_debug.py +360 -0
- emulite-0.1.0/src/emulite/android/structs/dirent64.py +45 -0
- emulite-0.1.0/src/emulite/android/structs/dl_info32.py +30 -0
- emulite-0.1.0/src/emulite/android/structs/dl_info64.py +30 -0
- emulite-0.1.0/src/emulite/android/structs/dl_phdr_info32.py +39 -0
- emulite-0.1.0/src/emulite/android/structs/dl_phdr_info64.py +39 -0
- emulite-0.1.0/src/emulite/android/structs/epoll_event.py +30 -0
- emulite-0.1.0/src/emulite/android/structs/iovec32.py +28 -0
- emulite-0.1.0/src/emulite/android/structs/iovec64.py +28 -0
- emulite-0.1.0/src/emulite/android/structs/link_map32.py +24 -0
- emulite-0.1.0/src/emulite/android/structs/link_map64.py +32 -0
- emulite-0.1.0/src/emulite/android/structs/msghdr32.py +27 -0
- emulite-0.1.0/src/emulite/android/structs/msghdr64.py +27 -0
- emulite-0.1.0/src/emulite/android/structs/packed_struct.py +9 -0
- emulite-0.1.0/src/emulite/android/structs/pollfd.py +30 -0
- emulite-0.1.0/src/emulite/android/structs/r_debug32.py +30 -0
- emulite-0.1.0/src/emulite/android/structs/r_debug64.py +40 -0
- emulite-0.1.0/src/emulite/android/structs/rlimit32.py +36 -0
- emulite-0.1.0/src/emulite/android/structs/rlimit64.py +36 -0
- emulite-0.1.0/src/emulite/android/structs/rusage32.py +51 -0
- emulite-0.1.0/src/emulite/android/structs/rusage64.py +51 -0
- emulite-0.1.0/src/emulite/android/structs/sigaction32.py +35 -0
- emulite-0.1.0/src/emulite/android/structs/sigaction64.py +34 -0
- emulite-0.1.0/src/emulite/android/structs/sigcontext32.py +53 -0
- emulite-0.1.0/src/emulite/android/structs/sigcontext64.py +51 -0
- emulite-0.1.0/src/emulite/android/structs/stat32.py +85 -0
- emulite-0.1.0/src/emulite/android/structs/stat64.py +88 -0
- emulite-0.1.0/src/emulite/android/structs/statfs32.py +59 -0
- emulite-0.1.0/src/emulite/android/structs/statfs64.py +59 -0
- emulite-0.1.0/src/emulite/android/structs/statx.py +71 -0
- emulite-0.1.0/src/emulite/android/structs/sysinfo32.py +53 -0
- emulite-0.1.0/src/emulite/android/structs/sysinfo64.py +52 -0
- emulite-0.1.0/src/emulite/android/structs/timespec32.py +38 -0
- emulite-0.1.0/src/emulite/android/structs/timespec64.py +38 -0
- emulite-0.1.0/src/emulite/android/structs/timeval32.py +31 -0
- emulite-0.1.0/src/emulite/android/structs/timeval64.py +31 -0
- emulite-0.1.0/src/emulite/android/structs/tm64.py +76 -0
- emulite-0.1.0/src/emulite/android/structs/tms32.py +30 -0
- emulite-0.1.0/src/emulite/android/structs/tms64.py +30 -0
- emulite-0.1.0/src/emulite/android/structs/utsname.py +41 -0
- emulite-0.1.0/src/emulite/android/virtual_clock.py +40 -0
- emulite-0.1.0/src/emulite/android_device.py +290 -0
- emulite-0.1.0/src/emulite/android_emulator.py +192 -0
- emulite-0.1.0/src/emulite/android_emulator32.py +626 -0
- emulite-0.1.0/src/emulite/android_emulator64.py +610 -0
- emulite-0.1.0/src/emulite/android_profile.py +63 -0
- emulite-0.1.0/src/emulite/common/__init__.py +21 -0
- emulite-0.1.0/src/emulite/common/errors.py +50 -0
- emulite-0.1.0/src/emulite/common/log.py +121 -0
- emulite-0.1.0/src/emulite/cpu/__init__.py +4 -0
- emulite-0.1.0/src/emulite/cpu/arch/__init__.py +1 -0
- emulite-0.1.0/src/emulite/cpu/arch/arm32.py +57 -0
- emulite-0.1.0/src/emulite/cpu/arch/arm64.py +54 -0
- emulite-0.1.0/src/emulite/cpu/arch/base.py +50 -0
- emulite-0.1.0/src/emulite/cpu/backend.py +70 -0
- emulite-0.1.0/src/emulite/cpu/enums/cpu_arch.py +6 -0
- emulite-0.1.0/src/emulite/cpu/enums/hook_type.py +9 -0
- emulite-0.1.0/src/emulite/cpu/flags/memory_protection_flag.py +15 -0
- emulite-0.1.0/src/emulite/cpu/registers/arm32_reg.py +228 -0
- emulite-0.1.0/src/emulite/cpu/registers/arm64_reg.py +385 -0
- emulite-0.1.0/src/emulite/cpu/unicorn_backend.py +126 -0
- emulite-0.1.0/src/emulite/filesystem/__init__.py +4 -0
- emulite-0.1.0/src/emulite/filesystem/enums/dirent_type.py +14 -0
- emulite-0.1.0/src/emulite/filesystem/enums/fcntl_cmd.py +14 -0
- emulite-0.1.0/src/emulite/filesystem/enums/seek_whence.py +9 -0
- emulite-0.1.0/src/emulite/filesystem/enums/stat_type.py +18 -0
- emulite-0.1.0/src/emulite/filesystem/file_io.py +103 -0
- emulite-0.1.0/src/emulite/filesystem/flags/fd_flag.py +7 -0
- emulite-0.1.0/src/emulite/filesystem/flags/open_flag.py +24 -0
- emulite-0.1.0/src/emulite/filesystem/structs/file_stat.py +58 -0
- emulite-0.1.0/src/emulite/filesystem/structs/stat_result.py +10 -0
- emulite-0.1.0/src/emulite/hooks/call_event.py +19 -0
- emulite-0.1.0/src/emulite/hooks/call_tracer.py +95 -0
- emulite-0.1.0/src/emulite/hooks/disassembler.py +88 -0
- emulite-0.1.0/src/emulite/hooks/frame.py +13 -0
- emulite-0.1.0/src/emulite/hooks/hook_handle.py +36 -0
- emulite-0.1.0/src/emulite/hooks/hook_manager.py +337 -0
- emulite-0.1.0/src/emulite/hooks/hook_status.py +10 -0
- emulite-0.1.0/src/emulite/hooks/svc_trap.py +72 -0
- emulite-0.1.0/src/emulite/hooks/trace_info.py +44 -0
- emulite-0.1.0/src/emulite/hooks/tracer.py +72 -0
- emulite-0.1.0/src/emulite/hooks/unwinder.py +49 -0
- emulite-0.1.0/src/emulite/loader/__init__.py +7 -0
- emulite-0.1.0/src/emulite/loader/elf_loader.py +457 -0
- emulite-0.1.0/src/emulite/loader/module/linux_module.py +22 -0
- emulite-0.1.0/src/emulite/loader/module/native_module.py +163 -0
- emulite-0.1.0/src/emulite/loader/module/symbol.py +31 -0
- emulite-0.1.0/src/emulite/loader/module/virtual_module.py +8 -0
- emulite-0.1.0/src/emulite/memory/__init__.py +18 -0
- emulite-0.1.0/src/emulite/memory/heap_allocator.py +110 -0
- emulite-0.1.0/src/emulite/memory/memory_layout.py +27 -0
- emulite-0.1.0/src/emulite/memory/memory_manager.py +352 -0
- emulite-0.1.0/src/emulite/memory/memory_region.py +18 -0
- emulite-0.1.0/src/emulite/memory/native_pointer.py +119 -0
emulite-0.1.0/.gitignore
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
# Python
|
|
2
|
+
__pycache__/
|
|
3
|
+
*.py[cod]
|
|
4
|
+
*.egg-info/
|
|
5
|
+
|
|
6
|
+
# Build output
|
|
7
|
+
build/
|
|
8
|
+
dist/
|
|
9
|
+
|
|
10
|
+
# Tests and tooling
|
|
11
|
+
tests/
|
|
12
|
+
.pytest_cache/
|
|
13
|
+
.ruff_cache/
|
|
14
|
+
.mypy_cache/
|
|
15
|
+
.coverage
|
|
16
|
+
.coverage.*
|
|
17
|
+
htmlcov/
|
|
18
|
+
|
|
19
|
+
# Virtual environments
|
|
20
|
+
.venv/
|
|
21
|
+
venv/
|
|
22
|
+
env/
|
|
23
|
+
|
|
24
|
+
# Local configuration
|
|
25
|
+
.env
|
|
26
|
+
*.log
|
|
27
|
+
|
|
28
|
+
# Editors and operating systems
|
|
29
|
+
.idea/
|
|
30
|
+
.vscode/
|
|
31
|
+
.DS_Store
|
|
32
|
+
Thumbs.db
|
emulite-0.1.0/PKG-INFO
ADDED
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: emulite
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: A Python framework for emulating and instrumenting Android ARM32 and ARM64 native libraries.
|
|
5
|
+
Project-URL: Repository, https://github.com/retrowave3/emulite
|
|
6
|
+
Project-URL: Issues, https://github.com/retrowave3/emulite/issues
|
|
7
|
+
Requires-Python: >=3.10
|
|
8
|
+
Requires-Dist: capstone>=5
|
|
9
|
+
Requires-Dist: cryptography>=42
|
|
10
|
+
Requires-Dist: lief>=0.14
|
|
11
|
+
Requires-Dist: unicorn>=2.1.4
|
|
12
|
+
Provides-Extra: dev
|
|
13
|
+
Requires-Dist: pytest>=8; extra == 'dev'
|
|
14
|
+
Requires-Dist: ruff>=0.5; extra == 'dev'
|
|
15
|
+
Description-Content-Type: text/markdown
|
|
16
|
+
|
|
17
|
+
# About
|
|
18
|
+
|
|
19
|
+
Emulite is an emulation framework for Android native libraries, inspired by [Unidbg](https://github.com/zhkl0228/unidbg). iOS support is planned.
|
|
20
|
+
|
|
21
|
+
> [!WARNING]
|
|
22
|
+
> Emulite is an early release. Breaking API changes may occur in future releases, and bugs should be expected.
|
|
23
|
+
|
|
24
|
+
## Requirements
|
|
25
|
+
|
|
26
|
+
- Python 3.10+
|
|
27
|
+
- Unicorn 2.1.4+
|
|
28
|
+
- Capstone 5+
|
|
29
|
+
- LIEF 0.14+
|
|
30
|
+
- Cryptography 42+
|
|
31
|
+
|
|
32
|
+
## Project Status
|
|
33
|
+
|
|
34
|
+
### Supported Platforms
|
|
35
|
+
| Platform | ARM32 | ARM64 |
|
|
36
|
+
|----------|:-----:|:-----:|
|
|
37
|
+
| Android | ✅ AndroidEmulator32 | ✅ AndroidEmulator64 |
|
|
38
|
+
| iOS | — | ⏳ |
|
|
39
|
+
|
|
40
|
+
### Supported Engines
|
|
41
|
+
| Backend Engine | Status |
|
|
42
|
+
|----------|:-----:|
|
|
43
|
+
| Unicorn | ✅ |
|
|
44
|
+
| Dynarmic | — |
|
|
45
|
+
| Apple Silicon Hypervisor | — |
|
|
46
|
+
| Linux KVM Hypervisor | — |
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
<sub>✅ Supported · ⏳ Planned · — Not planned</sub>
|
|
50
|
+
|
|
51
|
+
## Examples
|
|
52
|
+
|
|
53
|
+
See the [examples](./examples) directory. To run them from a source checkout:
|
|
54
|
+
|
|
55
|
+
```console
|
|
56
|
+
python -m pip install -e .
|
|
57
|
+
python examples/apps/reddit_example.py
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
## Android Usage
|
|
61
|
+
|
|
62
|
+
Use `AndroidEmulator32` or `AndroidEmulator64` based on the target architecture. A default Android rootfs is included. Pass a path as the first argument to use a custom rootfs.
|
|
63
|
+
|
|
64
|
+
```python
|
|
65
|
+
from emulite import AndroidEmulator64, HookStatus, LogCategory, JniHandler
|
|
66
|
+
|
|
67
|
+
class CustomJniHandler(JniHandler):
|
|
68
|
+
# Unhandled methods raise `NotImplementedError`.
|
|
69
|
+
def call_static_method(self, method, args):
|
|
70
|
+
if method.java_class.name == "com/example/Device" and method.name == "getValue":
|
|
71
|
+
return "value"
|
|
72
|
+
return super().call_static_method(method, args)
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
def before_malloc(emu):
|
|
76
|
+
print("malloc size:", emu.arg(0))
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
def after_malloc(emu):
|
|
80
|
+
print("malloc returned:", hex(emu.ret))
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
def before_time(emu):
|
|
84
|
+
replacement_value = 150000
|
|
85
|
+
# emu.set_arg(0, replacement_value) # Store result in r0/x0
|
|
86
|
+
emu.finish(replacement_value)
|
|
87
|
+
return HookStatus.SKIP_ORIGINAL # Skip the original call
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
def on_instruction(emu, info):
|
|
91
|
+
print(info.format())
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
with AndroidEmulator64(jni_handler=CustomJniHandler(), log=LogCategory.NONE) as emu:
|
|
95
|
+
# Load the target ELF and its dependencies
|
|
96
|
+
module = emu.load("path/to/libnative.so")
|
|
97
|
+
|
|
98
|
+
# Hook malloc import
|
|
99
|
+
malloc_hook = emu.hook_symbol(
|
|
100
|
+
"malloc",
|
|
101
|
+
before_malloc,
|
|
102
|
+
after_malloc,
|
|
103
|
+
module_name=module.name, # Module name is optional
|
|
104
|
+
)
|
|
105
|
+
|
|
106
|
+
# Replace time() result
|
|
107
|
+
time_hook = emu.hook_symbol(
|
|
108
|
+
"time",
|
|
109
|
+
before_time,
|
|
110
|
+
module_name=module.name, # Module name is optional
|
|
111
|
+
)
|
|
112
|
+
|
|
113
|
+
# Run JNI_OnLoad
|
|
114
|
+
emu.call_jni_onload(module)
|
|
115
|
+
|
|
116
|
+
# Call JNI function
|
|
117
|
+
native = emu.java_class("com/example/Native")
|
|
118
|
+
result = native.call("getValue", "(I)I", 123)
|
|
119
|
+
|
|
120
|
+
# Trace executed instructions within the target module
|
|
121
|
+
trace = emu.trace_module(on_instruction, module.name)
|
|
122
|
+
result = native.call("getValue", "(I)I", 123)
|
|
123
|
+
trace.close()
|
|
124
|
+
|
|
125
|
+
malloc_hook.close()
|
|
126
|
+
time_hook.close()
|
|
127
|
+
|
|
128
|
+
# Allocate memory
|
|
129
|
+
buffer = emu.malloc(32)
|
|
130
|
+
buffer.write_cstr("testing")
|
|
131
|
+
print(buffer.read_cstr())
|
|
132
|
+
emu.free(buffer)
|
|
133
|
+
|
|
134
|
+
# Call a regular ELF export by name
|
|
135
|
+
result = module.call_symbol("exported_symbol", 123)
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
## Contributing
|
|
139
|
+
|
|
140
|
+
Bug reports and pull requests are welcome.
|
|
141
|
+
|
|
142
|
+
## Resources
|
|
143
|
+
|
|
144
|
+
- [Unidbg](https://github.com/zhkl0228/unidbg)
|
|
145
|
+
- [Unicorn](https://github.com/unicorn-engine/unicorn)
|
|
146
|
+
- [LIEF](https://github.com/lief-project/LIEF)
|
|
147
|
+
- [Capstone](https://github.com/capstone-engine/capstone)
|
emulite-0.1.0/README.md
ADDED
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
# About
|
|
2
|
+
|
|
3
|
+
Emulite is an emulation framework for Android native libraries, inspired by [Unidbg](https://github.com/zhkl0228/unidbg). iOS support is planned.
|
|
4
|
+
|
|
5
|
+
> [!WARNING]
|
|
6
|
+
> Emulite is an early release. Breaking API changes may occur in future releases, and bugs should be expected.
|
|
7
|
+
|
|
8
|
+
## Requirements
|
|
9
|
+
|
|
10
|
+
- Python 3.10+
|
|
11
|
+
- Unicorn 2.1.4+
|
|
12
|
+
- Capstone 5+
|
|
13
|
+
- LIEF 0.14+
|
|
14
|
+
- Cryptography 42+
|
|
15
|
+
|
|
16
|
+
## Project Status
|
|
17
|
+
|
|
18
|
+
### Supported Platforms
|
|
19
|
+
| Platform | ARM32 | ARM64 |
|
|
20
|
+
|----------|:-----:|:-----:|
|
|
21
|
+
| Android | ✅ AndroidEmulator32 | ✅ AndroidEmulator64 |
|
|
22
|
+
| iOS | — | ⏳ |
|
|
23
|
+
|
|
24
|
+
### Supported Engines
|
|
25
|
+
| Backend Engine | Status |
|
|
26
|
+
|----------|:-----:|
|
|
27
|
+
| Unicorn | ✅ |
|
|
28
|
+
| Dynarmic | — |
|
|
29
|
+
| Apple Silicon Hypervisor | — |
|
|
30
|
+
| Linux KVM Hypervisor | — |
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
<sub>✅ Supported · ⏳ Planned · — Not planned</sub>
|
|
34
|
+
|
|
35
|
+
## Examples
|
|
36
|
+
|
|
37
|
+
See the [examples](./examples) directory. To run them from a source checkout:
|
|
38
|
+
|
|
39
|
+
```console
|
|
40
|
+
python -m pip install -e .
|
|
41
|
+
python examples/apps/reddit_example.py
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
## Android Usage
|
|
45
|
+
|
|
46
|
+
Use `AndroidEmulator32` or `AndroidEmulator64` based on the target architecture. A default Android rootfs is included. Pass a path as the first argument to use a custom rootfs.
|
|
47
|
+
|
|
48
|
+
```python
|
|
49
|
+
from emulite import AndroidEmulator64, HookStatus, LogCategory, JniHandler
|
|
50
|
+
|
|
51
|
+
class CustomJniHandler(JniHandler):
|
|
52
|
+
# Unhandled methods raise `NotImplementedError`.
|
|
53
|
+
def call_static_method(self, method, args):
|
|
54
|
+
if method.java_class.name == "com/example/Device" and method.name == "getValue":
|
|
55
|
+
return "value"
|
|
56
|
+
return super().call_static_method(method, args)
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
def before_malloc(emu):
|
|
60
|
+
print("malloc size:", emu.arg(0))
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
def after_malloc(emu):
|
|
64
|
+
print("malloc returned:", hex(emu.ret))
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
def before_time(emu):
|
|
68
|
+
replacement_value = 150000
|
|
69
|
+
# emu.set_arg(0, replacement_value) # Store result in r0/x0
|
|
70
|
+
emu.finish(replacement_value)
|
|
71
|
+
return HookStatus.SKIP_ORIGINAL # Skip the original call
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
def on_instruction(emu, info):
|
|
75
|
+
print(info.format())
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
with AndroidEmulator64(jni_handler=CustomJniHandler(), log=LogCategory.NONE) as emu:
|
|
79
|
+
# Load the target ELF and its dependencies
|
|
80
|
+
module = emu.load("path/to/libnative.so")
|
|
81
|
+
|
|
82
|
+
# Hook malloc import
|
|
83
|
+
malloc_hook = emu.hook_symbol(
|
|
84
|
+
"malloc",
|
|
85
|
+
before_malloc,
|
|
86
|
+
after_malloc,
|
|
87
|
+
module_name=module.name, # Module name is optional
|
|
88
|
+
)
|
|
89
|
+
|
|
90
|
+
# Replace time() result
|
|
91
|
+
time_hook = emu.hook_symbol(
|
|
92
|
+
"time",
|
|
93
|
+
before_time,
|
|
94
|
+
module_name=module.name, # Module name is optional
|
|
95
|
+
)
|
|
96
|
+
|
|
97
|
+
# Run JNI_OnLoad
|
|
98
|
+
emu.call_jni_onload(module)
|
|
99
|
+
|
|
100
|
+
# Call JNI function
|
|
101
|
+
native = emu.java_class("com/example/Native")
|
|
102
|
+
result = native.call("getValue", "(I)I", 123)
|
|
103
|
+
|
|
104
|
+
# Trace executed instructions within the target module
|
|
105
|
+
trace = emu.trace_module(on_instruction, module.name)
|
|
106
|
+
result = native.call("getValue", "(I)I", 123)
|
|
107
|
+
trace.close()
|
|
108
|
+
|
|
109
|
+
malloc_hook.close()
|
|
110
|
+
time_hook.close()
|
|
111
|
+
|
|
112
|
+
# Allocate memory
|
|
113
|
+
buffer = emu.malloc(32)
|
|
114
|
+
buffer.write_cstr("testing")
|
|
115
|
+
print(buffer.read_cstr())
|
|
116
|
+
emu.free(buffer)
|
|
117
|
+
|
|
118
|
+
# Call a regular ELF export by name
|
|
119
|
+
result = module.call_symbol("exported_symbol", 123)
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
## Contributing
|
|
123
|
+
|
|
124
|
+
Bug reports and pull requests are welcome.
|
|
125
|
+
|
|
126
|
+
## Resources
|
|
127
|
+
|
|
128
|
+
- [Unidbg](https://github.com/zhkl0228/unidbg)
|
|
129
|
+
- [Unicorn](https://github.com/unicorn-engine/unicorn)
|
|
130
|
+
- [LIEF](https://github.com/lief-project/LIEF)
|
|
131
|
+
- [Capstone](https://github.com/capstone-engine/capstone)
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["hatchling"]
|
|
3
|
+
build-backend = "hatchling.build"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "emulite"
|
|
7
|
+
version = "0.1.0"
|
|
8
|
+
description = "A Python framework for emulating and instrumenting Android ARM32 and ARM64 native libraries."
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
requires-python = ">=3.10"
|
|
11
|
+
dependencies = [
|
|
12
|
+
"lief>=0.14",
|
|
13
|
+
"unicorn>=2.1.4",
|
|
14
|
+
"cryptography>=42",
|
|
15
|
+
"capstone>=5",
|
|
16
|
+
]
|
|
17
|
+
|
|
18
|
+
[project.optional-dependencies]
|
|
19
|
+
dev = ["pytest>=8", "ruff>=0.5"]
|
|
20
|
+
|
|
21
|
+
[project.urls]
|
|
22
|
+
Repository = "https://github.com/retrowave3/emulite"
|
|
23
|
+
Issues = "https://github.com/retrowave3/emulite/issues"
|
|
24
|
+
|
|
25
|
+
[tool.hatch.build.targets.wheel]
|
|
26
|
+
packages = ["src/emulite"]
|
|
27
|
+
|
|
28
|
+
[tool.hatch.build.targets.wheel.force-include]
|
|
29
|
+
"rootfs/android" = "emulite/rootfs/android"
|
|
30
|
+
|
|
31
|
+
[tool.hatch.build.targets.sdist]
|
|
32
|
+
include = [
|
|
33
|
+
"/src",
|
|
34
|
+
"/rootfs/android",
|
|
35
|
+
"/README.md",
|
|
36
|
+
"/pyproject.toml",
|
|
37
|
+
]
|
|
38
|
+
|
|
39
|
+
[tool.ruff]
|
|
40
|
+
line-length = 100
|