Skip to content
This repository has been archived by the owner on Aug 13, 2024. It is now read-only.

Commit

Permalink
merged PR #58
Browse files Browse the repository at this point in the history
  • Loading branch information
Cedric Halbronn committed Jun 17, 2020
2 parents a45b10e + 379b464 commit 3ad5823
Show file tree
Hide file tree
Showing 5 changed files with 95 additions and 59 deletions.
20 changes: 10 additions & 10 deletions idarling/core/events.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
import ida_lines
import ida_nalt
import ida_name
import ida_netnode
import ida_pro
import ida_range
import ida_segment
Expand Down Expand Up @@ -106,31 +107,28 @@ def __call__(self):
class MakeDataEvent(Event):
__event__ = "make_data"

def __init__(self, ea, flags, size, tid):
def __init__(self, ea, flags, size, sname):
super(MakeDataEvent, self).__init__()
self.ea = ea
self.flags = flags
self.size = size
self.tid = tid
self.sname = sname

def __call__(self):
ida_bytes.create_data(self.ea, ida_bytes.calc_dflags(self.flags, True), self.size, self.tid)
ida_bytes.create_data(self.ea, ida_bytes.calc_dflags(self.flags, True), self.size, ida_struct.get_struc_id(self.sname) if self.sname else ida_netnode.BADNODE)


class RenamedEvent(Event):
__event__ = "renamed"

def __init__(self, ea, new_name, old_name, local_name):
def __init__(self, ea, new_name, local_name):
super(RenamedEvent, self).__init__()
self.ea = ea
self.old_name = old_name
self.new_name = new_name
self.local_name = local_name

def __call__(self):
flags = ida_name.SN_LOCAL if self.local_name else 0
if self.old_name:
self.ea = ida_struct.get_member_by_fullname(self.old_name).id
ida_name.set_name(
self.ea, self.new_name, flags | ida_name.SN_NOWARN
)
Expand Down Expand Up @@ -297,7 +295,9 @@ def __call__(self):
py_type = py_type[1:]
if len(py_type) >= 2:
if self.name:
self.ea = ida_struct.get_member_by_fullname(self.name).id
r = ida_struct.get_member_by_fullname(self.name)
if r:
self.ea = r[0].id
ida_typeinf.apply_type(
None,
GetTypeString(py_type[0]),
Expand Down Expand Up @@ -603,7 +603,7 @@ def __init__(self, sname, fieldname, offset, flag, nbytes, extra):
def __call__(self):
mt = ida_nalt.opinfo_t()
if ida_bytes.is_struct(self.flag):
mt.tid = self.extra["id"]
mt.tid = ida_struct.get_struc_id(self.extra["struc_name"])
if ida_bytes.is_off0(self.flag) or ida_bytes.is_off1(self.flag):
mt.ri = ida_nalt.refinfo_t()
mt.ri.init(
Expand Down Expand Up @@ -640,7 +640,7 @@ def __init__(self, sname, soff, eoff, flag, extra):
def __call__(self):
mt = ida_nalt.opinfo_t()
if ida_bytes.is_struct(self.flag):
mt.tid = self.extra["id"]
mt.tid = ida_struct.get_struc_id(self.extra["struc_name"])
if ida_bytes.is_off0(self.flag) or ida_bytes.is_off1(self.flag):
mt.ri = ida_nalt.refinfo_t()
mt.ri.init(
Expand Down
26 changes: 16 additions & 10 deletions idarling/core/hooks.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
import ida_idp
import ida_kernwin
import ida_nalt
import ida_netnode
import ida_pro
import ida_segment
import ida_struct
Expand Down Expand Up @@ -78,7 +79,7 @@ def local_types_changed(self):
# self._plugin.logger.trace(self._plugin.core.local_type_map)
for i in range(1, ida_typeinf.get_ordinal_qty(ida_typeinf.get_idati())):
t = ImportLocalType(i)
if t and t.name and ida_struct.get_struc_id(t.name) == ida_idaapi.BADADDR:
if t and t.name and ida_struct.get_struc_id(t.name) == ida_idaapi.BADADDR and ida_enum.get_enum(t.name) == ida_idaapi.BADADDR:
if i in self._plugin.core.local_type_map:
t_old = self._plugin.core.local_type_map[i]
if t_old and not t.isEqual(t_old):
Expand Down Expand Up @@ -167,11 +168,12 @@ def local_types_changed(self):
# return 0

def ti_changed(self, ea, type, fname):
self._plugin.logger.debug("ti_changed(ea = 0x%X, type = %s, fname = %s)" % (ea, type, fname))
name = ""
if ida_struct.is_member_id(ea):
name = ida_struct.get_struc_name(ea)
type = ida_typeinf.idc_get_type_raw(ea)
self._send_packet(evt.TiChangedEvent(ea, (ParseTypeString(type[0]), type[1]), name))
self._send_packet(evt.TiChangedEvent(ea, (ParseTypeString(type[0]) if type else [], type[1] if type else None), name))
return 0

def op_ti_changed(self, ea, n, type, fnames):
Expand Down Expand Up @@ -341,7 +343,7 @@ def struc_member_created(self, sptr, mptr):
)
)
elif flag & ida_bytes.stru_flag():
extra["id"] = mt.tid
extra["struc_name"] = ida_struct.get_struc_name(mt.tid)
if flag & ida_bytes.strlit_flag():
extra["strtype"] = mt.strtype
self._send_packet(
Expand Down Expand Up @@ -396,7 +398,7 @@ def struc_member_changed(self, sptr, mptr):
)
)
elif flag & ida_bytes.stru_flag():
extra["id"] = mt.tid
extra["struc_name"] = ida_struct.get_struc_name(mt.tid)
if flag & ida_bytes.strlit_flag():
extra["strtype"] = mt.strtype
self._send_packet(
Expand Down Expand Up @@ -525,16 +527,20 @@ def sgr_changed(self, start_ea, end_ea, regnum, value, old_value, tag):
# return 0

def make_data(self, ea, flags, tid, size):
# TODO: tid --> struct name
self._plugin.logger.debug("make_data(ea = %x, flags = %x, tid = %x, size = %x)" % (ea, flags, tid, size))
self._send_packet(evt.MakeDataEvent(ea, flags, size, tid))
# Note: MakeDataEvent.sname == '' is convention for BADNODE
self._send_packet(evt.MakeDataEvent(ea, flags, size, ida_struct.get_struc_name(tid) if tid != ida_netnode.BADNODE else ''))
return 0

def renamed(self, ea, new_name, local_name):
old_name = ""
if ida_struct.is_member_id(ea):
old_name = ida_struct.get_struc_name(ea)
self._send_packet(evt.RenamedEvent(ea, new_name, old_name, local_name))
self._plugin.logger.debug("renamed(ea = %x, new_name = %s, local_name = %d)" % (ea, new_name, local_name))
if ida_struct.is_member_id(ea) or ida_struct.get_struc(ea) or ida_enum.get_enum_name(ea):
# Drop hook to avoid duplicate since already handled by the following hooks:
# - renaming_struc_member() -> sends 'StrucMemberRenamedEvent'
# - renaming_struc() -> sends 'StrucRenamedEvent'
# - renaming_enum() -> sends 'EnumRenamedEvent'
return 0
self._send_packet(evt.RenamedEvent(ea, new_name, local_name))
return 0

def byte_patched(self, ea, old_value):
Expand Down
44 changes: 28 additions & 16 deletions idarling/interface/dialogs.py
Original file line number Diff line number Diff line change
Expand Up @@ -248,11 +248,15 @@ def _delete_group_clicked(self):
d.add_callback(partial(self._group_deleted, group))
d.add_errback(self._plugin.logger.exception)

def _group_deleted(self, group, _):
for e in self._groups:
if e.name == group.name:
self._groups.remove(e)
self._refresh_groups()
def _group_deleted(self, group, reply):
if reply.deleted:
for e in self._groups:
if e.name == group.name:
self._groups.remove(e)
self._refresh_groups()
else:
QMessageBox.about(self, "IDArling Error", "Unable to delete.\n"
"Likely more than one client connected to target?")

##### PROJECTS #####

Expand Down Expand Up @@ -310,12 +314,16 @@ def _delete_project_clicked(self):
d.add_callback(partial(self._project_deleted, project))
d.add_errback(self._plugin.logger.exception)

def _project_deleted(self, project, _):
for e in self._projects:
if e.name == project.name:
self._projects.remove(e)
self._refresh_projects()
self._databases_table.clearContents()
def _project_deleted(self, project, reply):
if reply.deleted:
for e in self._projects:
if e.name == project.name:
self._projects.remove(e)
self._refresh_projects()
self._databases_table.clearContents()
else:
QMessageBox.about(self, "IDArling Error", "Unable to delete.\n"
"Likely more than one client connected to target?")

def _rename_project_button_clicked(self, _):
current_project = self._projects_table.selectedItems()[0].data(Qt.UserRole).name
Expand Down Expand Up @@ -389,11 +397,15 @@ def _delete_database_clicked(self):
d.add_callback(partial(self._database_deleted, database))
d.add_errback(self._plugin.logger.exception)

def _database_deleted(self, database, _):
for e in self._databases:
if e.name == database.name:
self._databases.remove(e)
self._refresh_databases()
def _database_deleted(self, database, reply):
if reply.deleted:
for e in self._databases:
if e.name == database.name:
self._databases.remove(e)
self._refresh_databases()
else:
QMessageBox.about(self, "IDArling Error", "Unable to delete.\n"
"Likely more than one client connected to target?")

def _database_double_clicked(self):
project_type = self._projects_table.selectedItems()[0].data(Qt.UserRole).type
Expand Down
18 changes: 12 additions & 6 deletions idarling/shared/commands.py
Original file line number Diff line number Diff line change
Expand Up @@ -114,8 +114,10 @@ def __init__(self, group_name):
super(DeleteGroup.Query, self).__init__()
self.group_name = group_name

class Reply(IReply, Command):
pass
class Reply(IReply, DefaultCommand):
def __init__(self, query, deleted):
super(DeleteGroup.Reply, self).__init__(query)
self.deleted = deleted

class CreateProject(ParentCommand):
__command__ = "create_project"
Expand Down Expand Up @@ -143,8 +145,10 @@ def __init__(self, group_name, project_name):
self.group_name = group_name
self.project_name = project_name

class Reply(IReply, Command):
pass
class Reply(IReply, DefaultCommand):
def __init__(self, query, deleted):
super(DeleteProject.Reply, self).__init__(query)
self.deleted = deleted


class CreateDatabase(ParentCommand):
Expand Down Expand Up @@ -174,8 +178,10 @@ def __init__(self, group_name, project_name, database_name):
self.project_name = project_name
self.database_name = database_name

class Reply(IReply, Command):
pass
class Reply(IReply, DefaultCommand):
def __init__(self, query, deleted):
super(DeleteDatabase.Reply, self).__init__(query)
self.deleted = deleted

class UpdateFile(ParentCommand):
__command__ = "update_file"
Expand Down
46 changes: 29 additions & 17 deletions idarling/shared/server.py
Original file line number Diff line number Diff line change
Expand Up @@ -375,28 +375,40 @@ def _delete_database_files(self, group_name, project_name, database_name):
pass

def _handle_delete_group(self, packet):
def match_group(group_name,user):
def match_group(user, group_name):
return user.group == group_name

self._delete_group_files(packet.group_name)
self.parent().storage.delete_group(packet.group_name)
self.parent().forward_users(self,packet,partial(match_group,group_name=packet.group_name))
self.send_packet(DeleteGroup.Reply(packet))
if len(self.parent().get_users(self,partial(match_group, group_name=packet.group_name))):
self.send_packet(DeleteGroup.Reply(packet, False))
else:
self._delete_group_files(packet.group_name)
self.parent().storage.delete_group(packet.group_name)
# self.parent().forward_users(self,packet,partial(match_group,group_name=packet.group_name))
self.send_packet(DeleteGroup.Reply(packet, True))

def _handle_delete_project(self,packet):
def match_user(group_name, project_name, user):
def match_user(user, group_name, project_name):
return user.group == group_name and user.project == project_name

self._delete_project_files(packet.group_name, packet.project_name)
self.parent().storage.delete_project(packet.group_name, packet.project_name)
self.parent().forward_users(self,packet,partial(match_user, group_name=packet.group_name,project_name=packet.project_name))
self.send_packet(DeleteProject.Reply(packet))
if len(self.parent().get_users(self, partial(match_user, group_name=packet.group_name, project_name=packet.project_name))):
self.send_packet(DeleteProject.Reply(packet, False))
else:
self._delete_project_files(packet.group_name, packet.project_name)
self.parent().storage.delete_project(packet.group_name, packet.project_name)
# self.parent().forward_users(self,packet,partial(match_user, group_name=packet.group_name,project_name=packet.project_name))
self.send_packet(DeleteProject.Reply(packet, True))

def _handle_delete_database(self, packet):
self._delete_database_files(packet.group_name, packet.project_name, packet.database_name)
self.parent().storage.delete_database(packet.group_name, packet.project_name, packet.database_name)
self.parent().forward_users(self, packet)
self.send_packet(DeleteDatabase.Reply(packet))
def match_user(user, group_name, project_name, database_name):
return user.group == group_name and user.project == project_name and user.database == database_name

if len(self.parent().get_users(self,partial(match_user, group_name=packet.group_name, project_name=packet.project_name,database_name=packet.database_name))):
self.send_packet(DeleteDatabase.Reply(packet, False))
else:
self._delete_database_files(packet.group_name, packet.project_name, packet.database_name)
self.parent().storage.delete_database(packet.group_name, packet.project_name, packet.database_name)
# self.parent().forward_users(self, packet)
self.send_packet(DeleteDatabase.Reply(packet, True))


class Server(ServerSocket):
Expand Down Expand Up @@ -522,9 +534,9 @@ def get_users(self, client, matches=None):
"""Get the other users on the same database."""
users = []
for user in self._clients:
if (
user.project != client.project
or user.database != client.database
if (matches is None and
(user.project != client.project
or user.database != client.database)
):
continue
if user == client or (matches and not matches(user)):
Expand Down

0 comments on commit 3ad5823

Please sign in to comment.