ejschwartz's picture
extra_args
4fecb04
import os
from typing import Any
import frontmatter
import gradio as gr
from gradio_client import Client, handle_file
from tenacity import retry, stop_after_attempt, wait_fixed, before_log, after_log
import logging
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)
SPACE_URL = "https://ejschwartz-ghidrafunctioncppexporter-space.hf.space/"
@retry(stop=stop_after_attempt(10), wait=wait_fixed(120), before=before_log(logger, logging.INFO))
def _connect_client(url: str) -> Client:
return Client(url)
client = _connect_client(SPACE_URL)
def _load_intro_text() -> str:
readme_path = os.path.join(os.path.dirname(__file__), "README.md")
try:
post = frontmatter.load(readme_path)
except (OSError, ValueError):
return "Upload an executable file to get started."
return post.content.strip()
INTRO_TEXT = _load_intro_text()
with gr.Blocks() as demo:
intro = gr.Markdown(INTRO_TEXT)
file_widget = gr.File(label="Executable file")
with gr.Column(visible=False) as col:
gr.Markdown(
"""
Great, you selected an executable! Now pick the function you would like
to analyze.
"""
)
fun_dropdown = gr.Dropdown(
label="Select a function", choices=["Woohoo!"], interactive=True
)
gr.Markdown(
"""
Below you can find some information.
"""
)
extra_args = gr.Textbox(label="Extra args to export.bash", placeholder="emit_type_definitions false", value="")
with gr.Row(visible=True):
disassembly = gr.Code(
label="Disassembly",
lines=20,
max_lines=20,
)
original_decompile = gr.Code(
language="c",
label="Decompilation",
lines=20,
max_lines=20,
)
examples_dir = os.path.join(os.path.dirname(__file__), "examples")
examples = [f.path for f in os.scandir(examples_dir)] if os.path.isdir(examples_dir) else []
gr.Examples(
examples=examples,
inputs=file_widget,
outputs=[disassembly, original_decompile],
)
@file_widget.change(inputs=file_widget, outputs=[intro, col, fun_dropdown])
def file_change_fn(file):
if file is None:
return {
intro: INTRO_TEXT,
col: gr.update(visible=False),
fun_dropdown: gr.update(choices=["Woohoo!"], value=None),
}
try:
markdown_value, funs = client.predict(
file=handle_file(file),
api_name="/file_change_fn",
)
except Exception as e:
raise gr.Error(f"Unable to analyze binary with remote app: {e}")
return {
intro: markdown_value,
col: gr.update(visible=True),
fun_dropdown: gr.update(**funs),
}
@fun_dropdown.change(inputs=[fun_dropdown, extra_args], outputs=[disassembly, original_decompile])
@extra_args.submit(inputs=[fun_dropdown, extra_args], outputs=[disassembly, original_decompile])
def function_change_fn(selected_fun, extra_args):
if selected_fun is None:
return {
disassembly: "",
original_decompile: "",
}
try:
disassembly_str, decompile_str = client.predict(
selected_fun=selected_fun,
extra_args=extra_args,
api_name="/function_change_fn",
)
except Exception as e:
raise gr.Error(f"Unable to select function {selected_fun} from remote app: {e}")
return {
disassembly: disassembly_str,
original_decompile: decompile_str,
}
demo.queue()
demo.launch(server_name="0.0.0.0", server_port=7860, show_error=True, debug=True)