Pages: [1]
Author Topic: Running Simos18 / Tricore in QEMU  (Read 6507 times)
d3irb
Full Member
***

Karma: +131/-1
Offline Offline

Posts: 186


« on: February 07, 2021, 09:13:17 AM »

Hi everyone,

As part of my ongoing research into Simos18 I have moved from static analysis (Ghidra only) to dynamic analysis (inspecting code as it executes). This is a very powerful tool and makes things like indirect generated pointer tables or tedious iterative algorithms (like the header/scrambling used to generate the checksummed material in the Simos18 digital signature algorithm) a non-issue as you can simply execute the code which generates them.

To do this, I use "QEMU", a popular emulation/virtualization tool which has Tricore support. A few other Tricore emulators also exist, like the official Infineon one, "Tsim," which is available in the Hightec Tricore GCC package.

To get QEMU working for Simos18, I added a simple "machine configuration" to set up the memory map correctly: https://github.com/qemu/qemu/compare/master...bri3d:tricore-simos18 . In Tsim, this is set up using a memory config file instead. This file should give you a fairly obvious pattern which can be applied to other ECUs as well.

The "one cool trick" that really unlocks using QEMU effectively is learning about the "loader" device, which lets you map files into mem/flash without having to edit the source.

I also used gdb, the GNU debugger. The GDB interface is famously obtuse but is very powerful once you learn it (especially now it has Python built in), but if you wish you can also check out and compile the Ghidra Debugger branch, which plugs GDB into Ghidra to give it a nice UI.

This was all very simple to set up, really - the hardest part was finding a tricore-gdb. I eventually stumbled upon one here: https://github.com/Gigallith/gdb-tricore . I have no idea where it came from but it seems to work great!

I very loosely documented the setup process here: https://gist.github.com/bri3d/5429c0b25346a0830c01042e77d6914c (you will need to read the documentation for QEMU and GDB about which dependencies are required on which platform - I am actually on an Apple Silicon M1 Mac so a lot of my documentation may not be useful to others).

The big "gotcha" when using either Tsim or QEMU is that they correctly implement the CPU, which means you need to have the task context system set up correctly for call/ret instructions to work (otherwise, they will jump into the trap vector table). I have found that the easiest way to do this is to simply jump through the setup code for whichever piece of the software you are trying to inspect - for SBOOT, I just set a breakpoint at the end of the "start" code and set the instruction pointer to the beginning of the start code, and let it run wild. This has the additional advantage of setting the low registers that your compiled code may be using (a0,a8,a9, etc.) as well as the a10 "stack pointer" for free. Pretty cool, huh?

Here's my GDB init script for debugging the Simos18 SBOOT recovery shell, just as an example so you can understand the basic patterns at play:

Code:
# start QEMU using for example ../qemu/build/qemu-system-tricore -machine tricore_s18 -kernel simos18_flash.bin.sboot -device loader,file=simos18_flash.bin.cal,addr=0x80800000 -singlestep -s -S

layout asm
layout regs

target remote localhost:1234

# CONFIGURE STACK

set $pc=0x80007672
break *0x80007862
continue

# CONFIGURE RECOVERY SHELL CONTEXT

set $pc=0x80004838
break *0x80004956
continue


At this point I have the CPU ready for me to set the $pc to whatever sub-routine in the recovery shell I want to inspect.

When it comes to peripherals, QEMU supports literally _none_ - peripheral register read/writes are just considered as memory read/writes and do nothing but persist. This is where Tsim (as the official Infineon simulator) has an advantage - Tsim tries to implement the STM timer, the interrupt wiring, and the PLLs. This can be really useful in some situations but can also actually be kind of a pain (I usually turn it off) - often times just enough of the tasking / context switch system will start working to confuse and annoy you.

I am working on implementing a few peripherals that I will find helpful (port I/O and CAN) but all peripherals on Tricore are really quite complex so it may be a while before I have more to show.

At any rate, this is already a very powerful tool set that can save you a lot of time manually clicking through stores and defining memory bytes by hand in Ghidra. And even if you are working on another ECU, I hope this gets the gears turning around tools available for debugging and reversing that can save you a ton of time.

 
Logged
fastboatster
Full Member
***

Karma: +2/-0
Offline Offline

Posts: 64


« Reply #1 on: February 07, 2021, 08:03:23 PM »

great content as always! I will try to play with this and perhaps try to run simos 8.4 with this.
Logged
navatar_
Newbie
*

Karma: +1/-1
Offline Offline

Posts: 18


« Reply #2 on: February 07, 2021, 09:06:59 PM »

d3irb, following your Sim18 developments has been absolutely fascinating. I've thought about emulation wrt ECU RE but quite honestly had no idea where to begin. This is awesome.

Out of interest, are you an electronic/computer engineer?
Logged
prj
Hero Member
*****

Karma: +915/-428
Offline Offline

Posts: 5848


« Reply #3 on: February 08, 2021, 05:21:14 AM »

As cool as it is, the main issue is that peripherals are not emulated.
So if you want to use anything to do with CAN you need to basically implement at least a part of the CAN controller in software.

Until that is done, there is not much use beyond it being a PoC. I do not believe static analysis on TriCore is THAT hard. Usually the structures used are fairly primitive.
It is also possible to run code on the ECU by dumping stuff in RAM and forcing the ECU to jump to it. There is also hardware debugging available, but I have never tried to see if it is possible to make it work on a production PCB.

Furthermore, for what you are trying to do, by far the easiest is to just sniff some tool that has service mode password reading implemented.
There is no need to re-invent something that's already been done.
« Last Edit: February 08, 2021, 05:23:02 AM by prj » Logged

PM's will not be answered, so don't even try.
Log your car properly.
d3irb
Full Member
***

Karma: +131/-1
Offline Offline

Posts: 186


« Reply #4 on: February 08, 2021, 08:23:44 AM »

As cool as it is, the main issue is that peripherals are not emulated.
So if you want to use anything to do with CAN you need to basically implement at least a part of the CAN controller in software.

Until that is done, there is not much use beyond it being a PoC. I do not believe static analysis on TriCore is THAT hard. Usually the structures used are fairly primitive.
It is also possible to run code on the ECU by dumping stuff in RAM and forcing the ECU to jump to it. There is also hardware debugging available, but I have never tried to see if it is possible to make it work on a production PCB.

Furthermore, for what you are trying to do, by far the easiest is to just sniff some tool that has service mode password reading implemented.
There is no need to re-invent something that's already been done.

Hmm. I agree and disagree.

For Simos18, which to your point, is quite simple really, there are just a few base pointers in memory and nothing complex is going on code-wise which cannot be statically analyzed. I certainly agree it's more of a novelty than a necessary tool.

But, I will say that emulation has been very useful in exploring some corners of the ECU, like what material is actually checksummed to generate the SHA256-RSA signatures. This is mostly an academic interest rather than a practical one, but it has still provided some insight.

I do find emulation to be a time-saver even for simple things too, once the workflow is well integrated via scripting. For example when starting a new project, it's really convenient to just run the init routines and dump RAM - all of the copy-to-RAM tables and base pointers are already set up that way.

As for peripherals - yes, CAN and the timer-interrupt system would be the most important components to bringing up an ECU in emulation. CAN is tedious but straightforward, since the CAN controller in Tricore is so high-level it is really just a matter of mapping the message object tables to the outside world and defining the structs. But to your point, spending that time just defining the message structures out in IDA or Ghidra will yield pretty much the same result in terms of understanding.

What would really be crucial to getting full-ECU emulation going (i.e. being able to bring up a simulated ECU and talk to it over UDS) would be getting the timers and SRN (Service Request Nodes, basically PICs/interrupt routers) emulated, which would be a slightly more challenging undertaking since they're pretty complex.

I will say that static analysis becomes much harder on the newest TriCore based ECUs which have started doing things that have been common in the PC and mobile phone world for years, like code sections which are compressed and encrypted in flash and loaded at runtime. In these cases dynamic analysis is a really good tool - anyone who's ever done a packer in the PC world will know that the easiest way to deal with most of them is to just let them load themselves up and then dump the executable image from memory.

From what I know, hardware debugging can work on some production PCBs and not others, I have heard of it being possible on some older Bosch ECUs with a few extra components for example. But, without schematics and with the complex multilayer boards in use these days, I would think this would be quite a time sink to sound out the pins. With schematics it could be a viable option. And yes, using a bootstrap loader and a little stub debugger is also a very handy approach which I have been taking advantage of as well.

Another option you didn't mention is to use a TriCore development/debugging sample board with a close or matching CPU and the same sort of "jump through" debugging techniques around setting $pc and a breakpoint.

And as to your last point, yes, of course, I could just dump a commercial tool and have the exploit in seconds - if I actually had a need for it. But what I am trying to do is a hobby, not a need. I have been tuning my own personal car for a long time now, the tools I have already made work great for that, everything since then has just been for fun! Stealing an exploit would be much less fun for me, not to mention not particularly ethical in many senses, as I choose to share my work along the way.

As for my background, I am in software, but nothing related to low-level or ECU programming professionally (which is probably why I still enjoy it as a hobby). As a kid/teenager I reverse engineered game consoles in my spare time which is where I got into RE and analysis. ECUs today are just getting where game consoles were 10+ years ago in terms of low-level protections (although at the same time, ECUs are inherently more secure too since they don't take in a lot of crappy binary file formats to screw up at unpacking). One of my goals in sharing the knowledge I pick up, like running TriCore in QEMU, is to get more folks from that side of the world interested in ECUs too.
Logged
prj
Hero Member
*****

Karma: +915/-428
Offline Offline

Posts: 5848


« Reply #5 on: February 08, 2021, 09:00:06 AM »

I will say that static analysis becomes much harder on the newest TriCore based ECUs which have started doing things that have been common in the PC and mobile phone world for years, like code sections which are compressed and encrypted in flash and loaded at runtime.
No ECU's do that for the application. How the HSM works I have no idea, but there is no exploit for the HSM yet.
Quote
Another option you didn't mention is to use a TriCore development/debugging sample board with a close or matching CPU and the same sort of "jump through" debugging techniques around setting $pc and a breakpoint.
This is a good approach, yes. Much better than what you are trying to do now, especially for bootloading and the like. To actually boot up the application you have to patch some checks tho.
Quote
And as to your last point, yes, of course, I could just dump a commercial tool and have the exploit in seconds - if I actually had a need for it. But what I am trying to do is a hobby, not a need. I have been tuning my own personal car for a long time now, the tools I have already made work great for that, everything since then has just been for fun! Stealing an exploit would be much less fun for me, not to mention not particularly ethical in many senses, as I choose to share my work along the way.
Don't feel bad. ONE person did it, and then EVERYONE ELSE copied it.
This is how the chiptuning tools work. They develop NOTHING themselves.
Someone finds a new exploit and offers it to the chiptuning tool makers or maker. One of them toolmakers buys the exploit and pays the person who found the exploit a lump sum of money.
They then release it. At that point, because every single tuning tool maker owns every single tuning tool, it gets sniffed and everyone else has it the next day. This is how this has been going on forever now.
So really, you don't need to white hat reverse this, it is a waste of time. You can do much better/cooler things with your abilities. I even have some ideas.

Quote
As a kid/teenager I reverse engineered game consoles in my spare time which is where I got into RE and analysis.
I did x86 apps and games. TriCore is STILL so very simple compared to what x86 was over 20 years ago.
« Last Edit: February 08, 2021, 09:02:55 AM by prj » Logged

PM's will not be answered, so don't even try.
Log your car properly.
fastboatster
Full Member
***

Karma: +2/-0
Offline Offline

Posts: 64


« Reply #6 on: February 08, 2021, 01:52:00 PM »

nevertheless, even if peripherals are not implemented, it's still useful, especially for the folks just starting out to dive into the assembly and ecu/tcu reverse engineering. Setting all the registers and initializing the RAM (especially the RAM) can save a lot of time and work understanding the ecu. OP and myself are not "need driven", he can tune his car with the tools he got, and I can tune my car with PCMFlash or just purchase an APR 3.0T tune which probably would have been the quickest and the most cost effective option. Seems to me, OP's goal is wider community education and just plain fun. This may not be a top priority for people doing this for a living but these are valid goals nevertheless. I think this can make it easier for some people to understand the tricore ecus.
Logged
prj
Hero Member
*****

Karma: +915/-428
Offline Offline

Posts: 5848


« Reply #7 on: February 09, 2021, 03:50:51 AM »

nevertheless, even if peripherals are not implemented, it's still useful, especially for the folks just starting out to dive into the assembly and ecu/tcu reverse engineering. Setting all the registers and initializing the RAM (especially the RAM) can save a lot of time and work understanding the ecu. OP and myself are not "need driven", he can tune his car with the tools he got, and I can tune my car with PCMFlash or just purchase an APR 3.0T tune which probably would have been the quickest and the most cost effective option. Seems to me, OP's goal is wider community education and just plain fun. This may not be a top priority for people doing this for a living but these are valid goals nevertheless. I think this can make it easier for some people to understand the tricore ecus.

You are assuming the ASW will boot in this. It won't.
Part of the SBOOT/CBOOT might, but then you have no way to communicate with them.

I can not think of a practical application for this, besides going "this is cool". To get to a practical application a huge amount of work is required, and it will be much easier to get a dev board Smiley
Logged

PM's will not be answered, so don't even try.
Log your car properly.
d3irb
Full Member
***

Karma: +131/-1
Offline Offline

Posts: 186


« Reply #8 on: February 09, 2021, 08:27:35 AM »

I think it's just different perspectives here: from an application software developer's point of view (aka someone making useful stuff  Wink ), emulation is mostly useless without peripherals (and even a dev board or bench ECU has limited utility). Since, in ASW development you are usually writing either patches to the generated logic in ASW (switching axes, adding conditions, bypassing sections of the model, etc.) or new UDS functionality. Those pieces of code can't really be well tested without the whole system brought up and playing together.

From an exploit/bootloader developers or curious researcher's point of view, emulation is extremely useful. For example, in SBOOT there is a table (ok not that huge, but like 20+ entries) of data that is used to initialize memory - each block in the table can be copied from one location to another, zeroed, or stored to registers. To set up the execution state of SBOOT in a static analysis tool, you'd have to either correctly reverse the functionality and write a script or painstakingly copy each memory block across by hand. With emulation, you can just jump through the segment and boom, RAM is set up how you want and you can dump it out and import it back into your tools.

Another good example is the Mersenne Twister Seed/Key algorithm in S18 SBOOT. Yes, it turns out the PRNG is just standard Mersenne Twister, but if you aren't experienced enough to see the MT algorithm and recognize it right away, no worries with a debugger - you can also just alter the seed value and run it through the algorithm running in emulation to generate a table of possible values for a given range of seeds.
Logged
H2Deetoo
Sr. Member
****

Karma: +26/-1
Offline Offline

Posts: 256


« Reply #9 on: February 11, 2021, 08:04:46 AM »

Impressive!


Rgs H2Deetoo
Logged
fastboatster
Full Member
***

Karma: +2/-0
Offline Offline

Posts: 64


« Reply #10 on: February 16, 2021, 09:32:23 PM »

Alright, I'm trying to play with this stuff, can compile qemu just fine but tricore-gdb compilation with
Quote
make
fails with
Quote
tricore-tdep.c:38:10: fatal error: 'opcodes/tricore-dis.h' file not found
after
Quote
./configure --disable-werror --target=tricore
there's an opcodes/tricore-dis.c file, there, though. Running on x86 Apple platform.
Logged
d3irb
Full Member
***

Karma: +131/-1
Offline Offline

Posts: 186


« Reply #11 on: February 17, 2021, 10:23:22 AM »

Just checked my checkout again. I simply removed the include because the opcodes are defined correctly in the C file, I think it is a mistake. If you remove the include from that file it should work.
Logged
fastboatster
Full Member
***

Karma: +2/-0
Offline Offline

Posts: 64


« Reply #12 on: February 17, 2021, 10:56:06 AM »

Thanks, that worked) I'll try to make a simos 8.4 qemu machine, can't try with simos 18 because I don't have an SBOOT for it.
Logged
Pages: [1]
  Print  
 
Jump to:  

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines Page created in 0.027 seconds with 17 queries. (Pretty URLs adds 0s, 0q)