← All talks

Making Sense Of Your Car: Reverse Engineering AUTOSAR Classic Firmware - Martin Petráň

BSides Prague38:0778 viewsPublished 2025-10Watch on YouTube ↗
Speakers
Tags
CategoryTechnical
StyleTalk
Show transcript [en]

so I don't have issues with time. So hello again. My name is Martin and like to tell you how to make sense of your car by reverse engineering classic firmware. Uh first briefly about me. I'm from here. I live in here in Prague where I work also as an embedded system security engineer at Accenture. Uh primarily on tasks that are related to reversing of some firmware. Uh when I don't do that, I'd usually be eating something or I'll write some code that I'll open source later. So you may also know me as author of some of the plugins for well-known reverse engineering tools. Uh now let's move on to the actual content with some introduction to

AutoSAR. Uh AutoSAR is actually just an acronym and it's stands for automotive open system architecture. It is name of a group that was originally formed in 2003 as a global partnership of leading companies in automotive industry. And the main goal of this group was to establish some standards for end to-end software support in vehicles. meaning that they wanted to achieve something like code reusability, code transferability and they wanted to define some general interoperability rules for AutoSAR uh for car software. Up until m March 2017, AutoSAR was just defining AutoSAR classic platform which aimed at ECUs or electronic control units that were powered by low power microcontrollers. Uh this was because they only cared about things that directly interact with

the driving experience. So things such as power steering, engine control, and all of these things that try not to kill you while you're driving. Uh this has changed in March 2017 with introduction of AutoSar adaptive. Uh not that autostar would suddenly starting care about the head units and radios you have in your car. Uh but people kind of want their cars to drive themselves and AutoSAR adaptive allows you to have ECUs with more computational power that could be used as part of the autonomous driving. As every group of this type, Autosar has multiple levels of membership. I'm not going to go through all of them. You can look it up on the web page. Uh but I mentioned two

different platforms defined by AutoSAR. The classic and adaptive one. As I said, the classic one will be running on the low power microcontrollers whereas the adaptive one will be running on those beefier processors. You can imagine this as an analogy with ARM processors where the classic platform would be running on the M cores and adaptive on the A cores. Uh since the adaptive has these aores available, it can also leverage a POSIX compliant operating systems to provide interface with the hardware which is a luxury that the classic platform does not have. So it uses OS RTOS uh where OSC is an acronym that stands for quite a lot of uh German words I'm never going

to remember but it's a real-time operating system as any other with some slight adjustments towards automotive. So scheduling is slightly adjusted and you are not allowed to do any runtime memory allocations. That means any variable memory space or anything that you need during runtime must be known at the compile time. Uh this makes it ideal for simple tasks performed by these engine controls and things like that. And that's because it does simple tasks in real time. Whereas the adaptive platform with it computational power is used in these advanced driver assistance systems or ADAS which do uh allow you to perform this decision making based on the sensors that perform that autonomous driving operation. I'm not going to talk

about adaptive platform at all. So this talk is classic platform only and we can start that with an architecture. Uh the goals that we talked about in the beginning such as code reusability and transferability were achieved by implementing something called layered architecture. That's just a screenshot from their web page. And at the very top we have application layer. Application layer can host one or actually multiple applications. And those applications are in typical scenario implemented in kind of generic way and they're accompanied by something called calibration data. Now if that tier one supplier who creates this ECU uh wants to sell the same exact ECU with the same exact application to multiple vendors or to have it deployed in multiple models.

They don't change the application. They just change the calibration data so that they fine-tune the behavior of the app. uh regardless of how many apps you have or how they're implemented all of them have same restriction and that is that they cannot talk outside of their own domain without using a runtime environment layer. So if it's hardware communication or if it's talking to other app on the same ECU they must always use runtime environment for that operation. The runtime environment is some sort of kind of mandatory middleman in any such communication and it's the only thing that can interact with the drivers and everything which are defined in the basic software layer. That's all of these small squares in between the

bottom microcontroller and the runtime environment. This basic software is further sublayered into the microcontroller abstraction layer, ECU abstraction layer and services layer. But we're going to get back to these uh sub layers a bit later. So this layered architecture isn't really implemented by AutoSAR by them giving you SDKs, frameworks or any piece of code really. Uh they implement it by giving you PDF files. Uh there's hundreds of them and they state how an autocarer compliant software should behave. They usually take a form of requirement and a specification and if you want to start a company that would develop ECU firmware you download all of them read them carefully and then you'll open your favorite IDE and start writing a code

that should be compatible with C doesn't necessarily have to be C in all of the current ECUs in cars that you see on the road it will be either C or C++ but there are some experiments with Rust so maybe the rest is the future h and you'll start writing your basic software layer and your application as you will be doing that you will also create huge ARXML files. It's not really intended for you to read, so don't worry that you can't uh that define what interfaces it uses, how what messages it sends, how it behaves, what messages it expects to receive. This is something that's used in the integration phase when you take that ECU and put it in a vehicle as

well. When you have that uh the runtime environment is the last thing that you need to develop uh and this will link the basic software and application together and will kind of isolate the application from the hardware implementation completely so that if you do hardware change you don't have to rewrite that uh simplify it in these three points it's kind of easy but it's quite a lot of code to write uh but there are a couple things that will help you with first of all the microcontroller abstraction layer which is sub layer of the basic software will usually be provided to you by your MCU manufacture acture where either for free or for some small fee you'll get a code

that you can just majority of which copy paste and use you to do probably some minor modifications but that will save you a lot of time furthermore for a slightly larger fee uh there are third party companies that will offer you development tools frameworks SDKs code generators automatic clickth through wizards and all of that uh that will allow you to simplify the development process even further so you will have the runtime environment and completely generate it automatically. Uh you will just click through and it will autogenerate the ARXML file. Basically, a lot of useful tools again for some fee. Uh obviously, if this isn't the first EC you're right, you're just going to reuse a lot of code from what you did

before. So that's going to save you some time as well. I've mentioned PDF files. Again, don't read it. Uh so let's just have a look at what they look like. uh usually you open the requirement which tells you on a very high level what is the requirement on what that module should do. So for example the DIIO driver shall allow reading from and writing to DIO ports channel groups and channels a simple highle requirement. Now, if you open a specification document, that's that second thing down below, which the endros probably can't see, and that will tell you that there should be a function DIO read channel group. And this should read the level of that DIIO channel group and signal the

results with bit value zero or one depending on whether that channel is in state low or high. So now you actually know how to implement that. And if you scroll a bit down in that document, you will go to the function uh API specification chapter where you get function declaration, type definitions, slightly more notes on how these functions should behave. Uh so now in theory, you just copy paste that function declaration to your favorite IDE and you start implementing the body of that function. That's how I imagine the development should work. I don't know if it should. Uh I have the architecture view here again because that DIO read channel group function is part of the IO

drivers. Those are in that orange highlighted thing right on top of the microcontroller which is good for you because that microcontroller abstraction layer and it means you will not have to implement that function because the MCU vendor is going to give that to you. When they give you the code they will usually also give you the part of the green thing which is EU abstraction layer and the purple thing which is services layer. uh services layer because it also contains things such as interrupts, scheduling and all of these kind of things that are also quite closely tied to the microcontroller and green thing because it contains complex drivers. Uh complex drivers aren't necessarily complex uh but they're just

any drivers for any interface that AutoSAR just doesn't define. So if your microcontroller has an interface that isn't defined by autosar, it automatically becomes complex driver and then it kind of makes sense that the microcontroller vendor will give you drivers for the interface that their microcontroller supports and that's why you get this ECU abstraction layer. Uh what uh this sub layering of the basic software serves is again these code reusability and transferability purposes. Uh so you can imagine for example a chip shortage situation where the microcontroller you're using is no longer on stock you need to replace it with something you find a compatible one and then in theory you should just be replacing the microcontroller

abstraction layer nothing else. Similarly if the car manufacturer you're working for asks you can you please just do the same ECU for our new car but with one more canvas interface then your changes should be isolated to the green part which is bound to the hardware of the ECU. So as long as your microcontroller supports additional canvas, you should isolate your changes to the green thing. I don't know if I'm not autoar developer so I don't know if it works that smooth. I can just provide the feedback from a customer experience of someone who bought the car during a chip shortage crisis and that is it doesn't work that smooth. Uh now let's put the reverse engineering hats on and

now focus on how to reverse things. Uh the layered architecture introduces a problem for us which is called complex call chains. uh this DIO_read channel group function that we talked about is actually having rather simple call chain and it's a rather simple operation application layer cannot call it directly so it goes to the runtime environment service whatever the name it would be and then it reaches to that DIO drivers grabs the value sends it back to the application simple call chain simple operation but even if we keep the operations rather simple the call chains could kind of explode and so if the application layer wants to send one or two bytes of data somewhere. It actually

doesn't care where. It just calls the runtime environment service to do that. Now the runtime environment service knows that this one or two bytes should go somewhere over the hardware. So it will go to the communication services while calling a com signal function. Comsense signal function will panic because it needs help to figure out what hardware interface to use. Uh so it will call PD router module. PD router will come decide this should go to the canvas. So it will go to the communication hardware abstraction by calling ken if transmit. Canif transmit should prepare the data to be sent over the canvas. But with one or two bytes of data, it's probably going to do just

nothing. And it's just going to pass it to the communication drivers by calling canv write. This is the simplest form of a call chain that you can have to send single canvas message. Uh in reality there would be at least four different rappers in between. the can right probably going to call something else at least twice and there will be bunch of calls on the side that will do things you usually don't even care about when you reverse something. Uh now these complex call chains come with some signs that you can see right when you open the firmware and we I'd like to show you these signs on a firmware image that I got from one of

these sites that offer you to download ECU firmware for a couple dollars. Uh so I have a function here. Uh, I've already pre-loaded that. I'll be running this script called subc counter a lot and all it does it this is just counts functions. Uh, so right now it tells me I hope that this is visible because I would love to have this visible and that I have zero functions that have some name assigned. Kind of makes sense. I've just loaded the firmware nothing out of 14,300. 14,300 is quite a lot of functions. If you recall that I told you that these ECUs do simple operations. Uh but AutoSAR isn't the only thing to blame here. First of all is the tool of

choice. If you would be using IDA or Kyra, the number would be slightly lower. Uh because the binary tends to identify a bit more functions than there really are. Uh but for some architectures, IDA and Hydra also kind of tend to miss real functions. So it's kind of the the difference in function count would be couple hundred. But what makes the most difference in between what developer sees and what we see here is the architecture of choice. This is tririccore. And tririccore has this awesome fast call feature which is used to save code flash space. And it does so by taking any repetitive piece of code making it to very tiny function and calling that with a fast call. So in

just this firmware I would estimate around 2 to 3,000 functions are just because of this compiler optimization for code flash space. Another thing that we very often do when we open some unknown binary is that we rush to the strings view. Uh if I can open that. Okay, I can't. Good. Uh uh no can. Yes. Uh so in this case I can just scroll through blindly. You can probably not really catch that. Uh but uh there aren't really usually usable strings. I've seen a couple cases where there were but in most of the cases you will not see any usable strings. Uh what you will see are these sequential lists of characters. Um sometimes ASKI,

sometimes UTF-16, sometimes UTF32 and these aren't really strings for the purpose of being strings. These aren't really placeholders for that calibration data we talked about. But these are also part of these complex call chains. Uh this is because another problem with these call chains is that they use a lot of indirect function calls. Meaning that there is lot of list of function pointers, list of structures with function pointers or just huge structures with a lot of function pointers. And these are then indexed to with some list of ids, lookup tables, ideally in combination. And all of these strings are usually just these lists of some ids or lookup tables that you have to deal with unfortunately.

Uh now obviously the biggest sign you're dealing with an auto start firmware is the fact you took it from a car. Uh but let's kind of assume that you know that uh in the previous case when I showed you the firmware I've already had it pre-loaded in the tool but that's skipping one important step that's loading the firmware somewhere. First of all you need a tool that supports architecture you're dealing with. So in majority of the cases this will either be ARM Power PCVLE Renaissance RH850 or Tricore. That would be the vast majority of what you'll see today in the back in the days like really ancient ECUs may have used C166 architecture which was

kind of popular at one point and obviously there are microcontrollers just have automotive in the label and they have they're using architecture you've never heard about so just be prepared for this as well and now when you have a tool that supports the architecture you need to load it loading isn't really different from any other microcontroller reversing uh you need to load the firmware into correct flash memory region and obviously you need to load it at a correct base offset. This is very important with autosar because of all of these indirect function calls. If you load it on an incorrect offset, you will lose information about these call chains, you will never be able to

recover that. Luckily for you, the sheer amount of indirect function calls also makes it kind of easy to figure out where this correct offset is. Uh so uh as part of this talk I'll be referencing a GitHub repo with like automation scripts quite quite a lot of the times and one of the scripts that's there uh is actually finding base address based on indirect function calls and this can just tell you automatically okay load it at this memory place. Uh once you have it at the correct memory place make sure that you use SVD files, reference manuals, hardware manuals, data sheets, anything that basically has information about the memory map. Uh this is again indifferent from any other

microcontroller reversing load all the peripherals and especially with autosar load all the RAM sections uh because as I said in the beginning every single variable is known at the compile time. So if you preload all the RAM sections you will have quite a lot of information about that firmware. Uh as we've seen these firmware images are huge. So automate anything that you can have a look at that bundle. I'll show you the GitHub repo at the end. Uh but have a look at that bundle. There's for also, for example, a script that parses PDF files and tries to extract memory maps out of them. But I kind of don't like parsing PDF files, so it kind of works

50/50. Uh, now let's assume that we have the firmware loaded correctly in our tool and we can start the process of reversing. I'm going to completely skip on strings because as we've seen, they're usually useless and when they are useful, you probably kind of know how to work with them. So I'm going to skip on them completely. Instead, we'll start looking at signature matching. Signature matching is performed by any major tool that you probably know of. And it's great thing because once you rename something in some assessment of some firmware, you save signatures. You get L file with a lot of symbols, you save signatures. And next time you deal with something unknown, the signatures

will get auto applied to your binary. Uh now let's see how that would apply to our awesome firmware image here. Uh let's quickly remind ourselves that we have renamed exactly nothing so far. And I have a database of signature that has over 10,000 functions in it. It's from like an L file where I have really 10,000 functions that were in the firmware. It wasn't these Trior thingies, real 10,000 functions. And if I rerun my counter script, I can see that I only have 57 functions that were renamed after I applied these 10,000 function signature file. Um 57 isn't bad. At least something. Uh but it's not great either, right? It probably means this ECU firmware was

developed by a different tier one supplier using different framework uh different development teams and they were not in a good mood when they were developing it or something like that. Plus the autogenerated code is never good for signatures and that's the result. So if you will be dealing with a firmware that has been developed using same framework by the same tier one supplier that number would be much better. But in this case, obviously, it's not that good, but it's still also not bad. So, definitely do use signatures. I'm not saying don't use them. Definitely use them. It costs you zero time, but just expect limitations. If you are a Guyra user and you hope that the BIM signatures are going to

save you. Uh they're not because they're not really made for the fact that someone is using completely different framework and that function just looks completely differently. Uh next thing that you may know if you do microcontroller reversing is mapping functions names based on the memory addresses that they reference. So in microcontroller every single interface has a hard-coded memory address. Uh SPI interface is going to have one CAN UART anything that the microcontroller does has some memory address range. Now you can find functions that cross reference this memory range and assign the meaning to these functions uh based on that memory range that they are referencing. This is definitely valid technique. Uh but it has a disadvantage that it kind

of gets too complex with these complex call chains and you just have to do too much to just use this. So in this case let's see that as well in action. I have absolutely zero idea what specific microcontroller this firmware was for because I just downloaded blindly from one of these sites and it didn't tell. Uh so I just loaded the only SVD file that exists for Tricore. So all of these peripherals are probably going to be wrong except one which is HSM. HSM is always going to be at this specific memory address when it's Tricore processor. Uh so now I can just look at the cross references to this HSM section and try to map out all that all of them

and see where this leads me. Now this would be too much manual work that I'm not really willing to do. Uh so uh in the bundle of the scripts that is released and you can access on GitHub, there's a script that will take uh the entire memory section. It will make you a call graph for every single variable in that section. these call graphs can get quite big and then if as they grow bigger and bigger they become useless completely. Uh so it has another option that allows you to specify that you only want paths that lead you to some function that has already been renamed. Uh this is great because you can tell that script, okay, just give me paths

that lead me to something that has been renamed. And if you run the signature matching, for example, before that, uh you can now see that this HSM may lead to some crypto module through 50 different jumps that you would just spend 5 days looking at and that whole graph. So that's why that's there. uh but even with this graphing it doesn't really change anything on the fact that it is heavily manually involved process usually uh so do use it but just again expect limitations uh when it comes to time efficiency what is probably the best thing that you can do when it comes to automotive firmware is just searching for constants that's just the best thing

in the world because automotive is crawled with constants every single thing in automotive has some constants for error code function codes and things like that so if we take example of uds protocol. It has single bite constants for services, subservices, subunctions or whatever they are called. It has a huge list of single bite constants for error codes. So for example, hex 35, 36 or 37 would usually point you to some UDS authentication routine. Same thing would apply to XCP and CCP protocols which are used for calibration. Uh they will have their own set of error codes and function codes that you can look for. Uh, another thing if you're dealing with something from your own car and you

want to for example enhance its performance is that you may look for a known limitation of an ECU. So if you have for example engine control unit and you'll know that there is some limit for a max RPM that it allows. You can try to search for these types of constants. Just keep in mind that these are usually in the U calibration data and if you don't have the calibration data and you just have the application you'll have hard time finding that. Same goes for crypto constants. Developers are lazy too. So if they have hardware security module with a library that they can just reuse, they will do that. They will not do software implementation of crypto. So

do use any of the billion of tools that search for crypto constants definitely. But just again expect some limitations with HSM. Since this is so good approach, let's actually see that in action as well. Uh so we talked about UDS. uh UDS has these constants and one of them is hex 37. Hex 37 stands for time delay not expired and it is something that if you fail to authenticate for example you get it as a response telling you you need to wait basically let me just cancel this search because I don't really need entire one and as you can see we I canceled at about 3% and I have 34 hits like I'm too lazy to go through 34 hits

let alone let it run for the entire binary and then go through hundreds so I need a better search for constants and if I look at the results results I actually see some that I don't really care about. I know it's an error code. So it's something that is sent to the requesttor of the operation. So I don't really care about this one which is in the condition. This one as well or this one which is some offset to a structure. I don't care about these. So what I have again in the bundle of the scripts there is a script that allows you to search for constants based on their context. You can tell the script search for

constant hex37 but only in cases where it's directly assigned somewhere or where it's being passed as a parameter somewhere. I can also further extend the conditions of this search by using the limited knowledge of the UDS protocol that I have. And I can tell this script only give me functions where this hex 37 in this specific context appears alongside hex 24 in the very same context. Uh what will 20 hex 24 mean in UDS is sequence error. UDS protocol for authentication is using challenge response algorithm and you can't really send response before you asked for challenge. Uh so that's what hex 24 would be used for. I again have prerun this search because I don't want to be

just staring here at you for 10 minutes and waiting for it to complete. And as you can see, it has 37 entries found, but it's 37 entries from the entire binary. And it searched for way more than just hex 37 constant. This is actually an example search that's on a GitHub with example constants related to automotive. And if I'm to just filter for that time delay not expired, I'll have three hits. I'm lazy, but three hits are kind of okay for me. Uh, if I go to the very last one, I kind of cheated because I've seen it like million times. I can see, let me just scroll a bit more up so that everybody can see that I can see the hex

37 being used right here. And I can also change the type so that it's more readable or perhaps not more readable. Uh so this would be by required time delay not expired constant. And if I scroll a bit up, I have my request sequence error. So in this case I'm very strongly suspecting that this is UDS authentication handler and now we should investigate how the authentication works whether we can bypass that and whether then we can do some of the fun stuff like rewriting uh reprogramming the ECU reading the memory and things like that. Uh we're not going to do any of that. Uh instead I'm going to use this opportunity to show you the thing that I

talk about but I haven't shown you up until now and that's these complex call chains. So this function is exactly called by single function. So probably of wrapper which is again called by another function probably of wrapper which is again called by another function probably of wrapper. And this function ending with b 0 actually is not called by anything. Uh that's not true. Uh oh wrong shortcut. Uh okay that's not true because this is one of those functions that are indirectly called. So it this function isn't called directly doesn't have any direct cross referring because there is some list of function pointers list of structures or just a huge structure of some sort uh that that calls this function and then

these strings that we've seen previously are something that is going to be uh using this structure and I kind of hope that this will recover if it not I will take some 2 minute break to reset everything uh but we've seen that constants search is really effective. We found the function quite easily. So that's something that should be used definitely. It's like a primary method of recovering something. Uh now I'd like to transition to an autosar specific techniques and see what we can do with these autosar standards and PDF files. One of them defines a module that's used for error handling. Uh this module has a function called that_report error which takes four arguments. module ID,

instance ID, API ID and error ID. Uh instance ID is usually completely useless. Uh so you can disregard it completely. Error ID is useful but it you kind of need to know the context of where it appears. Uh so it is not really something you can automate with. But module ID is there is another PDF file with a huge table that defines module ids for every single order standard function. So ADC driver is going to have 123 decimal can interface is going to have 60 etc etc. I think there are over 100 modules that have this definition. Uh the API ID is also very useful because in every single specification document right under the function

declaration there is a service ID field uh that is not called API ID for some reason. Uh but for example for ken if transmit function it takes value hex 49. Uh this hex 49 value would then appear inside that API ID parameter whenever an error would occur inside ken if transmit. So the module ID would be set to 60 because can interface and API ID would be set to 49 because of kif transmit function and each of these standard defined functions will have their own API and module ID combinations. Now, the problem is this is hundreds of PDF files you don't want to really deal with. So, I kind of turned my eye to these LLMs that say

that they support PDF files, which is true. They do, but they still kind of suck on providing exact data when you need them. Uh, so I went old school, created Python script that auto downloads everything, parses these PDF tables, and extracts all of that information that I wanted into a huge JSON file. Since I was already suffering with dumping PDF files, I've also extracted type information that's in that file. So now I have also a huge header file. Uh now with these two big files, the last thing that remains is to automate things. U there's one final catch with this and that is that you need to uh be careful because you're dealing with an unknown binary. You

can't just look at all the functions that have four arguments and point at this one and say it's this one. Uh because sometimes uh you will face a problem that this function is should be only used during the development. This will sometimes make it not appear in the firmware at all. Sometimes it will make it do whatever that is. Sometimes it will make it just do endlessly loop something because the real body of the functions that may have used these parameters has been scrapped out after the development process have ended. But sometimes they just leave the function there. So you need to really look at every single function and just look at cross references of every single

function, change its type so that it has four arguments and then look at all these cross references and match it against the huge JSON file. That would be best demonstrated with the real life demo. If this f it actually recovered. So let me just continue where I actually wanted to continue. uh we wanted to search for this uh address of this function which is ending with B 0. And if you find this, this will actually point us at this place in memory where I just blindly change anything to a pointer that at least looks like a pointer. And as you can see, the B 0 function right here is surrounded by some other functions. And

it's surrounded also by a constant eight bytes of spacing. Uh which probably suggests lists of structures with some function pointers. Uh now obviously we can assume that these are these UDS protocols. But we're going to leverage that autosar script to try to identify these uh some functions automatically. When you run the script that's again available in that GitHub repo. It has four different action. The first one will just go to the GitHub, grab the latest header file, load the types. I've already done that. That's nothing interesting about that. Uh, next one is scan for error handling. This will take the huge JSON file and try to find automatically this underscore report error for you. So, this is what we will

run. The third action is just there. If you find that function manually, you just click on that and it will start the renaming process. And the fourth action exists because I work in consulting where we look for vulnerabilities. And I just would know conveniently have a list of all functions that do read or write operations and are defined by auto start. So this will just create a list of them so that I can walk through them. Uh now as I said we will only be running the scan for error handling. I just wonder why it's so slow today. I tested everything today morning and I've never had this error like this problem with the beach

ball. I guess connectivity but with a bit of luck we will actually um get to this. I swear this isn't the problem of the script. I you can download it. It's on the git actually and look for that. Okay, let's me just mix up the things a bit. I will talk about other things as well uh before this wakes up. Huh. Okay. So now I can run it. Okay. Good. Great. Uh by default it will look for any function that has more than 50 cross references. In this case I've bumped it up because it would run for about 10 minutes. I don't want that. Uh so it will look for any function in this case that has more than 350 cross

references. Well it will match them against the JSON file and if it finds the best match it will store it and it will go through the entire binary up until the very end. uh then uh when it uh gets to the end of the binary it will present you with a dialogue which will propose you that with like a certain percentage of the probability this function has been selected as potential that underscore report error here and if you want to proceed with renaming I'm just going to click yes here and pray for best and this will again take the same JSON file look at all these cross references and start the renaming process of these

functions uh again This shouldn't really happen. I've never really I promise I've never really seen the beach ball here. Uh I guess the connectivity is just on my phone. Not very good because it goes to that GitHub, grabs that JSON file and this may have caused this, I don't know. H anyway uh it will start the process of auto renaming these functions and as we will see when it eventually decides to actually continue the execution and that these functions around our B 0 function were actually renamed to something called DCM diagnostics communication module that's a way how autosar defines UDS protocol and this will actually give us a final hint that this is really uh

handler for UDS protocol uh we We can also use the knowledge uh not just from the constant search, not just from this script, not just from the signatures or matching of peripherals, but we can also use the knowledge from the previous assessments. If you don't have any previous assessments on autosert classic firmware first of all, lucky you. Second of all, uh I have also I'm also it's actually already released on that GitHub repo uh this notebook which just gives basic information about how to do basic stuff. It's not going to replace years or countless experiences with doing so, but it's something that will help you get started. It has like the basic things for fancy things such as XCP UDS

and how to approach reversing of this type of firmware. I guess this one isn't going to wake up anyway. Uh so let's just see what we can also do. uh compilers, especially those optimized for code flash space, will just cramp one functions on another and they will very rarely mix up things from different modules. This is great for you because if you happen to rename two functions that they're from the same module and you'll have like a couple functions in between them that aren't renamed, don't be afraid to use an assumption and rename these functions as well because AutoSAR usually has these optimizations enabled. So you will be able to rename quite a lot of the functions just by

assuming that this mixup of the compilers is not happening. It will happen from time to time but not that very often. Let me just have a final look at whether this actually notheless. Okay. Uh let's move on to the conclusion. Uh I'd like to just uh summarize what we've seen. Autostar classic based binaries will contain a lot of autogenerated code. They will contain a lot of microcontroller specific code, ECU specific code, vendor specific code and they will have all of that combined in a complex call chains with a lot of indirect function calls. So they will always be pain to deal with assuming that these scripts will work. No. Okay. Uh it will always be pain to

work with them. But those scripts can actually make that pain slightly more enjoyable and you can actually recover quite a lot of things automatically. Obviously the best thing you can have is experience with these firmwares but the next best thing that you can have is automation and all of these uh automation pieces are released on this GitHub repo. So feel free to access them and I promise they work better than they worked in the demo. Uh I have really no idea why that didn't work. So with that, I'd like to wrap up and ask if you have any questions towards this topic that I can answer. I guess no. So if no, I will be

around. So you can just catch me whenever you want. I can leave this a bit longer.