Skip to content
This repository has been archived by the owner on Feb 19, 2021. It is now read-only.

Python3 support #99

Open
wants to merge 11 commits into
base: master
Choose a base branch
from
17 changes: 10 additions & 7 deletions idarling/core/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ def get_ida_dll(app_name=None):
idaname = "ida64" if "64" in app_name else "ida"
if sys.platform == "win32":
dllname, dlltype = idaname + ".dll", ctypes.windll
elif sys.platform == "linux2":
elif sys.platform in ["linux", "linux2"]:
dllname, dlltype = "lib" + idaname + ".so", ctypes.cdll
elif sys.platform == "darwin":
dllname, dlltype = "lib" + idaname + ".dylib", ctypes.cdll
Expand Down Expand Up @@ -233,9 +233,9 @@ def load_netnode(self):
"""
node = ida_netnode.netnode(Core.NETNODE_NAME, 0, True)

self._project = node.hashval("project") or None
self._database = node.hashval("database") or None
self._tick = int(node.hashval("tick") or "0")
self._project = node.hashstr("project") or None
self._database = node.hashstr("database") or None
self._tick = int(node.hashstr("tick") or "0")

self._plugin.logger.debug(
"Loaded netnode: project=%s, database=%s, tick=%d"
Expand All @@ -246,12 +246,15 @@ def save_netnode(self):
"""Save data into our custom netnode."""
node = ida_netnode.netnode(Core.NETNODE_NAME, 0, True)

# node.hashset does not work anymore with direct string
# use of hashet_buf instead
# (see https://github.com/idapython/src/blob/master/swig/netnode.i#L162)
if self._project:
node.hashset("project", str(self._project))
node.hashset_buf("project", str(self._project))
if self._database:
node.hashset("database", str(self._database))
node.hashset_buf("project", str(self._database))
if self._tick:
node.hashset("tick", str(self._tick))
node.hashset_buf("project", str(self._tick))

self._plugin.logger.debug(
"Saved netnode: project=%s, database=%s, tick=%d"
Expand Down
2 changes: 1 addition & 1 deletion idarling/core/hooks.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
import ida_struct
import ida_typeinf

import events as evt # noqa: I100,I202
from . import events # noqa: I100,I202
from .events import Event # noqa: I201


Expand Down
4 changes: 3 additions & 1 deletion idarling/interface/actions.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,9 @@ def install(self):
action_name = self.__class__.__name__

# Read and load the icon file
icon_data = str(open(self._icon, "rb").read())
icon_data_fd = open(self._icon, "rb")
icon_data = icon_data_fd.read()
icon_data_fd.close()
self._icon_id = ida_kernwin.load_custom_icon(data=icon_data)

# Create the action descriptor
Expand Down
13 changes: 10 additions & 3 deletions idarling/interface/dialogs.py
Original file line number Diff line number Diff line change
Expand Up @@ -259,7 +259,6 @@ def _create_project_clicked(self):
def _create_project_accepted(self, dialog):
"""Called when the project creation dialog is accepted."""
name = dialog.get_result()

# Ensure we don't already have a project with that name
if any(project.name == name for project in self._projects):
failure = QMessageBox()
Expand All @@ -274,11 +273,16 @@ def _create_project_accepted(self, dialog):

# Get all the information we need and sent it to the server
hash = ida_nalt.retrieve_input_file_md5().lower()
# Remove the trailing null byte, if exists
if hash.endswith(b'\x00'):
hash = hash[0:-1]
# This decode is safe, because we have an hash in hex format
hash = hash.decode('utf-8')
file = ida_nalt.get_root_filename()
type = ida_loader.get_file_type_name()
ftype = ida_loader.get_file_type_name()
date_format = "%Y/%m/%d %H:%M"
date = datetime.datetime.now().strftime(date_format)
project = Project(name, hash, file, type, date)
project = Project(name, hash, file, ftype, date)
d = self._plugin.network.send_packet(CreateProject.Query(project))
d.add_callback(partial(self._project_created, project))
d.add_errback(self._plugin.logger.exception)
Expand All @@ -294,6 +298,9 @@ def _project_created(self, project, _):
def _refresh_projects(self):
super(SaveDialog, self)._refresh_projects()
hash = ida_nalt.retrieve_input_file_md5().lower()
if hash.endswith(b'\x00'):
hash = hash[0:-1]
hash = hash.decode('utf-8')
for row in range(self._projects_table.rowCount()):
item = self._projects_table.item(row, 0)
project = item.data(Qt.UserRole)
Expand Down
2 changes: 1 addition & 1 deletion idarling/interface/invites.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ def __init__(self, plugin, parent=None):
self._popup_opacity = 0.0
self._animation = QPropertyAnimation()
self._animation.setTargetObject(self)
self._animation.setPropertyName("popup_opacity")
self._animation.setPropertyName(b"popup_opacity")
self._animation.finished.connect(self.hide)

# Timer used to auto-close the window
Expand Down
2 changes: 1 addition & 1 deletion idarling/plugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -204,6 +204,6 @@ def load_config(self):
def save_config(self):
"""Save the configuration file."""
config_path = self.user_resource("files", "config.json")
with open(config_path, "wb") as config_file:
with open(config_path, "w") as config_file:
config_file.write(json.dumps(self._config))
self._logger.debug("Saved config: %s" % self._config)
11 changes: 7 additions & 4 deletions idarling/shared/discovery.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,6 @@ def start(self, host, port, ssl):
"""Start the discovery process and broadcast the given information."""
self._logger.debug("Starting clients discovery")
self._info = "%s %d %s" % (host, port, ssl)

# Create a datagram socket capable of broadcasting
self._socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
self._socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
Expand Down Expand Up @@ -82,10 +81,14 @@ def _send_request(self):
request = request.encode("utf-8")
while len(request):
try:
sent = self._socket.sendto(request, ("<broadcast>", 31013))
sent = self._socket.sendto(request, socket.MSG_DONTWAIT, ("<broadcast>", 31013))
request = request[sent:]
except socket.error:
self._logger.warning("Couldn't send discovery request")
except socket.error as e:
self._logger.warning("Couldn't send discovery request: {}".format(e))
# Force return, otherwise the while loop will halt IDA
# This is a temporary fix, and it's gonna yield the above
# warning every every n seconds..
return

def _notify_read(self):
"""This function is called when a discovery reply is received."""
Expand Down
1 change: 1 addition & 0 deletions idarling/shared/sockets.py
Original file line number Diff line number Diff line change
Expand Up @@ -237,6 +237,7 @@ def _notify_write(self):

if self._write_cursor >= len(self._write_buffer):
if not self._outgoing:
self._write_notifier.setEnabled(False)
return # No more packets to send
self._write_packet = self._outgoing.popleft()

Expand Down