diff options
Diffstat (limited to 'src/pal/tests/palsuite/filemapping_memmgt/ReadProcessMemory/test2/helper.cpp')
-rw-r--r-- | src/pal/tests/palsuite/filemapping_memmgt/ReadProcessMemory/test2/helper.cpp | 249 |
1 files changed, 249 insertions, 0 deletions
diff --git a/src/pal/tests/palsuite/filemapping_memmgt/ReadProcessMemory/test2/helper.cpp b/src/pal/tests/palsuite/filemapping_memmgt/ReadProcessMemory/test2/helper.cpp new file mode 100644 index 0000000000..a10ad926c3 --- /dev/null +++ b/src/pal/tests/palsuite/filemapping_memmgt/ReadProcessMemory/test2/helper.cpp @@ -0,0 +1,249 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +/*============================================================= +** +** Source: helper.c +** +** Purpose: This helper process sets up a several blocks of memory, +** then uses a file to tell its parent process where that memory is +** So it can do a WriteProcessMemory on it. When the parent process is done +** we check here that it was written properly. +** +** +**============================================================*/ + +#include "commonconsts.h" + +#include <palsuite.h> + +#if defined(BIT64) && defined(PLATFORM_UNIX) +#define LLFORMAT "%I64u" +#else +#define LLFORMAT "%u" +#endif + +struct allhandles_t +{ + HANDLE hEvToHelper; + HANDLE hEvFromHelper; + char *valuesFileName; +}; + + +/* function: wpmDoIt + * + * This is a general WriteProcessMemory testing function that sets up + * the RAM pointed to and tells the companion process on the other end + * of the handles in 'Comms' to attempt to alter 'lenDest' bytes at + * '*pDest'. + * + * '*pBuffer'[0..'lenBuffer'] is expected to be a guard region + * surrounding the '*pDest'[0..'lenDest'] region so that this function + * can verify that only the proper bytes were altered. + */ + +int wpmDoIt(struct allhandles_t Comms, + char * pBuffer, unsigned int lenBuffer, + char * pDest, unsigned int lenDest, + const char* storageDescription) +{ + char *pCurr; + FILE *commsFile; + DWORD dwRet; + + if (pBuffer > pDest || lenDest > lenBuffer) + { + Trace("WriteProcessMemory::DoIt() test implementation: " + "(pBuffer > pDest || lenDest > lenBuffer)\n"); + return FALSE; + } + + /* set up the storage */ + memset(pBuffer, guardValue, lenBuffer); + memset(pDest, initialValue, lenDest); + + /* tell the parent what RAM to adjust */ + if(!(commsFile = fopen(Comms.valuesFileName, "w"))) + { + Trace("WriteProcessMemory: fopen of '%S' failed (%u). \n", + Comms.valuesFileName, GetLastError()); + return FALSE; + } + if (!fprintf(commsFile, LLFORMAT " " LLFORMAT " '%s'\n", + pDest, lenDest, storageDescription)) + { + Trace("WriteProcessMemory: fprintf to '%S' failed (%u). \n", + Comms.valuesFileName, GetLastError()); + return FALSE; + } + PEDANTIC1(fclose, (commsFile)); + + /* Tell the parent the data is ready for it to adjust */ + PEDANTIC(ResetEvent, (Comms.hEvToHelper)); + PEDANTIC(SetEvent, (Comms.hEvFromHelper)); + + dwRet = WaitForSingleObject(Comms.hEvToHelper, TIMEOUT); /* parent is done */ + if (dwRet != WAIT_OBJECT_0) + { + Trace("helper WaitForSingleObjectTest: WaitForSingleObject " + "failed (%u)\n", GetLastError()); + return FALSE; + } + + /* check the stuff that SHOULD have changed */ + for (pCurr = pDest; pCurr < (pDest + lenDest); pCurr++) + { + if ( *pCurr != nextValue) + { + Trace("When testing '%s': alteration test failed " + "at " LLFORMAT " offset " LLFORMAT " Found '%c' instead of '%c'\n.", + storageDescription, pDest, pCurr - pDest, *pCurr, nextValue); + Trace(" 'Altered' string: '%.*s'\n",lenBuffer, pBuffer); + return FALSE; + } + } + /* check the stuff that should NOT have changed */ + for (pCurr = pBuffer; pCurr < pDest; pCurr++ ) + { + if ( *pCurr != guardValue) + { + Trace("When testing '%s': leading guard zone test failed " + "at " LLFORMAT " offset " LLFORMAT ". Found '%c' instead of '%c'\n.", + storageDescription, pDest, pCurr - pBuffer, *pCurr, guardValue); + Trace(" 'Altered' string: '%.*s'\n",lenBuffer, pBuffer); + return FALSE; + } + } + for (pCurr = pDest + lenDest; pCurr < (pBuffer + lenBuffer); pCurr++ ) + { + if ( *pCurr != guardValue) + { + Trace("When testing '%s': trailing guard zone test failed " + "at " LLFORMAT " offset " LLFORMAT ". Found '%c' instead of '%c'\n.", + storageDescription, pDest + lenDest, pCurr - pBuffer, *pCurr, guardValue); + Trace(" 'Altered' string: '%.*s'\n",lenBuffer, pBuffer); + return FALSE; + } + } + + return TRUE; +} + +int __cdecl main(int argc, char *argv[]) +{ + + BOOL success = TRUE; /* assume success */ + struct allhandles_t Comms = {0,0,0} ; + + /* variables to track storage to alter */ + char *pTarget = NULL; + unsigned int sizeTarget; + + if(0 != (PAL_Initialize(argc, argv))) + { + return FAIL; + } + + /* hook up with the events created by the parent */ + Comms.hEvToHelper = OpenEventW(EVENT_ALL_ACCESS, 0, szcToHelperEvName); + if (!Comms.hEvToHelper) + { + Fail("WriteProcessMemory: OpenEvent of '%S' failed (%u). " + "(the event should already exist!)\n", + szcToHelperEvName, GetLastError()); + } + Comms.hEvFromHelper = OpenEventW(EVENT_ALL_ACCESS, 0, szcFromHelperEvName); + if (!Comms.hEvToHelper) + { + Trace("WriteProcessMemory: OpenEvent of '%S' failed (%u). " + "(the event should already exist!)\n", + szcFromHelperEvName, GetLastError()); + success = FALSE; + goto EXIT; + } + Comms.valuesFileName = argv[1]; + + { + char autoAllocatedOnStack[51]; + + /* Get the parent process to write to the local stack */ + success &= wpmDoIt(Comms, autoAllocatedOnStack, + sizeof(autoAllocatedOnStack), + autoAllocatedOnStack + sizeof(int), + sizeof(autoAllocatedOnStack) - 2 * sizeof(int), + "const size array on stack with int sized guards"); + } + + /* Get the parent process to write to stuff on the heap */ + sizeTarget = 2 * sizeof(int) + 23 ; /* 23 is just a random prime > 16 */ + if (!(pTarget = (char*)malloc(sizeTarget))) + { + Trace("WriteProcessMemory helper: unable to allocate '%s'->%d bytes of memory" + "(%u).\n", + argv[3], sizeTarget, GetLastError()); + success = FALSE; + goto EXIT; + + } + success &= wpmDoIt(Comms, pTarget, sizeTarget, + pTarget + sizeof(int), + sizeTarget - 2 * sizeof(int), + "array on heap with int sized guards"); + + /* just to be nice try something 16 - 2 * sizeof(int) bytes long */ + { + char autoAllocatedOnStack[16]; + + /* Get the parent process to write to the local stack */ + success &= wpmDoIt(Comms, autoAllocatedOnStack, + sizeof(autoAllocatedOnStack), + autoAllocatedOnStack + sizeof(int), + sizeof(autoAllocatedOnStack) - 2 * sizeof(int), + "another 16 byte array on stack with int sized guards inside"); + } + + /* NOTE: Don't try 0 bytes long. Win32 WriteProcessMemory claims + * it writes 8 bytes in that case! */ + + /* and 1 byte long... */ + { + char autoAllocatedOnStack[1+ 2 * sizeof(int)]; + + /* Get the parent process to write to the local stack */ + success &= wpmDoIt(Comms, autoAllocatedOnStack, + sizeof(autoAllocatedOnStack), + autoAllocatedOnStack + sizeof(int), + 1, + "no bytes with int sized guards outside on stack"); + } + + +EXIT: + /* Tell the parent that we are done */ + if (!DeleteFile(Comms.valuesFileName)) + { + Trace("helper: DeleteFile failed so parent (test1) is unlikely " + "to exit cleanly\n"); + } + PEDANTIC(ResetEvent, (Comms.hEvToHelper)); + if (!SetEvent(Comms.hEvFromHelper)) + { + Trace("helper: SetEvent failed so parent (test1) is unlikely " + "to exit cleanly\n"); + } + + free(pTarget); + PEDANTIC(CloseHandle, (Comms.hEvToHelper)); + PEDANTIC(CloseHandle, (Comms.hEvFromHelper)); + + if (!success) + { + Fail(""); + } + + PAL_Terminate(); + + return success ? PASS : FAIL; +} |