Troubleshooting
Server Won’t Start
# Check if port is already in use
adb shell "lsof | grep renef_server"
# Kill existing instance
adb shell "killall renef_server"
# Check permissions
adb shell "chmod +x /data/local/tmp/renef_server"
Injection Fails
# Check if process is running
adb shell "ps | grep <package>"
# Check SELinux status (may need permissive mode)
adb shell "getenforce"
# Try with root
adb root
Port Forwarding Issues
# Remove existing forward
adb forward --remove tcp:1907
# Re-setup forwarding
adb forward tcp:1907 localabstract:com.android.internal.os.RuntimeInit
# Verify forwarding
adb forward --list
Hooks Not Triggering
- Verify the offset is correct:
local exports = Module.exports("libc.so") for i, exp in ipairs(exports) do if exp.name == "malloc" then print(string.format("malloc offset: 0x%x", exp.offset)) end end - Check if hook type matches:
# Try PLT/GOT hooking instead of trampoline spawn com.example.app --hook=pltgot - Verify library is loaded:
local base = Module.find("libapp.so") if not base then print("Library not loaded yet") end
Memory Access Violations
-- Always check addresses before reading
local addr = 0x12345678
local success, err = pcall(function()
local data = Memory.read(addr, 16)
print("Data: " .. data)
end)
if not success then
print("Memory read failed: " .. err)
end
Client Connection Issues
# Check server is running
adb shell "ps | grep renef_server"
# Check port forwarding
adb forward --list
# Test connection
telnet localhost 1907
# Check firewall (macOS)
sudo pfctl -d # Disable firewall temporarily
Script Execution Errors
-- Use pcall for error handling
local success, err = pcall(function()
-- Your code here
hook("libc.so", 0x12340, {
onEnter = function(args)
print("Called")
end
})
end)
if not success then
print(RED .. "Error: " .. err .. RESET)
end
Build Errors
# Missing NDK
export NDK=$HOME/Library/Android/sdk/ndk/26.3.11579264
# Capstone not found
make setup
# Lua not found
make setup-lua
# Clean and rebuild
make clean
make all
Advanced Topics
Custom Hook Types
Renef supports two hooking methods:
Trampoline Hooking (Default)
- Inline hooking at function entry
- Modifies first instructions to jump to hook
- Works for any function
- Slight performance overhead
PLT/GOT Hooking
- Modifies Procedure Linkage Table / Global Offset Table
- Intercepts dynamic library calls
- Faster than trampoline
- Only works for imported functions
# Use trampoline (default)
spawn com.example.app
# Use PLT/GOT
spawn com.example.app --hook=pltgot
Session Keys
Renef uses session keys for security. Each injection generates a 32-character authentication key that must be prepended to agent commands. This is handled automatically by the client.
Filter Syntax
Many commands support filtering with the ~ operator:
# List apps containing "google"
la~google
# List specific package
la~com.example.app
The filter is sent to the agent, which applies it to the output.
Background Execution
# Start server in background on device
adb shell "nohup /data/local/tmp/renef_server > /dev/null 2>&1 &"
# Check if running
adb shell "ps | grep renef_server"
Multiple Devices
# List devices
adb devices
# Specify device
./build/renef -d emulator-5554 -s com.example.app
Performance Considerations
Hook Overhead
- Trampoline hooks add ~10-50ns per call
- PLT/GOT hooks add ~5-10ns per call
- Lua execution in hooks adds additional overhead
- Keep hook logic minimal for high-frequency functions
Memory Scanning
Memory.scan()scans all readable .so regions- Can be slow for large processes
- Use specific patterns to reduce matches
- Results are limited to 1000 matches by default
Script Loading
- Scripts are executed in the target process context
- Large scripts may cause temporary freeze
- Use
l script1.lua script2.luato load multiple files efficiently - Auto-watch mode (
-w) starts monitoring immediately after loading
API Comparison with Frida
Renef aims for API compatibility with Frida where possible:
| Frida | Renef | Notes |
|---|---|---|
Interceptor.attach() | hook() | Similar API, different syntax |
Module.load() | Module.find() | Returns base address |
Module.enumerateExports() | Module.exports() | Returns table |
Memory.scan() | Memory.scan() | Similar functionality |
Memory.readByteArray() | Memory.read() | Returns string |
Memory.writeByteArray() | Memory.patch() | Handles mprotect |
Java.use() | hook(class, method, sig) | Direct JNI hooking |
send() | print() | Output to client |