26 October, 2016

Trampolines for hooking

Here I would like to show all variants of trampolines which I know.

32-bits Intel architecture (x86):

; 5 code bytes
; relative addressing
; no registers modification
; EIP+78563412h == 0019fa9ah+78563412h == 78702each
0019fa95 e912345678 jmp 78702each
0019fa9a
; 6 code bytes
; absolute addressing
; no registers modification
0019fa95 6812345678 push 78563412h
0019fa9a c3         ret
0019fa9b
; 8 code bytes
; absolute addressing
; EAX value lost
0019fa95 c7c012345678 mov eax,78563412h
0019fa9b ffe0         jmp eax
0019fa9d
; 6 code bytes + 4 data bytes
; absolute addressing
; no registers modification
; data in execution code
; absolute data addressing
0019fa95 ff259bfa1900 jmp dword ptr ds:[19FA9Bh]
0019fa9b 12345678     dd  78563412h
0019fa9f

64-bits AMD architecture (amd64 / x86_64 / x64):

; 14 code bytes
; absolute addressing
; no registers modification
00000000`0014f605 6812345678       push 78563412h
00000000`0014f60a c74424049abcdef0 mov  dword ptr [rsp+4],0F0DEBC9Ah 
00000000`0014f612 c3               ret
00000000`0014f613
; 6 code bytes
; absolute addressing in lower 4Gb
; no registers modification
00000000`0014f605 6812345678 push 78563412h
00000000`0014f60a c3         ret
00000000`0014f60b
; 12 code bytes
; absolute addressing
; change RAX (return value register)
00000000`0014f605 48b8123456789abcdef0 mov  rax,0F0DEBC9A78563412h
00000000`0014f60f ffe0                 jmp  rax
00000000`0014f611
; 13 code bytes
; absolute addressing
; change R11 (temporary register)
00000000`0014f605 49bb123456789abcdef0 mov r11,0F0DEBC9A78563412h
00000000`0014f60f 41ffe3               jmp r11
00000000`0014f612
; 6 code bytes + 8 data bytes in range RIP±2Gb
; absolute addressing
; no registers modification
; data in execution code
; relative data addressing
; RIP+00000000h == 00000000`0014f60bh+00000000h == 00000000`0014f60bh
00000000`0014f605 ff2500000000     jmp qword ptr [00000000`0014f60bh]
00000000`0014f60b 123456789abcdef0 dq  0F0DEBC9A78563412h
00000000`0014f613
; 5 code bytes
; relative addressing RIP±2Gb
; no registers modification
; EIP+78563412h == 00000000`0014f60ah+78563412h == 00000000`786b2a1ch
00000000`0014f605 e912345678 jmp 00000000`786b2a1ch
00000000`0014f60a

P.S. Please let me know if you have new variant.

09 July, 2016

Solve the "no GUID has been associated with this object" compiler error for __uuidof in templates instantinations

As you know WinRT has C++ interfaces ABI::Windows::Foundation::Collections::IIterable and ABI::Windows::Foundation::Collections::IIterable to make iteration in collections universal. This is the very good idea, but you got interfaces with templates: (see windows.foundation.collections.h):

namespace ABI {
namespace Windows {
namespace Foundation {
namespace Collections { 

    template <class T> 
    struct IIterator 
        : IIterator_impl<T>
        , detail::not_yet_specialized<IIterator<T>>
    {
    };

    template <class T> 
    struct IIterable
        : IIterable_impl<T>
        , detail::not_yet_specialized<IIterable<T>>
    {
    };

    template <class T, bool isStruct>
    struct IIterator_impl : IInspectable
    {
    private:
        typedef typename Windows::Foundation::Internal::GetAbiType<T>::type     T_abi;
        typedef typename Windows::Foundation::Internal::GetLogicalType<T>::type T_logical;
    public:
        typedef T                                                               T_complex;

        virtual /* propget */ HRESULT STDMETHODCALLTYPE get_Current(_Out_ T_abi *current) = 0;
        virtual /* propget */ HRESULT STDMETHODCALLTYPE get_HasCurrent(_Out_ boolean *hasCurrent) = 0;
        virtual HRESULT STDMETHODCALLTYPE MoveNext(_Out_ boolean *hasCurrent) = 0;
        virtual HRESULT STDMETHODCALLTYPE GetMany(_In_ unsigned capacity, _Out_writes_to_(capacity,*actual) T_abi *value, _Out_ unsigned *actual) = 0;
    };

    template <class T>
    struct IIterable_impl : IInspectable
    {
    private:
        typedef typename Windows::Foundation::Internal::GetAbiType<T>::type     T_abi;
        typedef typename Windows::Foundation::Internal::GetLogicalType<T>::type T_logical;
    public:
         typedef T                                                               T_complex;

        virtual HRESULT STDMETHODCALLTYPE First(_Outptr_result_maybenull_ IIterator<T_logical> **first) = 0;
    };

}}}}