Skip to content
This repository was archived by the owner on Jul 8, 2025. It is now read-only.

Commit fc1a0db

Browse files
idapython: add api for enumerating exports
1 parent d9149a2 commit fc1a0db

File tree

2 files changed

+52
-0
lines changed

2 files changed

+52
-0
lines changed

idb/idapython.py

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1435,6 +1435,43 @@ def CodeRefsFrom(self, ea, flow):
14351435
yield xref.dst
14361436

14371437

1438+
class ida_entry:
1439+
def __init__(self, db, api):
1440+
self.idb = db
1441+
self.api = api
1442+
1443+
def get_entry_qty(self):
1444+
ents = idb.analysis.EntryPoints(self.idb)
1445+
return len(ents.functions) + len(ents.main_entry)
1446+
1447+
def get_entry_ordinal(self, index):
1448+
ents = idb.analysis.EntryPoints(self.idb)
1449+
try:
1450+
return ents.ordinals[index + 1]
1451+
except KeyError:
1452+
# once we enumerate all the exports by ordinal,
1453+
# then wrap into the "main entry".
1454+
# not sure that there can be more than one, but we attempt to deal here.
1455+
return sorted(ents.main_entry)[index - len(ents.functions) - 1]
1456+
1457+
def get_entry(self, ordinal):
1458+
# for the "main entry", ordinal is actually an address.
1459+
ents = idb.analysis.EntryPoints(self.idb)
1460+
return ents.functions[ordinal]
1461+
1462+
def get_entry_name(self, ordinal):
1463+
ents = idb.analysis.EntryPoints(self.idb)
1464+
try:
1465+
return ents.function_names[ordinal]
1466+
except KeyError:
1467+
# for the "main entry", ordinal is actually an address.
1468+
return ents.main_entry_name[ordinal]
1469+
1470+
def get_entry_forwarder(self, ordinal):
1471+
ents = idb.analysis.EntryPoints(self.idb)
1472+
return ents.forwarded_symbols.get(ordinal)
1473+
1474+
14381475
class IDAPython:
14391476
def __init__(self, db, ScreenEA=None):
14401477
self.idb = db
@@ -1447,3 +1484,5 @@ def __init__(self, db, ScreenEA=None):
14471484
self.ida_bytes = ida_bytes(db, self)
14481485
self.ida_netnode = ida_netnode(db, self)
14491486
self.ida_nalt = ida_nalt(db, self)
1487+
self.ida_entry = ida_entry(db, self)
1488+

tests/test_idaapi.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -666,3 +666,16 @@ def cb(addr, name, ordinal):
666666
api.ida_nalt.enum_import_names(1, cb)
667667
assert len(names) == 388
668668
assert names[0] == (0x689dd014, 'NtMapUserPhysicalPagesScatter', None)
669+
670+
671+
@kern32_test()
672+
def test_exports(kernel32_idb, version, bitness, expected):
673+
api = idb.IDAPython(kernel32_idb)
674+
assert api.ida_entry.get_entry_qty() == 1572
675+
assert api.ida_entry.get_entry_ordinal(0x0) == 1
676+
assert api.ida_entry.get_entry(api.ida_entry.get_entry_ordinal(0x0)) == 0x6890172d
677+
assert api.ida_entry.get_entry_name(api.ida_entry.get_entry_ordinal(0x0)) == 'BaseThreadInitThunk'
678+
assert api.ida_entry.get_entry_forwarder(api.ida_entry.get_entry_ordinal(0x10)) is None
679+
680+
assert api.ida_entry.get_entry_ordinal(1572) == 0x68901695
681+
assert api.ida_entry.get_entry_name(0x68901695) == 'DllEntryPoint'

0 commit comments

Comments
 (0)