I am currently analysing a regular Windows x86 executable (-> protected mode) and I came across several far call instructions in the disassembly. I know that far calls, for example, are used in WOW64 to switch from 32bit to 64bit mode (by a far call to code segment 0x33, see here). However, I can not make any sense of the far calls in that executable. They look like this:

<somewhere near 0x00123400>:  9a 34 12 cd ab 34 12    call   0x1234:0xabcd1234

The code segemt is in most cases the same as the lower 16 bits of the call address. At the same time, the code segment is rougly the same as the middle (!) 16 bits of the instruction's own address (as illustrated above). The call addresses always point to unmapped/invalid memory areas in the code segment of the process itself.

How can I identify the call target of these far calls? Is it even possible/pratical to have hard coded code segments? Or could it be an alignment issue of the disassembler?

Edit: For example, the first far call in the image occurs in a chunk of code starting at a 16-byte boundary (identified by leading int3 instructions). The far call comes 2 bytes after the (only) return instruction in that chunk (some 2000 bytes after its start). The offset of the far call instruction is used as an indirect jump offfset like this:

jmp    DWORD PTR [eax*4+<far call offset>]
  • can you paste some real code instead of made-up one? and also some overview of the memory map and addresses involved. – Igor Skochinsky Aug 2 '17 at 8:13
  • @IgorSkochinsky tbh, I am a bit reluctant to post the actual code, but I added some details. – InkassoHeinzi Aug 2 '17 at 8:53
  • I just want to see real selector values used, not 0x1234. Also, "same as the lower 16 bits of the call address" is a bit difficult to visualize without an example. – Igor Skochinsky Aug 2 '17 at 8:56
  • These are the first selectors: 0x4b 0x4f 0x50 0x5d 0x61 0x65 0xa6 0xa8 0xaa 0xae 0xb0 0xbb 0xbc 0xd0 0x106 0x116, there are 47 different in total. They appear to be quite random. The highest is 0xe69e – InkassoHeinzi Aug 2 '17 at 9:03

it seems the "code" you're trying to disassemble is not actually code but just the table of offsets for the indirect jump (likely a switch implementation). Try interpreting it as a list of 4-byte flat addresses. E.g. :

.text:667013BC 03C                 cmp     ebx, 7 ; SWITCH ; switch 8 cases
.text:667013BF 03C                 ja      loc_667015AB ; SWITCH ; jumptable 667013C5 default case
.text:667013C5 03C                 jmp     ds:off_667060CC[ebx*4] ; switch jump
.rdata:667060CC     off_667060CC    dd offset loc_667015DE ; jump table for switch statement
.rdata:667060CC                     dd offset loc_667015D6  
.rdata:667060CC                     dd offset loc_667015EE
.rdata:667060CC                     dd offset loc_667015E6
.rdata:667060CC                     dd offset loc_667015F6
.rdata:667060CC                     dd offset loc_667015A5
.rdata:667060CC                     dd offset loc_66701663
.rdata:667060CC                     dd offset loc_66701658
| improve this answer | |
  • Thank you, that really makes most sense. Do you have an example how a "legitimate" far call would look like (or even what the use case would be) in a regular windows application, apart from kernel-related functions like the 64/32 switch? – InkassoHeinzi Aug 2 '17 at 9:38
  • I don't think I've ever seen far calls in standard win32 apps. Malware may use them and sometimes UEFI modules (which use PE format). – Igor Skochinsky Aug 2 '17 at 12:42

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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