remill icon indicating copy to clipboard operation
remill copied to clipboard

Support (partially) far calls

Open tathanhdinh opened this issue 6 years ago • 6 comments

Hello

This PR is for early review only (my purpose is to support far call/ret in both 64-bit/compat modes). E.g.

9a 50 04 00 00 33 00        call far 0x33:0x450

There as some detail in remill for which I'm still confused:

https://github.com/trailofbits/remill/blob/d37ee6bc30b689480d9ef274e3f96fc7d76a190c/remill/Arch/X86/Semantics/CALL_RET.cpp#L21-L28

What is the purpose of _IF_32BIT macro in this line?

Write(WritePtr<addr_t>(next_sp _IF_32BIT(REG_SS_BASE)), Read(return_pc)); 

And a bizzare error, when I try to lift the instruction using:

remill-lift-7.0 --arch x86 --bytes 9a500400003300 --ir-out /dev/stdout

but get

F0802 19:25:22.794279  3980 Util.cpp:842] Cannot declare internal function _ZN12_GLOBAL__N_112CALL_FAR_PTRI2InIjES1_ItEEEP6MemoryS5_R5StateT_T0_S2_ as external in another module

Many thanks for any help.

tathanhdinh avatar Aug 02 '19 17:08 tathanhdinh

The _IF_32BIT(REG_SS_BASE) expands to , REG_SS_BASE [1] when ADDRESS_SIZE_BITS == 32, and expands to nothing otherwise, meaning that the two-argument version of WritePtr is called [2]: WritePtr<addr_t>(next_sp, REG_SS_BASE), and so the writes to the stack end up doing next_sp + REG_SS_BASE. On amd64, it would just write to next_sp.

[1] https://github.com/trailofbits/remill/blob/487228c9b61a1dae7dd7a264d71b9905130bea02/remill/Arch/Runtime/Definitions.h#L38 [2] https://github.com/trailofbits/remill/blob/487228c9b61a1dae7dd7a264d71b9905130bea02/remill/Arch/Runtime/Operators.h#L1396-L1400

pgoodman avatar Aug 05 '19 02:08 pgoodman

Does the return address get written in the "destination" address space? If so, it may make sense to have a sync hyper call, somewhat like...

template <typename S1, typename S2>
DEF_SEM(CALL_FAR_PTR, S1 target_pc, S2 target_seg, PC return_pc) {

  // New---------
  state.segment_to_load = Read(target_seg);
  memory = __remill_sync_hyper_call(state, memory, SyncHyperCall::kX86GetMemoryForSegment);
  // End new----------

  HYPER_CALL = AsyncHyperCall::kX86CallFar;

  addr_t next_sp = USub(REG_XSP, ADDRESS_SIZE_BYTES * 2);

   // stack update
  WriteZExt(WritePtr<addr_t>(next_sp + ADDRESS_SIZE_BYTES), Read(REG_CS.flat));  // _IF_32BIT?
  Write(WritePtr<addr_t>(next_sp _IF_32BIT(REG_SS_BASE)), Read(return_pc));

   // register update
  Write(REG_XSP, Read(next_sp));
  WriteZExt(REG_PC, Read(target_pc));
  Write(REG_CS.flat, Read(target_seg));

  return memory;
}

Where segment_to_load is added here [1], and the semantic of to-add kX86GetMemoryForSegment sync hyper call returns an opaque Memory * representing us being in the new address space, so that the writes to the stack can reflect this.

Some additional _IF_32BIT(..) will probably be needed.

You're likely in the best position to evaluate if these semantics are actually working, as I'm not particularly familiar with the intricacies of far calls/jumps. I've always kind of punted on them ;-)

That is a bizarre error... It probably has to do with the trace lifter not being sufficiently aggressive at cloning the function into the "final" module. Can you file an issue for it?

[1] https://github.com/trailofbits/remill/blob/8e0a28ebae9460bc71302ab9dc4b8fe4fbbf32a0/remill/Arch/Runtime/State.h#L31

pgoodman avatar Aug 05 '19 02:08 pgoodman

Ping @tathanhdinh.

pgoodman avatar Aug 16 '19 19:08 pgoodman

Hello @pgoodman,

Sorry for the delay, I'm on vacation this week. I will come back next week.

tathanhdinh avatar Aug 16 '19 20:08 tathanhdinh

ping @tathanhdinh

pgoodman avatar Oct 24 '19 20:10 pgoodman

Hi @pgoodman,

Sorry again for the late, following is a summary for the current progress:

  • for a need of "natural" test cases for these instructions (since I'm afraid of "side-effects" that I may omit) so I've tried to check on several ring-0 traces to see if they're used, but I still cannot find them.
  • but never mind, I will try with some "artificial" tests (i.e. loading a driver containing far call/ret)

tathanhdinh avatar Oct 24 '19 23:10 tathanhdinh