unicornux
Full Member
Karma: +2/-6
Offline
Posts: 83
|
|
« on: November 10, 2020, 12:36:13 AM »
|
|
|
Hi guys. I recently start Tricore Arch. And during reversing an ECU dump, I was confronted to some problem. One of the ways that there is for addressing mode is that uses 'a0' register. For example : a15, [a0]-0x68C6But when I was looking for a0 value I couldn't find anything. How I can calculate and find this address value? Can anyone explain me this issue?
|
|
|
Logged
|
|
|
|
nyet
|
|
« Reply #1 on: November 10, 2020, 12:45:15 AM »
|
|
|
A0 is a global register that is generally only set up once. iirc the only op that is used to modify it is MTCR (move to core register) It provides the base address of small data storage globals, which can be accessed quickly with the base addr addressing mode w/o a ton of operations. Generally never modified, even in ISRs.
you'll need an a2l or something to give you the memory map, which should tell you where small data storage starts.
|
|
« Last Edit: November 10, 2020, 12:46:55 AM by nyet »
|
Logged
|
ME7.1 tuning guideECUx PlotME7Sum checksumTrim heatmap toolPlease do not ask me for tunes. I'm here to help people make their own. Do not PM me technical questions! Please, ask all questions on the forums! Doing so will ensure the next person with the same issue gets the opportunity to learn from your ex
|
|
|
Basano
Full Member
Karma: +90/-3
Offline
Posts: 192
|
|
« Reply #2 on: November 10, 2020, 02:41:05 AM »
|
|
|
This is what worked for me (in my scenario)
You know that A0 needs to get initialised (loaded with some value)
Therefore do a text search in your disassembler like this - "lea a0"
And you’ll find a result like this:
seg002:808835CC movh.a a0, #0xD002 seg002:808835D0 lea a0, [a0]-0x8000 seg002:808835D4 movh.a a1, #0xA081 seg002:808835D8 lea a1, [a1]-0x8000 seg002:808835DC movh.a a8, #0x8005 seg002:808835E0 lea a8, [a8]-0x7800 seg002:808835E4 movh.a a9, #0xD001 seg002:808835E8 lea a9, [a9]-0x4000
In this example, A0, A1, A8 and A9 are used as ‘helper registers’ – base address plus offset.
This is just one way of figuring it out. There are other ways as well, there's a thread on this forum that works it out using known map addresses.
|
|
|
Logged
|
|
|
|
unicornux
Full Member
Karma: +2/-6
Offline
Posts: 83
|
|
« Reply #3 on: November 11, 2020, 12:04:41 AM »
|
|
|
This is what worked for me (in my scenario)
You know that A0 needs to get initialised (loaded with some value)
Therefore do a text search in your disassembler like this - "lea a0"
And you’ll find a result like this:
seg002:808835CC movh.a a0, #0xD002 seg002:808835D0 lea a0, [a0]-0x8000 seg002:808835D4 movh.a a1, #0xA081 seg002:808835D8 lea a1, [a1]-0x8000 seg002:808835DC movh.a a8, #0x8005 seg002:808835E0 lea a8, [a8]-0x7800 seg002:808835E4 movh.a a9, #0xD001 seg002:808835E8 lea a9, [a9]-0x4000
In this example, A0, A1, A8 and A9 are used as ‘helper registers’ – base address plus offset.
This is just one way of figuring it out. There are other ways as well, there's a thread on this forum that works it out using known map addresses.
This approach worked for me, too. Thanks a lot. But the addressing mode for assign value to a0 is different for me that I have shown below: movh.a a0, #@HIS(unk_D00032E0) lea a0, [a0]@LOS(unk_D00032E0) As you see it seems I need procedures that copy data from FLASH to RAM(probably they show by structures). Is there any approach to find these procedures? I have no idea how can I find out what is going to be executed. PS: Unfortunately I have not any A2L file Thanks in advance.
|
|
|
Logged
|
|
|
|
unicornux
Full Member
Karma: +2/-6
Offline
Posts: 83
|
|
« Reply #4 on: November 11, 2020, 12:06:40 AM »
|
|
|
you'll need an a2l or something to give you the memory map, which should tell you where small data storage starts.
Interesting reply but unfortunately I have not any A2L file.
|
|
|
Logged
|
|
|
|
nyet
|
|
« Reply #5 on: November 11, 2020, 12:35:07 AM »
|
|
|
movh.a a0, #@HIS(unk_D00032E0) lea a0, [a0]@LOS(unk_D00032E0)
What? you're looking at it. unk_D00032E0 is literally D00032E0. It means the disassembler is seeing d00032e0 but doesn't know what it is, hence the unk so this is movh.a a0, d000 lea a0, [a0]+32e0 or a0 = d00032e0
|
|
|
Logged
|
ME7.1 tuning guideECUx PlotME7Sum checksumTrim heatmap toolPlease do not ask me for tunes. I'm here to help people make their own. Do not PM me technical questions! Please, ask all questions on the forums! Doing so will ensure the next person with the same issue gets the opportunity to learn from your ex
|
|
|
unicornux
Full Member
Karma: +2/-6
Offline
Posts: 83
|
|
« Reply #6 on: November 11, 2020, 12:49:23 AM »
|
|
|
What? you're looking at it.
unk_D00032E0 is literally D00032E0. It means the disassembler is seeing d00032e0 but doesn't know what it is, hence the unk
so this is movh.a a0, d000 lea a0, [a0]+32e0
or a0 = d00032e0
According to this thread( http://nefariousmotorsports.com/forum/index.php?topic=6990.msg87488#msg87488) I thought need a struct for rest of works.
|
|
|
Logged
|
|
|
|
nyet
|
|
« Reply #7 on: November 11, 2020, 12:55:14 AM »
|
|
|
What does this have to do with your original question For example : a15, [a0]-0x68C6
in which you asked what a0 was?
|
|
|
Logged
|
ME7.1 tuning guideECUx PlotME7Sum checksumTrim heatmap toolPlease do not ask me for tunes. I'm here to help people make their own. Do not PM me technical questions! Please, ask all questions on the forums! Doing so will ensure the next person with the same issue gets the opportunity to learn from your ex
|
|
|
unicornux
Full Member
Karma: +2/-6
Offline
Posts: 83
|
|
« Reply #8 on: November 11, 2020, 01:05:01 AM »
|
|
|
What does this have to do with your original question
in which you asked what a0 was?
OOOM, I guess maybe I should create a new topic for next question. I want to associate all the related question in this topic. Excuse Me. Thanks.
|
|
|
Logged
|
|
|
|
crystal_imprezav
Newbie
Karma: +5/-0
Offline
Posts: 12
|
|
« Reply #9 on: November 30, 2020, 05:49:21 PM »
|
|
|
Look in the tricore helper sticky for the parse indirect script. Then find the main routine in the asw. From there you will be able to find a0, csa_smalldata2, and a10(sp) to use with the indirect script.
|
|
|
Logged
|
|
|
|
360trev
Full Member
Karma: +68/-2
Offline
Posts: 235
|
|
« Reply #10 on: December 04, 2020, 07:21:20 AM »
|
|
|
Have a play with Ghidra, it can translate Tricore instructions into pseudo code and will massively accelerate your understanding of the instruction set!
|
|
|
Logged
|
|
|
|
terminator
|
|
« Reply #11 on: March 04, 2021, 10:01:32 AM »
|
|
|
What is a stack pointer? I know the basics like push and pop, sp points to the value stored on the stack. From the instruction set I read:
SUB.A A[10], const8 Decrement the Stack Pointer (A[10]) by the zero-extended value of const8 (a range of 0 through to 255).
sp is actually a10 and like a0, a1, a8, a9 in most cases set up only once: movh.a sp, #@HIS(unk_D000C380) lea sp, [sp]@LOS(unk_D000C380)
I would appreciate if anyone could comment on this part of the code.
0x80006EA8 sub.a sp, #0x20 // allocate a space 0x80006EAA movh.a a15, #0xD000 0x80006EAE lea a4, [sp]0x14 // load address to a4. 0xD000C380 + 0x14? 0x80006EB2 lea a15, [a15]0xBF4 0x80006EB6 ld.w d4, [a15]0x00 0x80006EB8 call 0x80007086 0x80006EBC ld.w d4, [a15]0x01 0x80006EBE lea a4, [sp]0x08 0x80006EC2 call 0x80007086 0x80006EC6 ld.hu d2, [sp]0x16 0x80006ECA jeq d2, #0x00, 0x80006F1A 0x80006ECE ld.hu d1, [sp]0x0A 0x80006ED2 jeq d1, #0x00, 0x80006F1A 0x80006ED6 ld.w d15, [sp], #0x07 0x80006ED8 jlt.u d15, #0x02, 0x80006F1A 0x80006EDC ld.w d15, [sp], #0x04 0x80006EDE jlt.u d15, #0x02, 0x80006F1A 0x80006EE2 ld.hu d0, [sp]0x18 0x80006EE6 ld.hu d15, [sp]0x0C 0x80006EEA jeq d0, d15, 0x80006F1A 0x80006EEE mov d0, #0x00 0x80006EF0 mov.aa a15, sp
|
|
|
Logged
|
|
|
|
prj
|
|
« Reply #12 on: March 04, 2021, 10:16:19 AM »
|
|
|
You need to read a book about programming basics or you need some formal education on that matter. This Wiki article is pretty good: https://en.wikipedia.org/wiki/Stack_registerYour first comment is already wrong. A4 is loaded with address that is 0x14 offset from current sp.
|
|
|
Logged
|
|
|
|
terminator
|
|
« Reply #13 on: March 04, 2021, 12:06:21 PM »
|
|
|
Thanks for the answer. I hope I understood it right.
By default, the stack grows downward in memory, so newer values are placed at lower memory addresses. sub.a sp, #0x20 lea a4, [sp]0x14 // 0xD000C380 - 0x20 + 0x14 = 0xD000C374 ? ld.bu d15, [a4]0x00 // load byte from 0xD000C374 to d15? right?
|
|
« Last Edit: March 04, 2021, 12:10:28 PM by terminator »
|
Logged
|
|
|
|
prj
|
|
« Reply #14 on: March 04, 2021, 03:44:12 PM »
|
|
|
Your assumptions towards the stack pointer is wrong. You have zero guarantees that it is D000C380 at that point. There can be and most likely are more function calls in the callstack. Each of them makes use of the stackpointer for storage. You never know what it exactly points to (apart from exactly at the initialization) nor should you care. It is simply function-local storage that does not fit into registers. Your only care should be that you do not overflow the stack due to too much recursion or function call chains. Trying to find the absolute address is a complete waste of time, nor is it the intended usage of the stack pointer. In fact the absolute address is different every time the function is called from a different place.
You need to study the basics, you are trying to run before you can walk. Try to learn how a stack pointer fits into an architecture and everything will become clear.
|
|
« Last Edit: March 04, 2021, 03:47:21 PM by prj »
|
Logged
|
|
|
|
|