Skip to content
New issue

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

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

Already on GitHub? Sign in 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
Collaborator

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
Collaborator

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
Collaborator

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
Collaborator

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)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in 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