It may take a few iterations before getting the lay of the land. I don't know anything about the V6 ecm's. Getting r2 / r13 set will help. Hopefully its not VLE and also hopefully r2 / r13 stays stable for all the os code. If you can source an a2l + bin for something similar that will help you set up the memory blocks.
Load it in as you've done. Hit analyse, leave all default. Do a search for all instructions that write to r2 / r13. Depending on candidate count you will need to follow the call trees. Typically, after entry to the os code is where you'll be looking for it, but as said earlier, I have no idea about this ecm, this is just generalised advice based off prior learnings from t43 & e38 disassembly.
Example patterns:
lis r13[r2] / addi r13[r2] / oris r13[r2] / ori r13[r2]
Help Getting Started With Ghidra For MPC562 ME9.6.1 VE E77 LY7
-
hjtrbo
- Posts: 353
- Joined: Tue Jul 06, 2021 8:57 am
- cars: VF2 R8 LSA
FG XR6T
HJ Ute w/RB25DET
-
Lucasperks06
- Posts: 42
- Joined: Tue Jun 09, 2026 8:09 am
- cars: Cammed ve alloytec
Re: Help Getting Started With Ghidra For MPC562 ME9.6.1 VE E77 LY7
how did you do that with universal patcher? i downloaded it before but wasnt sure how to work it?
but thanks so much for getting that info, so im assuming ill put that into the ghidra file and itll create different sections for each part of the bin? ill see if i can figure out how to do that.
and ill send a A2L and hex file ive been using for my maps. im not sure if this will be helpful though as it only contains the calibration data. its from an Opel with a e55 ME9.6, more similar to the VZ. i havent been able to get my hands on a e77 A2L, i believe they exist somewhere, the only one ive seen requires you to have winols purchased which i dont.
but ill do as you said and see what i can come up with for the r2 and r13 values.
should i input the data you sent before into my file or is it not necessary at this point?
https://drive.google.com/file/d/1PpBJCn ... sp=sharing (A2L File)
but thanks so much for getting that info, so im assuming ill put that into the ghidra file and itll create different sections for each part of the bin? ill see if i can figure out how to do that.
and ill send a A2L and hex file ive been using for my maps. im not sure if this will be helpful though as it only contains the calibration data. its from an Opel with a e55 ME9.6, more similar to the VZ. i havent been able to get my hands on a e77 A2L, i believe they exist somewhere, the only one ive seen requires you to have winols purchased which i dont.
but ill do as you said and see what i can come up with for the r2 and r13 values.
should i input the data you sent before into my file or is it not necessary at this point?
https://drive.google.com/file/d/1PpBJCn ... sp=sharing (A2L File)
You do not have the required permissions to view the files attached to this post.
-
Lucasperks06
- Posts: 42
- Joined: Tue Jun 09, 2026 8:09 am
- cars: Cammed ve alloytec
Re: Help Getting Started With Ghidra For MPC562 ME9.6.1 VE E77 LY7
so after some searching in the bin ive found 3 sections i believe it could be in, based off how ive seen others r2/r13 written out im gonna say its the last photo thats correct, but the location isnt like others, i thought they were supposed to be written near the start of the bin. that third photo is near the end, the other 2 are alot closer to the start but are written differently to how others are.
whats your thoughts?
whats your thoughts?
You do not have the required permissions to view the files attached to this post.
-
hjtrbo
- Posts: 353
- Joined: Tue Jul 06, 2021 8:57 am
- cars: VF2 R8 LSA
FG XR6T
HJ Ute w/RB25DET
Re: Help Getting Started With Ghidra For MPC562 ME9.6.1 VE E77 LY7
Code: Select all
r2 (_SDA2_BASE_) 0x005C9FF0
r13 (_SDA_BASE_) 0x007FFFF0You need to look at your current cross references to see if they're hitting those ram areas. Shift the bin offset around till they line up. AI will do this for you if you can't be fucked. Everyone has their own preference. I use claude code for RE work.
Advanced mode. No need just yet to chop up the memory areas. Leave it as a block until you've got the right offset.
You do not have the required permissions to view the files attached to this post.
-
Lucasperks06
- Posts: 42
- Joined: Tue Jun 09, 2026 8:09 am
- cars: Cammed ve alloytec
Re: Help Getting Started With Ghidra For MPC562 ME9.6.1 VE E77 LY7
so when you say my chip may be 8mb, would that mean my bin is supposed to be 8mb too?
and its always confused me with offsets, if i offset my file to read at say 0x005C9FF0, wouldnt it just be nothing as it ends at 1DDFFF
i understand the offsets ive done for my hp tuner file to line up the calibration.
or would there still potentially be something at those addresses as what you found before references those addresses?
and when you say my current cross-references is that just where ive found r2/r13 to be referenced?
and im happy to do it myself, ill use AI once i know what im actually doing just do im not watching random things happening and ill have no idea whats going on.
and are you just saying to shift the bin offset to the referenced addresses?
i did what you said aswell with universal patcher but it didnt work, ive got an error saying "File not found: C:\Users\Lucas\Downloads\uni pathcer\UniversalPatcher-master\XML\gm-os-bosch1.xml" when i click the little 'i'
am i supposed to have these files or do i need to source them myself or something?
and its always confused me with offsets, if i offset my file to read at say 0x005C9FF0, wouldnt it just be nothing as it ends at 1DDFFF
i understand the offsets ive done for my hp tuner file to line up the calibration.
or would there still potentially be something at those addresses as what you found before references those addresses?
and when you say my current cross-references is that just where ive found r2/r13 to be referenced?
and im happy to do it myself, ill use AI once i know what im actually doing just do im not watching random things happening and ill have no idea whats going on.
and are you just saying to shift the bin offset to the referenced addresses?
i did what you said aswell with universal patcher but it didnt work, ive got an error saying "File not found: C:\Users\Lucas\Downloads\uni pathcer\UniversalPatcher-master\XML\gm-os-bosch1.xml" when i click the little 'i'
am i supposed to have these files or do i need to source them myself or something?
You do not have the required permissions to view the files attached to this post.
-
hjtrbo
- Posts: 353
- Joined: Tue Jul 06, 2021 8:57 am
- cars: VF2 R8 LSA
FG XR6T
HJ Ute w/RB25DET
Re: Help Getting Started With Ghidra For MPC562 ME9.6.1 VE E77 LY7
See if the highlighted e69 xml files are in the universal patcher xml folder. It should have picked them up. If not I'll attach them.
The os code will have cross references for rpm as an example. rpm is a ram variable. It will be in one of the 2 sda blocks. If the os code cross reference for rpm is not landing in the sda regions, you need to shift the bin up or down until it is. Obviously you need to be more accurate than that, but that's the gist of it.
You do not have the required permissions to view the files attached to this post.
-
antus
- Site Admin
- Posts: 10014
- Joined: Sat Feb 28, 2009 10:34 am
- cars: TX Gemini 2L Twincam 8psi
TX Gemini SR20 18psi
Datsun 1200 Ute
Subaru Blitzen '06 EZ30 4th gen, 3.0R Spec B
Subaru WRX 2007
Re: Help Getting Started With Ghidra For MPC562 ME9.6.1 VE E77 LY7
MCP versus build in for AI? MCP is the general standard protocol for LLM tool use that everything uses (Model Context Protocol), so its probably is MCP in the first place. But if you want to start hooking up your own things to AI or extending it the tools to make the AI then an MCP server is probably the go. I've not seen Ghidras built in, so its probably fine. But there still needs to be something the tool can talk too. For IDA there an ida-lib for tool use (maybe equivalent to what you are calling built in) then the MCP tool talks MCP tool protocol to whatever environment you are working from and interfaces with the tool in the tools own protocol.
That code for r2, r13, looks like you have he answer, but you'd usually start with the code from the reset vector entry point and then for that one I'd cut n paste the specific function and ask it to comment what value is expected to be in r2, r12 after each instruction modifies it.
For AI, for pay versions of Claude is winning at the moment. Has to be Opus 4.8. but things are moveing so quick, it's always changing. Including Antropic (the company that make it) seem to drop performance on old models when new ones come out (even if they say they don't, but so many people have seen it including myself) so sometimes it goes dumb and you have to notice before it trashes your work and move to a higher / newer tier one.
I've also been playing with AI models locally running on my own PC to see if I can do it without the cloud. I'll put a quick summary here for interest, though I would not recommend it. Stick to the cloud for now. So far I've found you need lots of VRAM. I've hung a second GPU out the side of my PC so that I have 28gb of VRAM and it's still a real challenge to get it to be smart. I've found at the moment google gemma4 is looking pretty good for speed at 12B density but it can only answer basic questions before it's tiny brain explodes and you get an "EOS Token Found" which is where the LLM says it got no more to say because the model just gave up and stopped prematurely. It seems to think it can think about things in smaller parts but in practice for RE that's not true. The moment it starts thinking about PPC registers.. premature EOS. I've been moving up to larger and larger models. Essentially the density is in billions so something like 4b, 12b, 26b, 31b and so on up which essentially is a measure of how big the brain is and how much it can comprehend at once. And context is its short term memory. All of the billions of tensors need to evaluate the context tokens so this is why its gets so VRAM expensive when you get large. And AI is evolving and people are realising it works better if the models save text files of things put them out of mind and recall later when they need them (long term memory), to keep the context down. So because of this, you don't necessarily need the biggest context. But even at 31b models, getting performance is really really pushing 28G. I have to use quaninizaton (very similar to JPEG compression) which makes the model smaller, but also reduces its accuracy. Normally you start with 32bit float, then 16bit float halves the RAM/Size and it still works pretty well. Then usually you drop to integer 8, which is still good (and 25% the size of the full 32 bit model). But even with 28G VRAM, I'm having to get down to Q4 for 29b, and I tried Q3, and quantized QV cache for the model, and it did bring the size down further and become usable for speed, but the hallucinations were too much and it lost its usefulness. Q4 is as low you can really push it, and Q8 or above is where you want to be. But until we get lots of fast memory in our home computers, cloud AI is really needed for this type of stuff. Having said that, a mix of cloud for complex tasks and local for regular stuff to keep the paid cloud usage down can be useful.
This is gemma4 31b at Q4 quantization and Q4 KV cache as well, got it down to about 26 Gb of RAM needed. It's outputting about 3 characters a second locally pushing my machine to the max. It couldn't quite get its head around the PPC because it saw the hex and tried to validate the disassembly which was too much for it. So here it is failing, on first try and then I clicked stop because I could see it was not taking the right approach and needed to be re-pointed with a new prompt. Not sure how much of it going wrong was the prompt wasn't good enough and how much might have been the quite extreme quantinization. 4 bits for each tensor, down from the native, in this case 16. It's one of the latest from https://huggingface.co/google/gemma-4-31B
And then this is the bit about from engineering. It needed more of a steer, to trust the disassembly and ignore the hex. Then it finds the correct answer and explains how the code works.The tokens per second is right, the overall time of 1.29s at the bottom is not
The 'thinking' (this is a reasoning model) can be very interesting to watch, and is often a good teacher. This model can also straight up read the screen shot images pasted in.
For the second one, I told it to trust the disassembler, and ignore the hex as the actual dissassmbly from bytes was challenging it more.
Then it carries on, double checks is work a few times, then thinks "I am confident in these values, lets tell the user" then it generates the to the point answer.
This is interesting, it thought it saw r11, but it was r12. That is likely a hallucination from the quantization, but it got past it and corrected itself (by looking at the hex!)
That code for r2, r13, looks like you have he answer, but you'd usually start with the code from the reset vector entry point and then for that one I'd cut n paste the specific function and ask it to comment what value is expected to be in r2, r12 after each instruction modifies it.
For AI, for pay versions of Claude is winning at the moment. Has to be Opus 4.8. but things are moveing so quick, it's always changing. Including Antropic (the company that make it) seem to drop performance on old models when new ones come out (even if they say they don't, but so many people have seen it including myself) so sometimes it goes dumb and you have to notice before it trashes your work and move to a higher / newer tier one.
I've also been playing with AI models locally running on my own PC to see if I can do it without the cloud. I'll put a quick summary here for interest, though I would not recommend it. Stick to the cloud for now. So far I've found you need lots of VRAM. I've hung a second GPU out the side of my PC so that I have 28gb of VRAM and it's still a real challenge to get it to be smart. I've found at the moment google gemma4 is looking pretty good for speed at 12B density but it can only answer basic questions before it's tiny brain explodes and you get an "EOS Token Found" which is where the LLM says it got no more to say because the model just gave up and stopped prematurely. It seems to think it can think about things in smaller parts but in practice for RE that's not true. The moment it starts thinking about PPC registers.. premature EOS. I've been moving up to larger and larger models. Essentially the density is in billions so something like 4b, 12b, 26b, 31b and so on up which essentially is a measure of how big the brain is and how much it can comprehend at once. And context is its short term memory. All of the billions of tensors need to evaluate the context tokens so this is why its gets so VRAM expensive when you get large. And AI is evolving and people are realising it works better if the models save text files of things put them out of mind and recall later when they need them (long term memory), to keep the context down. So because of this, you don't necessarily need the biggest context. But even at 31b models, getting performance is really really pushing 28G. I have to use quaninizaton (very similar to JPEG compression) which makes the model smaller, but also reduces its accuracy. Normally you start with 32bit float, then 16bit float halves the RAM/Size and it still works pretty well. Then usually you drop to integer 8, which is still good (and 25% the size of the full 32 bit model). But even with 28G VRAM, I'm having to get down to Q4 for 29b, and I tried Q3, and quantized QV cache for the model, and it did bring the size down further and become usable for speed, but the hallucinations were too much and it lost its usefulness. Q4 is as low you can really push it, and Q8 or above is where you want to be. But until we get lots of fast memory in our home computers, cloud AI is really needed for this type of stuff. Having said that, a mix of cloud for complex tasks and local for regular stuff to keep the paid cloud usage down can be useful.
This is gemma4 31b at Q4 quantization and Q4 KV cache as well, got it down to about 26 Gb of RAM needed. It's outputting about 3 characters a second locally pushing my machine to the max. It couldn't quite get its head around the PPC because it saw the hex and tried to validate the disassembly which was too much for it. So here it is failing, on first try and then I clicked stop because I could see it was not taking the right approach and needed to be re-pointed with a new prompt. Not sure how much of it going wrong was the prompt wasn't good enough and how much might have been the quite extreme quantinization. 4 bits for each tensor, down from the native, in this case 16. It's one of the latest from https://huggingface.co/google/gemma-4-31B
And then this is the bit about from engineering. It needed more of a steer, to trust the disassembly and ignore the hex. Then it finds the correct answer and explains how the code works.The tokens per second is right, the overall time of 1.29s at the bottom is not
The 'thinking' (this is a reasoning model) can be very interesting to watch, and is often a good teacher. This model can also straight up read the screen shot images pasted in.
For the second one, I told it to trust the disassembler, and ignore the hex as the actual dissassmbly from bytes was challenging it more.
Then it carries on, double checks is work a few times, then thinks "I am confident in these values, lets tell the user" then it generates the to the point answer.
This is interesting, it thought it saw r11, but it was r12. That is likely a hallucination from the quantization, but it got past it and corrected itself (by looking at the hex!)
You do not have the required permissions to view the files attached to this post.
Have you read the FAQ? For lots of information and links to significant threads see here: http://pcmhacking.net/forums/viewtopic.php?f=7&t=1396
-
Lucasperks06
- Posts: 42
- Joined: Tue Jun 09, 2026 8:09 am
- cars: Cammed ve alloytec
Re: Help Getting Started With Ghidra For MPC562 ME9.6.1 VE E77 LY7
how would you go about locating a variable like rpm, or load? how is it written in the code?
and these sda blocks, what are they reffering too?
also i should of asked this before, but what actually is r2 and r13, how do they help with disasembly?
but i think i get what your saying, use a variable (rpm) and adjust the bin offset until said variable is found, and adjust it until its perfect, if im getting it right.
and what about all the other code thats there with the offset at 0, wont it just move past all that, unless the offset is minor.
and that image you sent too, is that just a random example, or is that going to be applicable to my case? as in these sda blocks will be at that end of the bin (8000000)
sorry if im not fully getting it im just trying to wrap my head around it all, never done anything like this.
and these sda blocks, what are they reffering too?
also i should of asked this before, but what actually is r2 and r13, how do they help with disasembly?
but i think i get what your saying, use a variable (rpm) and adjust the bin offset until said variable is found, and adjust it until its perfect, if im getting it right.
and what about all the other code thats there with the offset at 0, wont it just move past all that, unless the offset is minor.
and that image you sent too, is that just a random example, or is that going to be applicable to my case? as in these sda blocks will be at that end of the bin (8000000)
sorry if im not fully getting it im just trying to wrap my head around it all, never done anything like this.
-
antus
- Site Admin
- Posts: 10014
- Joined: Sat Feb 28, 2009 10:34 am
- cars: TX Gemini 2L Twincam 8psi
TX Gemini SR20 18psi
Datsun 1200 Ute
Subaru Blitzen '06 EZ30 4th gen, 3.0R Spec B
Subaru WRX 2007
Re: Help Getting Started With Ghidra For MPC562 ME9.6.1 VE E77 LY7
you need something to identify it, a starting point, and work back from there. a good one for OBD can be the SAE data logging pids. Find the comms handler, find the table for the functions by pid, find where the value is comeing from in ram.
but keep in mind these PCMs are incredibly complex. There is probably more layers than you expect, and more copies of the variable for different use cases. Best case is you find a ram variable and that is it, but be ready for it to get more complex if you start trying to change things.
r2 and r13 are used for memory access and is required for proper decompilation. I've not done anywhere near as much PPC (yet) as I have 68k so I'll let someone else cover in more depth.
but keep in mind these PCMs are incredibly complex. There is probably more layers than you expect, and more copies of the variable for different use cases. Best case is you find a ram variable and that is it, but be ready for it to get more complex if you start trying to change things.
r2 and r13 are used for memory access and is required for proper decompilation. I've not done anywhere near as much PPC (yet) as I have 68k so I'll let someone else cover in more depth.
Have you read the FAQ? For lots of information and links to significant threads see here: http://pcmhacking.net/forums/viewtopic.php?f=7&t=1396
-
Gatecrasher
- Posts: 435
- Joined: Fri Apr 24, 2020 8:09 pm
Re: Help Getting Started With Ghidra For MPC562 ME9.6.1 VE E77 LY7
The flash isn't 8MB, and "just slide things around" is terrible advice. That's why I said at the beginning you need to KNOW where the flash is loaded at.
Look on the bottom of page 95, and the charts on the following 2 pages of the reference manual. https://www.nxp.com/docs/en/data-sheet/MPC561RM.pdf
It says the user can assign the internal memory space (flash + RAM + registers) to one of eight internal ranges.
Finding those suspected R2 and R13 values are big hints. If we assume those are right, that means we're using block 2 (0x400000 to 0x7FFFFF). That would put the start of the external flash at 0x480000. It would also put the end of the RAM at 0x800000. Suddenly that R13 value makes sense. It's a relative reference from the end of the RAM. R2 doesn't make sense at the moment. Maybe it's a pointer to a data structure the OS uses frequently.
The bootloader block would start executing from the beginning of the flash. We don't have that, so you'd load the flash file into Ghidra starting at the beginning of the OS. 0x480000 + 0x20000 = 0x4A0000.
So in Ghirda, you import the file, set the language to powerPC 32 bit, big endian, default compiler. Then click options, and set the base address to 4A0000, the file offset to 0, and leave the length as default. Block name can be anything you want. I just call it flash.
Once the file is loaded, cancel the prompt that asks if you want to auto-analyze. Go to the Select menu, click Bytes, and then select all. Next hit ctrl + R to set the registers. Set R2 to and R13 to the values you already found. R2 is 0x5D0000 - 0x6010 = 0x5C9FF0 and R13 is 0x800000 - 0x10 = 0x7FFFF0.
Once the registers are set, go to 0x4A0014 and hit D to disassemble. You'll start to get blocks of code, like so. Since we have R13 set, it automatically calculates the relative reference. 0x7FFFF0 - 0x7e38 = 0x7F81B8, for example. Before you go too far, go to Window > Memory Map, and hit the green plus sign to add a block for the CALRAM. Set the start address to 0x7F8000 and the length to 0x8000. Leave everything else as default. Once you have some more code disassembled, you'll be able to click on those RAM or Flash addresses and see what other blocks of code reference them. That's when you can start naming stuff.
If you go to 0x5F99B8 and hit D, you'll see the R2 and R13 code you already found. It just has the correct offset now.
This is where it gets annoying. Without the boot block, or a normal GM style OS header, we don't know where the code actually starts executing. Maybe you can find some ideas in documentation for similar Bosch ME9 systems. Otherwise you're going to have to just start disassembling blocks until it starts to make sense.
Antus has some good advice. You're going to need to find fixed points to work backward from. Known ME9 structures. Known, fixed diagnostic values like part numbers. OBD is good because it's explicitly defined in standards.
There is no way around it. This is HARD. AI can only help so much because it doesn't actually know anything. It's just pattern matching and prediction at ludicrous scale. You're going to need to know some basics so you can tell it what patterns to look for, and so you can check its output.
Look on the bottom of page 95, and the charts on the following 2 pages of the reference manual. https://www.nxp.com/docs/en/data-sheet/MPC561RM.pdf
It says the user can assign the internal memory space (flash + RAM + registers) to one of eight internal ranges.
Finding those suspected R2 and R13 values are big hints. If we assume those are right, that means we're using block 2 (0x400000 to 0x7FFFFF). That would put the start of the external flash at 0x480000. It would also put the end of the RAM at 0x800000. Suddenly that R13 value makes sense. It's a relative reference from the end of the RAM. R2 doesn't make sense at the moment. Maybe it's a pointer to a data structure the OS uses frequently.
The bootloader block would start executing from the beginning of the flash. We don't have that, so you'd load the flash file into Ghidra starting at the beginning of the OS. 0x480000 + 0x20000 = 0x4A0000.
So in Ghirda, you import the file, set the language to powerPC 32 bit, big endian, default compiler. Then click options, and set the base address to 4A0000, the file offset to 0, and leave the length as default. Block name can be anything you want. I just call it flash.
Once the file is loaded, cancel the prompt that asks if you want to auto-analyze. Go to the Select menu, click Bytes, and then select all. Next hit ctrl + R to set the registers. Set R2 to and R13 to the values you already found. R2 is 0x5D0000 - 0x6010 = 0x5C9FF0 and R13 is 0x800000 - 0x10 = 0x7FFFF0.
Once the registers are set, go to 0x4A0014 and hit D to disassemble. You'll start to get blocks of code, like so. Since we have R13 set, it automatically calculates the relative reference. 0x7FFFF0 - 0x7e38 = 0x7F81B8, for example. Before you go too far, go to Window > Memory Map, and hit the green plus sign to add a block for the CALRAM. Set the start address to 0x7F8000 and the length to 0x8000. Leave everything else as default. Once you have some more code disassembled, you'll be able to click on those RAM or Flash addresses and see what other blocks of code reference them. That's when you can start naming stuff.
Code: Select all
**************************************************************
* FUNCTION *
**************************************************************
undefined FUN_004a0014()
assume r12 = 0x800000
assume r13 = 0x7ffff0
assume r2 = 0x5c9ff0
undefined <UNASSIGNED> <RETURN>
FUN_004a0014 XREF[1]: FUN_004a0c50:004a0c68(c)
004a0014 38 60 00 00 li r3,0x0
004a0018 98 6d 81 c8 stb r3,-0x7e38(r13)=>DAT_007f81b8 = ??
004a001c 38 80 00 ff li r4,0xff
004a0020 98 8d 81 c9 stb r4,-0x7e37(r13)=>DAT_007f81b9 = ??
004a0024 98 6d 81 c6 stb r3,-0x7e3a(r13)=>DAT_007f81b6 = ??
004a0028 98 8d 81 c7 stb r4,-0x7e39(r13)=>DAT_007f81b7 = ??
004a002c 4e 80 00 20 blr
Code: Select all
005f99b8 3d 60 00 80 lis r11,0x80
005f99bc 38 2b f4 50 subi r1,r11,0xbb0
005f99c0 3d a0 00 80 lis r13,0x80
005f99c4 39 ad ff f0 subi r13,r13,0x10
005f99c8 3c 40 00 5d lis r2,0x5d
005f99cc 38 42 9f f0 subi r2,r2,0x6010
Antus has some good advice. You're going to need to find fixed points to work backward from. Known ME9 structures. Known, fixed diagnostic values like part numbers. OBD is good because it's explicitly defined in standards.
There is no way around it. This is HARD. AI can only help so much because it doesn't actually know anything. It's just pattern matching and prediction at ludicrous scale. You're going to need to know some basics so you can tell it what patterns to look for, and so you can check its output.