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

Commit 58de7fe

Browse files
authored
Merge pull request #93 from imbillow/v500
V500 Support
2 parents 25faf6f + 740572f commit 58de7fe

File tree

5 files changed

+82
-39
lines changed

5 files changed

+82
-39
lines changed

idb/analysis.py

Lines changed: 22 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -485,7 +485,7 @@ def pcb_version(self):
485485
v_ea_t = v_word
486486
v_sel_t = v_word
487487

488-
if 610 <= self.version < 700:
488+
if 480 <= self.version < 700:
489489
self.vsAddField("lflags", v_uint8()) # 0x0d
490490
self.vsAddField("demnames", v_uint8())
491491

@@ -573,9 +573,9 @@ def pcb_version(self):
573573
self.vsAddField("margin", v_uint16())
574574
self.vsAddField("lenxref", v_uint16())
575575

576-
self.vsAddField("lprefix", v_str(size=16))
576+
self.vsAddField("lprefix", v_str(size=16)) # 167
577577

578-
self.vsAddField("lprefixlen", v_uint8())
578+
self.vsAddField("lprefixlen", v_uint8()) # 183
579579
self.vsAddField("compiler", v_uint8())
580580
self.vsAddField("model", v_uint8())
581581
self.vsAddField("sizeof_int", v_uint8())
@@ -586,7 +586,10 @@ def pcb_version(self):
586586
self.vsAddField("sizeof_long", v_uint8())
587587
self.vsAddField("sizeof_llong", v_uint8())
588588

589-
self.vsAddField("change_counter", v_uint32())
589+
if self.len_sbytes < 193:
590+
return
591+
592+
self.vsAddField("change_counter", v_uint32()) # 193
590593

591594
self.vsAddField("sizeof_ldbl", v_uint8())
592595

@@ -1051,10 +1054,13 @@ def get_type(self):
10511054
# nodeid: ff000078 tag: S index: 0x3000
10521055
# 00000000: 3D 0A 48 49 4E 53 54 41 4E 43 45 00 =.HINSTANCE.
10531056

1054-
v = self.netnode.supval(tag="S", index=0x3000)
1055-
s = TypeString()
1056-
s.vsParse(v)
1057-
return s.s
1057+
try:
1058+
v = self.netnode.supval(tag="S", index=0x3000)
1059+
s = TypeString()
1060+
s.vsParse(v)
1061+
return s.s
1062+
except KeyError:
1063+
return None
10581064

10591065
def get_enum_id(self):
10601066
return self.netnode.altval(tag="A", index=0xB)
@@ -1122,6 +1128,14 @@ class Struct:
11221128
"""
11231129

11241130
def __init__(self, db, identity):
1131+
"""from https://github.com/nlitsme/pyidbutil/blob/7705bcde167fd34a5800bfe54ba99d195b44bbbb/idblib.py#L1380
1132+
Decodes info for structures
1133+
(structnode, N) = structname
1134+
(structnode, D, address) = xref-type
1135+
(structnode, M, 0) = packed struct info
1136+
(structnode, S, 27) = packed value(addr, byte)
1137+
"""
1138+
11251139
self.idb = db
11261140

11271141
if isinstance(identity, six.integer_types):
@@ -1146,9 +1160,6 @@ def get_members(self):
11461160
flags = u.dd()
11471161
count = u.dd()
11481162

1149-
if not flags & STRUCT_FLAGS.SF_FRAME:
1150-
raise RuntimeError("unexpected frame header")
1151-
11521163
for i in range(count):
11531164
nodeid_offset = u.addr()
11541165
_ = u.addr()

tests/test_analysis.py

Lines changed: 21 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ def lpluck(prop, s):
3838
def test_root(kernel32_idb, version, bitness, expected):
3939
root = idb.analysis.Root(kernel32_idb)
4040

41-
assert root.version in (610, 640, 650, 670, 680, 695, 700)
41+
assert root.version in (480, 610, 640, 650, 670, 680, 695, 700)
4242
assert root.get_field_tag("version") == "A"
4343
assert root.get_field_index("version") == -1
4444

@@ -140,7 +140,7 @@ def test_struct(kernel32_idb, version, bitness, expected):
140140
"lpReserved",
141141
]
142142

143-
assert members[2].get_type() == "HINSTANCE"
143+
assert members[2].get_type() == ("HINSTANCE" if version > 500 else None)
144144

145145

146146
@kern32_test()
@@ -170,7 +170,7 @@ def test_function(kernel32_idb, version, bitness, expected):
170170
# .text:689016B8 8B EC mov ebp, esp
171171
# .text:689016BA 81 EC 14 02 00 00 sub esp, 214h
172172
sub_689016B5 = idb.analysis.Function(kernel32_idb, 0x689016B5)
173-
if version <= 700:
173+
if 500 < version <= 700:
174174
assert sub_689016B5.get_name() == "sub_689016B5"
175175
else:
176176
assert sub_689016B5.get_name() == "__BaseDllInitialize@12"
@@ -319,11 +319,15 @@ def test_segments(kernel32_idb, version, bitness, expected):
319319
0x689DB000,
320320
0x689DD000,
321321
]
322-
assert list(sorted(map(lambda s: s.endEA, segs.values()))) == [
323-
0x689DB000,
324-
0x689DD000,
325-
0x689DE230,
326-
]
322+
end_ea = list(sorted(map(lambda s: s.endEA, segs.values())))
323+
if version > 500:
324+
assert end_ea == [
325+
0x689DB000,
326+
0x689DD000,
327+
0x689DE230,
328+
]
329+
else:
330+
assert end_ea == [1755164672, 1755169504, 1755177520]
327331

328332

329333
@kern32_test(
@@ -621,21 +625,24 @@ def test_idainfo(kernel32_idb, version, bitness, expected):
621625
assert idainfo.tag == "IDA"
622626
elif version == 700:
623627
assert idainfo.tag == "ida"
624-
assert 610 <= idainfo.version <= 700
628+
assert 480 <= idainfo.version <= 700
625629
assert idainfo.procname == "metapc"
626630

627631
# Portable Executable (PE)
628632
assert idainfo.filetype == 11
629-
if version == 695:
633+
if version <= 695:
630634
assert idainfo.af == 0xFFFF
631635
assert idainfo.ascii_break == ord("\n")
632-
# Visual C++
633-
assert idainfo.compiler == 0x01
636+
if version == 630:
637+
assert idainfo.compiler == 129
638+
else:
639+
assert idainfo.compiler == 0x01
634640
assert idainfo.sizeof_int == 4
635-
assert idainfo.sizeof_bool == 1
641+
assert idainfo.sizeof_bool in (1, 4)
636642
assert idainfo.sizeof_long == 4
637643
assert idainfo.sizeof_llong == 8
638-
assert idainfo.sizeof_ldbl == 8
644+
if version > 500:
645+
assert idainfo.sizeof_ldbl == 8
639646
elif version >= 700:
640647
assert idainfo.af == 0xDFFFFFF7
641648
assert idainfo.strlit_break == ord("\n")

tests/test_idaapi.py

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -337,8 +337,10 @@ def test_func_t(kernel32_idb, version, bitness, expected):
337337
assert idb.idapython.is_flag_set(flags, api.ida_funcs.FUNC_THUNK) is False
338338
assert idb.idapython.is_flag_set(flags, api.ida_funcs.FUNC_BOTTOMBP) is False
339339
assert idb.idapython.is_flag_set(flags, api.ida_funcs.FUNC_NORET_PENDING) is False
340-
assert idb.idapython.is_flag_set(flags, api.ida_funcs.FUNC_SP_READY) is True
341-
assert idb.idapython.is_flag_set(flags, api.ida_funcs.FUNC_PURGED_OK) is True
340+
341+
if version > 500:
342+
assert idb.idapython.is_flag_set(flags, api.ida_funcs.FUNC_SP_READY) is True
343+
assert idb.idapython.is_flag_set(flags, api.ida_funcs.FUNC_PURGED_OK) is True
342344
assert idb.idapython.is_flag_set(flags, api.ida_funcs.FUNC_TAIL) is False
343345
# also demonstrate finding the func from an address it may contain.
344346
# note: this can be a pretty slow search, since we do everything on demand
@@ -554,6 +556,9 @@ def test_get_mnem(kernel32_idb, version, bitness, expected):
554556

555557
@kern32_test()
556558
def test_functions(kernel32_idb, version, bitness, expected):
559+
if version <= 500:
560+
return
561+
557562
api = idb.IDAPython(kernel32_idb)
558563

559564
funcs = api.idautils.Functions()
@@ -577,13 +582,14 @@ def test_function_names(kernel32_idb, version, bitness, expected):
577582
)
578583
assert (
579584
api.idc.GetFunctionName(0x689016B5) == "sub_689016b5"
580-
if version <= 700
585+
if 500 < version <= 700
581586
else "__BaseDllInitialize@12"
582587
)
583588

584-
with pytest.raises(KeyError):
585-
# this is issue #7.
586-
_ = api.idc.GetFunctionName(0x689018E5)
589+
if version > 500:
590+
with pytest.raises(KeyError):
591+
# this is issue #7.
592+
_ = api.idc.GetFunctionName(0x689018E5)
587593

588594

589595
@pytest.mark.slow
@@ -651,7 +657,7 @@ def test_all_comments(kernel32_idb, version, bitness, expected):
651657
def test_LocByName(kernel32_idb, version, bitness, expected):
652658
api = idb.IDAPython(kernel32_idb)
653659

654-
if version <= 700:
660+
if 500 < version <= 700:
655661
assert api.idc.LocByName("CancelIo") == 0x6892E70A
656662
assert api.idc.GetFunctionName(api.idc.LocByName("CancelIo")) == "CancelIo"
657663

@@ -976,7 +982,9 @@ def test_ida_structs(kernel32_idb, version, bitness, expected):
976982
idapy = idb.IDAPython(kernel32_idb)
977983
assert idapy.ida_struct.get_first_struc_idx() == 0
978984
last_idx = idapy.ida_struct.get_last_struc_idx()
979-
if version <= 630:
985+
if version == 500:
986+
assert last_idx == 23
987+
elif version <= 630:
980988
assert last_idx == 31
981989
elif version <= 700:
982990
assert last_idx == 0x29

tests/test_idb.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -255,7 +255,7 @@ def test_find_exact_match_min(kernel32_idb, version, bitness, expected):
255255

256256
@kern32_test()
257257
def test_find_exact_match_max(kernel32_idb, version, bitness, expected):
258-
if version <= 700:
258+
if 500 < version <= 700:
259259
maxkey = h2b("4e776373737472")
260260
assert kernel32_idb.id0.find(maxkey).key == maxkey
261261

tests/test_netnode.py

Lines changed: 22 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,16 @@ def test_valobj(kernel32_idb, version, bitness, expected):
2222
# Out[29]: 'Z:\\home\\user\\Downloads\\kernel32\\kernel32.dll\x00'
2323
root = idb.netnode.Netnode(kernel32_idb, ROOT_NODEID)
2424
assert root.value_exists() is True
25-
assert root.valobj().endswith(b"kernel32.dll\x00")
26-
assert root.valstr().endswith("kernel32.dll")
25+
if version > 500:
26+
assert root.valobj().endswith(b"kernel32.dll\x00")
27+
assert root.valstr().endswith("kernel32.dll")
28+
else:
29+
assert root.valobj().endswith(
30+
b"ba1bc09b7bb290656582b4e4d896105caf00825b557ce45621e76741cd5dc262\x00"
31+
)
32+
assert root.valstr().endswith(
33+
"ba1bc09b7bb290656582b4e4d896105caf00825b557ce45621e76741cd5dc262"
34+
)
2735

2836

2937
@kern32_test(
@@ -43,8 +51,9 @@ def test_sups(kernel32_idb, version, bitness, expected):
4351
def test_alts(kernel32_idb, version, bitness, expected):
4452
root = idb.netnode.Netnode(kernel32_idb, ROOT_NODEID)
4553
uint = kernel32_idb.uint
54+
alts = list(root.alts())
4655
if version > 680:
47-
assert list(root.alts()) == [
56+
assert alts == [
4857
uint(-8),
4958
uint(-6),
5059
uint(-5),
@@ -53,15 +62,23 @@ def test_alts(kernel32_idb, version, bitness, expected):
5362
uint(-2),
5463
uint(-1),
5564
]
56-
else:
57-
assert list(root.alts()) == [
65+
elif version >= 630:
66+
assert alts == [
5867
uint(-6),
5968
uint(-5),
6069
uint(-4),
6170
uint(-3),
6271
uint(-2),
6372
uint(-1),
6473
]
74+
else:
75+
alts == [
76+
uint(-5),
77+
uint(-4),
78+
uint(-3),
79+
uint(-2),
80+
uint(-1),
81+
]
6582

6683

6784
# the small netnode has a root btree node with a single child.

0 commit comments

Comments
 (0)