Pages: 1 ... 8 9 [10]
Author Topic: ASM based map locator platform  (Read 47372 times)
360trev
Full Member
***

Karma: +20/-1
Offline Offline

Posts: 122


« Reply #135 on: September 08, 2018, 06:31:13 AM »

I know prj has done all of this great research and work 6+ years ago now I still think a fresh pair of eyes by another time served developer (me) could potentially (using some different approaches) move the game on further too.

I think you may actually be able to develop a ME7.x heuristic search model which could identify 100% of all maps in any ME7.x firmware almost automatically without lots of community contributed needle/masks. Infact I am currently working on such an approach...

How?
By concentrating on and identifying all (only tens of) indirect Lookup functions in ME7.x firmwares (and dumped IROM!) which all table accesses seem to go through anyway (!) at least all of the ones I've manually explored so far,  you can then find those references 'generically' in the entire machine code of the functions which utilize table lookups.

Q. Why do this? Well once you know what function your dealing with you know the format of the table (sizes of the fields, etc.) so its easy to dump the tables correctly. No guessing!

Then you can walk through the firmware image and discover all references to the Lookup functions and thus ALL tables (every single one). The various lookup's do things slightly differently depending on the number of its or rows/columns in any given table and this makes it possible to write a generic search function which catches all tables...

So by identifying the lookup's first and then working backwards from those known 'hits' I think you can infact locate all of the tables that the rom uses and correctly extract the row/columns directly out of the discovered code (as well as extract the segmentation information to discover the table itself, again automatically).

I'd be interested in prj's thoughts on this...
Logged
nyet
Administrator
Hero Member
*****

Karma: +411/-47
Offline Offline

Posts: 9170


WWW
« Reply #136 on: September 08, 2018, 04:57:59 PM »

I absolutely agree that minimizing per ECU needle/mask requirement is a good idea, and finding more generic ways of locating both ram variables and map locations would be of great utility.
Logged

ME7.1 tuning guide (READ FIRST)
ECUx Plot
ME7Sum checksum checker/corrrector for ME7.x

Please 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 experience.
woj
Sr. Member
****

Karma: +20/-1
Offline Offline

Posts: 400


« Reply #137 on: September 09, 2018, 12:47:08 AM »

I have some thoughts, because I actually more or less went all the way through this, using the same principle idea, but in a slightly different way. My very own private ST10 disassembler does that. Goes through the code once, finds all calls to scale reading routines, identifies scale index variables and the corresponding scale sizes, then goes through the code again and finds all maps. For scale integrated maps does the same thing, only in one pass. And yes, it does have an almost 100% hit rate. It even identifies double indirect referenced maps (very common in some of my bins, when m/a gearbox map is selected through an additional pointer reference). All is needed is to identify the address to the IROM block where the OS routines for map reading are. So far this part is manual, but can be easily automated too (I work with only one family of ECUs, so I don't really know how different it is on the other MEs).

You can easily as well do it as an IDA script, I have chosen a different route because of he language I use for this, that has pattern recognition capabilities beyond your imagination.

Now, my actual points. This method is not 100% bullet proof, you'd still get weird code, like an indexing variable held in a register for couple of tens of instructions, with disassembly you can do something about that, with binary code matching not so much, unless you in fact turn it into a disassembler.

The second point is this: so what? (Don't read this as ball-breaking, but encouragement Wink) I mean finding map boundaries is one problem and not a difficult one, finding what these maps actually are and make ME version independent is another thing. For my ECU I am practically interested in knowing around 400 maps (or single parameters / bits!) and sorting which one is which (eg. which KFPED is which, sport, reverse, automatic, manual gearbox, etc.). This I have not found a solution to yet, I mean one that would have considerable automation. This is what PRJ did in his map locator, but it requires manually crafted patterns and is not automatic in this respect (correct me if I am wrong). If I understand it correctly, it works well if you have two ECUs of the same family, you identify maps in one and created a pattern, then it will get you quickly to these maps in another ECU based on the same ME version. (No PRJ, I have not used your program, only looked through it once, so excuse me if I got it all wrong).
Logged
360trev
Full Member
***

Karma: +20/-1
Offline Offline

Posts: 122


« Reply #138 on: September 09, 2018, 08:02:47 AM »

I have some thoughts, because I actually more or less went all the way through this, using the same principle idea, but in a slightly different way. My very own private ST10 disassembler does that. Goes through the code once, finds all calls to scale reading routines, identifies scale index variables and the corresponding scale sizes, then goes through the code again and finds all maps. For scale integrated maps does the same thing, only in one pass. And yes, it does have an almost 100% hit rate. It even identifies double indirect referenced maps (very common in some of my bins, when m/a gearbox map is selected through an additional pointer reference). All is needed is to identify the address to the IROM block where the OS routines for map reading are. So far this part is manual, but can be easily automated too (I work with only one family of ECUs, so I don't really know how different it is on the other MEs).

You can easily as well do it as an IDA script, I have chosen a different route because of he language I use for this, that has pattern recognition capabilities beyond your imagination.

Now, my actual points. This method is not 100% bullet proof, you'd still get weird code, like an indexing variable held in a register for couple of tens of instructions, with disassembly you can do something about that, with binary code matching not so much, unless you in fact turn it into a disassembler.

The second point is this: so what? (Don't read this as ball-breaking, but encouragement Wink) I mean finding map boundaries is one problem and not a difficult one, finding what these maps actually are and make ME version independent is another thing. For my ECU I am practically interested in knowing around 400 maps (or single parameters / bits!) and sorting which one is which (eg. which KFPED is which, sport, reverse, automatic, manual gearbox, etc.). This I have not found a solution to yet, I mean one that would have considerable automation. This is what PRJ did in his map locator, but it requires manually crafted patterns and is not automatic in this respect (correct me if I am wrong). If I understand it correctly, it works well if you have two ECUs of the same family, you identify maps in one and created a pattern, then it will get you quickly to these maps in another ECU based on the same ME version. (No PRJ, I have not used your program, only looked through it once, so excuse me if I got it all wrong).

Thank you woj for an intelligent well thought out reply.

I have actually just been writing a C167 dissassembler (as part of this just to become more familiar with the machine code, syntax and operations you can do with the various instructions) which I will also host into my github account shortly. I needed this to be able to 'walk' through the machine code sequences and find if they are 2 or 4 byte lengths as part of my scanning routines. IDA has a loverly abstracted interface to accomplish this via a plugin or IDA scripts (which I used initially to prove some concepts) but I want my work to be non incumbered by any commerical licensing requirements at all hence doing my own thing. As such I'm not interested in the slightest in using IDA scripting since in my (humble) opinion its also very useful to be able to do all of this work without utilizing ANY 3rd party tools which are commerical, no IDA, no WinOLS, etc. It should ideally be fully self contained with all the source-code available for inspection by the reader. Also makes it less likely to be broken by any updates Wink

Its all well and good keeping all this stuff private (and I absolutely respect your rights to do this) but in my situation where I am not making a living from any of this, its absolutely just a hobby I will open source all of my work as a help to others and so it can be improved on in the future or ported to other platforms. I'm not a huge fan of Java (hate it to be honest despite having had to use it before in some larger scale industry projects in a former life!) I just didn't want to use prj's map finder as I felt I wanted to take it in a different direction anyway.

In terms of the so what points I have a clever way (which for now I will keep under wrap [need to have some surprises!) which I automatically identify the map names from. I've done extensive work on my own rom now and as such I've identified over 3,000 variables and functions (!) as well as documented the all the xref's back from variables to defining functions. This is a very powerful database which I hope to deploy, I've already done some preliminary work on this and optimistically I think I can get the majority of functions and variables in any ME7.x rom defined automatically.
 
I'll keep you all posted as I progress the concept...
Logged
360trev
Full Member
***

Karma: +20/-1
Offline Offline

Posts: 122


« Reply #139 on: September 09, 2018, 08:06:49 AM »

I posted this before here...

Code:
atic void PlugIn_process(int iArg)
{
  char funcName[MAXSTR];
  char filename[MAXSTR];
  char mnem[MAXSTR];
  char tmp[1024*512];
  int offset=0;
  int inst_count,func_len;
  unsigned int x, num_funcs, num_segments;
  ea_t addr, start_addr;
  asize_t our_size;
  flags_t flags;
  func_t *f=0;
  segment_t *seg=0;

  // We are only interested in segments containing code.
  seg = getnseg(0);
  num_funcs = get_func_qty();

         // Loop through each function
  msg("Found <%d> functions\n",num_funcs);

for (x = 0; x < num_funcs; x++)
        {
        f = getn_func(x);      // get ptr to the function itself
if(f == 0) {
msg("func not found at address %p\n");
}
else
{
// start address of this function..
start_addr = f->startEA;
addr = start_addr;

get_func_name(addr, funcName, sizeof(funcName)-1); // find the function name
//      set_name(addr, new_funcName, SN_NOWARN);

flags = get_flags_novalue(addr);
msg("Found %-32.32s: at %p, func_flags(%lx)",funcName,addr,flags);
//  Add name if there's no meaningful name assigned.
if(has_name(flags) != 0)       { msg("(customized name   ) "); }
if(has_dummy_name(flags) != 0) { msg("(autogenerated name) "); }
if(has_auto_name(flags) != 0)  { msg("(has_auto_name     ) "); }

//
// calc number of instructions
//
inst_count = 0;
addr = start_addr; // start of function
func_len   = ((f->endEA)-(start_addr));

// count the number of instructions within the function
for (; addr < f->endEA;) {
  // Get the flags for this address
  flags = get_flags_novalue(addr);
  // Only look at the address if it's a head byte, i.e. the start of an instruction and is code.
  if (isHead(flags) && isCode(flags))  {   
  inst_count++; // increase number of instructions counter we have seenn within this function
  }
  our_size = get_item_size(addr); // get number of bytes within this function
  addr += our_size;                 // move addres pc to next instruction...
}
//
// at this point 'inst_count' is total number of asm instructions within the buffer
//
msg(" func len = %-8d bytes (%-8d instructions)\n",func_len, inst_count );

sprintf(filename,"c:\\bin\\%p_%s_%d.bin",start_addr,funcName,inst_count);

#if 1
addr = start_addr; // start of function
offset=0;
// lets now loop through the instructions in each function
for (; addr < f->endEA;)
{
  // Get the flags for this address
  flags = get_flags_novalue(addr);

    // get the size of this item (e.g. instruction length)
  our_size = get_item_size(addr);

  // Only look at the address if it's a head byte, i.e.
  // the start of an instruction and is code.
  if (isHead(flags) && isCode(flags))
  {   
char instruction[16];

// Fill the cmd structure with the disassembly of the current address and get the mnemonic text.
ua_mnem(addr, mnem, sizeof(mnem)-1);

ua_ana0(addr);
ua_mnem(addr, instruction, sizeof(instruction));
tag_remove(instruction, instruction, sizeof(instruction));

// lets view the mnemonic of *this* address
// msg("%p:[%-2.2d] ", addr, our_size);
#if 1
msg(".");
get_many_bytes(addr,&tmp[offset],our_size);
offset += our_size;
#else
for(int j=0;j < our_size; j++)
{
tmp[j] = get_byte(addr+j);
}
#endif
// show the hex dump of the instruction
// hex_dump((unsigned char *)&tmp[offset], our_size);
// show the mnemonic of the instruction
// msg(" %-8.8s\n",instruction);
  }
  // move addres pc to next instruction...
  addr += our_size;
}

// dump it..
msg("dumping %s\n",filename);
save_file(filename, (unsigned char *)tmp, (size_t)offset);

#endif
}//end if

  }//end for
}

Using IDA's instruction walking interface this alone dumps every function in a ME7... I'm sure its easy to do with IDA scripting. If you just add the masking out the reloc's you have a very powerful way to cross reference functions across different roms with very little work..
 
Logged
woj
Sr. Member
****

Karma: +20/-1
Offline Offline

Posts: 400


« Reply #140 on: September 09, 2018, 09:07:57 AM »

(PRJ is going to be thrilled to see all this ranting in his thread Cheesy)

Your motivation for not using IDA and such is more or less exactly as mine. In fact, the only commercial tool I use (and that is not even really commercial, just semi-closed source) is TunerPro, all of the other software I use is mine, including a flasher and a macro assembler to patch code.

These are poor excuses to keep my software private, but there are some: 1. it is very targeted in its current form, so using it in a more general context than my ECU won't work. 2. Releasing things means it needs to have decent SE quality, my stuff does not and I don't have time to fix it. (It's so bad, that I cannot even trace my own way of thinking in software I have written half a year before). 3. Releasing things usually causes a shit-storm of stupid questions and I simply cannot deal with it. 4. Some software requires custom made hardware, and without it it's useless.

So, what I do instead is I release bit and independent pieces of information here and there so that the inclined ones can make some use of it.

I am curious about your approach, but reading "database" scares me a bit.

A possible future direction to consider is to go beyond ST10 / ME, and develop something for TriCore for example Wink Wink

Logged
prj
Hero Member
*****

Karma: +280/-26
Offline Offline

Posts: 3449


« Reply #141 on: September 09, 2018, 01:51:32 PM »

I mean rant on, why not Wink

I think ME7 is ... well sorta dead for this stuff.
As in most stuff that exists is already decently defined or there is a hex/a2l for a similar firmware that can be found...
Logged
woj
Sr. Member
****

Karma: +20/-1
Offline Offline

Posts: 400


« Reply #142 on: September 09, 2018, 02:07:14 PM »

Well, that's one opinion and I partly agree with it. If one's a pro then defo the new stuff counts much more. But then, you get tons of new people getting on here every day crying for help with maps, LC/NLS patches, gargles/pops, and what not. As long as there will be cars with ME7 there will be non zero interest. From amateurs. (Myself, I seem to be always two generations of ECUs behind the mainstream).

Having said that, I'd really like to see cutting edge tools for newer architectures. I recently realised Fiat has swapped my beloved ME7.9.10 technology for my beloved Fiat t-jet engine with ME17.3.0 which is a whole new ball game (for me at least). One that I would eventually want to get into, just some fucker some time ago decided a day should have only 24 hours :/
Logged
eliotroyano
Hero Member
*****

Karma: +38/-7
Offline Offline

Posts: 708


« Reply #143 on: September 10, 2018, 06:36:00 PM »

Maybe this kind of MAP locator tool can be tweaked for newer software and platforms. Of course if are not totaly encrypted or masked.
Logged
nyet
Administrator
Hero Member
*****

Karma: +411/-47
Offline Offline

Posts: 9170


WWW
« Reply #144 on: September 12, 2018, 10:05:11 PM »

Also: detect ram locations to extend/replace ME7Info
Logged

ME7.1 tuning guide (READ FIRST)
ECUx Plot
ME7Sum checksum checker/corrrector for ME7.x

Please 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 experience.
360trev
Full Member
***

Karma: +20/-1
Offline Offline

Posts: 122


« Reply #145 on: September 21, 2018, 03:48:44 AM »

Also: detect ram locations to extend/replace ME7Info

Yes, absolutely agree on this one as it finds virtually nothing for a Ferrari rom and I want to do realtime telemetry for my track days so this is a must..

I've just been finishing my C16x/ST10 dissassembler which I will spin off into its own seperate project on github as a shared library and simple frontend for other tools to use within them. This is already working in basic format...

Code:
-[ Basic Firmware information ]-----------------------------------------------------------------

>>> Scanning for ROM String Table Byte Sequence #1 [info]

found needle at offset=0x2cc04
found table at offset=00019A5C.

         0X2CC04 [+0   ]: mov      var_b, Rw_a                          [4] F6 F4 42 E2
         0X2CC08 [+4   ]: mov      var_b, Rw_a                          [4] F6 F5 44 E2
         0X2CC0C [+8   ]: jnb      cbitaddr_a, cbitaddr_c, Rel_b        [4] 9A 22 05 10
         0X2CC10 [+12  ]: movb     Rb_a,   #cdata16_b                   [4] E7 F8 11 00
         0X2CC14 [+16  ]: movb     var_b, Rb_a                          [4] F7 F8 0A E2
         0X2CC18 [+20  ]: jmpr     ccc_0000,Rel_l_a                     [2] 0D 04
         0X2CC1A [+22  ]: movb     Rb_a,   #cdata16_b                   [4] E7 F8 14 00
         0X2CC1E [+26  ]: movb     var_b, Rb_a                          [4] F7 F8 0A E2
         0X2CC22 [+30  ]: mov      Rw_a,   #cdata16_b                   [4] E6 F4 C8 CD
         0X2CC26 [+34  ]: mov      Rw_a,   #cdata16_b                   [4] E6 F5 82 00
         0X2CC2A [+38  ]: mov      var_b, Rw_a                          [4] F6 F4 32 E2
         0X2CC2E [+42  ]: mov      var_b, Rw_a                          [4] F6 F5 34 E2
         0X2CC32 [+46  ]: rets                                          [2] DB 00
         0X2CC34 [+48  ]: mov      Rw_b,   Rw_a                         [2] 88 60
         0X2CC36 [+50  ]: mov      Rw_a,   #cdata16_b                   [4] E6 F4 86 2B
         0X2CC3A [+54  ]: mov      Rw_a,   #cdata16_b                   [4] E6 F5 00 00
         0X2CC3E [+58  ]: mov      var_b, Rw_a                          [4] F6 F4 B2 E1
***
Idx=1   { 182542.000              } 0x101a1 : VMECUHN [Vehicle Manufacturer ECU Hardware Number SKU]
Idx=2   { 0261204841              } 0x1018b : SSECUHN [Bosch Hardware Number]
Idx=4   { 0000000000              } 0x10196 : SSECUSN [Bosch Serial Number]
Idx=6   { F131 CHALLENGE          } 0x10177 : EROTAN  [Model Description]
Idx=8   { R.BOSCH001              } 0x19a50 : TESTID
Idx=10  { 069117/15H52CE2         } 0x10167 : DIF
Idx=11  { 0691175H                } 0x1015e : BRIF

>>> Scanning for EPK information [info]

found needle at offset=0x27902.
EPK: @ 0x10029 { /1/ME7.3/69/117/F131_US//15h52ce2/151299/ }

-[ PUKANS Air Pulsation correction Table ]-----------------------------------------------

Function byte-sequence found @ 0x4b8c2, needle offset is +44 bytes, seg offset is +48 bytes

         0X4B8C2 [+0   ]: mov      Rw_a,   #cdata16_b                   [4] E6 FC E4 0A
         0X4B8C6 [+4   ]: movbz    Rb_a,   cmm_b                        [4] C2 FD 6C F8
         0X4B8CA [+8   ]: movbz    Rb_a,   cmm_b                        [4] C2 FE 7B F9
         0X4B8CE [+12  ]: calls    cseg_a, ccadr_b                      [4] DA 00 12 73
         0X4B8D2 [+16  ]: movb     var_b, Rb_a                          [4] F7 F8 51 8B
         0X4B8D6 [+20  ]: movbz    Rb_a,   cmm_b                        [4] C2 F4 52 8B
         0X4B8DA [+24  ]: movbz    Rb_a,   cmm_b                        [4] C2 F5 51 8B
         0X4B8DE [+28  ]: mul      Rw_a,   Rw_b                         [2] 0B 45
         0X4B8E0 [+30  ]: mov      var_b, Rw_a                          [4] F6 07 CE 9D
         0X4B8E4 [+34  ]: mov      Rw_a,  cmm_b                         [4] F2 F4 0E FE
         0X4B8E8 [+38  ]: mov      Rw_a,   [Rw+]                        [2] 98 90
         0X4B8EA [+40  ]: rets                                          [2] DB 00
         0X4B8EC [+42  ]: mov      Rw_a,   #cdata16_b                   [4] E6 FC AA 05
         0X4B8F0 [+46  ]: mov      Rw_a,   #cdata16_b                   [4] E6 FD 06 02
         0X4B8F4 [+50  ]: movbz    Rb_a,   cmm_b                        [4] C2 FE B8 8B
         0X4B8F8 [+54  ]: calls    cseg_a, ccadr_b                      [4] DA 82 78 97
         0X4B8FC [+58  ]: movb     var_b, Rb_a                          [4] F7 F8 D0 9D
         0X4B900 [+62  ]: rets                                          [2] DB 00
         0X4B902 [+64  ]: mov      Rw_a,  cmm_b                         [4] F2 F4 2C 8F
         0X4B906 [+68  ]: cmp      ...                                  [2] 48 40
***

PUKANS
    Long identifier:           Pulsation correction dependent on intake air temperature.
    Display identifier:
    Address:                   0x8185aa
    Value:

 No.           |        0        1        2        3        4        5        6        7
            PHY|    11.00    37.00    64.00    91.00   104.00   117.00   131.00   171.00
 --------------+------------------------------------------------------------------------
            PHY|   1.0859   1.0391   1.0000   0.9688   0.9453   0.9375   0.9219   0.8828


    Cells:
      Unit:
      Conversion name:
      Conversion formula:      f(phys) = 0.0 + 0.007812 * phys
      Data type:               UBYTE
    X-axis:
      Unit:                    Grad C
      Conversion name:
      Conversion formula:      f(phys) = 0.0 + 1.000000 * phys
      Data type:               UBYTE

And I'm just finishing the bits required to make it into a proper disassembler and single line assembler.

The idea is you can then upload patched code at runtime (during telem sessions) as well as realtime map editing. If you have a function uplad feature you can add features on the fly without having to reflash which for my usage is a must as I want to be able to rapidly develop and test without the whole reflash cycle which is just too time consuming...

I needed the dissassembler so I could easily work on runtime/offline patching...

Watch this space a big update is coming soon on my ME7 Swiss Army Knife tool Wink

Logged
360trev
Full Member
***

Karma: +20/-1
Offline Offline

Posts: 122


« Reply #146 on: September 21, 2018, 03:52:46 AM »

Maybe this kind of MAP locator tool can be tweaked for newer software and platforms. Of course if are not totaly encrypted or masked.

Yes, I've already acquired a Hitex Shield Buddy which boasts a fully programmable Infineon TriCore TC275 with full SDK and compilers, etc. I will get to this in good time.. Wink
Logged
taco
Newbie
*

Karma: +0/-0
Offline Offline

Posts: 4


« Reply #147 on: December 27, 2018, 07:35:37 AM »

The tool is amazing. I used nyet's fork and it found a nice shortlist to add to my "in progress" def.
ME7Logger can monitor many different items....
If the source is available maybe something from it can be adapted to help the map finder?
Logged
zarboz
Newbie
*

Karma: +1/-0
Offline Offline

Posts: 12


« Reply #148 on: March 11, 2019, 09:59:10 AM »

I am having a slight issue with the software where the [Me7XmlPlugin] will print the proper hex offset but the xdf / UI does not display the proper hex address

It is either how the app is temporarily storing the offset when identifying the addr or its the string.format formatting an existing real hex offset into a null hex offset


Terminal shows:
[Me7XmlPlugin] Pattern for CLRHK found at: 0x782E8

XDF export shows
<title>CLRHK</title>
        <XDFAXIS id="z">
            <decimalpl>2</decimalpl>
            <EMBEDDEDDATA mmedtypeflags="0x0" mmedaddress="0x27F2" mmedelementsizebits="8"/>
            <MATH equation="0.000000+X*1.000000">
                <VAR>
                    <id>X</id>
                </VAR>
            </MATH>
        </XDFAXIS>

and UI also shows 27F2

but real offset is : 0x782E8 as reported by the initial Me7XmlPlugin which oddly enough uses the same string.format command

if anyone can help me out it would be awesome
TLDR:
Me7XmlPlugin reports proper offset in terminal but UI / XDF show completely different offset

my branch is here:
https://github.com/zarboz/me7-tools

« Last Edit: March 11, 2019, 10:05:55 AM by zarboz » Logged
Pages: 1 ... 8 9 [10]
  Print  
 
Jump to:  

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