myInjectFunction is the function to be injected, above code must be compiled by disabling inlining. If you run it through disassembler e.g. "dumpbin /disasm /all yourprogram.exe" you should get something like:

40 53 push rbx

48 83 EC 20 sub rsp,20h

8B 51 08 mov edx,dword ptr [rcx+8]

48 8B D9 mov rbx,rcx

48 8B 09 mov rcx,qword ptr [rcx]

FF 15 6B 10 00 00 call qword ptr [__imp_GetWindowLongPtrW]

48 89 43 10 mov qword ptr [rbx+10h],rax

48 83 C4 20 add rsp,20h

5B pop rbx

C3 ret

CC

Above is assembly 101 function body, with some ptr trickery. This assembly contains a one flaw though, for to be uses as is, even though GetWindowLongPtrW is in known memory location (user32 and kernel32 has de-facto memory locations) it's not in right form to be used.

The call to GetWindowLongPtrW must be in longer form:

40 53 push rbx

48 83 EC 20 sub rsp,20h

8B 51 08 mov edx,dword ptr [rcx+8]

48 8B D9 mov rbx,rcx

48 8B 09 mov rcx,qword ptr [rcx]

48 B8 XX XX XX XX XX XX XX XX movabs rax, GetWindowLongPtrW

FF D0 call rax

48 89 43 10 mov qword ptr [rbx+10h],rax

48 83 C4 20 add rsp,20h

5B pop rbx

C3 ret

CC

You can try out changing the assembly runtime with x64dbg until it works.In this demonstration I won't fill the 8 byte (XX) address because you have to determine it runtime by calling GetProcAddress and then transforming it to reversed hexadecimal form.

After this one simply writes the bytes using WriteProcessMemory and calls CreateRemoteThread with newly created memory address and it just works just like the C equivalent did.