Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Hardcoding data into unused channels? #19

Open
chupocro opened this issue Mar 15, 2024 · 2 comments
Open

Hardcoding data into unused channels? #19

chupocro opened this issue Mar 15, 2024 · 2 comments

Comments

@chupocro
Copy link

Hi,

this is awesome!! :-) It would be very interesting if you would document the process of how exactly you made the patch and if you would explain the syntax used in .ld and makefile. I am assuming you used IDA or Ghidra to reverse the firmware and when you located the function for processing the incoming data and the address of the call of the function you named prepare_ppm_buf(buf) then you replaced the call address with the address of your code from inject_rssi.c. From the code I can see you located the address of the get_signal_strength() too and deciphered how the value should be calculated. Of course, for writing the code you had to decipher the prepare_ppm_buf(buf)'s function signature as well.

Seems as you located the free space at 0x0800392A where you assembled the code to be injected and you patched the CRC check with nop.

I wonder how much free space is at 0x0800392A and if it would be possible to hardcode the bytes to a few unused channels so that data could be read via iBUS.

For example, I'd like to hardcode bytes e.g. 0xc9 0xa8 to channels 10 and 11 to be able to identify the receiver by reading the iBUS data via a microcontroller.

@chupocro chupocro changed the title Hardcoding data in unused channels? Hardcoding data into unused channels? Mar 15, 2024
@Cleric-K
Copy link
Owner

Hi,

yes, everything you describe is exactly how things work. I have used IDA. I didn't have any experience with such things prior to this project but I contacted qba667 (https://github.com/qba667/FlySkyI6) who gave me some very valuable directions. The structure of the makefile and the .ld script are inspired by his work.

To be honest, I don't remember most of the details now. In general, when code is compiled it produces intermediate object code .o, where the machine code is present but all pointers are present only as placeholders. Their exact values are calculated and replaced at link time.

The idea is that the original .bin file is used as the 'background' of the final linked file. This is the .org_fw section. Other sections are deliberately set to point inside the addresses occupied by the .org_fw section.

In the linked ELF file the sections are still separate chunks of data. But when ELF is converted into plain binary, you can imagine that the process goes section by section. It first takes .org_fw and lays down the new .bin file, which is still an exact copy of the original. Then it takes the next section, say .text. As you have noticed, the address of this section is indeed placed after all the bytes of the original firmware. So you have as much space as you want there (limited only by the remaining flash). When this section is processed it is appended after the original bin.

Then we have sections like .hook_rssi. If you look at the assembly .s file, you'll see that the code there is compiled into the corresponding sections. These exist as separate chunks in the ELF file. But when we convert to bin, the contents of the section is taken and placed at its address as specified in the .ld script. This now has the effect that some of the .org_fw section (the original .bin) is overwritten because the address is within its bounds. This is more or less the logic of the process. Effectively, through the .ld script we tell where the altered code has to be placed over the original .bin.

To hardcode the bytes you need to simply edit the inject function. After the RSSI you can add lines like:

buf[9] = 0xc9a8; // or 0xa8c9 I'm not sure in what endianness you need the channels
buf[10] = 0xc9a8;

or something like that. Remember that the indices of the buf array start from 0, so channel 1 is buf[0], channel 2 is buf[1], etc.

All you need is to get the cross-compiler from https://developer.arm.com/downloads/-/arm-gnu-toolchain-downloads
You need the arm-none-eabi variant.

@chupocro
Copy link
Author

You mean, you didn't have any experience with patching .bin with makefile and ld or you didn't have experience with reverse engineering the firmware? I am assuming you had quite a bit of experience with reverse engineering from before because what you did is quite complex and qba667 helped you only to make the patch script.

I wasn't even aware it is possible to insert combination of compiled C code and assembly code into the existing .bin using makefile and ld. I was searching quite a lot to find more about how that could be done but couldn't find not only one mention of such a method. Do you know if he developed the script himself or is there some document where these scripts are explained in details?

Thank you very much for your help! I'll try to compile the version with the hardcoded data in the unused channels.

I am looking at the FlySkyI6 repository from the link you've sent, does it mean he wrote the complete alternative firmware for the transmitter from scratch? It would be nice if someone wrote the complete firmware from scratch for the receiver too.

How complicated do you think it would be to change the baudrate of iBUS communication in the receiver's firmware? Maybe it is a matter of changing only the value of one register? It might be helpful to decrease the baudrate for using with software serial on AVR microcontrollers because 115200 is too fast for reliable software serial with ATmega328.

On the other hand, after decreasing the baudrate the new communication might take place before the last data could be sent.

I am waiting for FS-iA6B and FS-i6 to arrive and then I will try to compile and flash the new firmware. I hope the receiver wouldn't be using some unknown microcontroller.

Thank you again very much!

Best regards

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants