Unsupported jump table

The Windows kernel can use jump tables with entries equal to null (note: SEH is used to catch jumps to zero address). The decompiler does not look at other entries after the first null entry, thus missing necessary switch cases.

Let’s look at the sample

A jump table at address 0x1405165A0 contains these entries:

1405165A0 jpt_140515C71 dd offset loc_140515C77 - 140000000h
1405165A4               dd offset loc_140515D02 - 140000000h ; jump table for switch statement
1405165A8               dd offset loc_140515D02 - 140000000h
1405165AC               dd offset loc_140515D02 - 140000000h
1405165B0               dd 0
1405165B4               dd 0
1405165B8               dd offset loc_140515D02 - 140000000h ; jumptable 0000000140515C71 cases 3-5
1405165BC               dd offset loc_140515D4E - 140000000h
1405165C0               dd offset loc_140515D84 - 140000000h
1405165C4               dd offset loc_140515D02 - 140000000h ; jumptable 0000000140515C71 cases 3-5
1405165C8               dd offset loc_140515D27 - 140000000h
1405165CC               dd offset loc_140515D02 - 140000000h ; jumptable 0000000140515C71 cases 3-5
1405165D0               dd offset loc_140515D02 - 140000000h ; jumptable 0000000140515C71 cases 3-5
1405165D4               dd offset loc_140515CB2 - 140000000h

A jump code:

140515C59 ; __try { // __except at loc_140516520 ; switch 4 cases
140515C59               lea     eax, [rsi-2]
140515C5C               cmp     eax, 13
140515C5F               ja      def_140515C71   ; jumptable 0000000140515C71 default case
140515C65               cdqe
140515C67               mov     ecx, ds:(jpt_140515C71 - 140000000h)[rdx+rax*4]
140515C6E               add     rcx, rdx
140515C71               jmp     rcx             ; switch jump

A microcode explorer shows that only 4 cases are used (0, 1, 2, 3) + default case:

; ????-BLOCK 14 PROP [START=140515C65 END=140515C73] STK=0/ARG=1D0, MAXBSP: 0
14. 0 mov    rax.8, kr10_8.8                      ; 140515C65
14. 1 xds    eax.4, rax.8                         ; 140515C65
14. 2 jtbl   kr08_8.8, {0 => 15, 1,2,3 => 22, def => 136} ; 140515C71

So, cases 6-13 are missed.

Hi @lvm

The reason IDA trims the table to 4 entries is because such null entries are not valid:

1405165B0               dd 0
1405165B4               dd 0

IDA allows you to fix it.

First, make sure all table entries have the appropriate type.

Second, identify the branching instruction, in this case the jmp at 0x140515C71.Having your cursor on this address, Edit → Other → Specify Switch Idiom…

In the decompiled switch statement, these null entries will be marked with a red JUMPOUT statement.

If you want to read more on this topic, Igor’s post is worth a quick look.

@apetenchea, thank you, this is helpful.

Since such jump tables are used in the Microsoft compiler, perhaps it would be worthwhile to detect and handle them correctly?

Switch recognition can be improved during analysis, but this is something specific to MSVC and may produce lots of false positive in other cases. It’s difficult for me right now to say concretely “This will be improved in the next release”, but I already started an internal discussion about it and there will be a ticket for sure.

1 Like