Skip to content

Commit a4ed99e

Browse files
authored
Merge pull request #6 from mrexodia/usability-improvements
some minor usability improvements and better error messages
2 parents 0e6650e + f8abe98 commit a4ed99e

10 files changed

Lines changed: 108 additions & 59 deletions

File tree

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
__pycache__/

README.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,3 +63,6 @@ It is also important that attaching a debugger will create a new debugger instan
6363

6464
## Demo
6565
![demo](idacode/images/preview.gif)
66+
67+
## Contributors
68+
* [mrexodia](https://github.com/mrexodia)

ida/idacode.py

Lines changed: 6 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -1,47 +1,9 @@
1-
import socket, sys, os, threading, inspect, asyncio
2-
import tornado, debugpy
3-
import idaapi
4-
import idacode_utils.dbg as dbg
5-
import idacode_utils.hooks as hooks
6-
import idacode_utils.settings as settings
7-
from idacode_utils.socket_handler import SocketHandler
1+
import sys
2+
if sys.version_info < (3, 3):
3+
print("[IDACode] Python 2.7 is not (yet) supported, vote at https://github.com/ioncodes/idacode/issues/3")
4+
sys.exit()
85

9-
def setup_patches():
10-
hooks.install()
11-
sys.executable = settings.PYTHON
12-
13-
def create_socket_handler():
14-
asyncio.set_event_loop(asyncio.new_event_loop())
15-
app = tornado.web.Application([
16-
(r"/ws", SocketHandler),
17-
])
18-
server = tornado.httpserver.HTTPServer(app)
19-
print(f"IDACode listening on {settings.HOST}:{settings.PORT}")
20-
server.listen(address=settings.HOST, port=settings.PORT)
21-
22-
def start_server():
23-
setup_patches()
24-
create_socket_handler()
25-
tornado.ioloop.IOLoop.current().start()
26-
27-
class IDACode(idaapi.plugin_t):
28-
def __init__(self):
29-
self.flags = idaapi.PLUGIN_UNL
30-
self.comment = "IDACode"
31-
self.help = "IDACode"
32-
self.wanted_name = "Start IDACode"
33-
self.wanted_hotkey = ""
34-
35-
def init(self):
36-
return idaapi.PLUGIN_OK
37-
38-
def run(self, args):
39-
thread = threading.Thread(target=start_server)
40-
thread.daemon = True
41-
thread.start()
42-
43-
def term(self):
44-
pass
6+
import idacode_utils.plugin as plugin
457

468
def PLUGIN_ENTRY():
47-
return IDACode()
9+
return plugin.IDACode()

ida/idacode_utils/dbg.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,5 +14,5 @@ def bp(*args):
1414
break
1515
if condition:
1616
if message:
17-
print(message)
17+
print(f"[IDACode] {message}")
1818
api.breakpoint()

ida/idacode_utils/plugin.py

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
import socket, sys, os, threading, inspect, asyncio, subprocess
2+
try:
3+
import tornado, debugpy
4+
except ImportError:
5+
print("[IDACode] Dependencies missing, run: python3 -m pip install --user debugpy tornado")
6+
sys.exit()
7+
import idaapi
8+
import idacode_utils.dbg as dbg
9+
import idacode_utils.hooks as hooks
10+
import idacode_utils.settings as settings
11+
from idacode_utils.socket_handler import SocketHandler
12+
13+
VERSION = "0.1.2"
14+
initialized = False
15+
16+
def setup_patches():
17+
hooks.install()
18+
sys.executable = settings.PYTHON
19+
20+
def create_socket_handler():
21+
asyncio.set_event_loop(asyncio.new_event_loop())
22+
app = tornado.web.Application([
23+
(r"/ws", SocketHandler),
24+
])
25+
server = tornado.httpserver.HTTPServer(app)
26+
print(f"[IDACode] listening on {settings.HOST}:{settings.PORT}")
27+
server.listen(address=settings.HOST, port=settings.PORT)
28+
29+
def start_server():
30+
setup_patches()
31+
create_socket_handler()
32+
tornado.ioloop.IOLoop.current().start()
33+
34+
def get_python_versions():
35+
settings_version = subprocess.check_output([settings.PYTHON, "-c", "import sys; print(sys.version + sys.platform)"])
36+
settings_version = settings_version.decode("utf-8", "ignore").strip()
37+
ida_version = f"{sys.version}{sys.platform}"
38+
return (settings_version, ida_version)
39+
40+
class IDACode(idaapi.plugin_t):
41+
def __init__(self):
42+
self.flags = idaapi.PLUGIN_UNL
43+
self.comment = "IDACode"
44+
self.help = "IDACode"
45+
self.wanted_name = "IDACode"
46+
self.wanted_hotkey = ""
47+
48+
def init(self):
49+
global initialized
50+
if not initialized:
51+
initialized = True
52+
if os.path.isfile(settings.PYTHON):
53+
settings_version, ida_version = get_python_versions()
54+
if settings_version != ida_version:
55+
print("[IDACode] settings.PYTHON version mismatch, aborting load:")
56+
print(f"[IDACode] IDA interpreter: {ida_version}")
57+
print(f"[IDACode] settings.PYTHON: {settings_version}")
58+
return idaapi.PLUGIN_SKIP
59+
else:
60+
print(f"[IDACode] settings.PYTHON ({settings.PYTHON}) does not exist, aborting load")
61+
print("[IDACode] To fix this issue, modify idacode_utils/settings.py to point to the python executable")
62+
return idaapi.PLUGIN_SKIP
63+
print(f"[IDACode] Plugin version {VERSION}")
64+
print("[IDACode] Plugin loaded, use Edit -> Plugins -> IDACode to start the server")
65+
return idaapi.PLUGIN_OK
66+
67+
def run(self, args):
68+
thread = threading.Thread(target=start_server)
69+
thread.daemon = True
70+
thread.start()
71+
72+
def term(self):
73+
pass

ida/idacode_utils/socket_handler.py

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -16,21 +16,21 @@ def start_debug_server():
1616
if settings.LOGGING:
1717
tmp_path = tempfile.gettempdir()
1818
debugpy.log_to(tmp_path)
19-
print(f"Logging to {tmp_path} with pattern debugpy.*.log")
19+
print(f"[IDACode] Logging to {tmp_path} with pattern debugpy.*.log")
2020
debugpy.listen((settings.HOST, settings.DEBUG_PORT))
21-
print(f"IDACode debug server listening on {settings.HOST}:{settings.DEBUG_PORT}")
21+
print(f"[IDACode] IDACode debug server listening on {settings.HOST}:{settings.DEBUG_PORT}")
2222

2323
class SocketHandler(tornado.websocket.WebSocketHandler):
2424
def open(self):
25-
print("IDACode client connected")
25+
print("[IDACode] client connected")
2626

2727
def on_message(self, message):
2828
message = json.loads(message.decode("utf8"))
2929

3030
if message["event"] == "set_workspace":
3131
path = message["path"]
3232
hooks.set_script_folder(path)
33-
print(f"Set workspace folder to {path}")
33+
print(f"[IDACode] Set workspace folder to {path}")
3434
elif message["event"] == "attach_debugger":
3535
start_debug_server()
3636
self.write_message({
@@ -39,13 +39,13 @@ def on_message(self, message):
3939
elif message["event"] == "execute_script":
4040
script = message["path"]
4141
env = create_env()
42-
print(f"Executing {script}")
42+
print(f"[IDACode] Executing {script}")
4343
idaapi.execute_sync(
4444
lambda: idaapi.IDAPython_ExecScript(script, env),
4545
idaapi.MFF_WRITE
4646
)
4747
else:
48-
print(f"Invalid event {message['event']}")
48+
print(f"[IDACode] Invalid event {message['event']}")
4949

5050
def on_close(self):
51-
print("IDACode client disconnected")
51+
print("[IDACode] client disconnected")

idacode/CHANGELOG.md

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,4 +8,9 @@
88

99
## 0.1.1
1010

11-
- Added logging support
11+
- Added logging support
12+
13+
### 0.1.2
14+
15+
- Enhanced UX
16+
- Added configuration checks

idacode/README.md

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,4 +45,9 @@ IDACode doesn't support host to VM communication unless the VM uses a shared vol
4545

4646
### 0.1.1
4747

48-
- Added logging support
48+
- Added logging support
49+
50+
### 0.1.2
51+
52+
- Enhanced UX
53+
- Added configuration checks

idacode/package.json

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
"displayName": "IDACode",
44
"description": "Run and debug your IDA scripts from VS Code",
55
"icon": "images/icon.png",
6-
"version": "0.1.1",
6+
"version": "0.1.2",
77
"publisher": "Layle",
88
"license": "SEE LICENSE IN LICENSE.md",
99
"preview": true,
@@ -38,19 +38,19 @@
3838
"commands": [
3939
{
4040
"command": "idacode.connectToIDA",
41-
"title": "Connect to IDA"
41+
"title": "IDACode: Connect to IDA"
4242
},
4343
{
4444
"command": "idacode.attachToIDA",
45-
"title": "Attach a debugger to IDA"
45+
"title": "IDACode: Attach a debugger to IDA"
4646
},
4747
{
4848
"command": "idacode.connectAndAttachToIDA",
49-
"title": "Connect and attach a debugger to IDA"
49+
"title": "IDACode: Connect and attach a debugger to IDA"
5050
},
5151
{
5252
"command": "idacode.executeScript",
53-
"title": "Execute script in IDA"
53+
"title": "IDACode: Execute script in IDA"
5454
}
5555
],
5656
"configuration": {

images/commands.png

1.29 KB
Loading

0 commit comments

Comments
 (0)