47 78 BX PC 46 C0 NOP E5 5E C0 01 LDRB R12, [LR, #-1] E1 53 00 0C CMP R3, R12 37 DE 30 03 LDRCCB R3, [LR, R3] 27 DE 30 0C LDRCSB R3, [LR, R12] E0 8E C0 83 ADD R12, LR, R3, LSL#1 E1 2F FF 1C BX R12
So, let's start my new blog with a small riddle ;-)
I'll soon provide a sample calling this method and later a full explanation.
Update 1:
The function is called from thumb mode like this
0xB8: FX XX FX XX BL func 0xBC: 06 04 16 1B+ DCB 6, 4, 0x16, 0x1B, 0x20, 0x57, 0x5C, 0x61
Update 2:
Since I'm frustrated with DisplayLink and Intel... let's use the time to explain.
BX PC changes the mode from thumb to arm. Inside LR we have the next address that should be executed on a return. This is still in thumb mode (which is offset+1). So the LDRB will load 0x06 to R12. What is not visible, is that R3 is loaded with a value. In the next instruction this value is compared with the currently loaded byte. LDRCCB (UAL instruction) will load LR + R3 to R3 if R3 is lower than R12. Else it will use the R12 value. At the end it will jump to R3 << 1 offset from LR. So we have a jumptable (switch). The first byte after the call (BL) tells us the entries. The next one is the default branch. The left shift by two is done so it will always go to valid thumb mode instructions again.
If you have a valid IDA license you can follow the following instrcutions :-)
- Rename the switch function to switch or whatever
- Right click and set it will not return. This prevents parsing of the switch byte table.
- Place your cursor on a BL switch and choose Edit -> Other -> Specify switch idiom
- Address of jump table set to 0xBC (modify to meet the count entry in your case)
- Number of elements to the first byte + 2 (8)
- Size of table element to 1 (one byte for one switch case)
- Element shift count to 1, this is the LSL#1
- Input register to R3 (does not really matter)
- First(lowest) input value to -1 (because of the count at the beginning, so it will align switch cases correctly)
Thanks for this post. I just came across this exact same snippet of code in a binary I'm examining and couldn't quite figure out what it was doing.
ReplyDeleteI encountered a similar piece of code. After further analysis I found it in a lot of places in the code and decided to write a script. How can I post it?
ReplyDelete