QNX Development for CIC

rhodesman

Corporal
Mar 21, 2017
186
78
0
44
Maryland
rhodesman.com
Ride
2010 BMW E88 N54 135i
can someone explain to me what the Snoopy and Taco binaries are for or do!? It's been driving me crazy but I see them all over the CIC system and have no idea what they are.
 

dolphin78

Private
Jun 23, 2017
42
53
0
Ride
335i 2012 (F30)
Hi dolphin, is it possible to explain how you get idrive controller input?

Hi Deadknight,

iDrive controller input can be retrieved from this channel: /dev/ipc/ioc/ch4.

Here's how I'm getting it

Code:
void handle_cic_input(cic_input_data_t *data) {
    switch(data->code) {
        case CIC_ROTATE :
            //position is from 0 to 255
            unsigned rot_position = data->value;
            ...
            break;
        case CIC_CLICK :
            //check if button was pressed or released
            unsigned status = data->value;
            ...    
            break;
        case CIC_...
    }
}

...
//register CIC controller handler
init_cic_input(handle_cic_input);
...
 

Attachments

  • cicinput.zip
    1.5 KB · Views: 210

Deadknight

Lurker
Jul 29, 2017
24
14
0
After looking at @dolphin78's code i found out a pattern on input binaries.

I'm uploading the files,

they are from /dev/ipc/ioc/ch4 and /dev/ioc/ipc/ch5

/fs/usb0 is glovebox usb path

For example ch4_1 means while i'm doing "cat /dev/ioc/ipc/ch4 > /fs/usb0/ch4_1.txt" on telnet i tapped "1" button on radio controller "10" times.

After opening files with hex editor (in little endian mode), i found out there is a pattern.

Start of ch4_1 looks like this:
1d 01 16 01 01 e0 00 05 15 0c 00 0b 06 00 00 00 05 13 19 13 1d 0f 08 07 e1 fa de 1e 01 0d 01 02 05 00 06 21 0c 00 02 06 00 00 00 fa de 1f 01 0d 01 02 05 00 02 21 0c 00 02 06 00 00 00 fa de 00 01 13 00 00 d6 01 02 00 0c 00 08 00 ff 00 00 01 01 00 00 00 00 fa de 21 01 13 01

There are a two bytes that recurs
1d 01 16 01 01 e0 00 05 15 0c 00 0b 06 00 00 00 05 13 19 13 1d 0f 08 07 e1 fa de 1e 01 0d 01 02 05 00 06 21 0c 00 02 06 00 00 00 fa de 1f 01 0d 01 02 05 00 02 21 0c 00 02 06 00 00 00 fa de 20 01 13 00 00 d6 01 02 00 0c 00 08 00 ff 00 00 01 01 00 00 00 00 fa de 21 01 13 01

I believe these two bytes may dictate two things.

a) Ending of that stream
b) Starting of stream

For us it doesn't matter if its ending or beginning, we can split data from these bytes.
The byte after fa de looks like some kind of counter.
1d 01 16 01 01 e0 00 05 15 0c 00 0b 06 00 00 00 05 13 19 13 1d 0f 08 07 e1 fa de 1e 01 0d 01 02 05 00 06 21 0c 00 02 06 00 00 00 fa de 1f 01 0d 01 02 05 00 02 21 0c 00 02 06 00 00 00 fa de 20 01 13 00 00 d6 01 02 00 0c 00 08 00 ff 00 00 01 01 00 00 00 00 fa de 21 01 13 01

After counter byte there are three bytes that indicates the what is data.(i believe)
1d 01 16 01 01 e0 00 05 15 0c 00 0b 06 00 00 00 05 13 19 13 1d 0f 08 07 e1 fa de 1e 01 0d 01 02 05 00 06 21 0c 00 02 06 00 00 00 fa de 1f 01 0d 01 02 05 00 02 21 0c 00 02 06 00 00 00 fa de 20 01 13 00 00 d6 01 02 00 0c 00 08 00 ff 00 00 01 01 00 00 00 00 fa de 21 01 13 01

From @dolphin78's code we know that idrive controller uses 01 12 01(or 00)

First byte is mostly 01
Second byte is some kind of identifier that changes (12,13,14,19), i'm calling this opcode
Third one is either 01 or 00 (maybe pressed state?)

These are my findings till now.

On all tests i clicked buttons ten times, but i could not find an opcode which was exactly written ten times. (It is possible that it cant register 10 clicks). After parsing data i found out there are two candidates for input from radio again. Opcode 12 or 13 (i might be wrong).

I havent looked ch5 data for now. If you are good at tracing data you can look too.

The purpose of this research is, it may be good to double tap radio buttons (mode button for example) to run our custom application, which may wait on idle state in usb drive.

Thanks to @dolphin78 for his initial research
 

Attachments

  • ch4_1.txt
    2.7 KB · Views: 389
  • ch4_1_touch.txt
    6 KB · Views: 364
  • ch4_2.txt
    3.2 KB · Views: 379
  • ch4_4.txt
    3 KB · Views: 373
  • ch4_3.txt
    4.1 KB · Views: 368
  • ch4_8.txt
    1.9 KB · Views: 369
  • ch5_1.txt
    2.5 KB · Views: 387
Last edited:

dolphin78

Private
Jun 23, 2017
42
53
0
Ride
335i 2012 (F30)
After looking at @dolphin78's code i found out a pattern on input binaries.

I'm uploading the files,

they are from /dev/ipc/ioc/ch4 and /dev/ioc/ipc/ch5

/fs/usb0 is glovebox usb path

For example ch4_1 means while i'm doing "cat /dev/ioc/ipc/ch4 > /fs/usb0/ch4_1.txt" on telnet i tapped "1" button on radio controller "10" times.

After opening files with hex editor (in little endian mode), i found out there is a pattern.

Start of ch4_1 looks like this:
1d 01 16 01 01 e0 00 05 15 0c 00 0b 06 00 00 00 05 13 19 13 1d 0f 08 07 e1 fa de 1e 01 0d 01 02 05 00 06 21 0c 00 02 06 00 00 00 fa de 1f 01 0d 01 02 05 00 02 21 0c 00 02 06 00 00 00 fa de 00 01 13 00 00 d6 01 02 00 0c 00 08 00 ff 00 00 01 01 00 00 00 00 fa de 21 01 13 01

There are a two bytes that recurs
1d 01 16 01 01 e0 00 05 15 0c 00 0b 06 00 00 00 05 13 19 13 1d 0f 08 07 e1 fa de 1e 01 0d 01 02 05 00 06 21 0c 00 02 06 00 00 00 fa de 1f 01 0d 01 02 05 00 02 21 0c 00 02 06 00 00 00 fa de 20 01 13 00 00 d6 01 02 00 0c 00 08 00 ff 00 00 01 01 00 00 00 00 fa de 21 01 13 01

I believe these two bytes may dictate two things.

a) Ending of that stream
b) Starting of stream

For us it doesn't matter if its ending or beginning, we can split data from these bytes.
The byte after fa de looks like some kind of counter.
1d 01 16 01 01 e0 00 05 15 0c 00 0b 06 00 00 00 05 13 19 13 1d 0f 08 07 e1 fa de 1e 01 0d 01 02 05 00 06 21 0c 00 02 06 00 00 00 fa de 1f 01 0d 01 02 05 00 02 21 0c 00 02 06 00 00 00 fa de 20 01 13 00 00 d6 01 02 00 0c 00 08 00 ff 00 00 01 01 00 00 00 00 fa de 21 01 13 01

After counter byte there are three bytes that indicates the what is data.(i believe)
1d 01 16 01 01 e0 00 05 15 0c 00 0b 06 00 00 00 05 13 19 13 1d 0f 08 07 e1 fa de 1e 01 0d 01 02 05 00 06 21 0c 00 02 06 00 00 00 fa de 1f 01 0d 01 02 05 00 02 21 0c 00 02 06 00 00 00 fa de 20 01 13 00 00 d6 01 02 00 0c 00 08 00 ff 00 00 01 01 00 00 00 00 fa de 21 01 13 01

From @dolphin78's code we know that idrive controller uses 01 12 01(or 00)

First byte is mostly 01
Second byte is some kind of identifier that changes (12,13,14,19), i'm calling this opcode
Third one is either 01 or 00 (maybe pressed state?)

These are my findings till now.

On all tests i clicked buttons ten times, but i could not find an opcode which was exactly written ten times. (It is possible that it cant register 10 clicks). After parsing data i found out there are two candidates for input from radio again. Opcode 12 or 13 (i might be wrong).

I havent looked ch5 data for now. If you are good at tracing data you can look too.

The purpose of this research is, it may be good to double tap radio buttons (mode button for example) to run our custom application, which may wait on idle state in usb drive.

Thanks to @dolphin78 for his initial research
message format for buttons "1" through "8" is following:

Code:
16 01 13 00 00 15 0C 0C 02 0C 00 08 00 FF 00 00 00 00 00 00 00 00 FA DE
^                                         ^                    ^  
|                                         |-- buttons 1..8-----|  
message_id

  • first byte is message sequence number, incremental, 00->FF
  • 01 13 00 00 15 0C 0C 02 0C 00 08 00 FF is the pattern you should be looking for for 1..8 buttons
  • 8 bytes after FF are button statuses where each button is represented as separate byte:
    • 00 - button released
    • 01 - button touch sensor active (touching but not pressing)
    • 02 - button pressed
  • FA DA is end of message signature
 

dolphin78

Private
Jun 23, 2017
42
53
0
Ride
335i 2012 (F30)
Does anybody know a way to load an app every time CIC starts without a need to modify anything in flash memory?
 

dolphin78

Private
Jun 23, 2017
42
53
0
Ride
335i 2012 (F30)
btw, there is a tool called ipc-test which I found useful for reading and analyzing messages.
Put the attached script in CIC and run the following command there:
Code:
ipc-test read4.ipc
This is pretty much what I used to find all the iDrive controller messages and 1..8 buttons I posted above.
Modify the script if you need to read from another channel. It also can read data from files.

I think media button presses from steering wheel are also available (volume, mode, etc) but I don't need them as of now so I didn't bother to find the patterns. Cruise Control buttons are not available I think.

Sample output:
Code:
target:/fs/usb0> ipc-test read4.ipc
Verbose ON
Open channel ('/dev/ipc/ioc/ch4', 2)
Read from '/dev/ipc/ioc/ch4'
  Timeout: 0
  Count  : 4294967295
  00000192: 20 bytes received
  CE 01 0F 00 00 15 02 04 01 0C 00 04 00 FF 00 00
  00 01 FA DE
  00000297: 24 bytes received
  CF 01 13 00 00 05 00 02 20 0C 00 08 00 FF 00 00
  01 01 00 00 00 00 FA DE
  00000497: 17 bytes received
  D0 01 0C 00 00 C0 03 0C 27 0C 00 01 00 FF 20 FA
  DE
  00000805: 41 bytes received
  D1 02 0E 00 00 05 00 02 1F 0C 00 03 00 FF 0A 05
  0D FA DE 13 00 00 05 00 02 20 0C 00 08 00 FF 00
  00 01 01 00 00 00 00 FA DE
  00000813: 18 bytes received
  D2 01 0D 00 00 05 00 02 21 0C 00 02 00 FF 00 00
  FA DE
  00000814: 18 bytes received
  D3 01 0D 00 00 05 00 06 21 0C 00 02 00 FF 00 00
  FA DE
 

Attachments

  • read4.ipc.zip
    1.1 KB · Views: 167
Last edited:

dolphin78

Private
Jun 23, 2017
42
53
0
Ride
335i 2012 (F30)
Does anybody want to try Doom?

To run it unzip the package to a flash drive and insert it in glove box.
The script/game does not modify anything in CIC except creating /HBpersistence/NO_HMI_WATCHDOG file in the hard drive to disable CIC watchdog as otherwise CIC reboots in about 30 sec after the script suspends HmiMain (slay -h HmiMain)

Use iDrive controller to play. Do not distribute the package as is as it has doom2.wad file inside (game resources) which is copyrighted by idSoftware.

This build was tested only in F30 with 1280x480 screen, can't guarantee it'll work on others.

Controls:
Menu - menu
Controller Up/Down - go forward/back
Controller Left/Right - strafe left/right
Controller Rotate - turn
Controller Press - shoot
Back - action
Radio - run (same as Shift)
Media/Tel - change weapons
Nav - map

There are 3 cheat codes available, good luck finding them ;)
 

Attachments

  • BMWDoom_0.2.zip
    7.4 MB · Views: 267
Last edited:

doublespaces

Administrator
Oct 18, 2016
9,303
4,331
0
AZ
Ride
2009 E93 335i
That is sweet! I wonder if the heated steering wheel button can be identified using that script above.
 

dolphin78

Private
Jun 23, 2017
42
53
0
Ride
335i 2012 (F30)
That is sweet! I wonder if the heated steering wheel button can be identified using that script above.
I doubt it's available from ch4. My understanding is ch4 is a gate to MOST bus while heated wheel button is not connected there.

There's a lot of data coming from ch5 but I don't know what that is. Could be CAN bus but I'm not familiar with the message format
 
  • Informative
Reactions: doublespaces

doublespaces

Administrator
Oct 18, 2016
9,303
4,331
0
AZ
Ride
2009 E93 335i
Okay, this has evolved quite far from the original connected drive starting point. Would anyone more versed than myself be interested in making a simple thread summing some of the more public facing content of this CIC development? Should help drive some more contributors here to the private area.
 

dolphin78

Private
Jun 23, 2017
42
53
0
Ride
335i 2012 (F30)
Does anybody want to try Doom?

To run it unzip the package to a flash drive and insert it in glove box.
The script/game does not modify anything in CIC except creating /HBpersistence/NO_HMI_WATCHDOG file in the hard drive to disable CIC watchdog as otherwise CIC reboots in about 30 sec after the script suspends HmiMain (slay -h HmiMain)

Use iDrive controller to play. Do not distribute the package as is as it has doom2.wad file inside (game resources) which is copyrighted by idSoftware.

This build was tested only in F30 with 1280x480 screen, can't guarantee it'll work on others.

Controls:
Menu - menu
Controller Up/Down - go forward/back
Controller Left/Right - strafe left/right
Controller Rotate - turn
Controller Press - shoot
Back - action
Radio - run (same as Shift)
Media/Tel - change weapons
Nav - map

There are 3 cheat codes available, good luck finding them ;)
Nobody's interested?
 

Xer0449

Corporal
Jan 30, 2017
174
59
0
Does anybody know a way to load an app every time CIC starts without a need to modify anything in flash memory?

I posted the default boot order in the info dump thread IIRC - I'm confident we can 'autorun' via optical or flash media with little effort.

...and you bet your ass i'll try doom :p IDKFA/IDNOCLIP/IDKFA
 

Xer0449

Corporal
Jan 30, 2017
174
59
0
Also, I love that every time I check this thread there's more and more fantastic progress in reverse engineering. This kind of stuff gives me such a nerd boner.

I'm just a *nix admin that loves attempting to reverse engineer things in his spare time - but some of you guys are little more, uh, leet :)
 

toxx

Lurker
Sep 17, 2017
12
5
0
Dubai
Ride
BMW E60 530i LCI
Hi
So i've installed my DEV environment for QNX and compiled the script below as "enc" and ran it in QNX X86 test vm

I created one file with simple command : "cd /tmp ; ls" and saved it as "Test"

then i ran command: enc < test > test.sh

When i run test.sh i get something weird and not the contents of encrypted commands.

I studied the code and it seems that it gets the char as input, encodes it and returns it back encoded, so that's why i used the above command to input a file.

Any help would be appreciated.

PS: what is the encrypt/decrypt seed, parameter 'seed = 0x...' ?

Code:
#include <stdio.h>
 
unsigned int seed = 0x001be3ac;
 
unsigned int prng_rand() {
unsigned int r1, r3, r0;
 
r0 = seed;
r1 = (seed >> 1) | (seed << 31);
r3 = ((r1 >> 16) & 0xFF) + r1;
r1 = ((r3 >> 8) & 0xFF) << 16;
r3 -= r1;
seed = r3;
 
return r0;
}
 
int main(int argc, char *argv[]) {
int c;
 
prng_rand();
 
c = getchar();
while (c != EOF) {
c ^= (prng_rand() & 0xFF);
putchar(c);
c = getchar();
}
}
 
Last edited:

dolphin78

Private
Jun 23, 2017
42
53
0
Ride
335i 2012 (F30)
Hi
So i've installed my DEV environment for QNX and compiled the script below as "enc" and ran it in QNX X86 test vm

I created one file with simple command : "cd /tmp ; ls" and saved it as "Test"

then i ran command: enc < test > test.sh

When i run test.sh i get something weird and not the contents of encrypted commands.

I studied the code and it seems that it gets the char as input, encodes it and returns it back encoded, so that's why i used the above command to input a file.

Any help would be appreciated.

PS: what is the encrypt/decrypt seed, parameter 'seed = 0x...' ?

Code:
#include <stdio.h>
 
unsigned int seed = 0x001be3ac;
 
unsigned int prng_rand() {
unsigned int r1, r3, r0;
 
r0 = seed;
r1 = (seed >> 1) | (seed << 31);
r3 = ((r1 >> 16) & 0xFF) + r1;
r1 = ((r3 >> 8) & 0xFF) << 16;
r3 -= r1;
seed = r3;
 
return r0;
}
 
int main(int argc, char *argv[]) {
int c;
 
prng_rand();
 
c = getchar();
while (c != EOF) {
c ^= (prng_rand() & 0xFF);
putchar(c);
c = getchar();
}
}
  1. did you test your script in QNX before encoding it?
  2. CIC will not understand encoded files if you run them manually. Encoding is need only for autorun file (copie_scr.sh)
  3. you don't need QNX dev environment to encode/decode files. Any platform/OS/C compiler can be used
  4. seed is the encryption/decryption key used by CIC (same key is used by Audi MMI 3G). you must not change it if you want CIC to be able to decrypt and run your copie_scr.sh script.
  5. I attached a generic encoded copie_scr.sh script in this thread which runs run.sh from flash drive. you can put your code into run.sh instead of creating your custom copie_scr.sh. This way you don't have to deal with encoding, just put copie_scr.sh and run.sh in flash drive
 

toxx

Lurker
Sep 17, 2017
12
5
0
Dubai
Ride
BMW E60 530i LCI
  1. did you test your script in QNX before encoding it?
  2. CIC will not understand encoded files if you run them manually. Encoding is need only for autorun file (copie_scr.sh)
  3. you don't need QNX dev environment to encode/decode files. Any platform/OS/C compiler can be used
  4. seed is the encryption/decryption key used by CIC (same key is used by Audi MMI 3G). you must not change it if you want CIC to be able to decrypt and run your copie_scr.sh script.
  5. I attached a generic encoded copie_scr.sh script in this thread which runs run.sh from flash drive. you can put your code into run.sh instead of creating your custom copie_scr.sh. This way you don't have to deal with encoding, just put copie_scr.sh and run.sh in flash drive

Thanks for the answers and for the file, actually i ran the code via Target in QNX development workspace, and nothing happened (of course, because this code doesn't output anything), but running manually on QNX development doesn't work.

So from what i understand, the CIC shell interpreter "knows" that the file is encryped with the particular seed and runs the contents.

You guys are very knowledgeable, i would like to study about RTTI and how ConnectedDrive works, someone here started a thread on that, maybe we can build our own stuff. Didn't find many whitepapers about those technologies.
 
  • Like
Reactions: rhodesman