static PyObject *Triton_getMemValue(PyObject *self, PyObject *args) { PyObject *addr; PyObject *readSize; uint64 ad; uint64 rs; /* Extract arguments */ PyArg_ParseTuple(args, "O|O", &addr, &readSize); if (!ap.getCurrentCtxH()) return PyErr_Format(PyExc_TypeError, "getMemValue(): Can't call getMemValue() right now. You must run the program before."); if (!PyLong_Check(addr) && !PyInt_Check(addr)) return PyErr_Format(PyExc_TypeError, "getMemValue(): expected an address (integer) as argument"); ad = PyLong_AsLong(addr); rs = PyLong_AsLong(readSize); if (rs != DQWORD_SIZE && rs != QWORD_SIZE && rs != DWORD_SIZE && rs != WORD_SIZE && rs != BYTE_SIZE) return PyErr_Format(PyExc_TypeError, "getMemValue(): The readSize argument must be: DQWORD, QWORD, DWORD, WORD or BYTE"); if (PIN_CheckReadAccess(reinterpret_cast<void*>(ad)) == false) return PyErr_Format(PyExc_TypeError, "getMemValue(): The targeted address memory can not be read"); /* If this is a 128-bits read size, we must use uint128ToPyLongObject() */ if (rs == DQWORD_SIZE){ uint128 value = ap.getMemValue(ad, rs); return uint128ToPyLongObject(value); } return Py_BuildValue("k", ap.getMemValue(ad, rs)); }
static PyObject *Triton_checkReadAccess(PyObject *self, PyObject *addr) { uint64 ad; if (!PyLong_Check(addr) && !PyInt_Check(addr)) return PyErr_Format(PyExc_TypeError, "checkReadAccess(): expected an address (integer) as argument"); ad = PyLong_AsLong(addr); if (PIN_CheckReadAccess(reinterpret_cast<void*>(ad)) == true) Py_RETURN_TRUE; Py_RETURN_FALSE; }
/* Used to deref a pointer address and returns the targeted byte by size of read */ uint128 PINContextHandler::getMemValue(uint64 mem, uint32 readSize) const { if (PIN_CheckReadAccess(reinterpret_cast<void*>(mem)) == false) { std::cout << "[Bugs] Invalid read at " << std::hex << mem << std::endl; exit(0); } switch(readSize){ case BYTE_SIZE: return static_cast<uint128>(*(reinterpret_cast<uint8 *>(mem))); case WORD_SIZE: return static_cast<uint128>(*(reinterpret_cast<UINT16 *>(mem))); case DWORD_SIZE: return static_cast<uint128>(*(reinterpret_cast<uint32 *>(mem))); case QWORD_SIZE: return static_cast<uint128>(*(reinterpret_cast<uint64 *>(mem))); case DQWORD_SIZE: return static_cast<uint128>(*(reinterpret_cast<uint128 *>(mem))); } throw std::runtime_error("Error: PINContextHandler::getMemValue() - Invalid read size"); return 0; // Never go there }
VOID MmapAfter(ADDRINT ret) { TraceFile << dec << PIN_CheckReadAccess((void * )ret); TraceFile << dec << PIN_CheckWriteAccess((void * )ret); TraceFile << endl; }
void HeapStackTrace::Resolve ( ADDRINT Address ) { // // If 'Address' is actually a RtlAllocHandle handle (i.e. MEM_MOVEABLE allocated // via GlobalAlloc or LocalAlloc), translate to the actual allocation. // // This breaks the 1:1-ness in some ways, but it's for the better. // ADDRINT ActualHeapAddr = TranslateThroughRtlHandle(Address); if (ActualHeapAddr) { Address = ActualHeapAddr; } // // Union for ease of manipulation // union { void * loopPvoid; ADDRINT loopAddrint; DPH_BLOCK_INFORMATION * loopBlock; }; loopAddrint = Address; // // See Microsoft's site for documentation of the PageHeap internals, at: // http://msdn.microsoft.com/en-us/library/ms220938(v=vs.90).aspx // size_t AllocatorAlignment = 8; size_t InitialSubtraction = sizeof(DPH_BLOCK_INFORMATION) - AllocatorAlignment; const size_t StampSize = sizeof(BlockHeaderStartFill); size_t BytesCopied = 0; ptrdiff_t StopStampOffset = FIELD_OFFSET(DPH_BLOCK_INFORMATION, EndStamp); size_t TotalBytes = 0; // // Align to allocator granularity // loopAddrint &= ~(AllocatorAlignment - 1); // // Skip back at least one struct size, minus the size we subtract // at the top of the loop // loopAddrint -= InitialSubtraction; // // Search backward, starting one full structure size back. // If an exception occurs, bail. // // For whatever reason, normal __try/__except handling doesn't work // inside pintools. Because of this, we have to use PIN_SafeCopy. // // Exit the loop if a copy fails (i.e. throws a #AV), if we find a match, // or if we process 64KB. // PageHeapBlock = NULL; for ( TotalBytes = 0; NULL == PageHeapBlock && TotalBytes < 0x10000; TotalBytes += AllocatorAlignment) { // // Work backwards in memory, as the block precedes the allocation // which the user should/ought to write to. // loopAddrint -= AllocatorAlignment; // // If the read will cross a new page boundary (moving backward), // ensure we won't throw a #AV. // // We don't have to check in the forward direction. // // N.B.: Using PIN_SafeCopy instead of this read check **DOUBLES** // the total run-time. // ADDRINT StartPage = loopAddrint & ~(0xfff); ADDRINT EndPage = (loopAddrint + sizeof(DPH_BLOCK_INFORMATION)) & ~(0xfff); if (StartPage != EndPage && !PIN_CheckReadAccess(loopPvoid)) { return; } // // Attempt to read and verify the contents of the stamps // switch (loopBlock->StartStamp) { case BlockHeaderStartFill: case FullBlockHeaderStartFillFree: case BlockHeaderStartFillFree: case FullBlockHeaderStartFill: break; default: continue; } switch (loopBlock->EndStamp) { case BlockHeaderEndFill: case FullBlockHeaderEndFill: case BlockHeaderEndFillFree: case FullBlockHeaderEndFillFree: break; default: continue; } // // Probe the stack entry to see if it's valid. If it contains a non-NULL // address, but points to invalid memory, do not accept it, and bail out. // if (loopBlock != NULL && PIN_CheckReadAccess(loopBlock->StackTrace)) { ResolvedAddress = Address; PageHeapBlock = loopBlock; } } }