//0.95 - 0.96 ULONG_PTR ScyllaTELock::fixType3(ULONG_PTR InvalidApiAddress) { const uint8_t MOV_EAX = 0xB8; const uint8_t PUSH_DW_EAX[] = {0xFF, 0x30}; const uint8_t RETN = 0xC3; const uint8_t JMP_DW_EAX[] = {0xFF, 0x20}; const uint8_t NOP = 0x90; static const uint8_t pattern_1[] = { MOV_EAX, 1, 1, 1, 1, PUSH_DW_EAX[0], PUSH_DW_EAX[1], RETN }; static const uint8_t pattern_2[] = { MOV_EAX, 1, 1, 1, 1, JMP_DW_EAX[0], JMP_DW_EAX[1], NOP }; static const char mask[] = "X????XXX"; const size_t offs_x = 1; const size_t MAX_BYTES = 35; /* <code> <...> MOV EAX, X JMP DWORD [EAX] ; or PUSH DWORD [EAX] + RETN */ const uint8_t* bPtr = reinterpret_cast<const uint8_t*>(InvalidApiAddress); if(validMemory(InvalidApiAddress, MAX_BYTES + std::max(sizeof(pattern_1), sizeof(pattern_2)))) { const uint8_t* found; if((found = findPattern(bPtr, MAX_BYTES + sizeof(pattern_1), pattern_1, sizeof(pattern_1), mask)) || (found = findPattern(bPtr, MAX_BYTES + sizeof(pattern_2), pattern_2, sizeof(pattern_2), mask))) { uint32_t X = *reinterpret_cast<const uint32_t*>(found+offs_x); if(validMemory(X, sizeof(ULONG_PTR))) { return *reinterpret_cast<const ULONG_PTR*>(X); } } } return NULL; }
// Find the native address for the start of the main entry function. // For Palm binaries, this is PilotMain. Address PalmBinaryLoader::getMainEntryPoint() { BinarySection *psect = m_binaryImage->getSectionByName("code1"); if (psect == nullptr) { return Address::ZERO; // Failed } // Return the start of the code1 section SWord *startCode = reinterpret_cast<SWord *>(psect->getHostAddr().value()); int delta = (psect->getHostAddr() - psect->getSourceAddr()).value(); // First try the CW first jump pattern const SWord *res = findPattern(startCode, sizeof(CWFirstJump) / sizeof(SWord), CWFirstJump, sizeof(CWFirstJump) / sizeof(SWord)); if (res) { // We have the code warrior first jump. Get the addil operand const int addilOp = static_cast<int>(Util::readDWord((startCode + 5), Endian::Big)); SWord *startupCode = reinterpret_cast<SWord *>( (HostAddress(startCode) + 10 + addilOp).value()); // Now check the next 60 SWords for the call to PilotMain res = findPattern(startupCode, 60, CWCallMain, sizeof(CWCallMain) / sizeof(SWord)); if (res) { // Get the addil operand const int _addilOp = Util::readDWord((res + 5), Endian::Big); // That operand plus the address of that operand is PilotMain Address offset_loc = Address(reinterpret_cast<const Byte *>(res) - reinterpret_cast<const Byte *>(startCode) + 5); return offset_loc + _addilOp; // ADDRESS::host_ptr(res) + 10 + addilOp - delta; } else { fprintf(stderr, "Could not find call to PilotMain in CW app\n"); return Address::ZERO; } } // Check for gcc call to main res = findPattern(startCode, 75, GccCallMain, sizeof(GccCallMain) / sizeof(SWord)); if (res) { // Get the operand to the bsr SWord bsrOp = res[7]; return Address((HostAddress(res) - delta).value() + 14 + bsrOp); } fprintf(stderr, "Cannot find call to PilotMain\n"); return Address::ZERO; }
/** * Main -- process command line, read in and pre-process the test file, * call other functions to do the actual tests. */ int main(int argc, const char** argv) { if (processOptions(argc, argv, opts) != TRUE || opt_help) { printf(gHelpString); return -1; } if (processCollator() != TRUE) { fprintf(stderr, "Error creating collator\n"); return -1; } if (processStringSearch() != TRUE) { fprintf(stderr, "Error creating string search\n"); return -1; } fprintf(stdout, "Finding pattern %s in source %s\n", opt_pattern, opt_source); findPattern(); ucol_close(collator); usearch_close(search); return 0; }
//0.51 - 0.85 ULONG_PTR ScyllaTELock::fixType1(ULONG_PTR InvalidApiAddress) { const uint8_t JMP_DW[] = {0xFF, 0x25}; static const uint8_t pattern[] = { JMP_DW[0], JMP_DW[1], 1, 1, 1, 1 }; static const char mask[] = "XX????"; const size_t offs_x = 2; /* JMP [X] */ const uint8_t* bPtr = reinterpret_cast<const uint8_t*>(InvalidApiAddress); if(validMemory(InvalidApiAddress, sizeof(pattern))) { if(findPattern(bPtr, sizeof(pattern), pattern, sizeof(pattern), mask)) { uint32_t X = *reinterpret_cast<const uint32_t*>(bPtr+offs_x); if(validMemory(X, sizeof(ULONG_PTR))) { return *reinterpret_cast<const ULONG_PTR*>(X); } } } return NULL; }
SvgPatternHelper* SvgParser::findPattern(const QString &id) { // check if pattern was already parsed, and return it if (m_patterns.contains(id)) return &m_patterns[ id ]; // check if pattern was stored for later parsing if (!m_context.hasDefinition(id)) return 0; SvgPatternHelper pattern; const KoXmlElement &e = m_context.definition(id); if (e.tagName() != "pattern") return 0; // are we referencing another pattern ? if (e.hasAttribute("xlink:href")) { QString mhref = e.attribute("xlink:href").mid(1); SvgPatternHelper *refPattern = findPattern(mhref); // inherit attributes of referenced pattern if (refPattern) pattern = *refPattern; } // ok parse pattern now parsePattern(pattern, m_context.definition(id)); // add to parsed pattern list m_patterns.insert(id, pattern); return &m_patterns[ id ]; }
void ScanPatternInMemory(BYTE * memory, DWORD memorySize,DWORD_PTR startOffset, TCHAR * pattern) { BYTE * bytePattern = 0; TCHAR * mask = 0; unsigned int len = _tcslen(pattern); if (len % 2) len++; len = (len/2) + 1; bytePattern = (BYTE *)malloc(len); mask = (TCHAR *)malloc(len * sizeof(TCHAR)); ZeroMemory(mask,len * sizeof(TCHAR)); ZeroMemory(bytePattern,len); TextToByteMask(pattern,bytePattern,mask,len); WriteLog(TEXT("Scanning pattern %s memory size 0x%X\r\n"),pattern,memorySize); WriteLog(TEXT("------------------------------------------------------\r\n")); DWORD found = findPattern((DWORD_PTR)memory,memorySize,bytePattern,mask, startOffset); WriteLog(TEXT("Found %d times\r\n"),found); WriteLog(TEXT("------------------------------------------------------\r\n")); free(mask); free(bytePattern); }
// Find the native address for the start of the main entry function. // For Palm binaries, this is PilotMain. ADDRESS PalmBinaryFile::GetMainEntryPoint() { SectionInfo* pSect = GetSectionInfoByName("code1"); if (pSect == 0) return 0; // Failed // Return the start of the code1 section SWord* startCode = (SWord*) pSect->uHostAddr; ptrdiff_t delta = pSect->uHostAddr - (unsigned char *)pSect->uNativeAddr; // First try the CW first jump pattern SWord* res = findPattern(startCode, CWFirstJump, sizeof(CWFirstJump) / sizeof(SWord), 1); if (res) { // We have the code warrior first jump. Get the addil operand int addilOp = (startCode[5] << 16) + startCode[6]; SWord* startupCode = (SWord*)((unsigned char *)startCode + 10 + addilOp); // Now check the next 60 SWords for the call to PilotMain res = findPattern(startupCode, CWCallMain, sizeof(CWCallMain) / sizeof(SWord), 60); if (res) { // Get the addil operand addilOp = (res[5] << 16) + res[6]; // That operand plus the address of that operand is PilotMain return (ADDRESS)res + 10 + addilOp - delta; } else { fprintf( stderr, "Could not find call to PilotMain in CW app\n" ); return 0; } } // Check for gcc call to main res = findPattern(startCode, GccCallMain, sizeof(GccCallMain) / sizeof(SWord), 75); if (res) { // Get the operand to the bsr SWord bsrOp = res[7]; return (ADDRESS)res + 14 + bsrOp - delta; } fprintf(stderr,"Cannot find call to PilotMain\n"); return 0; }
bool CustomPattern::findRt(InputArray image, InputArray cameraMatrix, InputArray distCoeffs, OutputArray rvec, OutputArray tvec, bool useExtrinsicGuess, int flags) { vector<Point2f> imagePoints; vector<Point3f> objectPoints; if (!findPattern(image, imagePoints, objectPoints)) return false; return solvePnP(objectPoints, imagePoints, cameraMatrix, distCoeffs, rvec, tvec, useExtrinsicGuess, flags); }
bool CustomPattern::findRtRANSAC(InputArray image, InputArray cameraMatrix, InputArray distCoeffs, OutputArray rvec, OutputArray tvec, bool useExtrinsicGuess, int iterationsCount, float reprojectionError, int minInliersCount, OutputArray inliers, int flags) { vector<Point2f> imagePoints; vector<Point3f> objectPoints; if (!findPattern(image, imagePoints, objectPoints)) return false; solvePnPRansac(objectPoints, imagePoints, cameraMatrix, distCoeffs, rvec, tvec, useExtrinsicGuess, iterationsCount, reprojectionError, minInliersCount, inliers, flags); return true; }
//0.98 ULONG_PTR ScyllaTELock::fixType4(ULONG_PTR InvalidApiAddress) { const uint8_t MOV_EAX = 0xB8; const uint8_t INC_EAX = 0x40; const uint8_t PUSH_DW_EAX[] = {0xFF, 0x30}; const uint8_t RETN = 0xC3; static const uint8_t pattern[] = { MOV_EAX, 1, 1, 1, 1, INC_EAX, PUSH_DW_EAX[0], PUSH_DW_EAX[1], RETN }; static const char mask[] = "X????XXXX"; const size_t offs_x = 1; const size_t MAX_BYTES = 35; /* <code> <...> MOV EAX, X INC EAX PUSH DWORD [EAX] RETN */ const uint8_t* bPtr = reinterpret_cast<const uint8_t*>(InvalidApiAddress); if(validMemory(InvalidApiAddress, MAX_BYTES + sizeof(pattern))) { const uint8_t* found = findPattern(bPtr, MAX_BYTES + sizeof(pattern), pattern, sizeof(pattern), mask); if(found) { uint32_t X = *reinterpret_cast<const uint32_t*>(found+offs_x); X++; if(validMemory(X, sizeof(ULONG_PTR))) { return *reinterpret_cast<const ULONG_PTR*>(X); } } } return NULL; }
bool LLTextParser::parseFullLineHighlights(const std::string &text, LLColor4 *color) { for (S32 i=0;i<mHighlights.size();i++) { if ((S32)mHighlights[i]["highlight"]==ALL || (S32)mHighlights[i]["condition"]==MATCHES) { if (findPattern(text,mHighlights[i]) >= 0 ) { LLSD color_llsd = mHighlights[i]["color"]; color->setValue(color_llsd); return TRUE; } } } return FALSE; //No matches found. }
// Sourcemod - Metamod - Allied Modders.net void *CSignatureFunction::findSignature ( void *addrInBase, const char *signature ) { // First, preprocess the signature unsigned char real_sig[511]; size_t real_bytes; real_bytes = decodeHexString(real_sig, sizeof(real_sig), signature); if (real_bytes >= 1) { return findPattern(addrInBase, (char*) real_sig, real_bytes); } return NULL; }
int main() { char a[][N] ={{'a','b','c','r','d'}, {'e','f','o','g','h'}, {'i','o','j','k','i'}, {'w','g','f','m','n'}, {'z','a','s','i','t'}}; char pattern[]="micrzsyft"; if(findPattern(a,pattern)) printf("Found Pattern\n"); else printf("No Pattern\n"); return 0; }
ULONG_PTR ScyllaRLP::resolveImport(ULONG_PTR ImportTableAddressPointer, ULONG_PTR InvalidApiAddress, ScyllaStatus& Status) { const uint8_t PUSH_DW = 0x68; const uint8_t ADD_DW_ESP[] = {0x81, 0x04, 0x24}; const uint8_t RETN = 0xC3; static const uint8_t pattern[] = { PUSH_DW, 1, 1, 1, 1, ADD_DW_ESP[0], ADD_DW_ESP[1], ADD_DW_ESP[2], 2, 2, 2, 2, RETN }; static const char mask[] = "X????XXX????x"; const size_t offs_x = 1; const size_t off_y = 8; /* PUSH X ADD [ESP], Y RETN */ if(!validMemory(InvalidApiAddress, sizeof(pattern))) { log("Invalid memory address\r\n"); Status = SCYLLA_STATUS_IMPORT_RESOLVING_FAILED; return NULL; } const uint8_t* bPtr = reinterpret_cast<const uint8_t*>(InvalidApiAddress); if(findPattern(bPtr, sizeof(pattern), pattern, sizeof(pattern), mask)) { uint32_t X = *reinterpret_cast<const uint32_t*>(bPtr+offs_x); uint32_t Y = *reinterpret_cast<const uint32_t*>(bPtr+off_y); return (X + Y); } log("Unsupported opcode found\r\n"); Status = SCYLLA_STATUS_UNSUPPORTED_PROTECTION; return NULL; }
//0.90 - 0.92 ULONG_PTR ScyllaTELock::fixType2(ULONG_PTR InvalidApiAddress) { const uint8_t PUSH_DW[] = {0xFF, 0x35}; const uint8_t RETN = 0xC3; static const uint8_t pattern[] = { PUSH_DW[0], PUSH_DW[1], 1, 1, 1, 1, 0, 0, 0, 0 }; static const char mask[] = "XX????????"; const size_t offs_x = 2; const size_t offs_retn_1 = 8; const size_t offs_retn_2 = 9; /* PUSH DWORD [X] <2-3 bytes junk> RETN <1 byte junk if only 2 before RETN> */ const uint8_t* bPtr = reinterpret_cast<const uint8_t*>(InvalidApiAddress); if(validMemory(InvalidApiAddress, sizeof(pattern))) { if(findPattern(bPtr, sizeof(pattern), pattern, sizeof(pattern), mask)) { if(bPtr[offs_retn_1] == RETN || bPtr[offs_retn_2] == RETN) { uint32_t X = *reinterpret_cast<const uint32_t*>(bPtr+offs_x); if(validMemory(X, sizeof(ULONG_PTR))) { return *reinterpret_cast<const ULONG_PTR*>(X); } } } } return NULL; }
LLSD LLTextParser::parsePartialLineHighlights(const std::string &text, const LLColor4 &color, EHighlightPosition part, S32 index) { //evil recursive string atomizer. LLSD ret_llsd, start_llsd, middle_llsd, end_llsd; for (S32 i=index;i<mHighlights.size();i++) { S32 condition = mHighlights[i]["condition"]; if ((S32)mHighlights[i]["highlight"]==PART && condition!=MATCHES) { if ( (condition==STARTS_WITH && part==START) || (condition==ENDS_WITH && part==END) || condition==CONTAINS || part==WHOLE ) { S32 start = findPattern(text,mHighlights[i]); if (start >= 0 ) { S32 end = std::string(mHighlights[i]["pattern"]).length(); S32 len = text.length(); EHighlightPosition newpart; if (start==0) { start_llsd[0]["text"] =text.substr(0,end); start_llsd[0]["color"]=mHighlights[i]["color"]; if (end < len) { if (part==END || part==WHOLE) newpart=END; else newpart=MIDDLE; end_llsd=parsePartialLineHighlights(text.substr( end ),color,newpart,i); } } else { if (part==START || part==WHOLE) newpart=START; else newpart=MIDDLE; start_llsd=parsePartialLineHighlights(text.substr(0,start),color,newpart,i+1); if (end < len) { middle_llsd[0]["text"] =text.substr(start,end); middle_llsd[0]["color"]=mHighlights[i]["color"]; if (part==END || part==WHOLE) newpart=END; else newpart=MIDDLE; end_llsd=parsePartialLineHighlights(text.substr( (start+end) ),color,newpart,i); } else { end_llsd[0]["text"] =text.substr(start,end); end_llsd[0]["color"]=mHighlights[i]["color"]; } } S32 retcount=0; //FIXME These loops should be wrapped into a subroutine. for (LLSD::array_iterator iter = start_llsd.beginArray(); iter != start_llsd.endArray();++iter) { LLSD highlight = *iter; ret_llsd[retcount++]=highlight; } for (LLSD::array_iterator iter = middle_llsd.beginArray(); iter != middle_llsd.endArray();++iter) { LLSD highlight = *iter; ret_llsd[retcount++]=highlight; } for (LLSD::array_iterator iter = end_llsd.beginArray(); iter != end_llsd.endArray();++iter) { LLSD highlight = *iter; ret_llsd[retcount++]=highlight; } return ret_llsd; } } } } //No patterns found. Just send back what was passed in. ret_llsd[0]["text"] =text; LLSD color_sd = color.getValue(); ret_llsd[0]["color"]=color_sd; return ret_llsd; }
ULONG_PTR ScyllaAlexProtector::resolveImport(ULONG_PTR ImportTableAddressPointer, ULONG_PTR InvalidApiAddress, ScyllaStatus& Status) { const uint8_t JMP_SHRT = 0xEB; const uint8_t PUSHAD = 0x60; const uint8_t RDTSC[] = {0x0F, 0x31}; const uint8_t PUSH = 0x68; const uint8_t RETN = 0xC3; static const uint8_t pattern[] = { JMP_SHRT, 0x01, 0, PUSHAD, RDTSC[0], RDTSC[1], 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, PUSH, 1, 1, 1, 1, 0, 0, 0, RETN }; static const char mask[] = "XX?XXX?????????????????????????????????????????????X???????X"; const size_t offs_api = 0x34; /* JMP +1 <junk> PUSHAD RDTSC JMP +1 <junk> MOV EBX, EAX JMP +1 <junk> MOV ECX, EDX RDTSC SUB EAX, EBX SBB EDX, ECX JMP +1 <junk> RDTSC ADD EAX, EBX ADC EDX, ECX RDTSC JMP +1 <junk> SUB EAX, EBX JMP +1 <junk> SBB EDX, ECX TEST EDX, EDX JNZ +Dh POPAD JMP +1 <junk> PUSH API ; offset of API = 0x34 from start JMP +1 <junk> RETN */ if(!validMemory(InvalidApiAddress, sizeof(pattern))) { log("Invalid memory address\r\n"); Status = SCYLLA_STATUS_IMPORT_RESOLVING_FAILED; return NULL; } const uint8_t* bPtr = reinterpret_cast<const uint8_t*>(InvalidApiAddress); if(findPattern(bPtr, sizeof(pattern), pattern, sizeof(pattern), mask)) { return *reinterpret_cast<const uint32_t*>(bPtr+offs_api); } log("Unsupported opcode found\r\n"); Status = SCYLLA_STATUS_UNSUPPORTED_PROTECTION; return NULL; }
void loadDataFromFile(StorageCacheImpl* cache) { bool structIsCorrect = true; char* name = NULL; unsigned int nameLen; unsigned int numExtra; unsigned int curFunc = 0; unsigned int curPatt = 0; unsigned int func; unsigned int patt; HfInfo file; if ( hfOpenRead(&file, cache->fpath) == FILE_NOT_FOUND ) { cache->isPopulate = false; return; } // Read file Header loadHeader(&file); // Read pattern header structIsCorrect &= loadPatternDataFromFile(&file, &name, &nameLen, &numExtra); while (structIsCorrect) { unsigned int func = curFunc; unsigned int patt = curPatt; bool ret; BlasPatternInfo* bPatt = getPatternInfo(cache, func, patt); while (bPatt != NULL && memcmp(name, bPatt->name, nameLen) != 0 ) { nextPattern(cache, &func, &patt); bPatt = getPatternInfo(cache, func, patt); } if (bPatt != NULL) { bPatt->sstatus = SS_CORRECT_DATA; // Read pattern data ret = readPatternData(&file, bPatt, numExtra); // go to next pattern nextPattern(cache, &func, &patt); // if the pattern is read witch error or not completely if (!ret) { bPatt = getPatternInfo(cache, func, patt); hfJump(&file, bPatt->offset); } curFunc = func; curPatt = patt; } free(name); name = NULL; structIsCorrect &= loadPatternDataFromFile(&file, &name, &nameLen, &numExtra ); } for (func =0; func < BLAS_FUNCTIONS_NUMBER; ++ func) { BlasFunctionInfo* bFunc = &cache->functionInfo[func]; for (patt =0; patt < bFunc->numPatterns; ++ patt){ BlasPatternInfo* bPatt = &bFunc->pattInfo[patt]; if (bPatt->sstatus == SS_NOLOAD) { POSFILE ret = findPattern(&file, bPatt->name); if (ret != 0) { loadPatternDataFromFile(&file, &name, &nameLen, &numExtra ); readPatternData(&file, bPatt, numExtra); } } } } free(name); cache->isPopulate = true; hfClose(&file); checkOffset(cache->functionInfo); }
// This is the key function of LZ77. // The input is a sequence of number and // it returns patterns like: i,(x,x,x,..)^r, ... PatChain<PatternUnit> PatternUtil::getPatChainFromSeq( vector<off_t> inits ) { //mlog(IDX_WARN, "Entering %s. inits: %s", // __FUNCTION__, printVector(inits).c_str()); vector<off_t> deltas = buildDeltas(inits); PatChain<PatternUnit> pattern, patterntrim; pattern = findPattern( deltas ); // find repeating pattern in deltas // Put the init back into the patterns int pos = 0; vector<PatternUnit>::iterator it; for ( it = pattern.chain.begin() ; it != pattern.chain.end() ; it++ ) { it->init = inits[pos]; pos += it->seq.size() * it->cnt; } // handle the missing last if ( ! inits.empty() ) { if ( ! pattern.chain.empty() && pattern.chain.back().seq.size() == 1 && pattern.chain.back().init + pattern.chain.back().seq[0] * pattern.chain.back().cnt == inits.back() ) { pattern.chain.back().cnt++; } else { PatternUnit punit; punit.init = inits.back(); punit.cnt = 1; pattern.push(punit); } } // combine the unecessary single patterns for ( it = pattern.chain.begin() ; it != pattern.chain.end() ; it++ ) { ostringstream oss; oss << it->show() ; // mlog(IDX_WARN, "TRIM:%s", oss.str().c_str()); if ( it != pattern.chain.begin() && it->cnt * it->seq.size() <= 1 && patterntrim.chain.back().seq.size() == 1 && patterntrim.chain.back().cnt > 1 && patterntrim.chain.back().init + patterntrim.chain.back().seq[0] * patterntrim.chain.back().cnt == it->init ) { // it can be represented by the last pattern. // mlog(IDX_WARN, "in back++"); patterntrim.chain.back().cnt++; } else { // mlog(IDX_WARN, "in push"); patterntrim.push(*it); } } /* ostringstream oss; oss << pattern.show() << endl; mlog(IDX_WARN, "Leaving %s:{%s}", __FUNCTION__, oss.str().c_str()); */ return patterntrim; }
//0.99 - 1.0 (private) ULONG_PTR ScyllaTELock::fixType5(ULONG_PTR InvalidApiAddress) { const uint8_t MOV_EAX = 0xB8; const uint8_t JMP_SHRT = 0xEB; const uint8_t ADD_EAX = 0x05; const uint8_t MOV_EAX_DW_EAX[] = {0x8B, 0x00}; const uint8_t XOR_EAX = 0x35; const uint8_t NOP = 0x90; const uint8_t PUSH_EAX = 0x50; const uint8_t RETN = 0xC3; static const uint8_t pattern[] = { MOV_EAX, 1, 1, 1, 1, JMP_SHRT, 0x02, 0, 0, ADD_EAX, 2, 2, 2, 2, MOV_EAX_DW_EAX[0], MOV_EAX_DW_EAX[1], XOR_EAX, 3, 3, 3, 3, NOP, NOP, PUSH_EAX, RETN }; static const char mask[] = "X????XX??X????XXX????XXXX"; const size_t offs_x = 1; const size_t offs_y = 10; const size_t offs_z = 17; const size_t MAX_BYTES = 35; /* <code> <...> MOV EAX, X JMP SHORT +2 <junk> ADD EAX, Y MOV EAX, [EAX] XOR EAX, Z NOP NOP PUSH EAX RETN */ const uint8_t* bPtr = reinterpret_cast<const uint8_t*>(InvalidApiAddress); if(validMemory(InvalidApiAddress, MAX_BYTES + sizeof(pattern))) { const uint8_t* found = findPattern(bPtr, MAX_BYTES + sizeof(pattern), pattern, sizeof(pattern), mask); if(found) { uint32_t X = *reinterpret_cast<const uint32_t*>(found+offs_x); uint32_t Y = *reinterpret_cast<const uint32_t*>(found+offs_y); X += Y; if(validMemory(X, sizeof(ULONG_PTR))) { ULONG_PTR resolved = *reinterpret_cast<const ULONG_PTR*>(X); uint32_t Z = *reinterpret_cast<const uint32_t*>(found+offs_z); return (resolved ^ Z); } } } return NULL; }
void SvgParser::applyFillStyle(KoShape *shape) { SvgGraphicsContext *gc = m_context.currentGC(); if (! gc) return; if (gc->fillType == SvgGraphicsContext::None) { shape->setBackground(QSharedPointer<KoShapeBackground>(0)); } else if (gc->fillType == SvgGraphicsContext::Solid) { shape->setBackground(QSharedPointer<KoColorBackground>(new KoColorBackground(gc->fillColor))); } else if (gc->fillType == SvgGraphicsContext::Complex) { // try to find referenced gradient SvgGradientHelper *gradient = findGradient(gc->fillId); if (gradient) { // great, we have a gradient fill QSharedPointer<KoGradientBackground> bg; if (gradient->gradientUnits() == SvgGradientHelper::ObjectBoundingBox) { bg = QSharedPointer<KoGradientBackground>(new KoGradientBackground(*gradient->gradient())); bg->setTransform(gradient->transform()); } else { QGradient *convertedGradient = SvgGradientHelper::convertGradient(gradient->gradient(), shape->size()); bg = QSharedPointer<KoGradientBackground>(new KoGradientBackground(convertedGradient)); QTransform invShapematrix = shape->transformation().inverted(); bg->setTransform(gradient->transform() * gc->matrix * invShapematrix); } shape->setBackground(bg); } else { // try to find referenced pattern SvgPatternHelper *pattern = findPattern(gc->fillId); KoImageCollection *imageCollection = m_documentResourceManager->imageCollection(); if (pattern && imageCollection) { // great we have a pattern fill QRectF objectBound = QRectF(QPoint(), shape->size()); QRectF currentBoundbox = gc->currentBoundbox; // properties from the object are not inherited // so we are creating a new context without copying SvgGraphicsContext *gc = m_context.pushGraphicsContext(pattern->content(), false); // the pattern establishes a new coordinate system with its // origin at the patterns x and y attributes gc->matrix = QTransform(); // object bounding box units are relative to the object the pattern is applied if (pattern->patternContentUnits() == SvgPatternHelper::ObjectBoundingBox) { gc->currentBoundbox = objectBound; gc->forcePercentage = true; } else { // inherit the current bounding box gc->currentBoundbox = currentBoundbox; } applyStyle(0, pattern->content()); // parse the pattern content elements QList<KoShape*> patternContent = parseContainer(pattern->content()); // generate the pattern image from the shapes and the object bounding rect QImage image = pattern->generateImage(objectBound, patternContent); m_context.popGraphicsContext(); // delete the shapes created from the pattern content qDeleteAll(patternContent); if (!image.isNull()) { QSharedPointer<KoPatternBackground> bg(new KoPatternBackground(imageCollection)); bg->setPattern(image); QPointF refPoint = shape->documentToShape(pattern->position(objectBound)); QSizeF tileSize = pattern->size(objectBound); bg->setPatternDisplaySize(tileSize); if (pattern->patternUnits() == SvgPatternHelper::ObjectBoundingBox) { if (tileSize == objectBound.size()) bg->setRepeat(KoPatternBackground::Stretched); } // calculate pattern reference point offset in percent of tileSize // and relative to the topleft corner of the shape qreal fx = refPoint.x() / tileSize.width(); qreal fy = refPoint.y() / tileSize.height(); if (fx < 0.0) fx = floor(fx); else if (fx > 1.0) fx = ceil(fx); else fx = 0.0; if (fy < 0.0) fy = floor(fy); else if (fx > 1.0) fy = ceil(fy); else fy = 0.0; qreal offsetX = 100.0 * (refPoint.x() - fx * tileSize.width()) / tileSize.width(); qreal offsetY = 100.0 * (refPoint.y() - fy * tileSize.height()) / tileSize.height(); bg->setReferencePointOffset(QPointF(offsetX, offsetY)); shape->setBackground(bg); } } else { // no referenced fill found, use fallback color shape->setBackground(QSharedPointer<KoColorBackground>(new KoColorBackground(gc->fillColor))); } } } KoPathShape *path = dynamic_cast<KoPathShape*>(shape); if (path) path->setFillRule(gc->fillRule); }