最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

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

programmeradmin1浏览0评论

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.

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.

Share Improve this question asked Feb 2 at 0:13 user29463846user29463846 1
  • of course this supported on any platform(x86/x64/arm64). also it available as imported functions too. learn.microsoft/en-us/windows/win32/api/atlthunk – RbMm Commented Feb 2 at 8:29
Add a comment  | 

2 Answers 2

Reset to default 4

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);
    }
};

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).

发布评论

评论列表(0)

  1. 暂无评论