Skip to content

Commit

Permalink
Add support for multiline input
Browse files Browse the repository at this point in the history
  • Loading branch information
yotamN committed Oct 21, 2022
1 parent a497e4e commit 2c39f98
Show file tree
Hide file tree
Showing 10 changed files with 166 additions and 1 deletion.
97 changes: 97 additions & 0 deletions .github/workflows/package.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
name: package
on: [push, pull_request]
jobs:
linux_wheels:
strategy:
matrix:
arch: [x86, x86_64, arm64, armhf, mips]
runs-on: ubuntu-latest
container: ghcr.io/frida/x-tools-linux-${{ matrix.arch }}:latest
steps:
- uses: actions/checkout@v3
with:
submodules: recursive
- run: cd agents/tracer && npm install && npm run build
- run: |
LDFLAGS="-L/opt/x-tools/$XTOOLS_HOST/$XTOOLS_HOST/sysroot/usr/lib" CPPFLAGS="-I/opt/x-tools/$XTOOLS_HOST/$XTOOLS_HOST/sysroot/usr/include/python3.10" python3 -m pip install tree_sitter
- run: |
case ${{ matrix.arch }} in
x86)
py_arch=i686
;;
armhf)
py_arch=armv7l
;;
arm64)
py_arch=aarch64
;;
*)
py_arch=${{ matrix.arch }}
;;
esac
case ${{ matrix.arch }} in
x86*)
py_platform=manylinux_2_5_${py_arch}.manylinux1_${py_arch}
;;
arm*|ppc*|s390x)
py_platform=manylinux_2_17_${py_arch}.manylinux2014_${py_arch}
;;
*)
py_platform=manylinux_2_5_${py_arch}
;;
esac
bdist_wheel_py=/usr/lib/python3/dist-packages/wheel/bdist_wheel.py
sed "s/plat_name = plat_name\\.lower()\\.replace('-', '_')\\.replace('.', '_')/plat_name = plat_name.lower().replace('-', '_')/" \
$bdist_wheel_py > $bdist_wheel_py.patched
if cmp -s $bdist_wheel_py $bdist_wheel_py.patched; then
rm -f $bdist_wheel_py.patched
echo 'Unable to patch bdist_wheel.py' > /dev/stderr
exit 1
else
mv $bdist_wheel_py.patched $bdist_wheel_py
fi
export _PYTHON_HOST_PLATFORM=linux-$py_arch
echo "plat_name = $py_platform" >> setup.cfg
pip wheel -w ./dist --no-deps .
- uses: actions/upload-artifact@v3
with:
name: frida_tools_linux
path: dist

macos_wheels:
runs-on: macos-latest
steps:
- uses: actions/checkout@v3
with:
submodules: recursive
- uses: actions/setup-python@v4
with:
python-version: '3.10'
- run: cd agents/tracer && npm install && npm run build
- run: python3 -m pip install wheel
- run: python3 -m pip install tree_sitter
- run: python3 setup.py bdist_wheel --plat-name=macosx_10_9_x86_64
- run: python3 setup.py bdist_wheel --plat-name=macosx_11_0_x86_64
- uses: actions/upload-artifact@v3
with:
name: frida_tools_macos
path: dist

windows_wheels:
runs-on: windows-latest
steps:
- uses: actions/checkout@v3
with:
submodules: recursive
- uses: actions/setup-python@v4
with:
python-version: '3.10'
- run: cd agents/tracer && npm install && npm run build
- run: python3 -m pip install wheel
- run: python3 -m pip install tree_sitter
- run: python3 setup.py bdist_wheel --plat-name=win_amd64
- run: python3 setup.py bdist_wheel --plat-name=win32
- uses: actions/upload-artifact@v3
with:
name: frida_tools_windows
path: dist
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,4 @@
/build/
/dist/
/frida_tools/*_agent.js
/frida_tools/treesitter.so
3 changes: 3 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
[submodule "vendor/tree-sitter-javascript"]
path = vendor/tree-sitter-javascript
url = https://github.com/tree-sitter/tree-sitter-javascript
18 changes: 18 additions & 0 deletions build_aux/build_treesitter.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
#!/usr/bin/env python3

import os

from tree_sitter import Language


def build() -> None:
Language.build_library(
os.path.join("frida_tools", "treesitter.so"),
[
os.path.join("vendor", "tree-sitter-javascript"),
],
)


if __name__ == "__main__":
build()
2 changes: 2 additions & 0 deletions build_aux/meson.build
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
python = find_program('python3', 'python')
run_command(python, 'build_treesitter.py')
37 changes: 37 additions & 0 deletions frida_tools/repl.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,14 @@
from prompt_toolkit import PromptSession
from prompt_toolkit.completion import CompleteEvent, Completer, Completion
from prompt_toolkit.document import Document
from prompt_toolkit.filters import Condition, Filter
from prompt_toolkit.history import FileHistory
from prompt_toolkit.lexers import PygmentsLexer
from prompt_toolkit.shortcuts import prompt
from prompt_toolkit.styles import Style as PromptToolkitStyle
from pygments.lexers.javascript import JavascriptLexer
from pygments.token import Token
from tree_sitter import Language, Parser

from frida_tools import _repl_magic
from frida_tools.application import ConsoleApplication
Expand All @@ -34,6 +36,13 @@

T = TypeVar("T")

try:
JS_LANGUAGE = Language(os.path.join(os.path.dirname(__file__), "treesitter.so"), "javascript")
ERROR_QUERY = JS_LANGUAGE.query("(_ (ERROR) @error)")
except Exception:
JS_LANGUAGE = None
ERROR_QUERY = None


class REPLApplication(ConsoleApplication):
def __init__(self) -> None:
Expand All @@ -53,6 +62,12 @@ def __init__(self) -> None:

super().__init__(self._process_input, self._on_stop)

try:
self._parser = Parser()
self._parser.set_language(JS_LANGUAGE)
except Exception:
self._parser = None

if self._have_terminal and not self._plain_terminal:
style = PromptToolkitStyle(
[
Expand All @@ -69,6 +84,7 @@ def __init__(self) -> None:
complete_in_thread=True,
enable_open_in_editor=True,
tempfile_suffix=".js",
multiline=self._input_complete(),
)
self._dumb_stdin_reader = None
else:
Expand Down Expand Up @@ -339,6 +355,27 @@ def _monitor(self, path: AnyStr) -> None:
monitor.enable()
self._monitored_files[path] = monitor

def _input_complete(self) -> Filter:
"""
check if the current input is a valid javascript code
"""

@Condition
def inner() -> bool:
assert self._cli is not None
if self._parser is None or ERROR_QUERY is None:
return False

tree = self._parser.parse(self._cli.default_buffer.document.text.encode())
query_results = ERROR_QUERY.captures(tree.root_node)
# It would have been nice to be able to query a MISSING node properly but as of when this code was written
# it was just not possible. There is an open issue for it in tree-sitter/tree-sitter#606 so maybe one day we
# could fix it. I hope it doesn't break some code that contain the work MISSING or something but I checked it
# a bit and it seems to be fine.
return len(query_results) or "MISSING" in tree.root_node.sexp()

return inner

def _process_input(self, reactor: Reactor) -> None:
if not self._quiet:
self._print_startup_message()
Expand Down
1 change: 1 addition & 0 deletions meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -24,3 +24,4 @@ subdir('agents')
subdir('frida_tools')
subdir('scripts')
subdir('completions')
subdir('build_aux')
2 changes: 2 additions & 0 deletions setup.cfg
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
[bdist_wheel]
py_limited_api = cp37
5 changes: 4 additions & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@

agents = glob.glob(os.path.join(pkg_dir, "*_agent.*"))
assert len(agents) > 0, "Agents not compiled; run “npm install && npm run build” in agents/*/"
os.system("python ./build_aux/build_treesitter.py")
package_data = agents + ["treesitter.so"]

setup(
name="frida-tools",
Expand All @@ -24,6 +26,7 @@
"frida >= 16.0.0, < 17.0.0",
"prompt-toolkit >= 2.0.0, < 4.0.0",
"pygments >= 2.0.2, < 3.0.0",
"tree_sitter==0.20.1",
],
license="wxWindows Library Licence, Version 3.1",
zip_safe=True,
Expand Down Expand Up @@ -51,7 +54,7 @@
],
packages=["frida_tools"],
package_data={
"frida_tools": agents,
"frida_tools": package_data,
},
entry_points={
"console_scripts": [
Expand Down
1 change: 1 addition & 0 deletions vendor/tree-sitter-javascript
Submodule tree-sitter-javascript added at 936d97

0 comments on commit 2c39f98

Please sign in to comment.