Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Support (partially) far calls #355

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

tathanhdinh
Copy link
Contributor

@tathanhdinh tathanhdinh commented Aug 2, 2019

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.

@pgoodman
Copy link
Contributor

pgoodman commented Aug 5, 2019

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
Copy link
Contributor

pgoodman commented Aug 5, 2019

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
Copy link
Contributor

Ping @tathanhdinh.

@tathanhdinh
Copy link
Contributor Author

Hello @pgoodman,

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

@mike-myers-tob mike-myers-tob added enhancement x86 Related to x86/x86-64/AMD64 lifting support labels Oct 3, 2019
@pgoodman
Copy link
Contributor

ping @tathanhdinh

@tathanhdinh
Copy link
Contributor Author

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)

# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
enhancement x86 Related to x86/x86-64/AMD64 lifting support
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants