I have come across the following x86 (Built with some version of Visual Studio AFAIK) switch statement:
0x1009E476 cmp edx, 0x3B
0x1009E479 jnz switch_statement
switch_statement:
0x1009E591 movzx ecx, byte [indirect_table+edx]
0x1009E598 jmp dword [table1+ecx*4]
indirect_table:
0x1009E7AB db 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07
db 0x07, 0x07, 0x06, 0x8B, 0xFF
table1:
0x1009E7B8 dd ptr code1
dd ptr code2
dd ptr code3
dd ptr code4
dd ptr code5
dd ptr code6
dd 0x00000000
0x1009E7D4 dd 0x01060600, 0x06020606, 0x06060306, 0x06060606 ; Note: nothing directly references this data.
dd 0x06040606, 0x06060606, 0x06060606, 0x06060606
dd 0x06060606, 0x06060606, 0x06060606, 0x06060606
dd 0x06060606, 0x06060606, 0x06060606, 0x06060606
dd 0x06060606
No index in the indirect_table
will end up referencing any of the 6 pointers in table1
. Index 6 will dereference a null pointer, index 7 will dereference 0x01060600
and indexes 0x8B
and 0xFF
will end up dereferencing garbage. So everything will end up access violating.
So perhaps this is a compiler optimization, the data at table1 following the 6 code pointers and 1 null pointer looks like an indirect table, and coincidentally all indexes are suitable for this switch statement (0-6). While the binary has no references to this data, if EBX
was known to be 0x29
or upwards, it would reference into this. The compiler may have decided EBX
will not be 0
-0x29
so moved the indirect table location backwards to line things up correctly. What then is the role of cmp edx, 0x3B
in this?
Is this a compiler code gen issue, a compiler optimization, or have I grossly misunderstood the code?
If an optimization, any supporting reading material would be greatly appreciated.