如何加载dll文件计算UDS服务的秘钥

在使用UDS(ISO 14229)做诊断的过程中,27服务(Security Access)用于对ECU进行解锁工作。一般的流程是:在对应的ECU会话状态,发送27 01向ECU请求种子,然后根据种子算出秘钥并用27 02将秘钥发送给ECU完成解锁。在这个过程中,将种子计算得到秘钥的过程通常需要使用dll文件实现。

这里我们以PEAK的硬件设备为例,配合使用PEAK免费提供的PCAN UDS API,演示如何通过加载一个dll文件来完成诊断中的计算秘钥功能。

1.生成一个dll文件

首先我们先说一下如何制作一个dll文件,这里我用的编译器是VS2015。首先新建一个工程文件,选择Win32项目和应用程序类型为dll,其它选项按照需求即可。

这里我编写了一个简单的例子。在编译的时候推荐添加 extern “C”,表示用C语言的编译方式导出dll文件;也可以选择在工程中加一个def文件。另外需要注意在输出dll文件时选择好32位还是64位,如果dll文件的位数和后续调用它的程序不一致,会发生无法导入的错误。这里我做的dll文件就是把所有输入的字节和0x59进行与操作,测试的时候比较方便。

用VS生成这个工程,就可以在对应的文件夹中获取到我们需要的dll文件了。

2.调用dll文件

在调用dll时我们需要知道的是,dll文件函数是如何定义的,以及dll文件放置的位置。另外需要注意dll文件是32位还是64位的,这个必须dll文件和程序保持一致。不一致的时候加载dll文件会失败。文件放置的位置可以在工程文件的根目录,这个时候就只要写明dll文件的全名,不需要给出路径;另外也可以用完整路径的形式给出,例如”H:\\UDS-TEST\\Project1\\CalKey.dll”,请注意这部分需要使用”\”而不是”/”,并且由于使用了C格式的字符串所以需要打两个”\”。

调用dll的过程和PCAN UDS的dll文件类似,可以选用动态或静态将它们链接到项目中。这里选择使用动态链接,需要使用Windows API函数LoadLibrary,FreeLibrary和GetProcessAddress。LoadLibrary函数用于加载文件,需要输入dll文件的路径;FreeLibrary用于释放dll文件,参数是LoadLibrary函数的返回值;GetProcessAddress用于获取我们需要的函数的位置,这里的函数名称注意不要写错。如果在制作dll文件时没有使用extern “C”或是添加一个def文件,那么函数的名称有可能是和制作时的函数名不同,这种情况下具体的函数名称可以在WINDOWS的cmd界面进行查询。具体按照要求使用WIN API的函数并调用dll中的计算秘钥函数即可。如果出现什么问题,WIN API中的GetLastError函数可以用来获取错误代码,方便进行查错。

最后使用PCAN UDS API进行解锁的效果如下,可以看到我们的程序成功读取了种子并计算出正确的秘钥发给了设备(每个字节与0x59),并得到了正确的响应。