/** * Returns an XML string from the prefetch record provided. */ // Private helper functions; turn a prefect record into an XML string */ std::string prefetch_record_t::to_xml() { stringstream ss; // generate the prefetch feature in a stringstream ss << "<prefetch>"; ss << "<os>" << dfxml_writer::xmlescape(prefetch_version) << "</os>"; ss << "<filename>" << dfxml_writer::xmlescape(execution_filename) << "</filename>"; ss << "<header_size>" << header_size << "</header_size>"; ss << "<atime>" << microsoftDateToISODate(execution_time) << "</atime>"; ss << "<runs>" << execution_counter << "</runs>"; ss << "<filenames>"; for(vector<string>::const_iterator it = files.begin(); it != files.end(); it++) { ss << "<file>" << dfxml_writer::xmlescape(*it) << "</file>"; } ss << "</filenames>"; ss << "<volume>"; ss << "<path>" << dfxml_writer::xmlescape(volume_path_name) << "</path>"; ss << "<creation>" << microsoftDateToISODate(volume_creation_time) << "</creation>"; ss << "<serial_number>" << hex << volume_serial_number << dec << "</serial_number>"; ss << "<dirnames>"; for(vector<string>::const_iterator it = directories.begin(); it != directories.end(); it++) { ss << "<dir>" << dfxml_writer::xmlescape(*it) << "</dir>"; } ss << "</dirnames>"; ss << "</volume>"; ss << "</prefetch>"; // return the xml as a string string prefetch_xml = ss.str(); return prefetch_xml; }
void scan_winlnk(const class scanner_params &sp,const recursion_control_block &rcb) { assert(sp.sp_version==scanner_params::CURRENT_SP_VERSION); if(sp.phase==scanner_params::PHASE_STARTUP){ assert(sp.info->si_version==scanner_info::CURRENT_SI_VERSION); sp.info->name = "winlnk"; sp.info->author = "Simson Garfinkel"; sp.info->description = "Search for Windows LNK files"; sp.info->feature_names.insert("winlnk"); debug = sp.info->config->debug; return; } if(sp.phase==scanner_params::PHASE_SCAN){ // phase 1: set up the feature recorder and search for winlnk features const sbuf_t &sbuf = sp.sbuf; feature_recorder *winlnk_recorder = sp.fs.get_name("winlnk"); // make sure that potential LNK file is large enough and has the correct signature if (sbuf.pagesize <= SMALLEST_LNK_FILE){ return; } for (size_t p=0;(p < sbuf.pagesize) && (p < sbuf.bufsize - SMALLEST_LNK_FILE); p++){ if ( sbuf.get32u(p+0x00) == 0x0000004c && sbuf.get32u(p+0x04) == 0x00021401 && sbuf.get32u(p+0x08) == 0x00000000 && sbuf.get32u(p+0x0c) == 0x000000c0 && sbuf.get32u(p+0x10) == 0x46000000 ){ dfxml_writer::strstrmap_t lnkmap; uint32_t LinkFlags = sbuf.get32u(p+0x0014); bool HasLinkTargetIDList = LinkFlags & (1 << 0); bool HasLinkInfo = LinkFlags & (1 << 1); //bool HasName = LinkFlags & (1 << 2); //bool HasRelativePath = LinkFlags & (1 << 3); //bool HasWorkingDir = LinkFlags & (1 << 4); //uint32_t FileAttributes = sbuf.get32u(p+0x0018); uint64_t CreationTime = sbuf.get64u(p+0x001c); uint64_t AccessTime = sbuf.get64u(p+0x0024); uint64_t WriteTime = sbuf.get64u(p+0x002c); size_t loc = 0x004c; // location of next section lnkmap["ctime"] = microsoftDateToISODate(CreationTime); lnkmap["atime"] = microsoftDateToISODate(AccessTime); lnkmap["wtime"] = microsoftDateToISODate(WriteTime); if (HasLinkTargetIDList ){ uint16_t IDListSize = sbuf.get16u(p+loc); loc += IDListSize + 2; } std::string path("NOLINKINFO"); if (HasLinkInfo ){ uint32_t LinkInfoSize = sbuf.get32u(p+loc); //uint32_t LinkInfoHeaderSize = sbuf.get32u(p+loc+4); //uint32_t LinkInfoFlags = sbuf.get32u(p+loc+8); //uint32_t VolumeIDOffset = sbuf.get32u(p+loc+12); uint32_t LocalBasePathOffset = sbuf.get32u(p+loc+16); //uint32_t CommonNetworkRelativeLinkOffset = sbuf.get32u(p+loc+20); //uint32_t CommonPathSuffixOffset = sbuf.get32u(p+loc+20); /* copy out the pathname */ path = ""; for(size_t i = p+loc+LocalBasePathOffset; i<sbuf.bufsize && sbuf[i]; i++){ path += sbuf[i]; } lnkmap["path"] = path; loc += LinkInfoSize; } winlnk_recorder->write(sbuf.pos0+p,path,dfxml_writer::xmlmap(lnkmap,"lnk","")); p += loc; } else /** * At present we don't entirely support LNK parsing, and * some blocks need to be carved because of this. */ if ( sbuf.get32u(p+0x00) == 0x00000060 && sbuf.get32u(p+0x04) == 0xa0000003 && sbuf.get32u(p+0x08) == 0x00000058 && sbuf.get32u(p+0x0c) == 0x00000000){ dfxml_writer::strstrmap_t lnkguid; std::string dvolid = get_guid(sbuf, p+32); lnkguid["droid_volumeid"] = dvolid; lnkguid["droid_fileid"] = get_guid(sbuf, p+48); lnkguid["birth_volumeid"] = get_guid(sbuf, p+64); lnkguid["birth_fileid"] = get_guid(sbuf, p+80); winlnk_recorder->write(sbuf.pos0+p,dvolid,dfxml_writer::xmlmap(lnkguid,"lnk-guid","")); p += 96; } } } }