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

Commit 252155c

Browse files
authored
Merge pull request #99 from imbillow/get_signature
Enhanced Function.get_signature
2 parents 8b9d5a4 + 1e457ad commit 252155c

File tree

8 files changed

+835
-249
lines changed

8 files changed

+835
-249
lines changed

idb/analysis.py

Lines changed: 33 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,7 @@
33
import itertools
44
import logging
55
import types
6-
from collections import Counter
7-
from collections import namedtuple
6+
from collections import Counter, namedtuple
87
from random import randint
98

109
import six
@@ -13,6 +12,8 @@
1312

1413
import idb
1514
import idb.netnode
15+
import idb.typeinf
16+
import idb.typeinf_flags
1617

1718
logger = logging.getLogger(__name__)
1819

@@ -1217,6 +1218,18 @@ def pairs(l):
12171218
StackChangePoint = namedtuple("StackChangePoint", ["effective_address", "change"])
12181219

12191220

1221+
def create_pstring_list(buf):
1222+
_lst = []
1223+
ofs = 0
1224+
while ofs < len(buf.strip(b"\x00")):
1225+
_len = struct.unpack_from("<B", buf, ofs)[0]
1226+
_lst.append(buf[ofs : ofs + _len][1:].decode("utf-8"))
1227+
ofs += _len
1228+
if _len == 0:
1229+
ofs += 1
1230+
return _lst
1231+
1232+
12201233
class Function:
12211234
"""
12221235
Example::
@@ -1238,41 +1251,24 @@ def get_name(self):
12381251
return "sub_%X" % (self.nodeid)
12391252

12401253
def get_signature(self):
1241-
typebuf = self.netnode.supval(tag="S", index=0x3000)
1242-
namebuf = self.netnode.supval(tag="S", index=0x3001)
1243-
1244-
if six.indexbytes(typebuf, 0x0) != 0xC:
1245-
raise RuntimeError("unexpected signature header")
1246-
1247-
if six.indexbytes(typebuf, 0x1) == ord("S"):
1248-
# this is just a guess...
1249-
conv = "__stdcall"
1250-
else:
1251-
raise NotImplementedError()
1252-
1253-
rtype = TypeString()
1254-
rtype.vsParse(typebuf, offset=2)
1255-
1256-
# this is a guess???
1257-
sp_delta = typebuf[2 + len(rtype)]
1258-
1259-
params = []
1260-
typeoffset = 0x2 + len(rtype) + 0x1
1261-
nameoffset = 0x0
1262-
while typeoffset < len(typebuf):
1263-
if six.indexbytes(typebuf, typeoffset) == 0x0:
1264-
break
1265-
typename = TypeString()
1266-
typename.vsParse(typebuf, offset=typeoffset)
1267-
typeoffset += len(typename)
1268-
1269-
paramname = PString()
1270-
paramname.vsParse(namebuf, offset=nameoffset)
1271-
nameoffset += len(paramname)
1272-
1273-
params.append(FunctionParameter(typename.s, paramname.s))
1274-
1275-
return FunctionSignature(conv, rtype.s, sp_delta, params)
1254+
try:
1255+
typebuf = self.netnode.supval(tag="S", index=0x3000)
1256+
namebuf = self.netnode.supval(tag="S", index=0x3001)
1257+
typ = six.indexbytes(typebuf, 0x0)
1258+
if not idb.typeinf_flags.is_type_func(typ):
1259+
raise RuntimeError("is not function")
1260+
1261+
names = create_pstring_list(namebuf)
1262+
typedata = idb.typeinf.FuncTypeData()
1263+
ts = idb.typeinf.TypeString(typebuf)
1264+
typedata.deserialize(self.idb.til, ts, names, [])
1265+
inf = Root(self.idb).idainfo
1266+
1267+
return idb.typeinf.TInfo(
1268+
typ, typedata, til=self.idb.til, name=self.get_name(), inf=inf
1269+
)
1270+
except KeyError:
1271+
return None
12761272

12771273
def get_chunks(self):
12781274
v = self.netnode.supval(tag="S", index=0x7000)

idb/fileformat.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313

1414
import idb
1515
import idb.netnode
16+
from idb.analysis import Root
1617
from idb.typeinf import TIL
1718

1819
try:
@@ -1194,6 +1195,8 @@ def pcb_header(self):
11941195

11951196
s = sectiondef.cls(buf=section.contents, wordsize=self.wordsize)
11961197
s.vsParse(section.contents)
1198+
if isinstance(s, TIL):
1199+
s.inf = Root(self).idainfo
11971200
# vivisect doesn't allow you to assign vstructs to
11981201
# attributes that are not part of the struct,
11991202
# so we need to override and use the default object behavior.

idb/idapython.py

Lines changed: 3 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,9 @@
11
# -*- coding: utf-8 -*-
22
import collections
3+
import logging
34
import os
45
import re
56
import struct
6-
import logging
7-
import re
87
import weakref
98

109
import six
@@ -1213,23 +1212,8 @@ def GetType(self, ea):
12131212
except Exception as e:
12141213
logger.warning("failed to fetch function for GetType: %s", e)
12151214
return None
1216-
1217-
try:
1218-
name = f.get_name()
1219-
sig = f.get_signature()
1220-
except KeyError:
1221-
return None
1222-
1223-
params = []
1224-
for param in sig.parameters:
1225-
params.append("%s %s" % (param.type, param.name))
1226-
1227-
return "{rtype:s} {cc:s} {name:s}({params:s})".format(
1228-
rtype=sig.rtype,
1229-
cc=sig.calling_convention,
1230-
name=name,
1231-
params=", ".join(params),
1232-
)
1215+
sig = f.get_signature()
1216+
return sig.get_typestr() if sig is not None else None
12331217

12341218
@staticmethod
12351219
def hasValue(flags):

0 commit comments

Comments
 (0)