Как я могу исправить Windows API во время выполнения, чтобы он возвращал 0 в x64? - PullRequest
3 голосов
/ 10 июня 2010

В x86 я получаю адрес функции с помощью GetProcAddress() и пишу в нем простое XOR EAX,EAX; RET 4;.Просто и эффективно.Как мне сделать то же самое в x64?

bool DisableSetUnhandledExceptionFilter()
{
  const BYTE PatchBytes[5] = { 0x33, 0xC0, 0xC2, 0x04, 0x00 }; // XOR EAX,EAX; RET 4;

  // Obtain the address of SetUnhandledExceptionFilter 
  HMODULE hLib = GetModuleHandle( _T("kernel32.dll") );
  if( hLib == NULL )
    return false;
  BYTE* pTarget = (BYTE*)GetProcAddress( hLib, "SetUnhandledExceptionFilter" );
  if( pTarget == 0 )
    return false;

  // Patch SetUnhandledExceptionFilter 
  if( !WriteMemory( pTarget, PatchBytes, sizeof(PatchBytes) ) )
    return false;
  // Ensures out of cache
  FlushInstructionCache(GetCurrentProcess(), pTarget, sizeof(PatchBytes));

  // Success 
  return true;
}

static bool WriteMemory( BYTE* pTarget, const BYTE* pSource, DWORD Size )
{
  // Check parameters 
  if( pTarget == 0 )
    return false;
  if( pSource == 0 )
    return false;
  if( Size == 0 )
    return false;
  if( IsBadReadPtr( pSource, Size ) )
    return false;
  // Modify protection attributes of the target memory page 
  DWORD OldProtect = 0;
  if( !VirtualProtect( pTarget, Size, PAGE_EXECUTE_READWRITE, &OldProtect ) )
    return false;
  // Write memory 
  memcpy( pTarget, pSource, Size );
  // Restore memory protection attributes of the target memory page 
  DWORD Temp = 0;
  if( !VirtualProtect( pTarget, Size, OldProtect, &Temp ) )
    return false;
  // Success 
  return true;
}

Этот пример адаптирован из кода, найденного здесь: http://www.debuginfo.com/articles/debugfilters.html#overwrite.

Ответы [ 2 ]

2 голосов
/ 11 июня 2010

В x64 возвращаемое значение в RAX, что является 64-битной версией EAX. Но поскольку старшие 32 бита очищаются при записи 32-битного субрегистра, «xor eax, eax» эквивалентно «xor rax, rax» и не нуждается в изменении.

Однако, поскольку соглашение о вызовах отличается в x64, та же самая инструкция возврата там не будет работать: В x86 функции winapi используют соглашение stdcall, в котором вызываемый объект извлекает аргументы из стека (отсюда и инструкция «retn 4», которая выталкивает этот один аргумент из SetUnhandledExceptionFilter из стека (вы можете исправить этот комментарий в своем коде)) , В x64 стек не очищается вызываемым объектом, поэтому необходимо использовать обычную команду «retn»:

const BYTE PatchBytes[3] = { 0x33, 0xC0, 0xC3 }; // XOR EAX,EAX; RET;
0 голосов
/ 10 июня 2010

Используйте библиотеку, такую ​​как Microsoft Detours или EasyHook , обе из которых поддерживают именно этот вид исправлений, и одна из которых по крайней мере работает в x64.

...