mirror of
https://github.com/frida/frida-python
synced 2026-06-08 14:16:17 +00:00
Compare commits
262 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 522366a55e | |||
| 8017d10e3e | |||
| e78a5fd3b3 | |||
| 5cbef2fb1f | |||
| 8694918de7 | |||
| ab16fe04c5 | |||
| a1d1740541 | |||
| 09d2a1aa54 | |||
| 215669c151 | |||
| f7b08f8375 | |||
| 133687aafc | |||
| 06130770e1 | |||
| 2d72d0be57 | |||
| d463d7f2f2 | |||
| 11613adee6 | |||
| 8dc6509929 | |||
| 3f8b122ce7 | |||
| 29abf88e31 | |||
| 5370147e85 | |||
| 507917744d | |||
| 8f2858fd8d | |||
| c2cf7fa951 | |||
| 9ff0651481 | |||
| 2674d6ef7d | |||
| 5d65919693 | |||
| d453cdd5ba | |||
| e8fd88f3d4 | |||
| 414cf0e029 | |||
| 76825537e8 | |||
| 2ab18cf80f | |||
| aaa703436b | |||
| 387962ab9d | |||
| 97f4c236a6 | |||
| 88cb2c97b8 | |||
| ec5035fd96 | |||
| bd883147ed | |||
| f7c32b2772 | |||
| 68009a8df9 | |||
| 85d56a0e45 | |||
| 228610a79c | |||
| d4b1b6aa8b | |||
| 29661c6b3b | |||
| d5b2a6fd18 | |||
| b862e9ae82 | |||
| 6e6f84969d | |||
| d6933eccf3 | |||
| 3bee61ffdb | |||
| 647e45f8bf | |||
| 5b6cfeba8b | |||
| c2b8043d8d | |||
| 69a4fa2ad2 | |||
| 546f65f25b | |||
| 168fcd5fe6 | |||
| 2ae7df42d0 | |||
| e8eff270ce | |||
| 62b6839d12 | |||
| d83456efe7 | |||
| fa62593fed | |||
| 305d2c1360 | |||
| 67b563a72c | |||
| d988aa2920 | |||
| d346babcf9 | |||
| 96a3777eb0 | |||
| 6c4ad9bf98 | |||
| 0490814f79 | |||
| 3c21f23327 | |||
| fe24ef56d1 | |||
| 2d8dca8d53 | |||
| 77f7d0f3c3 | |||
| c8f3b40aad | |||
| 7416839ae5 | |||
| 5c782dcc1c | |||
| de4f0e906d | |||
| 623cb160f8 | |||
| 3c265a483d | |||
| f43a1ed12c | |||
| 9201c4c007 | |||
| 135dac88ec | |||
| 28e8b1f32e | |||
| 0b7bde2fd4 | |||
| 6a18d4c4cc | |||
| 9a3ec81843 | |||
| ec55dcb3bc | |||
| e5404ae4eb | |||
| 64396bce72 | |||
| ccdd63dccc | |||
| e8f69618da | |||
| d809147cd0 | |||
| 24cc1fbcc9 | |||
| 7a2762ecc7 | |||
| d92b8e684c | |||
| 7c17bd5330 | |||
| 5991067e4e | |||
| 0780e5f813 | |||
| ce326094be | |||
| 092f6c38a1 | |||
| 9e83d29bd9 | |||
| 90533db5d4 | |||
| 30e009997e | |||
| 32e3c1922b | |||
| 69c5696aee | |||
| 0394ff3585 | |||
| c15b92fd55 | |||
| c53b453059 | |||
| d467d91e4f | |||
| ed3fdb8ce0 | |||
| 4d4632dbbe | |||
| aab9c4e76f | |||
| 2be19bcdad | |||
| 915c0678bd | |||
| 573a5a7d24 | |||
| 148ca1461d | |||
| 8eb4987563 | |||
| 84c7375044 | |||
| 267d5d555d | |||
| e219e5edbc | |||
| 70aaa04070 | |||
| 463fd65f03 | |||
| 41c3092dfe | |||
| 1b11eeab12 | |||
| 10aad4273c | |||
| d921e98e0c | |||
| 8935cf3651 | |||
| 2e3b9474bf | |||
| 582c2860c0 | |||
| 7c7947ee7c | |||
| 0f68038a10 | |||
| e9a3a37ea1 | |||
| f642de8a6b | |||
| c541ac027c | |||
| facd6756b2 | |||
| f29f486c0d | |||
| 2135414777 | |||
| ba032180c6 | |||
| b29cbcd499 | |||
| 55cdadea6a | |||
| 17d39c725c | |||
| 72f1d651b6 | |||
| 6d5c64d215 | |||
| 2b5f6492a2 | |||
| 316f88974d | |||
| fee73e852b | |||
| 37847fd8c9 | |||
| 7158638eb9 | |||
| 77d9c51109 | |||
| 040fa5536b | |||
| c9226b976a | |||
| d851e4eb6a | |||
| ccea05e00b | |||
| 6416edc773 | |||
| ce718c1dc9 | |||
| 0b854499cd | |||
| 243cce22e6 | |||
| c4d0fe55a5 | |||
| f3d767ecb6 | |||
| 8838d885ce | |||
| 213e373056 | |||
| 8b888558c7 | |||
| de55d964a0 | |||
| e920bad7f5 | |||
| 2b947e6d75 | |||
| 9992e8ad7a | |||
| 3c7eb89653 | |||
| 16f1be2a88 | |||
| 280c6d73f3 | |||
| 140dc6d13a | |||
| eac203e327 | |||
| bc3429a80d | |||
| e929477ecd | |||
| ebeb7a86b1 | |||
| 458a1f055a | |||
| de0b1643de | |||
| 7c39166f77 | |||
| 56e92493f5 | |||
| efdbd80fc6 | |||
| acfa48ac4a | |||
| 799745783d | |||
| 9d21327ee6 | |||
| 5b4dca5ad3 | |||
| cdba01185d | |||
| 57de3f8f39 | |||
| a8d4972d1a | |||
| 0c8080dfb1 | |||
| 6d9765c16d | |||
| e3e77ee884 | |||
| ccafc2f828 | |||
| 6eeda89bba | |||
| c06b6774e3 | |||
| 1086ae645d | |||
| 25270d43dd | |||
| 6ebf0fa13f | |||
| 4f7b72c769 | |||
| f30febad99 | |||
| 088ff058ca | |||
| 4d8f87ccaa | |||
| 801088b107 | |||
| f17944358d | |||
| 290e5f7c42 | |||
| 5643f45b2d | |||
| 091dfa2dbb | |||
| 78d0c062c7 | |||
| 433b067a50 | |||
| 980249dfc3 | |||
| daaa2cf7b3 | |||
| 0853244c43 | |||
| 555eeee4d8 | |||
| 8d85017a49 | |||
| 2095592071 | |||
| 238286a6c3 | |||
| 16061c58b2 | |||
| 961dbd8ea3 | |||
| a80896b788 | |||
| 91e2e4ff54 | |||
| 341d0e0dd0 | |||
| 49e716f803 | |||
| cd19587f34 | |||
| 2ce32efaff | |||
| 8935f80619 | |||
| 938e784957 | |||
| 73228d61f4 | |||
| e2fd7aaf9f | |||
| 338ff6f55f | |||
| a78280ea6f | |||
| 56ec6a46e7 | |||
| 9706e4be99 | |||
| 03206cfae4 | |||
| dfe260d7ac | |||
| 1b34793f14 | |||
| 17043a998f | |||
| 1f3ae462a6 | |||
| 37588948eb | |||
| 61fbf134c5 | |||
| 1d6f42e85f | |||
| d42d945be5 | |||
| cda2280dfc | |||
| 279313366b | |||
| 8cf13283ec | |||
| b33951be23 | |||
| 779dc7456c | |||
| bdece31ffa | |||
| 946d111ddd | |||
| a49088b8a0 | |||
| 241a2854c6 | |||
| d976283ca1 | |||
| 197cc4262c | |||
| 4bf45994a1 | |||
| c193dd49cd | |||
| 04e9308368 | |||
| d8da49058d | |||
| ae7c708934 | |||
| 8bf6a11aee | |||
| 88330bfbb9 | |||
| a053489965 | |||
| bd3e280cbf | |||
| 7df15667cc | |||
| a3c889855a | |||
| 8e2126da9a | |||
| 8685505b3e | |||
| ef1da26d94 | |||
| 59467c03c7 | |||
| ada39ecc55 | |||
| db97443e51 |
@@ -0,0 +1 @@
|
||||
github: frida
|
||||
+2
-1
@@ -1,5 +1,6 @@
|
||||
*.pyc
|
||||
*.user
|
||||
/*.egg-info/
|
||||
/build/
|
||||
/deps/
|
||||
/dist/
|
||||
/subprojects/*
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
[submodule "releng"]
|
||||
path = releng
|
||||
url = https://github.com/frida/releng.git
|
||||
@@ -0,0 +1,6 @@
|
||||
all: .DEFAULT
|
||||
|
||||
.DEFAULT:
|
||||
@gmake ${.MAKEFLAGS} ${.TARGETS}
|
||||
|
||||
.PHONY: all
|
||||
+19
@@ -0,0 +1,19 @@
|
||||
include meson.build
|
||||
include frida/meson.build
|
||||
include frida/_frida/extension.c
|
||||
include frida/_frida/extension.version
|
||||
include frida/_frida/meson.build
|
||||
include subprojects/frida-core.wrap
|
||||
|
||||
include BSDmakefile
|
||||
include Makefile
|
||||
include configure
|
||||
include configure.bat
|
||||
include make.bat
|
||||
include releng/*.py
|
||||
include releng/*.toml
|
||||
graft releng/devkit-assets/
|
||||
graft releng/meson-scripts/
|
||||
include releng/meson/meson.py
|
||||
graft releng/meson/mesonbuild/
|
||||
graft releng/tomlkit/tomlkit/
|
||||
@@ -0,0 +1,16 @@
|
||||
PYTHON ?= $(shell which python3 >/dev/null && echo python3 || echo python)
|
||||
|
||||
all $(MAKECMDGOALS):
|
||||
@$(PYTHON) \
|
||||
-c "import sys; sys.path.insert(0, sys.argv[1]); from releng.meson_make import main; main()" \
|
||||
"$(shell pwd)" \
|
||||
./build \
|
||||
$(MAKECMDGOALS)
|
||||
|
||||
git-submodules:
|
||||
@if [ ! -f releng/meson/meson.py ]; then \
|
||||
git submodule update --init --recursive --depth 1; \
|
||||
fi
|
||||
-include git-submodules
|
||||
|
||||
.PHONY: all $(MAKECMDGOALS)
|
||||
-19
@@ -1,19 +0,0 @@
|
||||
/* config.h.in. Generated from configure.ac by autoheader. */
|
||||
|
||||
/* Define to 1 if OS is Android based. */
|
||||
#mesondefine HAVE_ANDROID
|
||||
|
||||
/* Define to 1 if OS is Darwin based. */
|
||||
#mesondefine HAVE_DARWIN
|
||||
|
||||
/* Define to 1 if OS is iOS. */
|
||||
#mesondefine HAVE_IOS
|
||||
|
||||
/* Define to 1 if OS is Linux based. */
|
||||
#mesondefine HAVE_LINUX
|
||||
|
||||
/* Define to 1 if OS is macOS. */
|
||||
#mesondefine HAVE_MACOS
|
||||
|
||||
/* Define to 1 if OS is QNX based. */
|
||||
#mesondefine HAVE_QNX
|
||||
@@ -0,0 +1,18 @@
|
||||
#!/bin/sh
|
||||
|
||||
[ -z "$PYTHON" ] && PYTHON=$(which python3 >/dev/null && echo python3 || echo python)
|
||||
|
||||
cd $(dirname $0)
|
||||
|
||||
srcroot=$(pwd)
|
||||
|
||||
if [ ! -f releng/meson/meson.py ]; then
|
||||
git submodule update --init --recursive --depth 1 || exit $?
|
||||
fi
|
||||
|
||||
cd - >/dev/null
|
||||
|
||||
exec "$PYTHON" \
|
||||
-c "import sys; sys.path.insert(0, sys.argv[1]); from releng.meson_configure import main; main()" \
|
||||
"$srcroot" \
|
||||
"$@"
|
||||
@@ -0,0 +1,22 @@
|
||||
@setlocal
|
||||
@echo off
|
||||
rem:: Based on: https://github.com/microsoft/terminal/issues/217#issuecomment-737594785
|
||||
goto :_start_
|
||||
|
||||
:set_real_dp0
|
||||
set dp0=%~dp0
|
||||
set "dp0=%dp0:~0,-1%"
|
||||
goto :eof
|
||||
|
||||
:_start_
|
||||
call :set_real_dp0
|
||||
|
||||
if not exist "%dp0%\releng\meson\meson.py" (
|
||||
pushd "%dp0%" & git submodule update --init --recursive --depth 1 & popd
|
||||
if %errorlevel% neq 0 exit /b %errorlevel%
|
||||
)
|
||||
|
||||
endlocal & goto #_undefined_# 2>nul || title %COMSPEC% & python ^
|
||||
-c "import sys; sys.path.insert(0, sys.argv[1]); from releng.meson_configure import main; main()" ^
|
||||
"%dp0%" ^
|
||||
%*
|
||||
@@ -0,0 +1,9 @@
|
||||
import pprint
|
||||
|
||||
import frida
|
||||
|
||||
device = frida.get_usb_device()
|
||||
|
||||
deviceinfo = device.open_service("dtx:com.apple.instruments.server.services.deviceinfo")
|
||||
response = deviceinfo.request({"method": "runningProcesses"})
|
||||
pprint.pp(response)
|
||||
@@ -0,0 +1,27 @@
|
||||
import sys
|
||||
|
||||
import frida
|
||||
|
||||
|
||||
def on_message(message):
|
||||
print("on_message:", message)
|
||||
|
||||
|
||||
device = frida.get_usb_device()
|
||||
|
||||
opengl = device.open_service("dtx:com.apple.instruments.server.services.graphics.opengl")
|
||||
opengl.on("message", on_message)
|
||||
opengl.request(
|
||||
{
|
||||
"method": "setSamplingRate:",
|
||||
"args": [5.0],
|
||||
}
|
||||
)
|
||||
opengl.request(
|
||||
{
|
||||
"method": "startSamplingAtTimeInterval:",
|
||||
"args": [0.0],
|
||||
}
|
||||
)
|
||||
|
||||
sys.stdin.read()
|
||||
@@ -0,0 +1,31 @@
|
||||
import sys
|
||||
|
||||
import frida
|
||||
|
||||
|
||||
def on_message(message):
|
||||
print("on_message:", message)
|
||||
|
||||
|
||||
device = frida.get_usb_device()
|
||||
|
||||
control = device.open_service("dtx:com.apple.instruments.server.services.processcontrol")
|
||||
control.on("message", on_message)
|
||||
pid = control.request(
|
||||
{
|
||||
"method": "launchSuspendedProcessWithDevicePath:bundleIdentifier:environment:arguments:options:",
|
||||
"args": [
|
||||
"",
|
||||
"no.oleavr.HelloIOS",
|
||||
{},
|
||||
[],
|
||||
{
|
||||
"StartSuspendedKey": False,
|
||||
},
|
||||
],
|
||||
}
|
||||
)
|
||||
control.request({"method": "startObservingPid:", "args": [pid]})
|
||||
|
||||
print(f"App spawned, PID: {pid}. Kill it to see an example message being emitted.")
|
||||
sys.stdin.read()
|
||||
@@ -0,0 +1,15 @@
|
||||
import sys
|
||||
|
||||
import frida
|
||||
|
||||
if len(sys.argv) != 2:
|
||||
print(f"Usage: {sys.argv[0]} outfile.png", file=sys.stderr)
|
||||
sys.exit(1)
|
||||
outfile = sys.argv[1]
|
||||
|
||||
device = frida.get_usb_device()
|
||||
|
||||
screenshot = device.open_service("dtx:com.apple.instruments.server.services.screenshot")
|
||||
png = screenshot.request({"method": "takeScreenshot"})
|
||||
with open(outfile, "wb") as f:
|
||||
f.write(png)
|
||||
@@ -0,0 +1,29 @@
|
||||
import time
|
||||
|
||||
import frida
|
||||
|
||||
|
||||
def on_message(message):
|
||||
print("on_message:", message)
|
||||
|
||||
|
||||
device = frida.get_usb_device()
|
||||
|
||||
sysmon = device.open_service("dtx:com.apple.instruments.server.services.sysmontap")
|
||||
sysmon.on("message", on_message)
|
||||
sysmon.request(
|
||||
{
|
||||
"method": "setConfig:",
|
||||
"args": [
|
||||
{
|
||||
"ur": 1000,
|
||||
"cpuUsage": True,
|
||||
"sampleInterval": 1000000000,
|
||||
},
|
||||
],
|
||||
}
|
||||
)
|
||||
sysmon.request({"method": "start"})
|
||||
time.sleep(5)
|
||||
sysmon.request({"method": "stop"})
|
||||
time.sleep(1)
|
||||
@@ -0,0 +1,7 @@
|
||||
import frida
|
||||
|
||||
device = frida.get_usb_device()
|
||||
|
||||
diag = device.open_service("plist:com.apple.mobile.diagnostics_relay")
|
||||
diag.request({"type": "query", "payload": {"Request": "Sleep", "WaitForDisconnect": True}})
|
||||
diag.request({"type": "query", "payload": {"Request": "Goodbye"}})
|
||||
@@ -0,0 +1,64 @@
|
||||
import pprint
|
||||
import sys
|
||||
from threading import Thread
|
||||
|
||||
import frida
|
||||
|
||||
|
||||
def main():
|
||||
device = frida.get_usb_device()
|
||||
|
||||
stdout_uuid, stdout_stream = create_stdio_socket(device)
|
||||
stderr_uuid, stderr_stream = create_stdio_socket(device)
|
||||
|
||||
appservice = device.open_service("xpc:com.apple.coredevice.appservice")
|
||||
response = appservice.request(
|
||||
{
|
||||
"CoreDevice.featureIdentifier": "com.apple.coredevice.feature.launchapplication",
|
||||
"CoreDevice.action": {},
|
||||
"CoreDevice.input": {
|
||||
"applicationSpecifier": {
|
||||
"bundleIdentifier": {"_0": "no.oleavr.HelloIOS"},
|
||||
},
|
||||
"options": {
|
||||
"arguments": [],
|
||||
"environmentVariables": {},
|
||||
"standardIOUsesPseudoterminals": True,
|
||||
"startStopped": False,
|
||||
"terminateExisting": True,
|
||||
"user": {"active": True},
|
||||
"platformSpecificOptions": b'<?xml version="1.0" encoding="UTF-8"?><plist version="1.0"><dict/></plist>',
|
||||
},
|
||||
"standardIOIdentifiers": {
|
||||
"standardOutput": ("uuid", stdout_uuid),
|
||||
"standardError": ("uuid", stderr_uuid),
|
||||
},
|
||||
},
|
||||
}
|
||||
)
|
||||
pprint.pp(response)
|
||||
|
||||
workers = set()
|
||||
for stream, sink in {(stdout_stream, sys.stdout), (stderr_stream, sys.stderr)}:
|
||||
t = Thread(target=process_console_output, args=(stream, sink))
|
||||
t.start()
|
||||
workers.add(t)
|
||||
for worker in workers:
|
||||
worker.join()
|
||||
|
||||
|
||||
def create_stdio_socket(device):
|
||||
stream = device.open_channel("tcp:com.apple.coredevice.openstdiosocket")
|
||||
return (stream.read_all(16), stream)
|
||||
|
||||
|
||||
def process_console_output(stream, sink):
|
||||
while True:
|
||||
chunk = stream.read(4096)
|
||||
if not chunk:
|
||||
break
|
||||
sink.write(chunk.decode("utf-8"))
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
@@ -0,0 +1,15 @@
|
||||
import pprint
|
||||
|
||||
import frida
|
||||
|
||||
device = frida.get_usb_device()
|
||||
|
||||
appservice = device.open_service("xpc:com.apple.coredevice.appservice")
|
||||
response = appservice.request(
|
||||
{
|
||||
"CoreDevice.featureIdentifier": "com.apple.coredevice.feature.listprocesses",
|
||||
"CoreDevice.action": {},
|
||||
"CoreDevice.input": {},
|
||||
}
|
||||
)
|
||||
pprint.pp(response)
|
||||
@@ -1,176 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug|Win32">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Debug|x64">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|Win32">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|x64">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<ProjectGuid>{7505F884-DD69-4F23-ADE6-1E0E049AB018}</ProjectGuid>
|
||||
<RootNamespace>frida</RootNamespace>
|
||||
<Keyword>Win32Proj</Keyword>
|
||||
<ProjectName>frida-python</ProjectName>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<WholeProgramOptimization>false</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<WholeProgramOptimization>false</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(SolutionDir)releng\frida-toolchain.props" />
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
<Import Project="$(SolutionDir)releng\frida-$(Configuration).props" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
<Import Project="$(SolutionDir)releng\frida-$(Configuration).props" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
<Import Project="$(SolutionDir)releng\frida-$(Configuration).props" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
<Import Project="$(SolutionDir)releng\frida-$(Configuration).props" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup>
|
||||
<_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion>
|
||||
<OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(SolutionDir)build\frida-windows\$(PlatformName)-$(Configuration)\lib\python3.10\site-packages\</OutDir>
|
||||
<OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(SolutionDir)build\frida-windows\$(PlatformName)-$(Configuration)\lib\python3.10\site-packages\</OutDir>
|
||||
<OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(SolutionDir)build\frida-windows\$(PlatformName)-$(Configuration)\lib\python3.10\site-packages\</OutDir>
|
||||
<OutDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(SolutionDir)build\frida-windows\$(PlatformName)-$(Configuration)\lib\python3.10\site-packages\</OutDir>
|
||||
<TargetName Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">_frida</TargetName>
|
||||
<TargetName Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">_frida</TargetName>
|
||||
<TargetName Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">_frida</TargetName>
|
||||
<TargetName Condition="'$(Configuration)|$(Platform)'=='Release|x64'">_frida</TargetName>
|
||||
<TargetExt Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">.pyd</TargetExt>
|
||||
<TargetExt Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">.pyd</TargetExt>
|
||||
<TargetExt Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">.pyd</TargetExt>
|
||||
<TargetExt Condition="'$(Configuration)|$(Platform)'=='Release|x64'">.pyd</TargetExt>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<AdditionalLibraryDirectories>$(PythonLocation)\libs;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
</Link>
|
||||
<ClCompile>
|
||||
<AdditionalIncludeDirectories>$(IntDir)..\frida-core\api;$(PythonLocation)\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>$(FridaComponentDefines);%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
</ClCompile>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<AdditionalLibraryDirectories>$(PythonLocation)\libs;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
</Link>
|
||||
<ClCompile>
|
||||
<AdditionalIncludeDirectories>$(IntDir)..\frida-core\api;$(PythonLocation)\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>$(FridaComponentDefines);%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
</ClCompile>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<AdditionalLibraryDirectories>$(PythonLocation)\libs;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
</Link>
|
||||
<ClCompile>
|
||||
<AdditionalIncludeDirectories>$(IntDir)..\frida-core\api;$(PythonLocation)\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>$(FridaComponentDefines);%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
</ClCompile>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<AdditionalLibraryDirectories>$(PythonLocation)\libs;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
</Link>
|
||||
<ClCompile>
|
||||
<AdditionalIncludeDirectories>$(IntDir)..\frida-core\api;$(PythonLocation)\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>$(FridaComponentDefines);%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
</ClCompile>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\frida-core\frida-core.vcxproj">
|
||||
<Project>{b7dc9b02-a5ff-4aa1-b2a2-dc1653168d44}</Project>
|
||||
<Private>false</Private>
|
||||
<ReferenceOutputAssembly>true</ReferenceOutputAssembly>
|
||||
<CopyLocalSatelliteAssemblies>false</CopyLocalSatelliteAssemblies>
|
||||
<LinkLibraryDependencies>true</LinkLibraryDependencies>
|
||||
<UseLibraryDependencyInputs>false</UseLibraryDependencyInputs>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="src\_frida.c" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<CustomBuild Include="frida\__init__.py">
|
||||
<FileType>Document</FileType>
|
||||
<Message Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Installing frida package</Message>
|
||||
<Message Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Installing frida package</Message>
|
||||
<Message Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Installing frida package</Message>
|
||||
<Message Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Installing frida package</Message>
|
||||
<Command Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">rmdir /S /Q $(OutDir)frida 2>NUL
|
||||
mkdir $(OutDir)frida || exit 1
|
||||
copy /B /Y "$(ProjectDir)frida\*.py" $(OutDir)frida || exit 1
|
||||
echo. > $(IntDir)frida-package.stamp</Command>
|
||||
<Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(IntDir)frida-package.stamp</Outputs>
|
||||
<AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(ProjectDir)frida\core.py</AdditionalInputs>
|
||||
<Command Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">rmdir /S /Q $(OutDir)frida 2>NUL
|
||||
mkdir $(OutDir)frida || exit 1
|
||||
copy /B /Y "$(ProjectDir)frida\*.py" $(OutDir)frida || exit 1
|
||||
echo. > $(IntDir)frida-package.stamp</Command>
|
||||
<Outputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(IntDir)frida-package.stamp</Outputs>
|
||||
<AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(ProjectDir)frida\core.py</AdditionalInputs>
|
||||
<Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">rmdir /S /Q $(OutDir)frida 2>NUL
|
||||
mkdir $(OutDir)frida || exit 1
|
||||
copy /B /Y "$(ProjectDir)frida\*.py" $(OutDir)frida || exit 1
|
||||
echo. > $(IntDir)frida-package.stamp</Command>
|
||||
<Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(IntDir)frida-package.stamp</Outputs>
|
||||
<AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(ProjectDir)frida\core.py</AdditionalInputs>
|
||||
<Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">rmdir /S /Q $(OutDir)frida 2>NUL
|
||||
mkdir $(OutDir)frida || exit 1
|
||||
copy /B /Y "$(ProjectDir)frida\*.py" $(OutDir)frida || exit 1
|
||||
echo. > $(IntDir)frida-package.stamp</Command>
|
||||
<Outputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(IntDir)frida-package.stamp</Outputs>
|
||||
<AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(ProjectDir)frida\core.py</AdditionalInputs>
|
||||
</CustomBuild>
|
||||
<None Include="frida\core.py" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
||||
@@ -1,35 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup>
|
||||
<Filter Include="Source Files">
|
||||
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
|
||||
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="Header Files">
|
||||
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
|
||||
<Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="Resource Files">
|
||||
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
|
||||
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="Source Files\frida">
|
||||
<UniqueIdentifier>{e8366f87-de40-4415-8724-a51c48fc532d}</UniqueIdentifier>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="src\_frida.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="frida\core.py">
|
||||
<Filter>Source Files\frida</Filter>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<CustomBuild Include="frida\__init__.py">
|
||||
<Filter>Source Files\frida</Filter>
|
||||
</CustomBuild>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
+1
-1
@@ -1,7 +1,7 @@
|
||||
from typing import Any, Callable, Dict, List, Optional, Tuple, Union
|
||||
|
||||
try:
|
||||
import _frida
|
||||
from . import _frida
|
||||
except Exception as ex:
|
||||
print("")
|
||||
print("***")
|
||||
|
||||
@@ -23,6 +23,7 @@ class Object:
|
||||
Add a signal handler.
|
||||
"""
|
||||
...
|
||||
|
||||
def off(self, signal: str, callback: Callable[..., Any]) -> None:
|
||||
"""
|
||||
Remove a signal handler.
|
||||
@@ -36,18 +37,21 @@ class Application(Object):
|
||||
Application identifier.
|
||||
"""
|
||||
...
|
||||
|
||||
@property
|
||||
def name(self) -> str:
|
||||
"""
|
||||
Human-readable application name.
|
||||
"""
|
||||
...
|
||||
|
||||
@property
|
||||
def parameters(self) -> Dict[str, Any]:
|
||||
"""
|
||||
Parameters.
|
||||
"""
|
||||
...
|
||||
|
||||
@property
|
||||
def pid(self) -> int:
|
||||
"""
|
||||
@@ -61,6 +65,7 @@ class Bus(Object):
|
||||
Attach to the bus.
|
||||
"""
|
||||
...
|
||||
|
||||
def post(self, message: str, data: Optional[Union[bytes, str]]) -> None:
|
||||
"""
|
||||
Post a JSON-encoded message to the bus.
|
||||
@@ -73,47 +78,56 @@ class Cancellable(Object):
|
||||
Set cancellable to cancelled.
|
||||
"""
|
||||
...
|
||||
|
||||
def connect(self, callback: Callable[..., Any]) -> int:
|
||||
"""
|
||||
Register notification callback.
|
||||
"""
|
||||
...
|
||||
|
||||
def disconnect(self, handler_id: int) -> None:
|
||||
"""
|
||||
Unregister notification callback.
|
||||
"""
|
||||
...
|
||||
|
||||
@classmethod
|
||||
def get_current(cls) -> "Cancellable":
|
||||
"""
|
||||
Get the top cancellable from the stack.
|
||||
"""
|
||||
...
|
||||
|
||||
def get_fd(self) -> int:
|
||||
"""
|
||||
Get file descriptor for integrating with an event loop.
|
||||
"""
|
||||
...
|
||||
|
||||
def is_cancelled(self) -> bool:
|
||||
"""
|
||||
Query whether cancellable has been cancelled.
|
||||
"""
|
||||
...
|
||||
|
||||
def pop_current(self) -> None:
|
||||
"""
|
||||
Pop cancellable off the cancellable stack.
|
||||
"""
|
||||
...
|
||||
|
||||
def push_current(self) -> None:
|
||||
"""
|
||||
Push cancellable onto the cancellable stack.
|
||||
"""
|
||||
...
|
||||
|
||||
def raise_if_cancelled(self) -> None:
|
||||
"""
|
||||
Raise an exception if cancelled.
|
||||
"""
|
||||
...
|
||||
|
||||
def release_fd(self) -> None:
|
||||
"""
|
||||
Release a resource previously allocated by get_fd().
|
||||
@@ -127,36 +141,42 @@ class Child(Object):
|
||||
Argument vector.
|
||||
"""
|
||||
...
|
||||
|
||||
@property
|
||||
def envp(self) -> Dict[str, str]:
|
||||
"""
|
||||
Environment vector.
|
||||
"""
|
||||
...
|
||||
|
||||
@property
|
||||
def identifier(self) -> str:
|
||||
"""
|
||||
Application identifier.
|
||||
"""
|
||||
...
|
||||
|
||||
@property
|
||||
def origin(self) -> str:
|
||||
"""
|
||||
Origin.
|
||||
"""
|
||||
...
|
||||
|
||||
@property
|
||||
def parent_pid(self) -> int:
|
||||
"""
|
||||
Parent Process ID.
|
||||
"""
|
||||
...
|
||||
|
||||
@property
|
||||
def path(self) -> str:
|
||||
"""
|
||||
Path of executable.
|
||||
"""
|
||||
...
|
||||
|
||||
@property
|
||||
def pid(self) -> int:
|
||||
"""
|
||||
@@ -171,24 +191,28 @@ class Crash(Object):
|
||||
Parameters.
|
||||
"""
|
||||
...
|
||||
|
||||
@property
|
||||
def pid(self) -> int:
|
||||
"""
|
||||
Process ID.
|
||||
"""
|
||||
...
|
||||
|
||||
@property
|
||||
def process_name(self) -> str:
|
||||
"""
|
||||
Process name.
|
||||
"""
|
||||
...
|
||||
|
||||
@property
|
||||
def report(self) -> str:
|
||||
"""
|
||||
Human-readable crash report.
|
||||
"""
|
||||
...
|
||||
|
||||
@property
|
||||
def summary(self) -> str:
|
||||
"""
|
||||
@@ -203,45 +227,53 @@ class Device(Object):
|
||||
Device ID.
|
||||
"""
|
||||
...
|
||||
|
||||
@property
|
||||
def name(self) -> Optional[str]:
|
||||
"""
|
||||
Human-readable device name.
|
||||
"""
|
||||
...
|
||||
|
||||
@property
|
||||
def icon(self) -> Optional[Any]:
|
||||
"""
|
||||
Icon.
|
||||
"""
|
||||
...
|
||||
|
||||
@property
|
||||
def type(self) -> Optional[str]:
|
||||
"""
|
||||
Device type. One of: local, remote, usb.
|
||||
"""
|
||||
...
|
||||
|
||||
@property
|
||||
def bus(self) -> Optional[Bus]:
|
||||
"""
|
||||
Message bus.
|
||||
"""
|
||||
...
|
||||
|
||||
def attach(self, pid: int, realm: Optional[str] = None, persist_timeout: Optional[int] = None) -> "Session":
|
||||
"""
|
||||
Attach to a PID.
|
||||
"""
|
||||
...
|
||||
|
||||
def disable_spawn_gating(self) -> None:
|
||||
"""
|
||||
Disable spawn gating.
|
||||
"""
|
||||
...
|
||||
|
||||
def enable_spawn_gating(self) -> None:
|
||||
"""
|
||||
Enable spawn gating.
|
||||
"""
|
||||
...
|
||||
|
||||
def enumerate_applications(
|
||||
self, identifiers: Optional[Sequence[str]] = None, scope: Optional[str] = None
|
||||
) -> List[Application]:
|
||||
@@ -249,71 +281,91 @@ class Device(Object):
|
||||
Enumerate applications.
|
||||
"""
|
||||
...
|
||||
|
||||
def enumerate_pending_children(self) -> List[Child]:
|
||||
"""
|
||||
Enumerate pending children.
|
||||
"""
|
||||
...
|
||||
|
||||
def enumerate_pending_spawn(self) -> List["Spawn"]:
|
||||
"""
|
||||
Enumerate pending spawn.
|
||||
"""
|
||||
...
|
||||
|
||||
def enumerate_processes(self, pids: Optional[Sequence[int]] = None, scope: Optional[str] = None) -> List[Process]:
|
||||
"""
|
||||
Enumerate processes.
|
||||
"""
|
||||
...
|
||||
|
||||
def get_frontmost_application(self, scope: Optional[str] = None) -> Optional[Application]:
|
||||
"""
|
||||
Get details about the frontmost application.
|
||||
"""
|
||||
...
|
||||
|
||||
def inject_library_blob(self, pid: int, blob_buffer: bytes, entrypoint: str, data: str) -> int:
|
||||
"""
|
||||
Inject a library blob to a PID.
|
||||
"""
|
||||
...
|
||||
|
||||
def inject_library_file(self, pid: int, path: str, entrypoint: str, data: str) -> int:
|
||||
"""
|
||||
Inject a library file to a PID.
|
||||
"""
|
||||
...
|
||||
|
||||
def input(self, pid: int, data: bytes) -> None:
|
||||
"""
|
||||
Input data on stdin of a spawned process.
|
||||
"""
|
||||
...
|
||||
|
||||
def is_lost(self) -> bool:
|
||||
"""
|
||||
Query whether the device has been lost.
|
||||
"""
|
||||
...
|
||||
|
||||
def kill(self, pid: int) -> None:
|
||||
"""
|
||||
Kill a PID.
|
||||
"""
|
||||
...
|
||||
|
||||
def open_channel(self, address: str) -> "IOStream":
|
||||
"""
|
||||
Open a device-specific communication channel.
|
||||
"""
|
||||
...
|
||||
|
||||
def open_service(self, address: str) -> Service:
|
||||
"""
|
||||
Open a device-specific service.
|
||||
"""
|
||||
...
|
||||
|
||||
def unpair(self) -> None:
|
||||
"""
|
||||
Unpair device.
|
||||
"""
|
||||
...
|
||||
|
||||
def query_system_parameters(self) -> Dict[str, Any]:
|
||||
"""
|
||||
Returns a dictionary of information about the host system.
|
||||
"""
|
||||
...
|
||||
|
||||
def resume(self, pid: int) -> None:
|
||||
"""
|
||||
Resume a process from the attachable state.
|
||||
"""
|
||||
...
|
||||
|
||||
def spawn(
|
||||
self,
|
||||
program: str,
|
||||
@@ -342,21 +394,25 @@ class DeviceManager(Object):
|
||||
Add a remote device.
|
||||
"""
|
||||
...
|
||||
|
||||
def close(self) -> None:
|
||||
"""
|
||||
Close the device manager.
|
||||
"""
|
||||
...
|
||||
|
||||
def enumerate_devices(self) -> List[Device]:
|
||||
"""
|
||||
Enumerate devices.
|
||||
"""
|
||||
...
|
||||
|
||||
def get_device_matching(self, predicate: Callable[[Device], bool], timeout: int) -> Device:
|
||||
"""
|
||||
Get device matching predicate.
|
||||
"""
|
||||
...
|
||||
|
||||
def remove_remote_device(self, address: str) -> None:
|
||||
"""
|
||||
Remove a remote device.
|
||||
@@ -371,6 +427,7 @@ class FileMonitor(Object):
|
||||
Disable the file monitor.
|
||||
"""
|
||||
...
|
||||
|
||||
def enable(self) -> None:
|
||||
"""
|
||||
Enable the file monitor.
|
||||
@@ -383,26 +440,31 @@ class IOStream(Object):
|
||||
Close the stream.
|
||||
"""
|
||||
...
|
||||
|
||||
def is_closed(self) -> bool:
|
||||
"""
|
||||
Query whether the stream is closed.
|
||||
"""
|
||||
...
|
||||
|
||||
def read(self, size: int) -> bytes:
|
||||
"""
|
||||
Read up to the specified number of bytes from the stream.
|
||||
"""
|
||||
...
|
||||
|
||||
def read_all(self, size: int) -> bytes:
|
||||
"""
|
||||
Read exactly the specified number of bytes from the stream.
|
||||
"""
|
||||
...
|
||||
|
||||
def write(self, data: bytes) -> int:
|
||||
"""
|
||||
Write as much as possible of the provided data to the stream.
|
||||
"""
|
||||
...
|
||||
|
||||
def write_all(self, data: bytes) -> None:
|
||||
"""
|
||||
Write all of the provided data to the stream.
|
||||
@@ -423,46 +485,55 @@ class PortalService(Object):
|
||||
Device for in-process control.
|
||||
"""
|
||||
...
|
||||
|
||||
def broadcast(self, message: str, data: Optional[Union[str, bytes]] = None) -> None:
|
||||
"""
|
||||
Broadcast a message to all control channels.
|
||||
"""
|
||||
...
|
||||
|
||||
def enumerate_tags(self, connection_id: int) -> List[str]:
|
||||
"""
|
||||
Enumerate tags of a specific connection.
|
||||
"""
|
||||
...
|
||||
|
||||
def kick(self, connection_id: int) -> None:
|
||||
"""
|
||||
Kick out a specific connection.
|
||||
"""
|
||||
...
|
||||
|
||||
def narrowcast(self, tag: str, message: str, data: Optional[Union[str, bytes]] = None) -> None:
|
||||
"""
|
||||
Post a message to control channels with a specific tag.
|
||||
"""
|
||||
...
|
||||
|
||||
def post(self, connection_id: int, message: str, data: Optional[Union[str, bytes]] = None) -> None:
|
||||
"""
|
||||
Post a message to a specific control channel.
|
||||
"""
|
||||
...
|
||||
|
||||
def start(self) -> None:
|
||||
"""
|
||||
Start listening for incoming connections.
|
||||
"""
|
||||
...
|
||||
|
||||
def stop(self) -> None:
|
||||
"""
|
||||
Stop listening for incoming connections, and kick any connected clients.
|
||||
"""
|
||||
...
|
||||
|
||||
def tag(self, connection_id: int, tag: str) -> None:
|
||||
"""
|
||||
Tag a specific control channel.
|
||||
"""
|
||||
...
|
||||
|
||||
def untag(self, connection_id: int, tag: str) -> None:
|
||||
"""
|
||||
Untag a specific control channel.
|
||||
@@ -476,12 +547,14 @@ class Process(Object):
|
||||
Process ID.
|
||||
"""
|
||||
...
|
||||
|
||||
@property
|
||||
def name(self) -> str:
|
||||
"""
|
||||
Human-readable process name.
|
||||
"""
|
||||
...
|
||||
|
||||
@property
|
||||
def parameters(self) -> Dict[str, Any]:
|
||||
"""
|
||||
@@ -497,18 +570,21 @@ class Relay(Object):
|
||||
Network address or address:port of the TURN server.
|
||||
"""
|
||||
...
|
||||
|
||||
@property
|
||||
def kind(self) -> str:
|
||||
"""
|
||||
Relay kind. One of: turn-udp, turn-tcp, turn-tls.
|
||||
"""
|
||||
...
|
||||
|
||||
@property
|
||||
def password(self) -> str:
|
||||
"""
|
||||
The TURN password to use for the allocate request.
|
||||
"""
|
||||
...
|
||||
|
||||
@property
|
||||
def username(self) -> str:
|
||||
"""
|
||||
@@ -522,37 +598,62 @@ class Script(Object):
|
||||
Eternalize the script.
|
||||
"""
|
||||
...
|
||||
|
||||
def is_destroyed(self) -> bool:
|
||||
"""
|
||||
Query whether the script has been destroyed.
|
||||
"""
|
||||
...
|
||||
|
||||
def load(self) -> None:
|
||||
"""
|
||||
Load the script.
|
||||
"""
|
||||
...
|
||||
|
||||
def post(self, message: str, data: Optional[Union[str, bytes]] = None) -> None:
|
||||
"""
|
||||
Post a JSON-encoded message to the script.
|
||||
"""
|
||||
...
|
||||
|
||||
def unload(self) -> None:
|
||||
"""
|
||||
Unload the script.
|
||||
"""
|
||||
...
|
||||
|
||||
def enable_debugger(self, port: Optional[int]) -> None:
|
||||
"""
|
||||
Enable the Node.js compatible script debugger
|
||||
"""
|
||||
...
|
||||
|
||||
def disable_debugger(self) -> None:
|
||||
"""
|
||||
Disable the Node.js compatible script debugger
|
||||
"""
|
||||
...
|
||||
|
||||
class Service(Object):
|
||||
def activate(self) -> None:
|
||||
"""
|
||||
Activate the service.
|
||||
"""
|
||||
...
|
||||
|
||||
def cancel(self) -> None:
|
||||
"""
|
||||
Cancel the service.
|
||||
"""
|
||||
...
|
||||
|
||||
def request(self, parameters: Any) -> Any:
|
||||
"""
|
||||
Perform a request.
|
||||
"""
|
||||
...
|
||||
|
||||
class Session(Object):
|
||||
@property
|
||||
def pid(self) -> int:
|
||||
@@ -560,16 +661,19 @@ class Session(Object):
|
||||
Process ID.
|
||||
"""
|
||||
...
|
||||
|
||||
def compile_script(self, source: str, name: Optional[str] = None, runtime: Optional[str] = None) -> bytes:
|
||||
"""
|
||||
Compile script source code to bytecode.
|
||||
"""
|
||||
...
|
||||
|
||||
def create_script(self, source: str, name: Optional[str] = None, runtime: Optional[str] = None) -> Script:
|
||||
"""
|
||||
Create a new script.
|
||||
"""
|
||||
...
|
||||
|
||||
def create_script_from_bytes(
|
||||
self, data: bytes, name: Optional[str] = None, runtime: Optional[str] = None
|
||||
) -> Script:
|
||||
@@ -577,31 +681,37 @@ class Session(Object):
|
||||
Create a new script from bytecode.
|
||||
"""
|
||||
...
|
||||
|
||||
def snapshot_script(self, embed_script: str, warmup_script: Optional[str], runtime: Optional[str] = None) -> bytes:
|
||||
"""
|
||||
Evaluate script and snapshot the resulting VM state
|
||||
"""
|
||||
...
|
||||
|
||||
def detach(self) -> None:
|
||||
"""
|
||||
Detach session from the process.
|
||||
"""
|
||||
...
|
||||
|
||||
def disable_child_gating(self) -> None:
|
||||
"""
|
||||
Disable child gating.
|
||||
"""
|
||||
...
|
||||
|
||||
def enable_child_gating(self) -> None:
|
||||
"""
|
||||
Enable child gating.
|
||||
"""
|
||||
...
|
||||
|
||||
def is_detached(self) -> bool:
|
||||
"""
|
||||
Query whether the session is detached.
|
||||
"""
|
||||
...
|
||||
|
||||
def join_portal(
|
||||
self, address: str, certificate: Optional[str] = None, token: Optional[str] = None, acl: Optional[Any] = None
|
||||
) -> PortalMembership:
|
||||
@@ -609,11 +719,13 @@ class Session(Object):
|
||||
Join a portal.
|
||||
"""
|
||||
...
|
||||
|
||||
def resume(self) -> None:
|
||||
"""
|
||||
Resume session after network error.
|
||||
"""
|
||||
...
|
||||
|
||||
def setup_peer_connection(
|
||||
self, stun_server: Optional[str] = None, relays: Optional[Sequence[Relay]] = None
|
||||
) -> None:
|
||||
@@ -629,6 +741,7 @@ class Spawn(Object):
|
||||
Application identifier.
|
||||
"""
|
||||
...
|
||||
|
||||
@property
|
||||
def pid(self) -> int:
|
||||
"""
|
||||
@@ -648,6 +761,7 @@ class Compiler(Object):
|
||||
Build an agent.
|
||||
"""
|
||||
...
|
||||
|
||||
def watch(
|
||||
self,
|
||||
entrypoint: str,
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,21 @@
|
||||
py_sources = [
|
||||
'__init__.pyi',
|
||||
'py.typed',
|
||||
]
|
||||
python.install_sources(py_sources, subdir: 'frida' / '_frida', pure: false)
|
||||
|
||||
extra_link_args = []
|
||||
if host_os_family == 'darwin'
|
||||
extra_link_args += '-Wl,-exported_symbol,_PyInit__frida'
|
||||
elif host_os_family != 'windows'
|
||||
extra_link_args += '-Wl,--version-script,' + meson.current_source_dir() / 'extension.version'
|
||||
endif
|
||||
|
||||
extension = python.extension_module('_frida', 'extension.c',
|
||||
limited_api: '3.7',
|
||||
c_args: frida_component_cflags,
|
||||
link_args: extra_link_args,
|
||||
dependencies: [python_dep, frida_core_dep, os_deps],
|
||||
install: true,
|
||||
subdir: 'frida',
|
||||
)
|
||||
+163
-138
@@ -38,7 +38,7 @@ if sys.version_info >= (3, 11):
|
||||
else:
|
||||
from typing_extensions import NotRequired
|
||||
|
||||
import _frida
|
||||
from . import _frida
|
||||
|
||||
_device_manager = None
|
||||
|
||||
@@ -176,7 +176,8 @@ class ScriptExportsSync:
|
||||
js_name = _to_camel_case(name)
|
||||
|
||||
def method(*args: Any, **kwargs: Any) -> Any:
|
||||
return script._rpc_request("call", js_name, args, **kwargs)
|
||||
request, data = make_rpc_call_request(js_name, args)
|
||||
return script._rpc_request(request, data, **kwargs)
|
||||
|
||||
return method
|
||||
|
||||
@@ -202,7 +203,8 @@ class ScriptExportsAsync:
|
||||
js_name = _to_camel_case(name)
|
||||
|
||||
async def method(*args: Any, **kwargs: Any) -> Any:
|
||||
return await script._rpc_request_async("call", js_name, args, **kwargs)
|
||||
request, data = make_rpc_call_request(js_name, args)
|
||||
return await script._rpc_request_async(request, data, **kwargs)
|
||||
|
||||
return method
|
||||
|
||||
@@ -210,6 +212,16 @@ class ScriptExportsAsync:
|
||||
return self._script.list_exports_sync()
|
||||
|
||||
|
||||
def make_rpc_call_request(js_name: str, args: Sequence[Any]) -> Tuple[List[Any], Optional[bytes]]:
|
||||
if args and isinstance(args[-1], bytes):
|
||||
raw_args = args[:-1]
|
||||
data = args[-1]
|
||||
else:
|
||||
raw_args = args
|
||||
data = None
|
||||
return (["call", js_name, raw_args], data)
|
||||
|
||||
|
||||
class ScriptErrorMessage(TypedDict):
|
||||
type: Literal["error"]
|
||||
description: str
|
||||
@@ -334,16 +346,13 @@ class Script:
|
||||
self._impl.disable_debugger()
|
||||
|
||||
@overload
|
||||
def on(self, signal: Literal["destroyed"], callback: ScriptDestroyedCallback) -> None:
|
||||
...
|
||||
def on(self, signal: Literal["destroyed"], callback: ScriptDestroyedCallback) -> None: ...
|
||||
|
||||
@overload
|
||||
def on(self, signal: Literal["message"], callback: ScriptMessageCallback) -> None:
|
||||
...
|
||||
def on(self, signal: Literal["message"], callback: ScriptMessageCallback) -> None: ...
|
||||
|
||||
@overload
|
||||
def on(self, signal: str, callback: Callable[..., Any]) -> None:
|
||||
...
|
||||
def on(self, signal: str, callback: Callable[..., Any]) -> None: ...
|
||||
|
||||
def on(self, signal: str, callback: Callable[..., Any]) -> None:
|
||||
"""
|
||||
@@ -356,16 +365,13 @@ class Script:
|
||||
self._impl.on(signal, callback)
|
||||
|
||||
@overload
|
||||
def off(self, signal: Literal["destroyed"], callback: ScriptDestroyedCallback) -> None:
|
||||
...
|
||||
def off(self, signal: Literal["destroyed"], callback: ScriptDestroyedCallback) -> None: ...
|
||||
|
||||
@overload
|
||||
def off(self, signal: Literal["message"], callback: ScriptMessageCallback) -> None:
|
||||
...
|
||||
def off(self, signal: Literal["message"], callback: ScriptMessageCallback) -> None: ...
|
||||
|
||||
@overload
|
||||
def off(self, signal: str, callback: Callable[..., Any]) -> None:
|
||||
...
|
||||
def off(self, signal: str, callback: Callable[..., Any]) -> None: ...
|
||||
|
||||
def off(self, signal: str, callback: Callable[..., Any]) -> None:
|
||||
"""
|
||||
@@ -410,7 +416,7 @@ class Script:
|
||||
Asynchronously list all the exported attributes from the script's rpc
|
||||
"""
|
||||
|
||||
result = await self._rpc_request_async("list")
|
||||
result = await self._rpc_request_async(["list"])
|
||||
assert isinstance(result, list)
|
||||
return result
|
||||
|
||||
@@ -419,7 +425,7 @@ class Script:
|
||||
List all the exported attributes from the script's rpc
|
||||
"""
|
||||
|
||||
result = self._rpc_request("list")
|
||||
result = self._rpc_request(["list"])
|
||||
assert isinstance(result, list)
|
||||
return result
|
||||
|
||||
@@ -435,7 +441,7 @@ class Script:
|
||||
)
|
||||
return self.list_exports_sync()
|
||||
|
||||
def _rpc_request_async(self, *args: Any) -> asyncio.Future[Any]:
|
||||
def _rpc_request_async(self, args: Any, data: Optional[bytes] = None) -> asyncio.Future[Any]:
|
||||
loop = asyncio.get_event_loop()
|
||||
future: asyncio.Future[Any] = asyncio.Future()
|
||||
|
||||
@@ -448,14 +454,14 @@ class Script:
|
||||
request_id = self._append_pending(on_complete)
|
||||
|
||||
if not self.is_destroyed:
|
||||
self._send_rpc_call(request_id, *args)
|
||||
self._send_rpc_call(request_id, args, data)
|
||||
else:
|
||||
self._on_destroyed()
|
||||
|
||||
return future
|
||||
|
||||
@cancellable
|
||||
def _rpc_request(self, *args: Any) -> Any:
|
||||
def _rpc_request(self, args: Any, data: Optional[bytes] = None) -> Any:
|
||||
result = RPCResult()
|
||||
|
||||
def on_complete(value: Any, error: Optional[Union[RPCException, _frida.InvalidOperationError]]) -> None:
|
||||
@@ -472,7 +478,7 @@ class Script:
|
||||
request_id = self._append_pending(on_complete)
|
||||
|
||||
if not self.is_destroyed:
|
||||
self._send_rpc_call(request_id, *args)
|
||||
self._send_rpc_call(request_id, args, data)
|
||||
|
||||
cancellable = Cancellable.get_current()
|
||||
cancel_handler = cancellable.connect(on_cancelled)
|
||||
@@ -501,10 +507,8 @@ class Script:
|
||||
self._pending[request_id] = callback
|
||||
return request_id
|
||||
|
||||
def _send_rpc_call(self, request_id: int, *args: Any) -> None:
|
||||
message = ["frida:rpc", request_id]
|
||||
message.extend(args)
|
||||
self.post(message)
|
||||
def _send_rpc_call(self, request_id: int, args: Any, data: Optional[bytes]) -> None:
|
||||
self.post(["frida:rpc", request_id, *args], data)
|
||||
|
||||
def _on_rpc_message(self, request_id: int, operation: str, params: List[Any], data: Optional[Any]) -> None:
|
||||
if operation in ("ok", "error"):
|
||||
@@ -515,7 +519,10 @@ class Script:
|
||||
value = None
|
||||
error = None
|
||||
if operation == "ok":
|
||||
value = params[0] if data is None else data
|
||||
if data is not None:
|
||||
value = (params[1], data) if len(params) > 1 else data
|
||||
else:
|
||||
value = params[0]
|
||||
else:
|
||||
error = RPCException(*params[0:3])
|
||||
|
||||
@@ -691,12 +698,10 @@ class Session:
|
||||
self,
|
||||
signal: Literal["detached"],
|
||||
callback: SessionDetachedCallback,
|
||||
) -> None:
|
||||
...
|
||||
) -> None: ...
|
||||
|
||||
@overload
|
||||
def on(self, signal: str, callback: Callable[..., Any]) -> None:
|
||||
...
|
||||
def on(self, signal: str, callback: Callable[..., Any]) -> None: ...
|
||||
|
||||
def on(self, signal: str, callback: Callable[..., Any]) -> None:
|
||||
"""
|
||||
@@ -710,12 +715,10 @@ class Session:
|
||||
self,
|
||||
signal: Literal["detached"],
|
||||
callback: SessionDetachedCallback,
|
||||
) -> None:
|
||||
...
|
||||
) -> None: ...
|
||||
|
||||
@overload
|
||||
def off(self, signal: str, callback: Callable[..., Any]) -> None:
|
||||
...
|
||||
def off(self, signal: str, callback: Callable[..., Any]) -> None: ...
|
||||
|
||||
def off(self, signal: str, callback: Callable[..., Any]) -> None:
|
||||
"""
|
||||
@@ -755,16 +758,13 @@ class Bus:
|
||||
self._impl.post(raw_message, **kwargs)
|
||||
|
||||
@overload
|
||||
def on(self, signal: Literal["detached"], callback: BusDetachedCallback) -> None:
|
||||
...
|
||||
def on(self, signal: Literal["detached"], callback: BusDetachedCallback) -> None: ...
|
||||
|
||||
@overload
|
||||
def on(self, signal: Literal["message"], callback: BusMessageCallback) -> None:
|
||||
...
|
||||
def on(self, signal: Literal["message"], callback: BusMessageCallback) -> None: ...
|
||||
|
||||
@overload
|
||||
def on(self, signal: str, callback: Callable[..., Any]) -> None:
|
||||
...
|
||||
def on(self, signal: str, callback: Callable[..., Any]) -> None: ...
|
||||
|
||||
def on(self, signal: str, callback: Callable[..., Any]) -> None:
|
||||
"""
|
||||
@@ -777,16 +777,13 @@ class Bus:
|
||||
self._impl.on(signal, callback)
|
||||
|
||||
@overload
|
||||
def off(self, signal: Literal["detached"], callback: BusDetachedCallback) -> None:
|
||||
...
|
||||
def off(self, signal: Literal["detached"], callback: BusDetachedCallback) -> None: ...
|
||||
|
||||
@overload
|
||||
def off(self, signal: Literal["message"], callback: BusMessageCallback) -> None:
|
||||
...
|
||||
def off(self, signal: Literal["message"], callback: BusMessageCallback) -> None: ...
|
||||
|
||||
@overload
|
||||
def off(self, signal: str, callback: Callable[..., Any]) -> None:
|
||||
...
|
||||
def off(self, signal: str, callback: Callable[..., Any]) -> None: ...
|
||||
|
||||
def off(self, signal: str, callback: Callable[..., Any]) -> None:
|
||||
"""
|
||||
@@ -808,6 +805,70 @@ class Bus:
|
||||
traceback.print_exc()
|
||||
|
||||
|
||||
ServiceCloseCallback = Callable[[], None]
|
||||
ServiceMessageCallback = Callable[[Any], None]
|
||||
|
||||
|
||||
class Service:
|
||||
def __init__(self, impl: _frida.Service) -> None:
|
||||
self._impl = impl
|
||||
|
||||
@cancellable
|
||||
def activate(self) -> None:
|
||||
"""
|
||||
Activate the service
|
||||
"""
|
||||
|
||||
self._impl.activate()
|
||||
|
||||
@cancellable
|
||||
def cancel(self) -> None:
|
||||
"""
|
||||
Cancel the service
|
||||
"""
|
||||
|
||||
self._impl.cancel()
|
||||
|
||||
def request(self, parameters: Any) -> Any:
|
||||
"""
|
||||
Perform a request
|
||||
"""
|
||||
|
||||
return self._impl.request(parameters)
|
||||
|
||||
@overload
|
||||
def on(self, signal: Literal["close"], callback: ServiceCloseCallback) -> None: ...
|
||||
|
||||
@overload
|
||||
def on(self, signal: Literal["message"], callback: ServiceMessageCallback) -> None: ...
|
||||
|
||||
@overload
|
||||
def on(self, signal: str, callback: Callable[..., Any]) -> None: ...
|
||||
|
||||
def on(self, signal: str, callback: Callable[..., Any]) -> None:
|
||||
"""
|
||||
Add a signal handler
|
||||
"""
|
||||
|
||||
self._impl.on(signal, callback)
|
||||
|
||||
@overload
|
||||
def off(self, signal: Literal["close"], callback: ServiceCloseCallback) -> None: ...
|
||||
|
||||
@overload
|
||||
def off(self, signal: Literal["message"], callback: ServiceMessageCallback) -> None: ...
|
||||
|
||||
@overload
|
||||
def off(self, signal: str, callback: Callable[..., Any]) -> None: ...
|
||||
|
||||
def off(self, signal: str, callback: Callable[..., Any]) -> None:
|
||||
"""
|
||||
Remove a signal handler
|
||||
"""
|
||||
|
||||
self._impl.off(signal, callback)
|
||||
|
||||
|
||||
DeviceSpawnAddedCallback = Callable[[_frida.Spawn], None]
|
||||
DeviceSpawnRemovedCallback = Callable[[_frida.Spawn], None]
|
||||
DeviceChildAddedCallback = Callable[[_frida.Child], None]
|
||||
@@ -1035,6 +1096,14 @@ class Device:
|
||||
|
||||
return IOStream(self._impl.open_channel(address))
|
||||
|
||||
@cancellable
|
||||
def open_service(self, address: str) -> Service:
|
||||
"""
|
||||
Open a device-specific service
|
||||
"""
|
||||
|
||||
return Service(self._impl.open_service(address))
|
||||
|
||||
@cancellable
|
||||
def unpair(self) -> None:
|
||||
"""
|
||||
@@ -1052,40 +1121,31 @@ class Device:
|
||||
return self.bus
|
||||
|
||||
@overload
|
||||
def on(self, signal: Literal["spawn-added"], callback: DeviceSpawnAddedCallback) -> None:
|
||||
...
|
||||
def on(self, signal: Literal["spawn-added"], callback: DeviceSpawnAddedCallback) -> None: ...
|
||||
|
||||
@overload
|
||||
def on(self, signal: Literal["spawn-removed"], callback: DeviceSpawnRemovedCallback) -> None:
|
||||
...
|
||||
def on(self, signal: Literal["spawn-removed"], callback: DeviceSpawnRemovedCallback) -> None: ...
|
||||
|
||||
@overload
|
||||
def on(self, signal: Literal["child-added"], callback: DeviceChildAddedCallback) -> None:
|
||||
...
|
||||
def on(self, signal: Literal["child-added"], callback: DeviceChildAddedCallback) -> None: ...
|
||||
|
||||
@overload
|
||||
def on(self, signal: Literal["child-removed"], callback: DeviceChildRemovedCallback) -> None:
|
||||
...
|
||||
def on(self, signal: Literal["child-removed"], callback: DeviceChildRemovedCallback) -> None: ...
|
||||
|
||||
@overload
|
||||
def on(self, signal: Literal["process-crashed"], callback: DeviceProcessCrashedCallback) -> None:
|
||||
...
|
||||
def on(self, signal: Literal["process-crashed"], callback: DeviceProcessCrashedCallback) -> None: ...
|
||||
|
||||
@overload
|
||||
def on(self, signal: Literal["output"], callback: DeviceOutputCallback) -> None:
|
||||
...
|
||||
def on(self, signal: Literal["output"], callback: DeviceOutputCallback) -> None: ...
|
||||
|
||||
@overload
|
||||
def on(self, signal: Literal["uninjected"], callback: DeviceUninjectedCallback) -> None:
|
||||
...
|
||||
def on(self, signal: Literal["uninjected"], callback: DeviceUninjectedCallback) -> None: ...
|
||||
|
||||
@overload
|
||||
def on(self, signal: Literal["lost"], callback: DeviceLostCallback) -> None:
|
||||
...
|
||||
def on(self, signal: Literal["lost"], callback: DeviceLostCallback) -> None: ...
|
||||
|
||||
@overload
|
||||
def on(self, signal: str, callback: Callable[..., Any]) -> None:
|
||||
...
|
||||
def on(self, signal: str, callback: Callable[..., Any]) -> None: ...
|
||||
|
||||
def on(self, signal: str, callback: Callable[..., Any]) -> None:
|
||||
"""
|
||||
@@ -1095,40 +1155,31 @@ class Device:
|
||||
self._impl.on(signal, callback)
|
||||
|
||||
@overload
|
||||
def off(self, signal: Literal["spawn-added"], callback: DeviceSpawnAddedCallback) -> None:
|
||||
...
|
||||
def off(self, signal: Literal["spawn-added"], callback: DeviceSpawnAddedCallback) -> None: ...
|
||||
|
||||
@overload
|
||||
def off(self, signal: Literal["spawn-removed"], callback: DeviceSpawnRemovedCallback) -> None:
|
||||
...
|
||||
def off(self, signal: Literal["spawn-removed"], callback: DeviceSpawnRemovedCallback) -> None: ...
|
||||
|
||||
@overload
|
||||
def off(self, signal: Literal["child-added"], callback: DeviceChildAddedCallback) -> None:
|
||||
...
|
||||
def off(self, signal: Literal["child-added"], callback: DeviceChildAddedCallback) -> None: ...
|
||||
|
||||
@overload
|
||||
def off(self, signal: Literal["child-removed"], callback: DeviceChildRemovedCallback) -> None:
|
||||
...
|
||||
def off(self, signal: Literal["child-removed"], callback: DeviceChildRemovedCallback) -> None: ...
|
||||
|
||||
@overload
|
||||
def off(self, signal: Literal["process-crashed"], callback: DeviceProcessCrashedCallback) -> None:
|
||||
...
|
||||
def off(self, signal: Literal["process-crashed"], callback: DeviceProcessCrashedCallback) -> None: ...
|
||||
|
||||
@overload
|
||||
def off(self, signal: Literal["output"], callback: DeviceOutputCallback) -> None:
|
||||
...
|
||||
def off(self, signal: Literal["output"], callback: DeviceOutputCallback) -> None: ...
|
||||
|
||||
@overload
|
||||
def off(self, signal: Literal["uninjected"], callback: DeviceUninjectedCallback) -> None:
|
||||
...
|
||||
def off(self, signal: Literal["uninjected"], callback: DeviceUninjectedCallback) -> None: ...
|
||||
|
||||
@overload
|
||||
def off(self, signal: Literal["lost"], callback: DeviceLostCallback) -> None:
|
||||
...
|
||||
def off(self, signal: Literal["lost"], callback: DeviceLostCallback) -> None: ...
|
||||
|
||||
@overload
|
||||
def off(self, signal: str, callback: Callable[..., Any]) -> None:
|
||||
...
|
||||
def off(self, signal: str, callback: Callable[..., Any]) -> None: ...
|
||||
|
||||
def off(self, signal: str, callback: Callable[..., Any]) -> None:
|
||||
"""
|
||||
@@ -1239,20 +1290,16 @@ class DeviceManager:
|
||||
self._impl.remove_remote_device(address=address)
|
||||
|
||||
@overload
|
||||
def on(self, signal: Literal["added"], callback: DeviceManagerAddedCallback) -> None:
|
||||
...
|
||||
def on(self, signal: Literal["added"], callback: DeviceManagerAddedCallback) -> None: ...
|
||||
|
||||
@overload
|
||||
def on(self, signal: Literal["removed"], callback: DeviceManagerRemovedCallback) -> None:
|
||||
...
|
||||
def on(self, signal: Literal["removed"], callback: DeviceManagerRemovedCallback) -> None: ...
|
||||
|
||||
@overload
|
||||
def on(self, signal: Literal["changed"], callback: DeviceManagerChangedCallback) -> None:
|
||||
...
|
||||
def on(self, signal: Literal["changed"], callback: DeviceManagerChangedCallback) -> None: ...
|
||||
|
||||
@overload
|
||||
def on(self, signal: str, callback: Callable[..., Any]) -> None:
|
||||
...
|
||||
def on(self, signal: str, callback: Callable[..., Any]) -> None: ...
|
||||
|
||||
def on(self, signal: str, callback: Callable[..., Any]) -> None:
|
||||
"""
|
||||
@@ -1262,20 +1309,16 @@ class DeviceManager:
|
||||
self._impl.on(signal, callback)
|
||||
|
||||
@overload
|
||||
def off(self, signal: Literal["added"], callback: DeviceManagerAddedCallback) -> None:
|
||||
...
|
||||
def off(self, signal: Literal["added"], callback: DeviceManagerAddedCallback) -> None: ...
|
||||
|
||||
@overload
|
||||
def off(self, signal: Literal["removed"], callback: DeviceManagerRemovedCallback) -> None:
|
||||
...
|
||||
def off(self, signal: Literal["removed"], callback: DeviceManagerRemovedCallback) -> None: ...
|
||||
|
||||
@overload
|
||||
def off(self, signal: Literal["changed"], callback: DeviceManagerChangedCallback) -> None:
|
||||
...
|
||||
def off(self, signal: Literal["changed"], callback: DeviceManagerChangedCallback) -> None: ...
|
||||
|
||||
@overload
|
||||
def off(self, signal: str, callback: Callable[..., Any]) -> None:
|
||||
...
|
||||
def off(self, signal: str, callback: Callable[..., Any]) -> None: ...
|
||||
|
||||
def off(self, signal: str, callback: Callable[..., Any]) -> None:
|
||||
"""
|
||||
@@ -1417,46 +1460,38 @@ class PortalService:
|
||||
self._impl.untag(connection_id, tag)
|
||||
|
||||
@overload
|
||||
def on(self, signal: Literal["node-joined"], callback: PortalServiceNodeJoinedCallback) -> None:
|
||||
...
|
||||
def on(self, signal: Literal["node-joined"], callback: PortalServiceNodeJoinedCallback) -> None: ...
|
||||
|
||||
@overload
|
||||
def on(self, signal: Literal["node-left"], callback: PortalServiceNodeLeftCallback) -> None:
|
||||
...
|
||||
def on(self, signal: Literal["node-left"], callback: PortalServiceNodeLeftCallback) -> None: ...
|
||||
|
||||
@overload
|
||||
def on(self, signal: Literal["controller-connected"], callback: PortalServiceControllerConnectedCallback) -> None:
|
||||
...
|
||||
def on(
|
||||
self, signal: Literal["controller-connected"], callback: PortalServiceControllerConnectedCallback
|
||||
) -> None: ...
|
||||
|
||||
@overload
|
||||
def on(
|
||||
self, signal: Literal["controller-disconnected"], callback: PortalServiceControllerDisconnectedCallback
|
||||
) -> None:
|
||||
...
|
||||
) -> None: ...
|
||||
|
||||
@overload
|
||||
def on(self, signal: Literal["node-connected"], callback: PortalServiceNodeConnectedCallback) -> None:
|
||||
...
|
||||
def on(self, signal: Literal["node-connected"], callback: PortalServiceNodeConnectedCallback) -> None: ...
|
||||
|
||||
@overload
|
||||
def on(self, signal: Literal["node-disconnected"], callback: PortalServiceNodeDisconnectedCallback) -> None:
|
||||
...
|
||||
def on(self, signal: Literal["node-disconnected"], callback: PortalServiceNodeDisconnectedCallback) -> None: ...
|
||||
|
||||
@overload
|
||||
def on(self, signal: Literal["authenticated"], callback: PortalServiceAuthenticatedCallback) -> None:
|
||||
...
|
||||
def on(self, signal: Literal["authenticated"], callback: PortalServiceAuthenticatedCallback) -> None: ...
|
||||
|
||||
@overload
|
||||
def on(self, signal: Literal["subscribe"], callback: PortalServiceSubscribeCallback) -> None:
|
||||
...
|
||||
def on(self, signal: Literal["subscribe"], callback: PortalServiceSubscribeCallback) -> None: ...
|
||||
|
||||
@overload
|
||||
def on(self, signal: Literal["message"], callback: PortalServiceMessageCallback) -> None:
|
||||
...
|
||||
def on(self, signal: Literal["message"], callback: PortalServiceMessageCallback) -> None: ...
|
||||
|
||||
@overload
|
||||
def on(self, signal: str, callback: Callable[..., Any]) -> None:
|
||||
...
|
||||
def on(self, signal: str, callback: Callable[..., Any]) -> None: ...
|
||||
|
||||
def on(self, signal: str, callback: Callable[..., Any]) -> None:
|
||||
"""
|
||||
@@ -1552,47 +1587,37 @@ class Compiler:
|
||||
return self._impl.watch(entrypoint, **kwargs)
|
||||
|
||||
@overload
|
||||
def on(self, signal: Literal["starting"], callback: CompilerStartingCallback) -> None:
|
||||
...
|
||||
def on(self, signal: Literal["starting"], callback: CompilerStartingCallback) -> None: ...
|
||||
|
||||
@overload
|
||||
def on(self, signal: Literal["finished"], callback: CompilerFinishedCallback) -> None:
|
||||
...
|
||||
def on(self, signal: Literal["finished"], callback: CompilerFinishedCallback) -> None: ...
|
||||
|
||||
@overload
|
||||
def on(self, signal: Literal["output"], callback: CompilerOutputCallback) -> None:
|
||||
...
|
||||
def on(self, signal: Literal["output"], callback: CompilerOutputCallback) -> None: ...
|
||||
|
||||
@overload
|
||||
def on(self, signal: Literal["diagnostics"], callback: CompilerDiagnosticsCallback) -> None:
|
||||
...
|
||||
def on(self, signal: Literal["diagnostics"], callback: CompilerDiagnosticsCallback) -> None: ...
|
||||
|
||||
@overload
|
||||
def on(self, signal: str, callback: Callable[..., Any]) -> None:
|
||||
...
|
||||
def on(self, signal: str, callback: Callable[..., Any]) -> None: ...
|
||||
|
||||
def on(self, signal: str, callback: Callable[..., Any]) -> None:
|
||||
self._impl.on(signal, callback)
|
||||
|
||||
@overload
|
||||
def off(self, signal: Literal["starting"], callback: CompilerStartingCallback) -> None:
|
||||
...
|
||||
def off(self, signal: Literal["starting"], callback: CompilerStartingCallback) -> None: ...
|
||||
|
||||
@overload
|
||||
def off(self, signal: Literal["finished"], callback: CompilerFinishedCallback) -> None:
|
||||
...
|
||||
def off(self, signal: Literal["finished"], callback: CompilerFinishedCallback) -> None: ...
|
||||
|
||||
@overload
|
||||
def off(self, signal: Literal["output"], callback: CompilerOutputCallback) -> None:
|
||||
...
|
||||
def off(self, signal: Literal["output"], callback: CompilerOutputCallback) -> None: ...
|
||||
|
||||
@overload
|
||||
def off(self, signal: Literal["diagnostics"], callback: CompilerDiagnosticsCallback) -> None:
|
||||
...
|
||||
def off(self, signal: Literal["diagnostics"], callback: CompilerDiagnosticsCallback) -> None: ...
|
||||
|
||||
@overload
|
||||
def off(self, signal: str, callback: Callable[..., Any]) -> None:
|
||||
...
|
||||
def off(self, signal: str, callback: Callable[..., Any]) -> None: ...
|
||||
|
||||
def off(self, signal: str, callback: Callable[..., Any]) -> None:
|
||||
self._impl.off(signal, callback)
|
||||
|
||||
+5
-3
@@ -1,6 +1,8 @@
|
||||
frida_sources = [
|
||||
subdir('_frida')
|
||||
|
||||
py_sources = [
|
||||
'__init__.py',
|
||||
'core.py',
|
||||
'py.typed',
|
||||
]
|
||||
|
||||
install_data(frida_sources, install_dir: join_paths(python_site_packages, 'frida'))
|
||||
python.install_sources(py_sources, subdir: 'frida', pure: false)
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
@setlocal
|
||||
@echo off
|
||||
rem:: Based on: https://github.com/microsoft/terminal/issues/217#issuecomment-737594785
|
||||
goto :_start_
|
||||
|
||||
:set_real_dp0
|
||||
set dp0=%~dp0
|
||||
set "dp0=%dp0:~0,-1%"
|
||||
goto :eof
|
||||
|
||||
:_start_
|
||||
call :set_real_dp0
|
||||
|
||||
if not exist "%dp0%\releng\meson\meson.py" (
|
||||
pushd "%dp0%" & git submodule update --init --recursive --depth 1 & popd
|
||||
if %errorlevel% neq 0 exit /b %errorlevel%
|
||||
)
|
||||
|
||||
endlocal & goto #_undefined_# 2>nul || title %COMSPEC% & python ^
|
||||
-c "import sys; sys.path.insert(0, sys.argv[1]); from releng.meson_make import main; main()" ^
|
||||
"%dp0%" ^
|
||||
.\build ^
|
||||
%*
|
||||
+19
-78
@@ -1,11 +1,11 @@
|
||||
project('frida-python', 'c', version: '1.0.0')
|
||||
project('frida-python', 'c',
|
||||
version: run_command(find_program('python3'), files('setup.py'), '-V',
|
||||
capture: true,
|
||||
check: true).stdout().strip(),
|
||||
meson_version: '>=1.3.0',
|
||||
)
|
||||
|
||||
host_os = host_machine.system()
|
||||
if host_os == 'android'
|
||||
host_os_family = 'linux'
|
||||
else
|
||||
host_os_family = host_os
|
||||
endif
|
||||
python = import('python').find_installation()
|
||||
|
||||
cc = meson.get_compiler('c')
|
||||
|
||||
@@ -19,81 +19,22 @@ if ndebug == 'true' or (ndebug == 'if-release' and not get_option('debug'))
|
||||
]
|
||||
endif
|
||||
|
||||
target_conditionals_prefix = '#include <TargetConditionals.h>'
|
||||
python_dep = python.dependency()
|
||||
frida_core_dep = dependency('frida-core-1.0', default_options: [
|
||||
'frida_version=' + meson.project_version().replace('.dev', '-dev.'),
|
||||
])
|
||||
|
||||
is_macos_src = target_conditionals_prefix + '''
|
||||
#if !TARGET_OS_OSX
|
||||
# error Not macOS
|
||||
#endif
|
||||
'''
|
||||
if cc.compiles(is_macos_src, name: 'compiling for macOS')
|
||||
host_os = 'macos'
|
||||
endif
|
||||
|
||||
is_ios_src = target_conditionals_prefix + '''
|
||||
#if !TARGET_OS_IOS
|
||||
# error Not iOS
|
||||
#endif
|
||||
'''
|
||||
if cc.compiles(is_ios_src, name: 'compiling for iOS')
|
||||
host_os = 'ios'
|
||||
endif
|
||||
|
||||
if cc.has_header('android/api-level.h')
|
||||
host_os = 'android'
|
||||
endif
|
||||
|
||||
python_incdir = get_option('python_incdir')
|
||||
if python_incdir == ''
|
||||
python = get_option('python')
|
||||
if python == ''
|
||||
python = find_program('python3', required: false)
|
||||
if not python.found()
|
||||
python = find_program('python')
|
||||
endif
|
||||
endif
|
||||
|
||||
result = run_command(python, '-c',
|
||||
'import sys; sys.stdout.write(f"{sys.version_info[0]}.{sys.version_info[1]}")',
|
||||
check: true)
|
||||
python_version = result.stdout()
|
||||
python_name = 'python' + python_version
|
||||
|
||||
result = run_command(python, '-c',
|
||||
'from distutils import sysconfig; import sys; sys.stdout.write(sysconfig.get_python_inc())',
|
||||
check: true)
|
||||
python_incdir = result.stdout()
|
||||
else
|
||||
py_major_v = cc.get_define('PY_MAJOR_VERSION',
|
||||
prefix: '#include <patchlevel.h>',
|
||||
args: ['-I' + python_incdir])
|
||||
|
||||
py_minor_v = cc.get_define('PY_MINOR_VERSION',
|
||||
prefix: '#include <patchlevel.h>',
|
||||
args: ['-I' + python_incdir])
|
||||
|
||||
python_version = py_major_v + '.' + py_minor_v
|
||||
python_name = 'python' + python_version
|
||||
endif
|
||||
|
||||
python_site_packages = join_paths(get_option('libdir'), python_name, 'site-packages')
|
||||
|
||||
cdata = configuration_data()
|
||||
|
||||
cdata.set('HAVE_' + host_os_family.to_upper(), 1)
|
||||
if host_os != host_os_family
|
||||
cdata.set('HAVE_' + host_os.to_upper(), 1)
|
||||
endif
|
||||
|
||||
frida_core_dep = dependency('frida-core-1.0')
|
||||
os_deps = []
|
||||
host_os_family = host_machine.system()
|
||||
if host_os_family != 'windows'
|
||||
os_deps += dependency('gio-unix-2.0')
|
||||
endif
|
||||
|
||||
configure_file(input: 'config.h.in',
|
||||
output: 'config.h',
|
||||
configuration: cdata)
|
||||
|
||||
subdir('src')
|
||||
subdir('frida')
|
||||
|
||||
test('frida-python', python,
|
||||
args: ['-m', 'unittest', 'discover'],
|
||||
workdir: meson.current_source_dir(),
|
||||
env: {'PYTHONPATH': meson.current_build_dir() / 'src'},
|
||||
timeout: 30,
|
||||
)
|
||||
|
||||
@@ -1,11 +0,0 @@
|
||||
option('python',
|
||||
type: 'string',
|
||||
value: '',
|
||||
description: 'Python interpreter to build for'
|
||||
)
|
||||
|
||||
option('python_incdir',
|
||||
type: 'string',
|
||||
value: '',
|
||||
description: 'Python headers directory to build against'
|
||||
)
|
||||
Submodule
+1
Submodule releng added at 2eecc41cbe
@@ -1,109 +1,25 @@
|
||||
import os
|
||||
import platform
|
||||
import shutil
|
||||
import subprocess
|
||||
import sys
|
||||
from pathlib import Path
|
||||
from typing import Iterator
|
||||
|
||||
from setuptools import setup
|
||||
from setuptools.command.build_ext import build_ext
|
||||
from setuptools.extension import Extension
|
||||
|
||||
package_dir = os.path.dirname(os.path.realpath(__file__))
|
||||
pkg_info = os.path.join(package_dir, "PKG-INFO")
|
||||
in_source_package = os.path.isfile(pkg_info)
|
||||
if in_source_package:
|
||||
with open(pkg_info, "r", encoding="utf-8") as f:
|
||||
version_line = [line for line in f if line.startswith("Version: ")][0].strip()
|
||||
frida_version = version_line[9:]
|
||||
else:
|
||||
frida_version = os.environ.get("FRIDA_VERSION", "0.0.0")
|
||||
with open(os.path.join(package_dir, "README.md"), "r", encoding="utf-8") as f:
|
||||
long_description = f.read()
|
||||
frida_extension = os.environ.get("FRIDA_EXTENSION", None)
|
||||
SOURCE_ROOT = Path(__file__).resolve().parent
|
||||
FRIDA_EXTENSION = os.environ.get("FRIDA_EXTENSION", None)
|
||||
|
||||
|
||||
class FridaPrebuiltExt(build_ext):
|
||||
def build_extension(self, ext):
|
||||
target = self.get_ext_fullpath(ext.name)
|
||||
target_dir = os.path.dirname(target)
|
||||
os.makedirs(target_dir, exist_ok=True)
|
||||
|
||||
shutil.copyfile(frida_extension, target)
|
||||
|
||||
|
||||
class FridaMissingDevkitBuildExt(build_ext):
|
||||
def build_extension(self, ext):
|
||||
raise RuntimeError(
|
||||
"Need frida-core devkit to build from source.\n"
|
||||
"Download one from https://github.com/frida/frida/releases, "
|
||||
"extract it to a directory,\n"
|
||||
"and then add an environment variable named FRIDA_CORE_DEVKIT "
|
||||
"pointing at the directory."
|
||||
)
|
||||
|
||||
|
||||
include_dirs = []
|
||||
library_dirs = []
|
||||
libraries = []
|
||||
extra_link_args = []
|
||||
|
||||
cmdclass = {}
|
||||
if frida_extension is not None:
|
||||
cmdclass["build_ext"] = FridaPrebuiltExt
|
||||
else:
|
||||
devkit_dir = os.environ.get("FRIDA_CORE_DEVKIT", None)
|
||||
if devkit_dir is not None:
|
||||
include_dirs += [devkit_dir]
|
||||
library_dirs += [devkit_dir]
|
||||
libraries += ["frida-core"]
|
||||
|
||||
system = platform.system()
|
||||
if system == "Windows":
|
||||
pass
|
||||
elif system == "Darwin":
|
||||
extra_link_args += [
|
||||
"-Wl,-exported_symbol,_PyInit__frida",
|
||||
"-Wl,-dead_strip",
|
||||
]
|
||||
if "_PYTHON_HOST_PLATFORM" not in os.environ:
|
||||
if platform.machine() == "arm64":
|
||||
host_arch = "arm64"
|
||||
macos_req = "11.0"
|
||||
else:
|
||||
host_arch = "x86_64"
|
||||
macos_req = "10.9"
|
||||
os.environ["_PYTHON_HOST_PLATFORM"] = f"macosx-{macos_req}-{host_arch}"
|
||||
os.environ["ARCHFLAGS"] = f"-arch {host_arch}"
|
||||
os.environ["MACOSX_DEPLOYMENT_TARGET"] = macos_req
|
||||
else:
|
||||
version_script = os.path.join(package_dir, "src", "_frida.version")
|
||||
if not os.path.exists(version_script):
|
||||
with open(version_script, "w", encoding="utf-8") as f:
|
||||
f.write(
|
||||
"\n".join(
|
||||
[
|
||||
"{",
|
||||
" global:",
|
||||
" PyInit__frida;",
|
||||
"",
|
||||
" local:",
|
||||
" *;",
|
||||
"};",
|
||||
]
|
||||
)
|
||||
)
|
||||
extra_link_args += [
|
||||
f"-Wl,--version-script,{version_script}",
|
||||
"-Wl,--gc-sections",
|
||||
]
|
||||
else:
|
||||
cmdclass["build_ext"] = FridaMissingDevkitBuildExt
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
def main():
|
||||
setup(
|
||||
name="frida",
|
||||
version=frida_version,
|
||||
version=detect_version(),
|
||||
description="Dynamic instrumentation toolkit for developers, reverse-engineers, and security researchers",
|
||||
long_description=long_description,
|
||||
long_description=compute_long_description(),
|
||||
long_description_content_type="text/markdown",
|
||||
author="Frida Developers",
|
||||
author_email="oleavr@frida.re",
|
||||
@@ -134,19 +50,81 @@ if __name__ == "__main__":
|
||||
"Topic :: Software Development :: Debuggers",
|
||||
"Topic :: Software Development :: Libraries :: Python Modules",
|
||||
],
|
||||
packages=["frida", "_frida"],
|
||||
package_data={"frida": ["py.typed"], "_frida": ["py.typed", "__init__.pyi"]},
|
||||
packages=["frida", "frida._frida"],
|
||||
package_data={"frida": ["py.typed"], "frida._frida": ["py.typed", "__init__.pyi"]},
|
||||
ext_modules=[
|
||||
Extension(
|
||||
name="_frida",
|
||||
sources=["src/_frida.c"],
|
||||
include_dirs=include_dirs,
|
||||
library_dirs=library_dirs,
|
||||
libraries=libraries,
|
||||
extra_link_args=extra_link_args,
|
||||
name="frida._frida",
|
||||
sources=["frida/_frida/extension.c"],
|
||||
py_limited_api=True,
|
||||
)
|
||||
],
|
||||
cmdclass=cmdclass,
|
||||
cmdclass={"build_ext": FridaPrebuiltExt if FRIDA_EXTENSION is not None else FridaDemandBuiltExt},
|
||||
zip_safe=False,
|
||||
)
|
||||
|
||||
|
||||
def detect_version() -> str:
|
||||
pkg_info = SOURCE_ROOT / "PKG-INFO"
|
||||
in_source_package = pkg_info.exists()
|
||||
if in_source_package:
|
||||
version_line = [
|
||||
line for line in pkg_info.read_text(encoding="utf-8").split("\n") if line.startswith("Version: ")
|
||||
][0].strip()
|
||||
return version_line[9:]
|
||||
|
||||
version = os.environ.get("FRIDA_VERSION")
|
||||
if version is not None:
|
||||
return version
|
||||
|
||||
releng_location = next(enumerate_releng_locations(), None)
|
||||
if releng_location is not None:
|
||||
sys.path.insert(0, str(releng_location.parent))
|
||||
from releng.frida_version import detect
|
||||
|
||||
return detect(SOURCE_ROOT).name.replace("-dev.", ".dev")
|
||||
|
||||
return "0.0.0"
|
||||
|
||||
|
||||
def compute_long_description() -> str:
|
||||
return (SOURCE_ROOT / "README.md").read_text(encoding="utf-8")
|
||||
|
||||
|
||||
def enumerate_releng_locations() -> Iterator[Path]:
|
||||
val = os.environ.get("MESON_SOURCE_ROOT")
|
||||
if val is not None:
|
||||
parent_releng = Path(val) / "releng"
|
||||
if releng_location_exists(parent_releng):
|
||||
yield parent_releng
|
||||
|
||||
local_releng = SOURCE_ROOT / "releng"
|
||||
if releng_location_exists(local_releng):
|
||||
yield local_releng
|
||||
|
||||
|
||||
def releng_location_exists(location: Path) -> bool:
|
||||
return (location / "frida_version.py").exists()
|
||||
|
||||
|
||||
class FridaPrebuiltExt(build_ext):
|
||||
def build_extension(self, ext):
|
||||
target = self.get_ext_fullpath(ext.name)
|
||||
Path(target).parent.mkdir(parents=True, exist_ok=True)
|
||||
shutil.copy(FRIDA_EXTENSION, target)
|
||||
|
||||
|
||||
class FridaDemandBuiltExt(build_ext):
|
||||
def build_extension(self, ext):
|
||||
make = SOURCE_ROOT / "make.bat" if platform.system() == "Windows" else "make"
|
||||
subprocess.run([make], check=True)
|
||||
|
||||
outputs = [entry for entry in (SOURCE_ROOT / "build" / "frida" / "_frida").glob("_frida.*") if entry.is_file()]
|
||||
assert len(outputs) == 1
|
||||
target = self.get_ext_fullpath(ext.name)
|
||||
Path(target).parent.mkdir(parents=True, exist_ok=True)
|
||||
shutil.copy(outputs[0], target)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
|
||||
@@ -1,17 +0,0 @@
|
||||
extra_link_args = []
|
||||
if host_os_family == 'darwin'
|
||||
extra_link_args += ['-Wl,-exported_symbol,_PyInit__frida']
|
||||
elif host_os_family != 'windows'
|
||||
extra_link_args += ['-Wl,--version-script,' + join_paths(meson.current_source_dir(), '_frida.version')]
|
||||
endif
|
||||
|
||||
extension = shared_module('_frida', '_frida.c',
|
||||
name_prefix: '',
|
||||
name_suffix: 'so',
|
||||
c_args: frida_component_cflags,
|
||||
include_directories: include_directories(python_incdir),
|
||||
link_args: extra_link_args,
|
||||
dependencies: [frida_core_dep] + os_deps,
|
||||
install: true,
|
||||
install_dir: python_site_packages,
|
||||
)
|
||||
@@ -0,0 +1,8 @@
|
||||
[wrap-git]
|
||||
url = https://github.com/frida/frida-core.git
|
||||
revision = 16.7.11
|
||||
depth = 1
|
||||
|
||||
[provide]
|
||||
dependency_names = frida-core-1.0
|
||||
|
||||
+29
-15
@@ -31,27 +31,41 @@ class TestRpc(unittest.TestCase):
|
||||
name="test-rpc",
|
||||
source="""\
|
||||
rpc.exports = {
|
||||
add: function (a, b) {
|
||||
var result = a + b;
|
||||
add(a, b) {
|
||||
const result = a + b;
|
||||
if (result < 0)
|
||||
throw new Error("No");
|
||||
throw new Error("No");
|
||||
return result;
|
||||
},
|
||||
sub: function (a, b) {
|
||||
sub(a, b) {
|
||||
return a - b;
|
||||
},
|
||||
speak: function () {
|
||||
var buf = Memory.allocUtf8String("Yo");
|
||||
speak() {
|
||||
const buf = Memory.allocUtf8String("Yo");
|
||||
return Memory.readByteArray(buf, 2);
|
||||
}
|
||||
},
|
||||
speakWithMetadata() {
|
||||
const buf = Memory.allocUtf8String("Yo");
|
||||
return ['soft', Memory.readByteArray(buf, 2)];
|
||||
},
|
||||
processData(val, data) {
|
||||
return { val, dump: hexdump(data, { header: false }) };
|
||||
},
|
||||
};
|
||||
""",
|
||||
)
|
||||
script.load()
|
||||
self.assertEqual(script.exports.add(2, 3), 5)
|
||||
self.assertEqual(script.exports.sub(5, 3), 2)
|
||||
self.assertRaises(Exception, lambda: script.exports.add(1, -2))
|
||||
self.assertListEqual([x for x in iter(script.exports.speak())], [0x59, 0x6F])
|
||||
agent = script.exports_sync
|
||||
self.assertEqual(agent.add(2, 3), 5)
|
||||
self.assertEqual(agent.sub(5, 3), 2)
|
||||
self.assertRaises(Exception, lambda: agent.add(1, -2))
|
||||
self.assertEqual(agent.speak(), b"\x59\x6f")
|
||||
meta, data = agent.speak_with_metadata()
|
||||
self.assertEqual(meta, "soft")
|
||||
self.assertEqual(data, b"\x59\x6f")
|
||||
result = agent.process_data(1337, b"\x13\x37")
|
||||
self.assertEqual(result["val"], 1337)
|
||||
self.assertEqual(result["dump"], "00000000 13 37 .7")
|
||||
|
||||
def test_post_failure(self):
|
||||
script = self.session.create_script(
|
||||
@@ -64,7 +78,7 @@ rpc.exports = {
|
||||
""",
|
||||
)
|
||||
script.load()
|
||||
agent = script.exports
|
||||
agent = script.exports_sync
|
||||
|
||||
self.session.detach()
|
||||
self.assertRaisesScriptDestroyed(lambda: agent.init())
|
||||
@@ -82,7 +96,7 @@ rpc.exports = {
|
||||
""",
|
||||
)
|
||||
script.load()
|
||||
agent = script.exports
|
||||
agent = script.exports_sync
|
||||
|
||||
def unload_script_after_100ms():
|
||||
time.sleep(0.1)
|
||||
@@ -104,7 +118,7 @@ rpc.exports = {
|
||||
""",
|
||||
)
|
||||
script.load()
|
||||
agent = script.exports
|
||||
agent = script.exports_sync
|
||||
|
||||
def terminate_target_after_100ms():
|
||||
time.sleep(0.1)
|
||||
@@ -126,7 +140,7 @@ rpc.exports = {
|
||||
""",
|
||||
)
|
||||
script.load()
|
||||
agent = script.exports
|
||||
agent = script.exports_sync
|
||||
|
||||
def cancel_after_100ms():
|
||||
time.sleep(0.1)
|
||||
|
||||
Reference in New Issue
Block a user