프로그래밍/C,C++

포인터 인자 검증하기

MAKGA 2016. 7. 20. 10:41
320x100
/*  
IsWritableMemory : 주어진 메모리 주소의 상태가 쓰기가능인지 체크하는 함수 
    Param :  
        LPVOID  pMemoryAddr : 검사하고자 하는 메모리의 주소 
    Return Value :  
        ERROR_SUCCESS : 인자로 주어진 주소의 메모리가 Read/Write 가능한 경우 
        기타 값 : Read/Write 가능한 메모리가 아니면 해당 주소의 Protect Mode 를  
                    나타내는 0이 아닌 값을 리턴함. 
                    http://msdn.microsoft.com/en-us/library/aa915370.aspx 참조 
*/  
INT IsWritableMemory(LPVOID pMemoryAddr)  
{
    MEMORY_BASIC_INFORMATION    MemInfo = {0,};
    size_t  nResult = 0;

    nResult = VirtualQuery (pMemoryAddr, &MemInfo, sizeof(MemInfo));

    if (nResult == 0) // 커널 영역인 경우 VirtualQuery 자체가 Fail함.
    {
        return -1;
    }
    else if (MemInfo.Protect & (PAGE_EXECUTE_READWRITE | PAGE_READWRITE))
    {
        return  ERROR_SUCCESS;
    }
    else
    {
        return  MemInfo.Protect;
    }
}  

/*  
IsReadableMemory : 주어진 메모리 주소의 상태가 참조(Read)가능인지 체크하는 함수 
    Param :  
        LPVOID  pMemoryAddr : 검사하고자 하는 메모리의 주소 
    Return Value :  
        ERROR_SUCCESS : 인자로 주어진 주소의 메모리가 Read 가능한 경우 
        기타 값 : Read 가능한 메모리가 아니면 해당 주소의 State 를  
                    나타내는 0이 아닌 값을 리턴함. 
                    http://msdn.microsoft.com/en-us/library/aa915370.aspx 참조 
*/  
INT IsReadableMemory(LPVOID pMemoryAddr)  
{
    MEMORY_BASIC_INFORMATION    MemInfo = {0,};
    SIZE_T  nResult = 0;

    nResult = VirtualQuery (pMemoryAddr, &MemInfo, sizeof(MemInfo));

    if (nResult == 0) // 커널 영역인 경우 VirtualQuery 자체가 Fail함.
    {
        return -1;
    }
    else if (MemInfo.State & MEM_COMMIT)
    {
        return  ERROR_SUCCESS;
    }
    else
    {  
        return  MemInfo.State;
    }
}

BOOL    SampleFunc(LPTSTR   lpTargetBuffer, DWORD   dwBufferSize)  
{
    if (IsWritableMemory(lpTargetBuffer) != ERROR_SUCCESS)
    {
        return FALSE;   // 주어진 버퍼가 유효한 메모리가 아닐 경우
    }

    lstrcpyn(lpTargetBuffer, L"Some String", dwBufferSize);

    return TRUE;
}
  
int _tmain(int argc, _TCHAR* argv[])
{
    TCHAR   szSafeBuffer[1024] = {0,};  // 정상적인 버퍼
    LPTSTR  lpTest;     // 초기화 되지 않은 포인터!!

    BOOL    bResult = FALSE;

    bResult = SampleFunc(szSafeBuffer, _countof(szSafeBuffer));

    if (bResult != TRUE)
    {
        wprintf(L"Fail to Copy String\r\n");
        return FALSE;
    }  
    wprintf(L"Result String : %s\r\n", szSafeBuffer);

    bResult = SampleFunc(lpTest, sizeof(lpTest));  // Access Violation??
    if (bResult != TRUE)
    {
        wprintf(L"Fail to Copy String\r\n");  
        return FALSE;
    }
    wprintf(L"Result String : %s\r\n", lpTest);

    return TRUE;
}
320x100

'프로그래밍 > C,C++' 카테고리의 다른 글

람다(lambda)  (0) 2018.04.11
STL 알고리즘  (0) 2018.04.02
STL 컨테이너  (0) 2018.04.02
예외처리(exception)  (0) 2018.04.01
[C]Split함수 구현  (0) 2016.04.20