user29463846
user29463846

Reputation: 51

Do ATL thunks work cross-platform, including on ARM64?

My understanding is that ATL implements its window "thunks" using some clever assembly language hacks (see this question, for example).

I'm wondering whether these thunks (and really any similar thunks, for that matter) will work cross-platform. I've had access only to a x64 machine so far, so I was wondering, in particular, whether ATL would work on ARM64 processors.

Thanks for any insight.

Upvotes: 1

Views: 91

Answers (2)

user29463846
user29463846

Reputation: 51

Actually, upon further investigation, it appears from the source that ATL does some conditional compilation for various platforms, including ARM64:

#elif defined(_M_ARM64)
PVOID __stdcall __AllocStdCallThunk(VOID);
VOID  __stdcall __FreeStdCallThunk(PVOID);
#pragma pack(push,4)  
struct _stdcallthunk {
    ULONG   m_ldr_r16;      // ldr  x16, [pc, #24]
    ULONG   m_ldr_r0;       // ldr  x0, [pc, #12]
    ULONG   m_br;           // br   x16      
    ULONG   m_pad;  
    ULONG64 m_pThis;
    ULONG64 m_pFunc;
    BOOL Init(DWORD_PTR proc, void* pThis) {
        m_ldr_r16 = 0x580000D0;
        m_ldr_r0 = 0x58000060;
        m_br = 0xd61f0200;
        m_pThis = (ULONG64)pThis;
        m_pFunc = (ULONG64)proc;
        // write block from data cache and          
        //  flush from instruction cache        
        FlushInstructionCache(GetCurrentProcess(), this, sizeof(_stdcallthunk));  
        return TRUE;
    }
    void* GetCodeAddress() {
        return this;
    }
    void* operator new(size_t)
    {
        return __AllocStdCallThunk();
    }
    void operator delete(void* pThunk) {
        __FreeStdCallThunk(pThunk);
    }
};

Upvotes: 4

Peter Cordes
Peter Cordes

Reputation: 365517

It looks like the asm is just overwriting the first arg with a different pointer, then tailcalling another function by jumping to it. This is doable in any calling convention for any ISA.

But of course the machine-code byte sequence for doing that depends on the ISA and the calling convention (e.g. which register or stack location holds the first arg).

Upvotes: 0

Related Questions