4

I'm using a linear disassembler (beaEngine), and whenever I get to a jump table section, I get an error (or an incorrect decode since beaEngine mistakenly thinks it is code).

How can I recognize this section as a jump table? What is the characteristic of a jump table?

An example of a jump table which was found via a 3rd party application:

.text:600F49CB                 dd offset loc_600F496E  
.text:600F49CB                 dd offset loc_600F4984  
.text:600F49CB                 dd offset loc_600F4979  
.text:600F49CB                 dd offset loc_600F4979  
.text:600F49CB                 dd offset loc_600F4984  
.text:600F49CB                 dd offset loc_600F499E   
.text:600F49CB                 dd offset loc_600F499E   
.text:600F49CB                 dd offset loc_600F498F   
.text:600F49CB                 dd offset loc_600F498F   

In order to clarify and to answer a question raised in a comment: this executable does have a relocation table. beaEngine does not seem to use it, though, since I feed it a stream of bytes and not the whole binary.

Can I use the relocation table to comprehend whether it's a jump table and calculate its length? For a single example I've checked, it does seem to work.

2
  • Try, at least, to provide an example of a jump table you found.
    – perror
    Jan 4, 2016 at 20:27
  • Does this executable have a Relocation Table? Does beaEngine use it when it finds one?
    – Jongware
    Jan 5, 2016 at 10:12

4 Answers 4

2

Jump tables stand out in relocation tables because they are arrays of tightly packed code addresses whereas 'normal' code references are much more spaced out, with opcodes or other data between.

However, vtables (virtual function tables for C++ style objects) and function tables (for C-style objects, heavily used in some libraries) look almost exactly the same as jump tables when viewed through the lens of relocations. The difference is that the latter two types of 'code address arrays' contain function addresses whereas jump table entries usually point into functions.

However, it is difficult to analyse jump tables without analysing the code that references them. This means that the info gleaned from the relocation tables is more suited for auxiliary duties in this case, like telling you about potential jump tables that your disassembler might have missed, rather than for primary analysis.

2
  • unless a local/relative jump is used in the jump table. Then it won't be in the relocation table. Jan 7, 2016 at 11:32
  • @ratchet freak: Yes, indeed. That's why it pays to study the behaviour of the target compiler(s) in question, since they tend to utilise only a small fraction of the possibilities offered by the targetted processor architecture in their jump dispatch code. Often they use very fixed code patterns for this - much more.fixed than if the dispatch code had been written in the source language and compiled.
    – DarthGizka
    Jan 7, 2016 at 11:44
1

IMHO no easy way to do it. The best is to write smart disassembler so it will find and deduce the table size. For example one of the characteristic of a jump table code:

and eax, NUMBER_OF_CASES
jmp dword ptr ds:[eax*4 + switch_table_start_addr]

Another quick and error-prone way might be to look for a row of DWORDs with min and max RVA range e.g. :

dd IMAGEBASE+0x1000
dd IMAGEBASE+0xXXXX
dd IMAGEBASE+0xYYYY
dd IMAGEBASE+0xFFFF
...

but this will probably find more data not related to switch table, especially in large applications.

0

well.. i did find that indeed a jmp as you stated indicates a jump table.

so what i do now is

  1. looking for those jumps
  2. parsing the prior opcodes and looking for "cmp" which indicates the "default" part in a switch statement (and so, indicates the size of the jump table, since it is the number of cases * 4 (on 32 bit)).
  3. calculating the start address and end address of the jump table.

now i have a different problem though.. what i've described usually suits for contiguous values for the switch (lets say 1-10). but when it is not contiguous, than the compiler creates an "indirect table for switch statement" which looks a bit different, and i don't know how to calculate its size.

any ideas? isn't there a standard for those things? how can i tell whether i've covered all the options of a jump table?

1
  • The size of the index table is implied by the instructions preceding the lookup instruction; the general case is an 'anchoring' subtraction and a comparison to the highest index into the table (or its size, as the case may be). The highest value found in the index table - with the lowest value almost invariably being 0 - implies the size of the actual jump table.
    – DarthGizka
    Jan 5, 2016 at 13:13
0

The paper "Recovery of Jump Table Case Statements from Binary Code" by Cristina Cifuentes and Mike Van Emmerik (Proceedings of the 7th International Workshop on Program Comprehension, 1999) discusses this issue in some detail. It's an interesting read.

From a reverse engineering perspective, it can also be useful to understand how compilers typically map switch statements to machine code (they don't always get mapped to a single jump table). The paper "Producing good code for the case statement" by Robert Bernstein (Software: Practice and Experience, Oct. 1985) discusses this in some detail.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.