Search code examples
pythoncan-busunlockuds

How to perform UDS session unlock using security dll from python program?


I want to automate some WDBI services which requires security unlock. I have a dll which can be invoked from CANoe, but I don't want to use canoe hardware also I don't know the function calls in the dll. Is there any way that I can invoke dll from python program to perform session unlock?


Solution

  • With the DLL at hand you could use a tool like DependencyWalker to see the exported symbols of the DLL. But if you already know that your DLL works in CANoe, it will follow the APIs specified by Vector Informatik to be implemented in an Security Access DLL for CANoe: GenerateKeyEx & GenerateKeyExOpt.

    GenerateKeyEx:

    int VKeyGenResult ExGenerateKeyEx (
      const unsigned char* ipSeedArray,
      unsigned int iSeedArraySize,
      const unsigned int iSecurityLevel,
      const char* ipVariant,
      unsigned char* iopKeyArray,
      unsigned int iMaxKeyArraySize,
      unsigned int& oActualKeyArraySize );
    

    GenerateKeyExOpt:

    VKeyGenResult ExOptGenerateKeyExOpt (
      const unsigned char* ipSeedArray,
      unsigned int iSeedArraySize,
      const unsigned int iSecurityLevel,
      const char* ipVariant,
      const char* ipOptions,
      unsigned char* iopKeyArray,
      unsigned int iMaxKeyArraySize,
      unsigned int& oActualKeyArraySize );
    

    Then it is just a matter of calling to this Dll from python, i.e. using ctypes.

    import ctypes
    
    mylib = ctypes.WinDLL("./GenerateKeyExImpl.dll")
    seed = (ctypes.c_byte * 4)(0xff, 0xfe, 0xfd, 0xfc) # these bytes you should get from the ECU i.e.
    # Tx 27 01
    # Rx 67 01 ff fe fd fc
    key = (ctypes.c_byte * 4)() # this will contain the secret key after Dll call
    keylength = ctypes.c_int(4) # this will contain the secret key length after Dll call
    mylib.ExGenerateKeyEx(
         ctypes.pointer(seed), # Seed from the ECU
         ctypes.c_int(4), # Example: Seed length = 4 bytes
         ctypes.c_int(1), # Example: Security Level 1
         POINTER(c_int)(), # Example: NULL = No variant string
         ctypes.pointer(key), # Key to send back to the ECU
         ctypes.c_int(4), # Example: Key Max length = 4 bytes
         ctypes.pointer(keylength), # Example: Seed length = 4 bytes
    )
    # TODO: Send "key" back to the ECU i.e.
    # Tx 27 02 XX XX XX XX
    # Rx 67 02