Red.Yu Знаменитый Пользователь Сообщения 2 Розыгрыши 0 Репутация 0 Реакции 1 Баллы 1 235 26 Июл 2016 #1 Наткнулся на довольно странную реализацию, как такое может быть? Есть конструктор PHP: CUserSocket* __cdecl CUserSocket::UserSocketConstructor(CUserSocket* pUserSocket, SOCKET _s) { typedef CUserSocket* (__cdecl *t)(CUserSocket*, SOCKET); t f = (t)0x0093CADC; CUserSocket* pReturn = f(pUserSocket, _s); return pReturn; } Очень хорошо видно что соглашение о вызове указано __cdecl. Но если посмотреть на дизассемблированный код, видно что это __fastcall. Код: .text:000000000093CED6 mov rdx, rbx .text:000000000093CED9 mov rcx, rax .text:000000000093CEDC call sub_93CADC Вопрос почему это не приводит к ошибке, компилированная DLL, хорошо работает. Подмена происходит вот так: PHP: WriteInstruction(0x93CEDC, (UINT32)CUserSocket::UserSocketConstructor, 0xE8);
Наткнулся на довольно странную реализацию, как такое может быть? Есть конструктор PHP: CUserSocket* __cdecl CUserSocket::UserSocketConstructor(CUserSocket* pUserSocket, SOCKET _s) { typedef CUserSocket* (__cdecl *t)(CUserSocket*, SOCKET); t f = (t)0x0093CADC; CUserSocket* pReturn = f(pUserSocket, _s); return pReturn; } Очень хорошо видно что соглашение о вызове указано __cdecl. Но если посмотреть на дизассемблированный код, видно что это __fastcall. Код: .text:000000000093CED6 mov rdx, rbx .text:000000000093CED9 mov rcx, rax .text:000000000093CEDC call sub_93CADC Вопрос почему это не приводит к ошибке, компилированная DLL, хорошо работает. Подмена происходит вот так: PHP: WriteInstruction(0x93CEDC, (UINT32)CUserSocket::UserSocketConstructor, 0xE8);
Red.Yu Знаменитый Пользователь Сообщения 2 Розыгрыши 0 Репутация 0 Реакции 1 Баллы 1 235 27 Июл 2016 #2 Сам уже разобрался. _cdecl, _stdcall и т.п. в режиме x64 игнорируются, там аргументы всегда передаются через регистры (rcx, rdx, r8, r9, остальное через стек).
Сам уже разобрался. _cdecl, _stdcall и т.п. в режиме x64 игнорируются, там аргументы всегда передаются через регистры (rcx, rdx, r8, r9, остальное через стек).