/*! * Test the PIN_SafeCopy() function in the following scenarios: * A. Successful copy of an entire memory region * B. Partial copy of a memory region, whose tail is inaccessible * C. Failure to copy an inaccessible memory region */ VOID SafeCopyTest() { size_t pageSize = GetPageSize(); CHAR * src = (CHAR *)MemAlloc(2*pageSize); ASSERTX(src != 0); CHAR * srcBuf = src + 1; // +1 for testing unaligned access CHAR * dst = (CHAR *)MemAlloc(2*pageSize); ASSERTX(dst != 0); CHAR * dstBuf = dst + 1; // +1 for testing unaligned access size_t bufSize = 2*pageSize - 1; size_t halfBufSize = pageSize - 1; size_t copySize; //A. for (unsigned int i = 0; i < bufSize; ++i) { src[i] = i/256; dst[i] = 0; } copySize = PIN_SafeCopy(dstBuf, srcBuf, bufSize); ASSERT(((copySize == bufSize) && (memcmp(dstBuf, srcBuf, bufSize) == 0)), "SafeCopy (A) failed.\n"); out << "SafeCopy (A): Entire buffer has been copied successfully." << endl << flush; //B. for (unsigned int i = 0; i < pageSize; ++i) { dst[i] = 0; } MemProtect(src + pageSize, pageSize, FALSE); // second half of src is inaccessible copySize = PIN_SafeCopy(dstBuf, srcBuf, bufSize); ASSERT(((copySize == halfBufSize) && (memcmp(dstBuf, srcBuf, halfBufSize) == 0)), "SafeCopy (B) failed.\n"); // Check to see that all accessible bytes near the end of the first page are copied successfully for (unsigned int sz = 1; sz < 16; ++sz) { for (unsigned int i = 0; i < sz; ++i) { dstBuf[i] = 0; } copySize = PIN_SafeCopy(dstBuf, src + pageSize - sz, pageSize); ASSERT(((copySize == sz) && (memcmp(dstBuf, src + pageSize - sz, sz) == 0)), "SafeCopy (B) failed.\n"); } out << "SafeCopy (B): Accessible part of the buffer has been copied successfully." << endl << flush; //C. MemProtect(dst, pageSize, FALSE); // dst is inaccessible copySize = PIN_SafeCopy(dstBuf, srcBuf, bufSize); ASSERT((copySize == 0), "SafeCopy (C) failed.\n"); out << "SafeCopy (C): Inaccessible buffer has not been copied." << endl << flush; MemFree(src, 2*pageSize); MemFree(dst, 2*pageSize); }
//return the entropy value of the entire program float ProcInfo::GetEntropy(){ IMG binary_image = APP_ImgHead(); // trick in order to convert a ln in log2 const double d1log2 = 1.4426950408889634073599246810023; double Entropy = 0.0; unsigned long Entries[256]; unsigned char* Buffer; //calculate the entropy only on the main module address space ADDRINT start_address = IMG_LowAddress(binary_image); ADDRINT end_address = IMG_HighAddress(binary_image); UINT32 size = end_address - start_address; // copy the main module in a buffer in order to analyze it Buffer = (unsigned char *)malloc(size); PIN_SafeCopy(Buffer , (void const *)start_address , size); // set to all zero the matrix of the bytes occurrence memset(Entries, 0, sizeof(unsigned long) * 256); // increment the counter of the current read byte (Buffer[i])in the occurence matrix (Entries) for (unsigned long i = 0; i < size; i++) Entries[Buffer[i]]++; // do the shannon formula on the occurence matrix ( H = sum(P(i)*log2(P(i)) ) for (unsigned long i = 0; i < 256; i++) { double Temp = (double) Entries[i] / (double) size; if (Temp > 0) Entropy += - Temp*(log(Temp)*d1log2); } return Entropy; }
//-------------------------------------------------------------------------- static VOID app_start_cb(VOID *v) { IMG img = APP_ImgHead(); for( SEC sec= IMG_SecHead(img); SEC_Valid(sec); sec = SEC_Next(sec) ) { ADDRINT sec_ea = SEC_Address(sec); if ( sec_ea != 0 ) { ADDRINT check; size_t bytes = PIN_SafeCopy(&check, (void*)sec_ea, sizeof(ADDRINT)); if ( bytes == sizeof(ADDRINT) ) { if ( min_ea > sec_ea || min_ea == 0 ) min_ea = sec_ea; if ( max_ea < sec_ea || max_ea == (unsigned)-1 ) max_ea = sec_ea; segdata_t seg; seg.size = SEC_Size(sec); seg.check = check; seg.written = false; seg_bytes[sec_ea] = seg; //cerr << "Monitoring segment " << SEC_Name(sec) << " " << hexstr(sec_ea) // << ":" << hexstr(sec_ea+SEC_Size(sec)) << endl; } } } }
VOID EmitWrite(THREADID threadid, UINT32 size) { assert(size <= 100); char bytes[101]; struct timeval tv; VOID *ea = WriteEa[threadid]; if(MemregionTracker::address_mapped(ea)) { gettimeofday(&tv, NULL); PIN_SafeCopy(&bytes[0], static_cast<char *>(ea), size); bytes[size] = '\0'; m_dump_bytes(bytes, size); if(mwrite_tracker[threadid].next_location == ea && time_diff(tv, mwrite_tracker[threadid].last_time) < coalesce_microsecs) { mwrite_tracker[threadid].size += size; } else { flush_mwrite(threadid); PrintTime(&tv); output_stacktrace(); if(print_chars) { char tmp[100]; printable_string(bytes, tmp, 100); mprintf("mwrite(%p, \"%s\"..., ", ea, tmp); } else { mprintf("mwrite(%p, \"\"..., ", ea); } mwrite_tracker[threadid].size = size; } mwrite_tracker[threadid].next_location = (UINT8 *)ea + size; mwrite_tracker[threadid].last_time = tv; } }
static VOID SyscallEntry(THREADID threadIndex, CONTEXT *ctxt, SYSCALL_STANDARD std, VOID *v) { if (PIN_GetSyscallNumber(ctxt, std) != SYS_sysarch) return; ADDRINT pc = PIN_GetContextReg(ctxt, REG_INST_PTR); ADDRINT op = PIN_GetSyscallArgument(ctxt, std, 0); ADDRINT addr = PIN_GetSyscallArgument(ctxt, std, 1); ADDRINT value = 0; if (op == AMD64_SET_FSBASE || op == AMD64_SET_GSBASE) { if (PIN_SafeCopy(&value, Addrint2VoidStar(addr), sizeof(ADDRINT)) != sizeof(ADDRINT)) { Out << Header(threadIndex, pc) << "Failed to read actual TLS pointer" << endl; } } else { // Remember the location where to write the segment register in REG_INST_G0 PIN_SetContextReg(ctxt, REG_INST_G0, addr); value = addr; } Out << Header(threadIndex, pc) << "sysarch(" << SysArchFunc(op) << ", 0x" << std::hex << value << ")" << std::endl; }
ADDRINT PIN_FAST_ANALYSIS_CALL memoryCallback(PIN_MEM_TRANS_INFO* memTransInfo, VOID *v) { icountMemCall++; lastIp = memTransInfo->ip; if (memTransInfo->memOpType == PIN_MEMOP_STORE ) { lastWriteAddr = memTransInfo->addr; // Verify that we can call PIN API functions inside PIN PIN_SafeCopy((void*)memTransInfo->addr, (void*)memTransInfo->addr, memTransInfo->bytes); } else lastReadAddr = memTransInfo->addr; // Check void parameter if ((ADDRINT)v != 0xa5a5a5a5) { OutFile << "v incorrect inside callback: " << hex << v << endl; errors++; } //OutFile << "callback addresses: " << hex << (memTransInfo->addr) << " " << (memTransInfo->addr & mask) << " " <<memTransInfo->ip << endl; return (memTransInfo->addr & mask); }
// Move from memory to register ADDRINT DoLoad(REG reg, ADDRINT * addr) { *out << "Emulate loading from addr " << addr << " to " << REG_StringShort(reg) << endl; ADDRINT value; PIN_SafeCopy(&value, addr, sizeof(ADDRINT)); return value; }
/****************************************************************** Title:getMemAddress Function:Get the memory address Input: int value:Memory address Output: ******************************************************************/ VOID getMemAddress(ADDRINT addr) { //memAddr = (int)addr; fprintf(log,"Address ins:0x%x\n",addr); PIN_SafeCopy(&memAddr, &addr, sizeof(ADDRINT)); }
VOID LeaAdd(THREADID tid, ADDRINT sp, ADDRINT eip, ADDRINT bp ) { size_t sizeread1, sizeread2, sizeread3; ADDRINT value, bpval, bp18 = bp + 0x18, bp18val; PIN_LockClient(); sizeread1 = PIN_SafeCopy(&value, (const VOID *)sp, sizeof(uint64_t)); sizeread2 = PIN_SafeCopy(&bpval, (const VOID *)bp, sizeof(uint64_t)); sizeread3 = PIN_SafeCopy(&bp18val, (const VOID *)bp18, sizeof(uint64_t)); if ( sizeread1 != sizeof(uint64_t) || sizeread2 != sizeof(uint64_t) || sizeread3 != sizeof(uint64_t) ) OutFile << "Incorrect Size read from stack for sp: " << hex << sp << " " << sizeread1 << " " << sizeread2 << endl; else OutFile << tid << " Stack " << hex << sp << " Val " << value << " BP " << bp << " BPVAL " << bpval << " BP+18 " << bp18 <<" Valbp+18 " << bp18val << endl; PIN_UnlockClient(); OutFile << dec << tid << " LEA " << hex << eip << " " << sp << " "<< bp << endl; }
static VOID DoSafeCopy() { // Before the bug was fixed in Pin, the first SafeCopy() would work, but would // reset the internal SEGV handler (because of SA_RESETHAND). This caused the // second SafeCopy() to fail. That's why we call SafeCopy() twice. // int word; size_t sz = PIN_SafeCopy(&word, 0, sizeof(word)); if (sz != 0) { std::cerr << "SafeCopy should fail (1)\n"; std::exit(1); } sz = PIN_SafeCopy(&word, 0, sizeof(word)); if (sz != 0) { std::cerr << "SafeCopy should fail (2)\n"; std::exit(1); } std::exit(0); }
void handle_analyze (PIN_REGISTER * pGdx, PIN_REGISTER * pGax, ADDRINT pDivisor, unsigned int opSize, CONTEXT * ctxt, THREADID thr_id) { ADDRINT divisor = 0; PIN_SafeCopy (&divisor, (VOID *)pDivisor, opSize); Divide_Handler div_handler (thr_id, ctxt); UINT64 dividend = *((ADDRINT *)pGdx); dividend <<= 32; dividend += *((ADDRINT *)pGax); *((ADDRINT *)pGax) = static_cast <ADDRINT> (dividend / divisor); *((ADDRINT *)pGdx) = static_cast <ADDRINT> (dividend % divisor); }
VOID EmulateMemDivide(ADDRINT * pGdx, ADDRINT * pGax, ADDRINT *pDivisor, unsigned int opSize, CONTEXT * ctxt, THREADID tid) { ADDRINT divisor = 0; PIN_SafeCopy(&divisor, pDivisor, opSize); PIN_TryStart(tid, DivideHandler, ctxt); UINT64 dividend = *pGdx; dividend <<= 32; dividend += *pGax; *pGax = dividend / divisor; *pGdx = dividend % divisor; PIN_TryEnd(tid); }
VOID Branch( THREADID tid, ADDRINT sp, ADDRINT target, ADDRINT eip ) { if ( target >= (start+FFI_CALL_UNIX64) && (target <= start+FF64END) ) { OutFile << tid << " BRANCH" << hex <<" "<< eip << " " << target << " " << sp << endl; leaflag = true; size_t sizeread; ADDRINT value; PIN_LockClient(); sizeread = PIN_SafeCopy(&value, (const VOID *)sp, sizeof(uint64_t)); if ( sizeread != sizeof(uint64_t) ) OutFile << "Incorrect Size read from stack for sp: " << hex << sp << " " << sizeread << endl; else OutFile << tid << " Stack " << hex << sp << " Val " << value << endl; PIN_UnlockClient(); } if ( target == (start+FF64PLT) ) OutFile << tid << " J-PLT64 " << hex <<" "<< eip << " " << target << " " << sp << endl; if ( eip >= (start+FFI_CALL_UNIX64) && eip <= (start+FF64END) ) { OutFile << tid << " J-FF64 " << hex << eip << " " << target << " " << sp << endl; } // Reading value on threads stack /* if ( eip >= (ANONST) && eip <= (ANONEND) ) { OutFile << tid << " BRANCH-I " << hex << eip << " " << target << " " << sp << endl; } if ( target >= (ANONST) && target <= (ANONEND) ) { OutFile << tid << " BRANCH-T " << hex << eip << " " << target << " " << sp << endl; } */ }
static void copy_from_aligned_store_buffer(ADDRINT store_addr, ADDRINT byte_len, ADDRINT ip, THREADID tid, sse_aligner_t* pthis) { thread_data_t* tdata = pthis->get_tls(tid); ADDRINT copied = PIN_SafeCopy(reinterpret_cast<uint8_t*>(store_addr), tdata->write, byte_len); if (copied != byte_len) { // The copy failed, this happens if the data is accessing an unmapped page. // To cause a similar fault we access the faulting data here... *(reinterpret_cast<uint8_t*>(store_addr) + copied) = tdata->write[copied]; } }
static VOID SyscallExit(THREADID threadIndex, CONTEXT *ctxt, SYSCALL_STANDARD std, VOID *v) { ADDRINT addr = PIN_GetContextReg(ctxt, REG_INST_G0); if (!addr) return; // Reset REG_INST_G0 PIN_SetContextReg(ctxt, REG_INST_G0, 0); ADDRINT pc = PIN_GetContextReg(ctxt, REG_INST_PTR); ADDRINT ret = PIN_GetSyscallReturn(ctxt, std); ADDRINT value = 0; if (ret == (ADDRINT)-1 || PIN_SafeCopy(&value, Addrint2VoidStar(addr), sizeof(ADDRINT)) != sizeof(ADDRINT)) { Out << Header(threadIndex, pc) << "Failed to read actual TLS pointer" << endl; } Out << Header(threadIndex, pc) << "sysarch returned: " << ", 0x" << std::hex << value << "" << std::endl; }
//by default memory buffers have direct access Handle<Value> MemoryBuffer(const Arguments& args) { HandleScope scope; if (args.Length() < 2) { return ThrowException( String::New("MemoryBuffer constructor must have two parameters (address and size).")); } TryCatch try_catch; uint32_t address = NumberToUint32(args[0], &try_catch); uint32_t length = convertToUint(args[1], &try_catch); uint8_t* data; bool is_external = false; if (try_catch.HasCaught()) return try_catch.Exception(); static const int32_t kMaxSize = 0x7fffffff; // Make sure the total size fits into a (signed) int. if (length < 0 || length > kMaxSize) { return ThrowException(String::New("ArrayBuffer exceeds maximum size (2G)")); } //check if we should snapshot the value if (args.Length() > 2 && args[2]->IsTrue()) { data = new uint8_t[length]; if (data == NULL) { return ThrowException(String::New("Memory allocation failed.")); } V8::AdjustAmountOfExternalAllocatedMemory(length); PIN_SafeCopy(data, reinterpret_cast<uint8_t *>(address), length); } else { data = reinterpret_cast<uint8_t *>(address); is_external = true; } Handle<Value> buffer = CreateExternalArrayBuffer(length, data); buffer->ToObject()->Set(String::New("snapshot"), (is_external ? False() : True()), ReadOnly); if (is_external) buffer->ToObject()->Set(String::New("externalBuffer"), True(), ReadOnly); return scope.Close(buffer); }
static ADDRINT copy_to_aligned_load_buffer_and_return_pointer(ADDRINT load_addr, ADDRINT byte_len, ADDRINT ip, THREADID tid, sse_aligner_t* pthis) { // return the address to use for the SSEx operation thread_data_t* tdata = pthis->get_tls(tid); ADDRINT copied = PIN_SafeCopy(tdata->read, reinterpret_cast<uint8_t*>(load_addr), byte_len); if (copied != byte_len) { // The copy failed, this happens if the data is accessing an unmapped page // to cause a similar fault we access the faulting data here... (void)*(reinterpret_cast<uint8_t*>(load_addr) + copied); } return reinterpret_cast<ADDRINT>(tdata->read); }
void push_log( memorylog_entry* memlogs, UINT32* pLogcnt, ADDRINT addr, UINT32 size, bool storePrev ) { memlogs[*pLogcnt].addr = addr; if ( storePrev ) assert( PIN_SafeCopy( &memlogs[*pLogcnt].val[0], (const void*) addr, size ) == size ); else {} memlogs[*pLogcnt].size = (UINT16) size; *pLogcnt += 1; assert( *pLogcnt < MAX_ENTRY ); }
/*! * Test SafeCopy in the trace instrumentation callback */ VOID Trace(TRACE trace, VOID *v) { static BOOL first = TRUE; if (first) { first = FALSE; out << "Test SafeCopy in the trace instrumentation callback." << endl << flush; SafeCopyTest(); TRACE_InsertCall(trace, IPOINT_BEFORE, (AFUNPTR)SafeCopyTestInTrace, IARG_END); } // Verify that pin-inserted probes are not visible through PIN_SafeCopy if (probeAddr != 0) { out << "Test SafeCopy in a region overwritten by probe." << endl << flush; CHAR buffer[8]; size_t copySize = PIN_SafeCopy(buffer, probeAddr, sizeof(buffer)); ASSERT((copySize == sizeof(buffer)), "SafeCopy failed in a region overwritten by probe.\n"); ASSERT((memcmp(buffer, probeAddr, copySize) != 0), "Pin inserted probes are visible through SafeCopy.\n"); probeAddr = 0; } }
//log the mem write value,addr and ip static ADDRINT RecordMemWrite(VOID* addr) { PIN_SafeCopy(&mem_value, MEMWR_addr, 8); //printf("%lu r\n",mem_value); //buf_ref->value=mem_value; //buf_ref=buf_ref+1; buffer[index].value=(UINT64)mem_value; printf("%lu\n",mem_value); //just for test if(index==MAX_SIZE-1) { StoreToFile(index);//buffer is full,store the content to file tem index=0; } else index=index+1; //fprintf(trace,"%lu \n", mem_value); return 0; }
float ProcInfo::GetEntropy(){ IMG binary_image = APP_ImgHead(); const double d1log2 = 1.4426950408889634073599246810023; double Entropy = 0.0; unsigned long Entries[256]; unsigned char* Buffer; ADDRINT start_address = IMG_LowAddress(binary_image); ADDRINT end_address = IMG_HighAddress(binary_image); UINT32 size = end_address - start_address; Buffer = (unsigned char *)malloc(size); MYLOG("size to dump is %d" , size); MYLOG("Start address is %08x" , start_address); MYLOG("Start address is %08x" , end_address); MYLOG("IMAGE NAME IS %s" , IMG_Name(binary_image)); PIN_SafeCopy(Buffer , (void const *)start_address , size); memset(Entries, 0, sizeof(unsigned long) * 256); for (unsigned long i = 0; i < size; i++) Entries[Buffer[i]]++; for (unsigned long i = 0; i < 256; i++) { double Temp = (double) Entries[i] / (double) size; if (Temp > 0) Entropy += - Temp*(log(Temp)*d1log2); } MYLOG("ENTROPY IS %f" , Entropy); return Entropy; }
unsigned int PinExecutionContext::setMemory(char *addr, size_t size, char *buffer) { return (unsigned int) PIN_SafeCopy(addr, buffer, size); }
/*! * Touch (read) the specified memory address. */ VOID TouchMemory(CHAR * addr) { CHAR value; PIN_SafeCopy(&value, addr, sizeof(CHAR)); }
instruction::instruction(const INS& ins) { this->address = INS_Address(ins); this->next_address = INS_NextAddress(ins); // this->opcode = INS_Mnemonic(ins); this->opcode_size = static_cast<uint8_t>(INS_Size(ins)); this->opcode_buffer = std::shared_ptr<uint8_t>(new uint8_t[this->opcode_size], std::default_delete<uint8_t[]>()); PIN_SafeCopy(opcode_buffer.get(), reinterpret_cast<const VOID*>(this->address), this->opcode_size); this->disassemble = INS_Disassemble(ins); // including image, routine auto img = IMG_FindByAddress(this->address); this->including_image = IMG_Valid(img) ? IMG_Name(img) : ""; // this->including_routine = RTN_FindNameByAddress(this->address); PIN_LockClient(); auto routine = RTN_FindByAddress(this->address); PIN_UnlockClient(); if (RTN_Valid(routine)) { auto routine_mangled_name = RTN_Name(routine); this->including_routine_name = PIN_UndecorateSymbolName(routine_mangled_name, UNDECORATION_NAME_ONLY); } else this->including_routine_name = ""; // has fall through this->has_fall_through = INS_HasFallThrough(ins); // is call, ret or syscall this->is_call = INS_IsCall(ins); this->is_branch = INS_IsBranch(ins); this->is_ret = INS_IsRet(ins); this->is_syscall = INS_IsSyscall(ins); this->category = static_cast<xed_category_enum_t>(INS_Category(ins)); this->iclass = static_cast<xed_iclass_enum_t>(INS_Opcode(ins)); // read registers auto read_reg_number = INS_MaxNumRRegs(ins); for (decltype(read_reg_number) reg_id = 0; reg_id < read_reg_number; ++reg_id) { this->src_registers.push_back(INS_RegR(ins, reg_id)); } // written registers auto written_reg_number = INS_MaxNumWRegs(ins); for (decltype(written_reg_number) reg_id = 0; reg_id < written_reg_number; ++reg_id) { this->dst_registers.push_back(INS_RegW(ins, reg_id)); } auto is_special_reg = [](const REG& reg) -> bool { return (reg >= REG_MM_BASE); }; this->is_special = std::any_of(std::begin(this->src_registers), std::end(this->src_registers), is_special_reg) || std::any_of(std::begin(this->dst_registers), std::end(this->dst_registers), is_special_reg) || (this->category == XED_CATEGORY_X87_ALU) || (this->iclass == XED_ICLASS_XEND) || (this->category == XED_CATEGORY_LOGICAL_FP) || (this->iclass == XED_ICLASS_PUSHA) || (this->iclass == XED_ICLASS_PUSHAD) || (this->iclass == XED_ICLASS_PUSHF) || (this->iclass == XED_ICLASS_PUSHFD) || (this->iclass == XED_ICLASS_PUSHFQ); // is memory read, write this->is_memory_read = INS_IsMemoryRead(ins); this->is_memory_write = INS_IsMemoryWrite(ins); this->is_memory_read2 = INS_HasMemoryRead2(ins); }
// Move from memory to register ADDRINT MovRM(ADDRINT op0, ADDRINT * op1) { ADDRINT value; PIN_SafeCopy(&value, op1, sizeof(ADDRINT)); return value; }
// Move a register or literal to memory VOID MovMV(ADDRINT * op0, ADDRINT op1) { PIN_SafeCopy(op0, &op1, sizeof(ADDRINT)); }
unsigned int PinExecutionContext::getMemory(const char *addr, size_t size, char *buffer) const { return (unsigned int) PIN_SafeCopy(buffer, addr, size); }
VOID Test(ADDRINT * sp) { ADDRINT value; PIN_SafeCopy(&value, sp, sizeof(ADDRINT)); TraceFile << value << endl; }