Pages: [1]
Author Topic: MED17 How to find maps?  (Read 5320 times)
Sagishm
Jr. Member
**

Karma: +1/-0
Offline Offline

Posts: 26


« on: August 22, 2021, 02:31:41 AM »

Hi All,
i tried to learn how to disassemble MED17, i tried to read in FR and some docs about Infineon chip.

i have a question about finding maps, there is logic like ME7.5?

for example in ME7. you can find the map by: page * 4000 + value (204 * 4000 + 2256)

so i try with Ghidra and i found this section:
                             LAB_00108592                                    XREF[1]:     0010857a(j) 
        00108592 37 01 68 f0     extr.u     d15,d1,#0x0,#0x8
        00108596 37 04 70 40     extr.u     d4,d4,#0x0,#0x10
        0010859a 13 af 24 f8     madd       d15,d8,d15,#0x4a
        0010859e 60 ff           mov.a      a15,d15
        001085a0 d9 f4 46 60     lea        a4,[a15]0x586

it looks like reference to a data map but i cant understand how to calculate the location, someone can give some information about that?

Thanks
Logged
Sagishm
Jr. Member
**

Karma: +1/-0
Offline Offline

Posts: 26


« Reply #1 on: August 25, 2021, 12:50:47 AM »

someone can help? also reference to information will be good, thanks.
Logged
kuebk
Jr. Member
**

Karma: +3/-0
Offline Offline

Posts: 44



« Reply #2 on: August 25, 2021, 03:18:50 AM »

http://nefariousmotorsports.com/forum/index.php?topic=6990.0title=
Logged
Herleybob
Newbie
*

Karma: +4/-0
Offline Offline

Posts: 11


« Reply #3 on: September 19, 2021, 12:02:54 PM »

        00108592 37 01 68 f0     extr.u     d15,d1,#0x0,#0x8
        00108596 37 04 70 40     extr.u     d4,d4,#0x0,#0x10
        0010859a 13 af 24 f8     madd       d15,d8,d15,#0x4a
        0010859e 60 ff           mov.a      a15,d15
        001085a0 d9 f4 46 60     lea        a4,[a15]0x586


First you need to go to the xref and determine what the value of d1. Once you determine that, take the first 8 bytes, then multiply it by 0x4a. Then you need to determine what d8 is (in the xref) then add them together. Then it will move the address/offset into the register a15.

You then need to determine the value of a4.  once you have that, add 0x586 to the value in a15 you previously calculated and then add that value to a4 and that will take you to the address you are looking for.


Edit: can i get the bin you are working on and any known ram addresses and i can help.
« Last Edit: September 19, 2021, 03:07:12 PM by Herleybob » Logged
Sagishm
Jr. Member
**

Karma: +1/-0
Offline Offline

Posts: 26


« Reply #4 on: January 31, 2022, 12:32:22 AM »

First you need to go to the xref and determine what the value of d1. Once you determine that, take the first 8 bytes, then multiply it by 0x4a. Then you need to determine what d8 is (in the xref) then add them together. Then it will move the address/offset into the register a15.

You then need to determine the value of a4.  once you have that, add 0x586 to the value in a15 you previously calculated and then add that value to a4 and that will take you to the address you are looking for.


Edit: can i get the bin you are working on and any known ram addresses and i can help.

Hi,
i attached the file.
basicly i think:
d1 = refrance to d0002298 - so what the logics there ? d0002298 * 4a? looks like not correct.
d8 = d8,[a9]LAB_00000660
a9 = i can't find that refrance, maybe i miss something in Ghidra.

Thanks
Logged
prj
Hero Member
*****

Karma: +915/-426
Offline Offline

Posts: 5839


« Reply #5 on: February 01, 2022, 02:21:05 AM »

I mean yeah, reversing MED17 is a little more than pressing "X" button.
Maps are accessed through a double pointer dereference and an offset.
It is possible to set up Ghidra, so it actually tracks the whole path nicely...
Logged

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

Karma: +1/-0
Offline Offline

Posts: 26


« Reply #6 on: February 04, 2022, 12:04:22 PM »

I mean yeah, reversing MED17 is a little more than pressing "X" button.
Maps are accessed through a double pointer dereference and an offset.
It is possible to set up Ghidra, so it actually tracks the whole path nicely...
Thanks you for response.
I know there is double pointer, i tried to find the table start area without knowing some of code, basically of my question i found that by reverse the ldrxn location but for me its not enough good.
Maybe i did not set the Ghidra properly, there is something special needs to do or just to load file with specific processor is enough?
Thanks
Logged
prj
Hero Member
*****

Karma: +915/-426
Offline Offline

Posts: 5839


« Reply #7 on: February 04, 2022, 01:41:51 PM »

With some simple analysis of binary you can find where a9 points to. If you look in this subforum, this was already talked about long ago.
You reached the limit of what the tools will do for you automatically, now at least some skill is required to set the global registers correctly... better read the TriCore EABI.
Logged

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

Karma: +15/-4
Offline Offline

Posts: 425


« Reply #8 on: February 04, 2022, 01:47:55 PM »

I think you do not clearly understand how Tricore works. I recommend you to read a user manual first.
Global registers (d0, d1, a8, a9) contain something like constants (they can't be quickly changed) and usually a9 points to the table(map) that contains offsets.


madd       d15,d8,d15,#0x4a // I believe d8 contains an offset of the map(74 x Rows), d15 is a line number
mov.a      a15,d15
lea          a4,[a15]0x586

And disassembly is not an easy way to find maps.
« Last Edit: February 04, 2022, 06:48:53 PM by terminator » Logged
Sagishm
Jr. Member
**

Karma: +1/-0
Offline Offline

Posts: 26


« Reply #9 on: February 05, 2022, 05:36:26 AM »

I know is not easy, but both you are right, someone can share the Tricore manual?
Thanks
Logged
prj
Hero Member
*****

Karma: +915/-426
Offline Offline

Posts: 5839


« Reply #10 on: February 05, 2022, 05:48:00 AM »

Google didn't help you?
Logged

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

Karma: +915/-426
Offline Offline

Posts: 5839


« Reply #11 on: February 05, 2022, 05:48:48 AM »

I think you do not clearly understand how Tricore works. I recommend you to read a user manual first.
Global registers (d0, d1, a8, a9) contain something like constants (they can't be quickly changed) and usually a9 points to the table(map) that contains offsets.


madd       d15,d8,d15,#0x4a // I believe d8 contains an offset of the map(74 x Rows), d15 is a line number
mov.a      a15,d15
lea          a4,[a15]0x586

And disassembly is not an easy way to find maps.
d0 and d1 are not global registers on TriCore
Logged

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

Karma: +15/-4
Offline Offline

Posts: 425


« Reply #12 on: February 05, 2022, 02:13:02 PM »

a0 a1 of course)
Logged
360trev
Full Member
***

Karma: +66/-2
Offline Offline

Posts: 235


« Reply #13 on: February 05, 2022, 05:05:52 PM »

a0 a1 of course)

Well not just... On the entry of the MED17 code the developers defined this common code on the entry point of the code, early on in the bootstrapping. bear in mind it can vary a little bit in terms of the optional a8 and a9 but this is a good signature search to find to isolate the setup on pretty much any MED17 binary that I downloaded and tried it on.


_main+0    4D 40 E0 0F                     mfcr            d0, #0xFE04
_main+4    8F 00 50 F1                     or32            d15, d0, #0x100
_main+8    CD 4F E0 0F                     mtcr            #0xFE04, d15
_main+C    0D 00 C0 04                     isync

_main+10   91 10 00 0D                     movh.a          a0, #@HIS(_SMALL_DATA_)
_main+14   D9 00 80 8A                     lea             a0, [a0]@LOS(_SMALL_DATA_)

_main+18   91 90 00 18                     movh.a          a1, #@HIS(_SMALL_DATA2_)
_main+1C   D9 11 20 FD                     lea             a1, [a1]@LOS(_SMALL_DATA2_)

_main+20   91 10 00 8C                     movh.a          a8, #@HIS(_SMALL_DATA3_)
_main+24   D9 88 20 E8                     lea             a8, [a8]@LOS(_SMALL_DATA3_)

_main+28   A0 09                           mov16.a         a9, #0

_main+2A   CD 40 E0 0F                     mtcr            #0xFE04, d0

_main+2E   0D 00 C0 04                     isync


Let's walk though this a bit further...


_main:
//----------------------------------------------------------------------------------------------------------

/*
 *       uint32 PswTemp_u32 = __mfcr($PSW);                             // save PSW
 *       __mtcr($PSW, (PswTemp_u32 | (1 << CSFR_PSW_GW_POS)));          // set bit GW 
 *
 *       _isync();                                                      // ISYNC       
 */


        0x80123224: 4d 40 e0 0F     mfcr       d0 ,#0xfe04
        0x80123228: 8f 00 50 F1     or         d15 ,d0 ,#0x100      // Init CSFR PSW, with addition of GW bit being set
        0x8012322c: cd 4f e0 0F     mtcr       #0xfe04 ,d15
 
        0x80123230: 0d 00 c0 04     isync


So yes, A0 is a global...


//----------------------------------------------------------------------------------------------------------

/*
 *      asm volatile ("movh.a %a0,   HI: _SMALL_DATA_ ");              // Set global register A0
 *      asm volatile ("lea %a0,[%a0] LO: _SMALL_DATA_ ");
 */

       
        0x80123234: 91 10 00 0D     movh.a     a0 ,#0xd001
        0x80123238: d9 00 80 8a     lea        a0 ,[a0 ]-0x5600      // _SMALL_DATA1 = 0xD0015600

//----------------------------------------------------------------------------------------------------------


And so is A1...


/*               
 *      asm volatile ("movh.a %a1,   HI: _SMALL_DATA2_ ");             // Set global register A1
 *      asm volatile ("lea %a1,[%a1] LO: _SMALL_DATA2_ ");
 */

 
        0x8012323c: 91 90 00 18     movh.a     a1 ,#0x8009
        0x80123240: d9 11 20 fd     lea        a1 ,[a1 ]-0x2c20      // _SMALL_DATA2 = 0x80092C20

//----------------------------------------------------------------------------------------------------------


On some implementations A8 is defined as a global too (or zero)...
 

/*     
 *      asm volatile ("mov.a %a8, 0 ");                                // Set global register A8 to 0
 *
 *      // or
 *
 *      asm volatile ("movh.a %a8,   HI: _SMALL_DATA3_ ");             // Set global register A8
 *      asm volatile ("lea %a1,[%a8] LO: _SMALL_DATA3_ ");
 */

         
        0x80123244: 91 10 00 8c     movh.a     a8 ,#0xc001
        0x80123248: d9 88 20 e8     lea        a8 ,[a8 ]-0x7c60      // _SMALL_DATA3 = 0xC0017C60

//----------------------------------------------------------------------------------------------------------


And even A9.. In this case its defined as Zero


/*
 *      asm volatile ("mov.a %a9, 0 ");                                // Set global register A9 to zero
 */

 
        0x8012324c: a0 09           mov.a      a9 ,#0x0
        0x8012324e: cd 40 e0 0f     mtcr       #0xfe04 ,d0

/*
 *   _isync();                                                      // ISYNC   
 */

        0x80123252: 0d 00 c0 04     isync

//----------------------------------------------------------------------------------------------------------


Furthermore its very common to see this kind of access on MED17. This is obviously dependent on the code generation of the GCC itself. It technically doesn't have to be like that but this gives you some idea.

Now that the GCC 4.9.2 binaries and source-code are available freely there is literally no excuse not to play around with code generation and bintools to see how C code is translated into tricore assembly... This approach will rapidly accelerate your learning.


; Source File : 'E_ACTIVATETASK.c'

extrn os_i_lsIntMask
extrn os_i_mon_Ptr
extrn os_suspend_interrupts
extrn os_i_fifoSize_Ptr
extrn os_i_taskFifoPtr_Ptr
extrn os_resume_interrupts
extrn GetSystemTimeLow
extrn os_ServiceId   
extrn OSErrorUnion   
extrn os_error       
extrn os_i_nofCoopLvls
extrn os_maxSwPreempPrio
extrn os_ceilingPrio
extrn os_i_schedIntCtrlTab_Ptr
extrn SC_INT_ADR
extrn os_nextCoopPrio

82 1F                                   mov16           d15, #1

91 xx xx F0                             movh.a          a15, #@HIS(os_osek_task)
D9 FF 01 10                             lea             a15, [a15]@LOS(os_osek_task)

28 0F                                   st16.b          [a15]0, d15 ; os_osek_task
                os_osek_task = 1;

91 xx xx C0                             movh.a          a12, #@HIS(os_ercosekSP)
D9 CC 04 10                             lea             a12, [a12]@LOS(os_ercosekSP)

D4 CD                                   ld16.a          a13, [a12]                     ;  a13  = os_ercosekSP

80 D4                                   mov16.d         d4, a13                        ;  d4   = a13 (copy of os_ercosekSP)

A0 4E                                   mov16.a         a14, #4                        ;  a14  = 4

01 ED 20 D0                             sub32.a         a13, a13, a14                  ;  a13 =- a14; (ie subtract 4 from os_ercosekSP)

F4 CD                                   st16.a          [a12], a13
                os_ercosekSP -= 4;
               
91 xx xx F0                             movh.a          a15, #@HIS(os_switchToStartupStack)
D9 FF 08 10                             lea             a15, [a15]@LOS(os_switchToStartupStack)

2D 0F xx xx                             calli           a15

                fp = (FP)os_switchToStartupStack;
                fp();                   


00 90                                   ret16


Logged
prj
Hero Member
*****

Karma: +915/-426
Offline Offline

Posts: 5839


« Reply #14 on: February 06, 2022, 03:35:28 AM »

@Trev, it is enough to read the TriCore EABI.
Quote
2.2.1.4 System Global Registers
Address registers A[0], A[1], A[8], and A[9] are designated as system global registers.
They are not part of either context partition and are not saved/restored across calls. They
can be protected against write access by user applications.

Sometimes a good old dose of RTFM is a good idea. Use the brain cells reversing where you actually need to reverse, not reversing what is laid out in the EABI.

Furthermore:
Quote
By convention, A[0] and A[1] are reserved for compiler use, while A[8] and A[9] are
reserved for OS or application use. A[0] is intended as a base pointer to the “small” data
section, where global data elements can be accessed using base + offset addressing. It
is part of the execution environment and will always be initialized in the startup code for
any EABI-compliant RTOS.
A[1] is intended as a base pointer to the “literal data section”. The literal data section is
a read-only data section intended for holding address constants and program literal
values. Like A[0], it is initialized in the startup code for any EABI-compliant RTOS. (See
Special Sections, page 4-4, for further information.)
As noted, A[8] and A[9] are reserved for OS use, or for application use in cases where
the application and OS are tightly coupled. The compiler may support a directive that
allows a global pointer variable to be bound to one of these registers. In the absence of
such a directive the registers can only be used from assembly coded functions. A typical
OS use would be as a pointer to the current task control block, or to the task ready
queue, for reducing executive overhead in task management functions.

All that remains to do is find where they are assigned (as in your post), and set them.
« Last Edit: February 06, 2022, 04:43:09 AM by prj » Logged

PM's will not be answered, so don't even try.
Log your car properly.
Pages: [1]
  Print  
 
Jump to:  

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