1

对于 C++ 代码中的异常处理程序,我需要以下内容。说,我有以下代码块:

void myFunction(LPCTSTR pStr, int ncbNumCharsInStr)
{
    __try
    {
        //Do work with 'pStr'

    }
    __except(1)
    {
        //Catch all

        //But here I need to log `pStr` into event log
        //For that I don't want to raise another exception
        //if memory block of size `ncbNumCharsInStr` * sizeof(TCHAR)
        //pointed by 'pStr' is unreadable.
        if(memory_readable(pStr, ncbNumCharsInStr * sizeof(TCHAR)))
        {
            Log(L"Failed processing: %s", pStr);
        }
        else
        {
            Log(L"String at 0x%X, %d chars long is unreadable!", pStr, ncbNumCharsInStr);
        }
    }
}

有什么方法可以实现memory_readable吗?

4

2 回答 2

5

VirtualQuery功能可能会有所帮助以下是如何memory_readable使用它来实现的快速说明。

bool memory_readable(void *ptr, size_t byteCount)
{
  MEMORY_BASIC_INFORMATION mbi;
  if (VirtualQuery(ptr, &mbi, sizeof(MEMORY_BASIC_INFORMATION)) == 0)
    return false;

  if (mbi.State != MEM_COMMIT)
    return false;

  if (mbi.Protect == PAGE_NOACCESS || mbi.Protect == PAGE_EXECUTE)
    return false;

  // This checks that the start of memory block is in the same "region" as the
  // end. If it isn't you "simplify" the problem into checking that the rest of 
  // the memory is readable.
  size_t blockOffset = (size_t)((char *)ptr - (char *)mbi.AllocationBase);
  size_t blockBytesPostPtr = mbi.RegionSize - blockOffset;

  if (blockBytesPostPtr < byteCount)
    return memory_readable((char *)ptr + blockBytesPostPtr,
                           byteCount - blockBytesPostPtr);

  return true;
}

注意:我的背景是 C,所以虽然我怀疑有比char *在 C++ 中转换为 a 更好的选择,但我不确定它们是什么。

于 2013-08-23T05:19:39.403 回答
0

您可以使用该ReadProcessMemory功能。如果函数返回0,则地址不可读,否则可读。

返回值

如果函数失败,则返回值为 0(零)。要获取扩展的错误信息,请调用GetLastError

如果请求的读取操作进入进程中不可访问的区域,则该函数将失败。

如果函数成功,则返回值非零。

于 2019-08-17T04:00:13.747 回答