Help Getting Started With Ghidra For MPC562 ME9.6.1 VE E77 LY7
-
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
Part 1
Here's a follow-along-at-home example, using Lucas's system calibration file (see attachment). I picked this one because it's small and only has one checksum range. The speedo cal is smaller, but doesn't have a Bosch checksum.
I'm going to use the addresses relative to this small file. Add 0x5ecf28 to any of them to get the addresses as they'd appear in the live ECM memory map.
I'm using HxD because it's free and simple enough to use. https://mh-nexus.de/en/hxd/
Open the file in HxD, and set up a custom checksum routine. Analysis > checksums > custom checksum button. Result width 16, addend 16, big endian.
First the GM checksum. This is a 2's complement sum
Select everything except the first 2 bytes. Edit > select block. Start offset 2, length 1FEE.
Go to Analysis > checksums. Select custom checksum from the list, make sure the button for 'selected data' is ticked, and click OK. You should see the result appear in the bottom of the main window.
Open windows calculator, set the mode to programmer, type in the checksum result, and hit the +/- button. The lowest two bytes should match the your GM checksum.
Now the Bosch checksum. This is a 1's complement sum
The address range and sum pair are located in this file at offset 0x18.
00 5E CF 28 <-- start
00 5E EF 17 <-- end
0C EC 00 00 <-- sum
F3 13 FF FF <-- complement
Go back to your custom checksum setup and change the result bit width from 16 to 32. Select the entire file and then run the checksum again. It should come out to 0CEC0000. Go into windows calc again, do +/-, but this time subtract 1 from the result. 0CEC0000 +/- = F3140000 - 1 = F313FFFF. This matches the Bosch sums shown above.
Here's a follow-along-at-home example, using Lucas's system calibration file (see attachment). I picked this one because it's small and only has one checksum range. The speedo cal is smaller, but doesn't have a Bosch checksum.
I'm going to use the addresses relative to this small file. Add 0x5ecf28 to any of them to get the addresses as they'd appear in the live ECM memory map.
I'm using HxD because it's free and simple enough to use. https://mh-nexus.de/en/hxd/
Open the file in HxD, and set up a custom checksum routine. Analysis > checksums > custom checksum button. Result width 16, addend 16, big endian.
First the GM checksum. This is a 2's complement sum
Select everything except the first 2 bytes. Edit > select block. Start offset 2, length 1FEE.
Go to Analysis > checksums. Select custom checksum from the list, make sure the button for 'selected data' is ticked, and click OK. You should see the result appear in the bottom of the main window.
Open windows calculator, set the mode to programmer, type in the checksum result, and hit the +/- button. The lowest two bytes should match the your GM checksum.
Now the Bosch checksum. This is a 1's complement sum
The address range and sum pair are located in this file at offset 0x18.
00 5E CF 28 <-- start
00 5E EF 17 <-- end
0C EC 00 00 <-- sum
F3 13 FF FF <-- complement
Go back to your custom checksum setup and change the result bit width from 16 to 32. Select the entire file and then run the checksum again. It should come out to 0CEC0000. Go into windows calc again, do +/-, but this time subtract 1 from the result. 0CEC0000 +/- = F3140000 - 1 = F313FFFF. This matches the Bosch sums shown above.
You do not have the required permissions to view the files attached to this post.
-
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
Part 2
Now lets change some data and update the sums manually. These steps have to be done very specifically in this order.
Save a new copy of the file so your original doesn't get damaged.
Zero out the GM sum, the Bosch sum, and the Bosch complement. (Two of the digits in this example were already zero, so that's why they're not highlighted in red)
Change your data. I'm just going to change the part number to 92259999. Doesn't really matter if you change one byte or a thousand. The logic is the same.
I'm going to say up from that this is some kind of mathematical sorcery that I simply cannot understand.
Select the entire file and generate a 32 bit sum and its 2's complement. You should get the following pair: 0CE980D9 / F3167F26
Now here's where it starts to get weird. Add each 16-bit chunk of the sum and the complement to the sum.
0CE980D9 + 0CE9 + 80D9 + F316 + 7F26 = 0CEB80D7. The complement is F3147F28. Paste those into your file and then re-run the select all, checksum procedure. It should check out.
Next update the GM sum. Select all but the first 2, rerun the sum, get the 1s complement and plug it into the first two bytes of the file. You should get a sum of 80D7 with a complement of 7F29.
Here's the brain melter. Add 7F29 to the Bosch sum and update the Bosch 2s complement again.
0CEB80D7 + 7F29 = 0CEC0000 (F313FFFF)
We changed 4 bytes of data, changed the GM checksum, and somehow the Bosch checksum is back to what we started with. WTF.
I didn't believe my results, so I went down to the bottom and added some arbitrary new data and recalculated again. The sum is actually different now, but it all still works. Somehow.
This is a pretty simple example to illustrate the concept. I haven't tried it with anything that has additional overlapping sum ranges. Like kur4o said, it can get pretty complicated. But I think the logic is sound. I'd love to hear what you guys think.
Now lets change some data and update the sums manually. These steps have to be done very specifically in this order.
Save a new copy of the file so your original doesn't get damaged.
Zero out the GM sum, the Bosch sum, and the Bosch complement. (Two of the digits in this example were already zero, so that's why they're not highlighted in red)
Change your data. I'm just going to change the part number to 92259999. Doesn't really matter if you change one byte or a thousand. The logic is the same.
I'm going to say up from that this is some kind of mathematical sorcery that I simply cannot understand.
Select the entire file and generate a 32 bit sum and its 2's complement. You should get the following pair: 0CE980D9 / F3167F26
Now here's where it starts to get weird. Add each 16-bit chunk of the sum and the complement to the sum.
0CE980D9 + 0CE9 + 80D9 + F316 + 7F26 = 0CEB80D7. The complement is F3147F28. Paste those into your file and then re-run the select all, checksum procedure. It should check out.
Next update the GM sum. Select all but the first 2, rerun the sum, get the 1s complement and plug it into the first two bytes of the file. You should get a sum of 80D7 with a complement of 7F29.
Here's the brain melter. Add 7F29 to the Bosch sum and update the Bosch 2s complement again.
0CEB80D7 + 7F29 = 0CEC0000 (F313FFFF)
We changed 4 bytes of data, changed the GM checksum, and somehow the Bosch checksum is back to what we started with. WTF.
I didn't believe my results, so I went down to the bottom and added some arbitrary new data and recalculated again. The sum is actually different now, but it all still works. Somehow.
This is a pretty simple example to illustrate the concept. I haven't tried it with anything that has additional overlapping sum ranges. Like kur4o said, it can get pretty complicated. But I think the logic is sound. I'd love to hear what you guys think.
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
Hey sorry man I’ve been so busy at work and haven’t had a chance to have a proper look at all this, hopefully I can tomorrow night but I really appreciate the explanation and effort 
-
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 i finally followed along with what you posted, and i believe i understand it all, it makes sense, and i get what you were saying now about how the checksum itself is included in the calculations, seems tricky at first but once you break it down its not too bad.
so is that how all bosch checksums are calculated, or do some have different ways to calculate them?
the gm checksums seem like a walk in the park too which is good
so from my understanding for the bosch checksum, once a change in the file has been made, (ill just use the cal range you provided for this example) youll zero out the checksums for that area (gm and bosch checksums) and then do a 32 bit checksum calculation, where you'll use the result and its complement to do another calculation, where youll add the sum, and then add the sum and complement 4 bytes at a time where youll get your final sum / complement, or in this case youll have to readjust it for the gm checksum too where youll add the gm checksum result to the bosch sum, and change the complement accordingly.
only thing i dont get fully, is where you say add the 1's complement or 2's complement, are you talking about adding 1 / 2 to the complement?
but other then that i think i understand it
so is that how all bosch checksums are calculated, or do some have different ways to calculate them?
the gm checksums seem like a walk in the park too which is good
so from my understanding for the bosch checksum, once a change in the file has been made, (ill just use the cal range you provided for this example) youll zero out the checksums for that area (gm and bosch checksums) and then do a 32 bit checksum calculation, where you'll use the result and its complement to do another calculation, where youll add the sum, and then add the sum and complement 4 bytes at a time where youll get your final sum / complement, or in this case youll have to readjust it for the gm checksum too where youll add the gm checksum result to the bosch sum, and change the complement accordingly.
only thing i dont get fully, is where you say add the 1's complement or 2's complement, are you talking about adding 1 / 2 to the complement?
but other then that i think i understand it
-
kur4o
- Posts: 1145
- Joined: Sun Apr 10, 2016 11:20 am
Re: Help Getting Started With Ghidra For MPC562 ME9.6.1 VE E77 LY7
Once you get the basic, you can use this to speed things or get other testing.
Patcher->open bin->checksum research
Patcher->open bin->checksum research
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
Any updates at all gatecrasher?
I’ve been looking into canbus reverse engineering and using Claude code aswell to help with that while I wait for any updates
I’ve been looking into canbus reverse engineering and using Claude code aswell to help with that while I wait for any updates
-
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 im trying to have a crack at defining things like rpm, ect load etc, ive imported every map from my xdf and have xrefs for most of them, but im trying to figure out the best way to go about it.
i saw gatecrasher posted the address of the diagnostic pids table, and it seems to make sense so far, there laid out for example like this "00 05 00 00" for the pid, and then the pointer is "00 08 36 ec" and it goes on for a while, but the pointers arent very helpful and dont point to any functions, and they only have maybe 1-3 xrefs, which some are in the cal area. im guessing there pointing to the ram location of that specific pid.
are they not going to be very helpful as there a diagnostic pid? or am i on the completly wrong track?
ive tried using xrefs from maps to figure it out but i cant get very far
any help is very appriciated
i saw gatecrasher posted the address of the diagnostic pids table, and it seems to make sense so far, there laid out for example like this "00 05 00 00" for the pid, and then the pointer is "00 08 36 ec" and it goes on for a while, but the pointers arent very helpful and dont point to any functions, and they only have maybe 1-3 xrefs, which some are in the cal area. im guessing there pointing to the ram location of that specific pid.
are they not going to be very helpful as there a diagnostic pid? or am i on the completly wrong track?
ive tried using xrefs from maps to figure it out but i cant get very far
any help is very appriciated
You do not have the required permissions to view the files attached to this post.
-
antus
- Site Admin
- Posts: 10012
- 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
I'd go the other way. Tell an AI which PID you want to know the RAM address for, and watch it work backwards from the comms handler back to the message builder back to where in RAM the value originally came from. That should get you both the answer, and something can follow to see how it did it.
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
yeah i was a bit skeptical about ai, but after using claude for a while, it is REALLY good. ive mainly been using it to create xdf's for other os's using my xdf, and it works so good, and any maps its unsure off, it just creates a 2nd xdf for me to manually go through, which most of the time there still right anyway. which is super helpful as im thinking about selling tunes and having an xdf for every OS is very handy.
im seeing how far i can push it, ive got a supermap pack from a e55 saab, which is what i used to define all the maps in my xdf, and i asked it to find as many maps as it can for a vz commodore (e55) and its found over 1000, and every single one looks right, i told it to only add maps it KNOWS are right.
but enough about my ai rant haha, i did try using claude to find rpm using the xrefs from the maps, i spent hours, but i didnt seem to get anywhere. i was sending it screenshots of areas and it was writing scripts.
is there some sort of way i can hook claude up to ghidra, or a faster way that it can analyse everything other then me sending screenshots? ive sent it the bin too but obviously it cant do what ghidra does (not by the looks anyway)
but yes i definelty think ai is the way to go, its already saved me 1000's of hours
im seeing how far i can push it, ive got a supermap pack from a e55 saab, which is what i used to define all the maps in my xdf, and i asked it to find as many maps as it can for a vz commodore (e55) and its found over 1000, and every single one looks right, i told it to only add maps it KNOWS are right.
but enough about my ai rant haha, i did try using claude to find rpm using the xrefs from the maps, i spent hours, but i didnt seem to get anywhere. i was sending it screenshots of areas and it was writing scripts.
is there some sort of way i can hook claude up to ghidra, or a faster way that it can analyse everything other then me sending screenshots? ive sent it the bin too but obviously it cant do what ghidra does (not by the looks anyway)
but yes i definelty think ai is the way to go, its already saved me 1000's of hours
-
antus
- Site Admin
- Posts: 10012
- 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
Yes, look in to getting an MCP server setup, and run claude in some kind of an environment that can talk to an MCP server. Then give it enough information about what it is looking at, and how to approach it, and how to connect to the MCP and let it rip.
I use vs code with claude extension. Sometimes I don't even open a folder, and just prompt it to start doing things and giving it full paths.
Having said that, I am an IDA user, and I found MCP was too slow, and it could drive the idat (text mode version) quicker and better to interact directly for reverse engineering. Once you have it running in vs code or some other environment as a plugin that can access your machine (and if you have tested and you decide you can trust it with security off, because you have to click yes a massive amount of times otherwise) then you can tell it what you have and ask it about MCP servers or if there is a quicker way and ask for help getting that setup, or as it to set it up. I'd suggest you do watch it and click yes for a while, then decide where to go from there.
This is an example of that request against 12617175 which is an E38 OS. I've attached the bin, but it should be possible to achieve the same with a similar environment and other bins.
This used 13% of the 5 hour quota of the pro plan and took a couple of minutes to run, with opus version 5 model (oooh new toys, it was 4.8 last time I used it).
Prompt:
Results:
Then I say "rewrite the summary in phpbb3 format for a forum post" then I say "rewrite the summary without extensions in phpbb3 format for a cut paste forum post" because it used extensions not present here, then....
E38 (2008 Impala, OSID 12617175) — CAN handler, SAE Mode 01, and the RPM variable
Target: 2008 E38 12617175.bin (Service No 12612384, Part No 12617174), analysed in IDA Pro 9.2 text mode (idat.exe -A -S) on a scratch copy of the IDB. 7510 functions, PPC.
1. CAN hardware and the CAN handler
The processor is a Freescale MPC5xx (PowerPC) with the internal register block at 0x300000. Two TouCAN modules are present. The register offsets match the MPC5xx TouCAN map exactly:
Which places the modules here:
The CAN interrupt handler is sub_1AA14 @ 0x0001AA14 (0x5D8 bytes). Evidence:
2. SAE Mode 01 path
The diagnostic service dispatcher is gmlan_service_dispatcher @ 0x13EECC, driven by a 27-entry table at 0x13F00C, 6 bytes per entry, binary-searched by sub_13EE58:
Service 0x01 (SAE Mode 01, ShowCurrentData) maps to sub_13858C @ 0x0013858C. It writes response SID 0x41 and builds the reply at 0x243128.
That handler calls:
This single table holds both the legislated SAE PIDs (0x00 - 0x52) and the GM extended PIDs (0x1121 - 0x1369).
PID 0x0C (Engine RPM) is table index 12 at 0x0013AEB6:
It is advertised as supported — the Mode 01 PID $00 bitmap is BE 3F B8 13, and byte_1C9AFC index 1 = 0x3F with mask 0x10 set.
3. Where RPM is loaded from
sub_BE96C @ 0x000BE96C:
RPM is loaded from 0x00241772 — a 16-bit variable, gated by the engine-running / valid flag at 0x00241760.
Scaling. sub_14E18(raw, 4, 3) computes (raw * 4) >> 3 = raw / 2, clamped to 0xFFFF. SAE J1979 defines PID 0x0C as ((A*256)+B)/4, i.e. the transmitted value is RPM x 4. Therefore:
The upstream raw engine-speed period comes from sub_3A4E8 ((capture << 7) / 125, clamped at 3,000,000) and is kept at 0x241764 / 0x241768. 0x241772 is the derived reciprocal (K / period) used for reporting.
Other readers of 0x241772: sub_BFBF0, sub_BFCA0, sub_BFE38 (x2), sub_C01EC.
Two caveats for anyone following along
Then to close it out I prompt "add any learnings to the database, you may modify it. define a segment for ram and add any x-refs." just to keep my database up to date and tidy for next time since I've already spent tokens doing the work.
Standard disclaimer, it's all AI and there could be errors. But its also probably mostly correct, and minor errors are not a problem for the most part so long as you know there may be some and you ask future AIs to confirm anything critical for new tasks if you get a failure and something seems off. Half the trick is watching it, and flagging it if something looks wrong or raises suspicions.
I use vs code with claude extension. Sometimes I don't even open a folder, and just prompt it to start doing things and giving it full paths.
Having said that, I am an IDA user, and I found MCP was too slow, and it could drive the idat (text mode version) quicker and better to interact directly for reverse engineering. Once you have it running in vs code or some other environment as a plugin that can access your machine (and if you have tested and you decide you can trust it with security off, because you have to click yes a massive amount of times otherwise) then you can tell it what you have and ask it about MCP servers or if there is a quicker way and ask for help getting that setup, or as it to set it up. I'd suggest you do watch it and click yes for a while, then decide where to go from there.
This is an example of that request against 12617175 which is an E38 OS. I've attached the bin, but it should be possible to achieve the same with a similar environment and other bins.
This used 13% of the 5 hour quota of the pro plan and took a couple of minutes to run, with opus version 5 model (oooh new toys, it was 4.8 last time I used it).
Prompt:
Code: Select all
use ida pro text mode, to investigate "2008 E38 12617175.bin.i64"
I want you to find the can handler, and the SAE pid for RPM, and identify what memory address RPM is loaded from.
Code: Select all
<snip>
run IDA text mode recon script
<snip>
Good — PPC (MPC5xx), 7510 functions, with some prior GMLAN naming. Now let me locate the TouCAN CAN modules and OBD identifiers.
<snip>
TouCAN modules located at 0x307080 (A) and 0x307480 (B). Now let me examine the CAN driver functions and the OBD service dispatcher.
<snip>
Found the diagnostic service table. Service 0x01 (SAE Mode 01) → handler at 0x13858C. Let me decompile it.
<snip>
Mode 01 confirmed (response SID 0x41). The PID data-getter is sub_13A950. Let me decompile it and sub_1381EC (PID-supported check).
<snip>
Decompile PID dispatcher
<snip>
PID table found at 0x13AE56 — 8-byte entries {u16 pid, u32 handler, u8 len, u8 ?}. Let me dump it and find PID 0x0C.
<snip>
Found it. PID 0x0C handler is sub_BE96C, reading RAM at 0x241772. Let me confirm the scaling and trace all accesses to that address.
<snip>
Scan effective addresses for RPM variable
<snip>
Scaling confirmed: (raw × 4) >> 3 = raw/2, and SAE PID 0x0C = RPM×4 ⇒ raw is RPM×8. Let me verify the writer and pin down the CAN ISR wiring.
<snip>
Find ISR vector wiring and scaling function
<snip>
Find ISR pointer table entry
<snip>
One last check — confirm PID 0x0C is advertised in the supported-PID bitmap, and grab the ISR's MB dispatch detail.
<snip>
Check supported PID bitmap
<snip>
Investigation complete. I worked on a copy of the IDB in the scratchpad (e38.i64) via idat.exe -A -S, so your original .i64 is untouched.
<snip>
E38 (2008 Impala, OSID 12617175) — CAN handler, SAE Mode 01, and the RPM variable
Target: 2008 E38 12617175.bin (Service No 12612384, Part No 12617174), analysed in IDA Pro 9.2 text mode (idat.exe -A -S) on a scratch copy of the IDB. 7510 functions, PPC.
1. CAN hardware and the CAN handler
The processor is a Freescale MPC5xx (PowerPC) with the internal register block at 0x300000. Two TouCAN modules are present. The register offsets match the MPC5xx TouCAN map exactly:
Code: Select all
+0x00 CANMCR +0x10 RXGMASK
+0x04 CANTCR +0x14 RX14MASK
+0x06 CANICR +0x18 RX15MASK
+0x08 CANCTRL0 +0x20 ESTAT
+0x09 CANCTRL1 +0x22 IMASK
+0x0A PRESDIV/CTRL2 +0x24 IFLAG
+0x26 RX/TX error counters
Code: Select all
Module Registers Message buffers
-------- --------- -----------------------
TouCAN A 0x307080 0x307100 - 0x3071FF (MB0-15)
TouCAN B 0x307480 0x307500 - 0x3075FF (MB0-15)
- Full first-level ISR prologue/epilogue — mfsrr0 / mfsrr1 / mfctr / mfxer / mfcr saved on entry, mtsrr1 / mtsrr0 restored on exit.
- Zero call xrefs. It is registered into the external-interrupt dispatch at runtime via sub_1C10 (the vector table entry at offset 0x28 = external interrupt, 8-byte vector spacing), so no static pointer to it exists anywhere in the image.
- It reads both IFLAG registers and packs them into a single 32-bit word: (IFLAG_B@0x3074A4 << 16) | IFLAG_A@0x3070A4, then loops over the set bits clearing each flag. This gives a unified message-buffer index space of 0-15 = CAN A, 16-31 = CAN B.
- MB addressing is 0x307100 + 16*idx for A and 0x307400 + 16*idx for B. The latter is a virtual base — with idx 16-31 it lands on 0x307500 onward, which is why you see the odd-looking 0x307401 / 0x307406 constants in the disassembly.
- It masks/unmasks via IMASK (0x3070A2 / 0x3074A2), tests bit 7 of the MB control byte, and dispatches per buffer.
Code: Select all
sub_1A3C4 init - MCR / CTRL / acceptance masks, both modules
sub_1A5E4 message buffer configure
sub_1A91C message buffer read
sub_1A84C (mode/enable helper)
sub_57C1C mode change, references CAN ID 0x7E0
sub_201AC periodic CAN task -> calls sub_57DE0 and sub_59A58
The diagnostic service dispatcher is gmlan_service_dispatcher @ 0x13EECC, driven by a 27-entry table at 0x13F00C, 6 bytes per entry, binary-searched by sub_13EE58:
Code: Select all
struct { u8 service_id; u8 pad; u32 handler; };
That handler calls:
- sub_1381EC — supported-PID bitmap check, bitmaps at 0x1C9AFC
- sub_13A950 — PID data getter
Code: Select all
struct { u16 pid; u32 handler; u8 len; u8 flags; };
PID 0x0C (Engine RPM) is table index 12 at 0x0013AEB6:
Code: Select all
pid = 000C handler = 000BE96C len = 02
3. Where RPM is loaded from
sub_BE96C @ 0x000BE96C:
Code: Select all
000BE980 lis r12, 0x24
000BE984 lbz r12, 0x1760(r12) ; validity flag @ 0x241760
000BE988 cmpwi r12, 1
000BE98C bne loc_BE99C
000BE990 lis r3, 0x24
000BE994 lhz r3, 0x1772(r3) ; <-- RPM read from 0x00241772
000BE998 b loc_BE9A0
000BE99C li r3, 0 ; not running -> report 0
000BE9A0 li r4, 4
000BE9A4 li r5, 3
000BE9A8 bl sub_14E18 ; (x * 4) >> 3, clamped to 0xFFFF
...
000BE9C4 b sub_14E28C ; store big-endian u16 into response
Scaling. sub_14E18(raw, 4, 3) computes (raw * 4) >> 3 = raw / 2, clamped to 0xFFFF. SAE J1979 defines PID 0x0C as ((A*256)+B)/4, i.e. the transmitted value is RPM x 4. Therefore:
Producers of 0x241772. These carry no IDA xrefs (see the caveat below), so they were found by emulating lis/addi base-register formation across all 7510 functions:0x241772 holds RPM x 8 (0.125 RPM/bit), range 0 - 8191 RPM.
Code: Select all
Address Function Action
--------- --------- ---------------------------------------------------
0x000C1AE8 sub_C1A74 Normal running update:
0x241772 = [0x2417C4] / period, flag 0x241760 = 1
0x000C21D4 sub_C21CC Reset/init: 0x241772 = 0, flag = 0
0x000C2280 sub_C220C Stall / not-running path, flag = 0
0x000C22A4 sub_C228C Restores from word_3FD9F6, flag = 0
Other readers of 0x241772: sub_BFBF0, sub_BFCA0, sub_BFE38 (x2), sub_C01EC.
Two caveats for anyone following along
- The ROM segment maps 1:1 to file offsets, so every 0x0 - 0x1FFFFF address above is also a .bin offset.
- The RAM region 0x200000 - 0x2FBFFF — which contains 0x241772 and the diagnostic response buffer at 0x243128 — has no segment defined in the stock IDB. That is why Hex-Rays renders these as MEMORY[0x241772] and why IDA generates no cross-references for them. Creating a segment over that range makes this area vastly easier to work with.
Then to close it out I prompt "add any learnings to the database, you may modify it. define a segment for ram and add any x-refs." just to keep my database up to date and tidy for next time since I've already spent tokens doing the work.
Standard disclaimer, it's all AI and there could be errors. But its also probably mostly correct, and minor errors are not a problem for the most part so long as you know there may be some and you ask future AIs to confirm anything critical for new tasks if you get a failure and something seems off. Half the trick is watching it, and flagging it if something looks wrong or raises suspicions.
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