improve int/Integer handling

This commit is contained in:
mr-tz
2023-03-08 16:06:57 +01:00
parent a7e4d265e2
commit 44d8e693b0
4 changed files with 145 additions and 134 deletions

View File

@@ -1,4 +1,3 @@
// Generated by the capa.render.proto translator. DO NOT EDIT!
syntax = "proto3";
message APIFeature {
@@ -10,8 +9,8 @@ message APIFeature {
message Address {
AddressType type = 1;
oneof value {
Integer v0 = 2;
Pair_Integer_Integer v1 = 3;
Integer v = 2;
Token_Offset token_offset = 3;
};
}
@@ -90,7 +89,7 @@ message ExportFeature {
}
message FeatureCounts {
uint64 file = 1; // TODO just int here and general int vs uint?!
uint64 file = 1;
repeated FunctionFeatureCount functions = 2;
}
@@ -257,8 +256,8 @@ message PropertyFeature {
message RangeStatement {
string description = 1;
Integer min = 2;
Integer max = 3;
uint32 min = 2;
uint32 max = 3;
oneof child {
OSFeature v0 = 4;
ArchFeature v1 = 5;
@@ -342,7 +341,7 @@ message SectionFeature {
message SomeStatement {
string description = 1;
Integer count = 2;
uint32 count = 2;
string type = 3;
}
@@ -381,12 +380,11 @@ message Pair_Address_Match {
Match v1 = 2;
}
message Pair_Integer_Integer {
Integer v0 = 1;
Integer v1 = 2;
message Token_Offset {
Integer token = 1;
uint64 offset = 2; // offset is always >= 0
}
message Integer { oneof value { uint64 u = 1; int64 i = 2; } }
message Number { oneof value { uint64 u = 1; int64 i = 2; double f = 3; } }
message Integer { oneof value { uint64 u = 1; sint64 i = 2; } } // unsigned or unsigned int
message Number { oneof value { uint64 u = 1; sint64 i = 2; double f = 3; } }

File diff suppressed because one or more lines are too long

View File

@@ -82,29 +82,29 @@ def addr_from_freeze(a: capa.features.freeze.Address) -> capa.render.proto.capa_
address = capa.render.proto.capa_pb2.Address()
if a.type is AddressType.ABSOLUTE:
address.type = capa.render.proto.capa_pb2.AddressType.ADDRESSTYPE_ABSOLUTE
address.v0.CopyFrom(capa.render.proto.capa_pb2.Integer(u=a.value))
address.v.CopyFrom(int_to_pb2(a.value))
return address
elif a.type is AddressType.RELATIVE:
address.type = capa.render.proto.capa_pb2.AddressType.ADDRESSTYPE_RELATIVE
address.v0.CopyFrom(capa.render.proto.capa_pb2.Integer(u=a.value))
address.v.CopyFrom(int_to_pb2(a.value))
return address
elif a.type is AddressType.FILE:
address.type = capa.render.proto.capa_pb2.AddressType.ADDRESSTYPE_FILE
address.v0.CopyFrom(capa.render.proto.capa_pb2.Integer(u=a.value))
address.v.CopyFrom(int_to_pb2(a.value))
return address
elif a.type is AddressType.DN_TOKEN:
address.type = capa.render.proto.capa_pb2.AddressType.ADDRESSTYPE_DN_TOKEN
address.v0.u = a.value # TODO or v0.CopyFrom(Integer(a.value))?
address.v.CopyFrom(int_to_pb2(a.value))
return address
elif a.type is AddressType.DN_TOKEN_OFFSET:
token, offset = a.value
address.type = capa.render.proto.capa_pb2.AddressType.ADDRESSTYPE_DN_TOKEN_OFFSET
address.v1.v0.CopyFrom(capa.render.proto.capa_pb2.Integer(u=token))
address.v1.v1.CopyFrom(capa.render.proto.capa_pb2.Integer(u=offset))
address.token_offset.token.CopyFrom(int_to_pb2(token))
address.token_offset.offset = offset
return address
elif a.type is AddressType.NO_ADDRESS:
@@ -113,7 +113,20 @@ def addr_from_freeze(a: capa.features.freeze.Address) -> capa.render.proto.capa_
return address
else:
raise NotImplementedError(f"type {a.type} not implemented")
raise NotImplementedError(f"unhandled address type {a.type} ({type(a.type).__name__})")
def int_to_pb2(v):
assert isinstance(v, int)
if v < -2_147_483_648:
raise ValueError("underflow")
if v > 0xFFFFFFFFFFFFFFFF:
raise ValueError("overflow")
if v < 0:
return capa.render.proto.capa_pb2.Integer(i=v)
else:
return capa.render.proto.capa_pb2.Integer(u=v)
if __name__ == "__main__":

View File

@@ -109,32 +109,32 @@ def test_addr_from_freeze():
a = capa.features.freeze.Address.from_capa(a)
a = capa.render.proto.proto.addr_from_freeze(a)
assert a.type == capa.render.proto.capa_pb2.ADDRESSTYPE_ABSOLUTE
assert a.v0.u == 0x400000
assert a.v.u == 0x400000
a = capa.features.address.RelativeVirtualAddress(0x100)
a = capa.features.freeze.Address.from_capa(a)
a = capa.render.proto.proto.addr_from_freeze(a)
assert a.type == capa.render.proto.capa_pb2.ADDRESSTYPE_RELATIVE
assert a.v0.u == 0x100
assert a.v.u == 0x100
a = capa.features.address.FileOffsetAddress(0x200)
a = capa.features.freeze.Address.from_capa(a)
a = capa.render.proto.proto.addr_from_freeze(a)
assert a.type == capa.render.proto.capa_pb2.ADDRESSTYPE_FILE
assert a.v0.u == 0x200
assert a.v.u == 0x200
a = capa.features.address.DNTokenAddress(0x123456)
a = capa.features.freeze.Address.from_capa(a)
a = capa.render.proto.proto.addr_from_freeze(a)
assert a.type == capa.render.proto.capa_pb2.ADDRESSTYPE_DN_TOKEN
assert a.v0.u == 0x123456
assert a.v.u == 0x123456
a = capa.features.address.DNTokenOffsetAddress(0x123456, 0x10)
a = capa.features.freeze.Address.from_capa(a)
a = capa.render.proto.proto.addr_from_freeze(a)
assert a.type == capa.render.proto.capa_pb2.ADDRESSTYPE_DN_TOKEN_OFFSET
assert a.v1.v0.u == 0x123456
assert a.v1.v1.u == 0x10
assert a.token_offset.token.u == 0x123456
assert a.token_offset.offset == 0x10
a = capa.features.address._NoAddress()
a = capa.features.freeze.Address.from_capa(a)