/*++ Function: CONTEXT_GetRegisters Abstract retrieve the machine registers value of the indicated process. Parameter processId: process ID registers: reg structure in which the machine registers value will be returned. Return returns TRUE if it succeeds, FALSE otherwise --*/ BOOL CONTEXT_GetRegisters(DWORD processId, ucontext_t *registers) { #if HAVE_BSD_REGS_T int regFd = -1; #endif // HAVE_BSD_REGS_T BOOL bRet = FALSE; if (processId == GetCurrentProcessId()) { #if HAVE_GETCONTEXT if (getcontext(registers) != 0) { ASSERT("getcontext() failed %d (%s)\n", errno, strerror(errno)); return FALSE; } #elif HAVE_BSD_REGS_T char buf[MAX_PATH]; struct reg bsd_registers; sprintf_s(buf, sizeof(buf), "/proc/%d/regs", processId); if ((regFd = PAL__open(buf, O_RDONLY)) == -1) { ASSERT("PAL__open() failed %d (%s) \n", errno, strerror(errno)); return FALSE; } if (lseek(regFd, 0, 0) == -1) { ASSERT("lseek() failed %d (%s)\n", errno, strerror(errno)); goto EXIT; } if (read(regFd, &bsd_registers, sizeof(bsd_registers)) != sizeof(bsd_registers)) { ASSERT("read() failed %d (%s)\n", errno, strerror(errno)); goto EXIT; } #define ASSIGN_REG(reg) MCREG_##reg(registers->uc_mcontext) = BSDREG_##reg(bsd_registers); ASSIGN_ALL_REGS #undef ASSIGN_REG #else #error "Don't know how to get current context on this platform!" #endif } else {
BOOL PALAPI PAL_Random( IN BOOL bStrong, IN OUT LPVOID lpBuffer, IN DWORD dwLength) { int rand_des = -1; BOOL bRet = FALSE; DWORD i; char buf; long num = 0; static BOOL sMissingDevRandom; static BOOL sMissingDevURandom; static BOOL sInitializedMRand; PERF_ENTRY(PAL_Random); ENTRY("PAL_Random(bStrong=%d, lpBuffer=%p, dwLength=%d)\n", bStrong, lpBuffer, dwLength); i = 0; if (bStrong == TRUE && i < dwLength && !sMissingDevRandom) { // request non-blocking access to avoid hangs if the /dev/random is exhausted // or just simply broken if ((rand_des = PAL__open(RANDOM_DEVICE_NAME, O_RDONLY | O_NONBLOCK)) == -1) { if (errno == ENOENT) { sMissingDevRandom = TRUE; } else { ASSERT("PAL__open() failed, errno:%d (%s)\n", errno, strerror(errno)); } // Back off and try /dev/urandom. } else { for( ; i < dwLength; i++) { if (read(rand_des, &buf, 1) < 1) { // the /dev/random pool has been exhausted. Fall back // to /dev/urandom for the remainder of the buffer. break; } *(((BYTE*)lpBuffer) + i) ^= buf; } close(rand_des); } } if (i < dwLength && !sMissingDevURandom) { if ((rand_des = PAL__open(URANDOM_DEVICE_NAME, O_RDONLY)) == -1) { if (errno == ENOENT) { sMissingDevURandom = TRUE; } else { ASSERT("PAL__open() failed, errno:%d (%s)\n", errno, strerror(errno)); } // Back off and try mrand48. } else { for( ; i < dwLength; i++) { if (read(rand_des, &buf, 1) < 1) { // Fall back to srand48 for the remainder of the buffer. break; } *(((BYTE*)lpBuffer) + i) ^= buf; } close(rand_des); } } if (!sInitializedMRand) { srand48(time(NULL)); sInitializedMRand = TRUE; } // always xor srand48 over the whole buffer to get some randomness // in case /dev/random is not really random for(i = 0; i < dwLength; i++) { if (i % sizeof(long) == 0) { num = mrand48(); } *(((BYTE*)lpBuffer) + i) ^= num; num >>= 8; } bRet = TRUE; LOGEXIT("PAL_Random returns %d\n", bRet); PERF_EXIT(PAL_Random); return bRet; }