P1sec / pycrate

A Python library to ease the development of encoders and decoders for various protocols and file formats; contains ASN.1 and CSN.1 compilers.
GNU Lesser General Public License v2.1
380 stars 130 forks source link

Proper way for modifying the message properties #234

Closed vazir closed 1 year ago

vazir commented 1 year ago

Dear @p1-bmu

Could you please advice for a proper way of setting the properties of the fields of the messages? For the instance TCAP_CAP message

<~ASN1~: continue : {
  otid '7786EE00'H,
  dtid '7401B756'H,
  components {
    basicROS : invoke : {
      invokeId present : 2,
      opcode local : 24,
      argument EventReportBCSMArg: {
        eventTypeBCSM oAnswer,
        eventSpecificInformationBCSM oAnswerSpecificInfo : { },
        legID receivingSideID : '02'H,
        miscCallInfo {
          messageType notification
        }
      }
    }
  }
}>

How to properly modify the OTID and dtid fields ?

Setting them directly like get_val_at(bcsm_oAnswer, ['continue'])['otid'] = unhexlify('7786EE00') also i can come up with something like int(tid).to_bytes(4, 'little')

it seems works but probably there is other, proper way?

Also, could you please advice, right now to make a NEW IDP I do apply a prdefined object template (from previos binary parsed export) and than modify parameters before encoding to a final way

self.msg = TCAP_CAP.TCAP_CAP_Messages.TCAP_CAP_Message
self.msg.set_val(self.idp_tcap_object_template)
self.msg.to_ber()

Here I also feel there is may be proper way doing that?

mitshell commented 1 year ago

You should be able to use the set_val_at method: https://github.com/P1sec/pycrate/blob/da145b1c39ad4edd4a90216ba6c56119eb877825/pycrate_asn1rt/asnobj.py#L1219

Something like:

self.msg.set_val_at(['continue', 'otid'], bytes([0x12, 0x34, 0x56, 0x78]))

For creating complete value, there is no magic on the other side, you need to set them entirely. Something like:

self.msg.set_val(('continue', {
'otid': uint_to_bytes(0x12345678),
'dtid': uint_to_bytes(0x87654321),
'components': [(
  'basicROS', ('invoke', {
    'invokeId': ('present', 1),
    'opcode': ('local', 24),
    'argument': ('SendRoutingInfoForGprsArg', {
      # whatever argument's values are required, to be set there
    })
  }))]
}))
vazir commented 1 year ago

Understood, thanks...

Than about adding missing (not yet present) optional elements, is there a way to determine what elements may be present/added at the specific level?

p1-bmu commented 1 year ago

You can call get_proto() on an object, to print its prototype. You have also the command-line tool pycrate_map_op_info.py bundled with the lib, which is for the exact purpose of checking TCAP-MAP and CAMEL request / answer and arguments.

vazir commented 1 year ago

Will try that, thank you so much for your answers!