/************************************************************** * This method will use the methods above combined to check all * three statuses at the same time * * @param solve the board for all three situation * @param row will use the current row * @param col will use the current col * @param num will find the number contained in section * @return bool type found for true not there for false **************************************************************/ bool canPlace(int grid[MAX][MAX], int row, int col, int num) { return checkRow(grid, row, num) == false && checkCol(grid, col, num) == false && checkSection(grid, row - row%3 , col - col%3, num)== false; }
void MachOChecker<A>::checkLoadCommands() { // check that all load commands fit within the load command space file const uint8_t* const endOfFile = (uint8_t*)fHeader + fLength; const uint8_t* const endOfLoadCommands = (uint8_t*)fHeader + sizeof(macho_header<P>) + fHeader->sizeofcmds(); const uint32_t cmd_count = fHeader->ncmds(); const macho_load_command<P>* const cmds = (macho_load_command<P>*)((uint8_t*)fHeader + sizeof(macho_header<P>)); const macho_load_command<P>* cmd = cmds; for (uint32_t i = 0; i < cmd_count; ++i) { uint32_t size = cmd->cmdsize(); if ( (size & this->loadCommandSizeMask()) != 0 ) throwf("load command #%d has a unaligned size", i); const uint8_t* endOfCmd = ((uint8_t*)cmd)+cmd->cmdsize(); if ( endOfCmd > endOfLoadCommands ) throwf("load command #%d extends beyond the end of the load commands", i); if ( endOfCmd > endOfFile ) throwf("load command #%d extends beyond the end of the file", i); switch ( cmd->cmd() ) { case macho_segment_command<P>::CMD: case LC_SYMTAB: case LC_UNIXTHREAD: case LC_DYSYMTAB: case LC_LOAD_DYLIB: case LC_ID_DYLIB: case LC_LOAD_DYLINKER: case LC_ID_DYLINKER: case macho_routines_command<P>::CMD: case LC_SUB_FRAMEWORK: case LC_SUB_UMBRELLA: case LC_SUB_CLIENT: case LC_TWOLEVEL_HINTS: case LC_PREBIND_CKSUM: case LC_LOAD_WEAK_DYLIB: case LC_UUID: break; default: throwf("load command #%d is an unknown kind 0x%X", i, cmd->cmd()); } cmd = (const macho_load_command<P>*)endOfCmd; } // check segments cmd = cmds; std::vector<std::pair<pint_t, pint_t> > segmentAddressRanges; std::vector<std::pair<pint_t, pint_t> > segmentFileOffsetRanges; const macho_segment_command<P>* linkEditSegment = NULL; for (uint32_t i = 0; i < cmd_count; ++i) { if ( cmd->cmd() == macho_segment_command<P>::CMD ) { const macho_segment_command<P>* segCmd = (const macho_segment_command<P>*)cmd; if ( segCmd->cmdsize() != (sizeof(macho_segment_command<P>) + segCmd->nsects() * sizeof(macho_section_content<P>)) ) throw "invalid segment load command size"; // see if this overlaps another segment address range uint64_t startAddr = segCmd->vmaddr(); uint64_t endAddr = startAddr + segCmd->vmsize(); for (typename std::vector<std::pair<pint_t, pint_t> >::iterator it = segmentAddressRanges.begin(); it != segmentAddressRanges.end(); ++it) { if ( it->first < startAddr ) { if ( it->second > startAddr ) throw "overlapping segment vm addresses"; } else if ( it->first > startAddr ) { if ( it->first < endAddr ) throw "overlapping segment vm addresses"; } else { throw "overlapping segment vm addresses"; } segmentAddressRanges.push_back(std::make_pair<pint_t, pint_t>(startAddr, endAddr)); } // see if this overlaps another segment file offset range uint64_t startOffset = segCmd->fileoff(); uint64_t endOffset = startOffset + segCmd->filesize(); for (typename std::vector<std::pair<pint_t, pint_t> >::iterator it = segmentFileOffsetRanges.begin(); it != segmentFileOffsetRanges.end(); ++it) { if ( it->first < startOffset ) { if ( it->second > startOffset ) throw "overlapping segment file data"; } else if ( it->first > startOffset ) { if ( it->first < endOffset ) throw "overlapping segment file data"; } else { throw "overlapping segment file data"; } segmentFileOffsetRanges.push_back(std::make_pair<pint_t, pint_t>(startOffset, endOffset)); // check is within file bounds if ( (startOffset > fLength) || (endOffset > fLength) ) throw "segment file data is past end of file"; } // verify it fits in file if ( startOffset > fLength ) throw "segment fileoff does not fit in file"; if ( endOffset > fLength ) throw "segment fileoff+filesize does not fit in file"; // keep LINKEDIT segment if ( strcmp(segCmd->segname(), "__LINKEDIT") == 0 ) linkEditSegment = segCmd; // cache interesting segments if ( fFirstSegment == NULL ) fFirstSegment = segCmd; if ( (fFirstWritableSegment == NULL) && ((segCmd->initprot() & VM_PROT_WRITE) != 0) ) fFirstWritableSegment = segCmd; // check section ranges const macho_section<P>* const sectionsStart = (macho_section<P>*)((char*)segCmd + sizeof(macho_segment_command<P>)); const macho_section<P>* const sectionsEnd = §ionsStart[segCmd->nsects()]; for(const macho_section<P>* sect = sectionsStart; sect < sectionsEnd; ++sect) { // check all sections are within segment if ( sect->addr() < startAddr ) throwf("section %s vm address not within segment", sect->sectname()); if ( (sect->addr()+sect->size()) > endAddr ) throwf("section %s vm address not within segment", sect->sectname()); if ( (sect->flags() &SECTION_TYPE) != S_ZEROFILL ) { if ( sect->offset() < startOffset ) throwf("section %s file offset not within segment", sect->sectname()); if ( (sect->offset()+sect->size()) > endOffset ) throwf("section %s file offset not within segment", sect->sectname()); } checkSection(segCmd, sect); } } cmd = (const macho_load_command<P>*)(((uint8_t*)cmd)+cmd->cmdsize()); } // verify there was a LINKEDIT segment if ( linkEditSegment == NULL ) throw "no __LINKEDIT segment"; // checks for executables bool isStaticExecutable = false; if ( fHeader->filetype() == MH_EXECUTE ) { isStaticExecutable = true; cmd = cmds; for (uint32_t i = 0; i < cmd_count; ++i) { switch ( cmd->cmd() ) { case LC_LOAD_DYLINKER: // the existence of a dyld load command makes a executable dynamic isStaticExecutable = false; break; } cmd = (const macho_load_command<P>*)(((uint8_t*)cmd)+cmd->cmdsize()); } if ( isStaticExecutable ) { if ( fHeader->flags() != MH_NOUNDEFS ) throw "invalid bits in mach_header flags for static executable"; } } // check LC_SYMTAB and LC_DYSYMTAB cmd = cmds; bool foundDynamicSymTab = false; for (uint32_t i = 0; i < cmd_count; ++i) { switch ( cmd->cmd() ) { case LC_SYMTAB: { const macho_symtab_command<P>* symtab = (macho_symtab_command<P>*)cmd; fSymbolCount = symtab->nsyms(); fSymbols = (const macho_nlist<P>*)((char*)fHeader + symtab->symoff()); if ( symtab->symoff() < linkEditSegment->fileoff() ) throw "symbol table not in __LINKEDIT"; if ( (symtab->symoff() + fSymbolCount*sizeof(macho_nlist<P>*)) > (linkEditSegment->fileoff()+linkEditSegment->filesize()) ) throw "symbol table end not in __LINKEDIT"; fStrings = (char*)fHeader + symtab->stroff(); fStringsEnd = fStrings + symtab->strsize(); if ( symtab->stroff() < linkEditSegment->fileoff() ) throw "string pool not in __LINKEDIT"; if ( (symtab->stroff()+symtab->strsize()) > (linkEditSegment->fileoff()+linkEditSegment->filesize()) ) throw "string pool extends beyond __LINKEDIT"; } break; case LC_DYSYMTAB: { if ( isStaticExecutable ) throw "LC_DYSYMTAB should not be used in static executable"; foundDynamicSymTab = true; const macho_dysymtab_command<P>* dsymtab = (struct macho_dysymtab_command<P>*)cmd; fIndirectTable = (uint32_t*)((char*)fHeader + dsymtab->indirectsymoff()); fIndirectTableCount = dsymtab->nindirectsyms(); if ( dsymtab->indirectsymoff() < linkEditSegment->fileoff() ) throw "indirect symbol table not in __LINKEDIT"; if ( (dsymtab->indirectsymoff()+fIndirectTableCount*8) > (linkEditSegment->fileoff()+linkEditSegment->filesize()) ) throw "indirect symbol table not in __LINKEDIT"; fLocalRelocationsCount = dsymtab->nlocrel(); if ( fLocalRelocationsCount != 0 ) { fLocalRelocations = (const macho_relocation_info<P>*)((char*)fHeader + dsymtab->locreloff()); if ( dsymtab->locreloff() < linkEditSegment->fileoff() ) throw "local relocations not in __LINKEDIT"; if ( (dsymtab->locreloff()+fLocalRelocationsCount*sizeof(macho_relocation_info<P>)) > (linkEditSegment->fileoff()+linkEditSegment->filesize()) ) throw "local relocations not in __LINKEDIT"; } fExternalRelocationsCount = dsymtab->nextrel(); if ( fExternalRelocationsCount != 0 ) { fExternalRelocations = (const macho_relocation_info<P>*)((char*)fHeader + dsymtab->extreloff()); if ( dsymtab->extreloff() < linkEditSegment->fileoff() ) throw "local relocations not in __LINKEDIT"; if ( (dsymtab->extreloff()+fExternalRelocationsCount*sizeof(macho_relocation_info<P>)) > (linkEditSegment->fileoff()+linkEditSegment->filesize()) ) throw "local relocations not in __LINKEDIT"; } } break; } cmd = (const macho_load_command<P>*)(((uint8_t*)cmd)+cmd->cmdsize()); } if ( !isStaticExecutable && !foundDynamicSymTab ) throw "missing dynamic symbol table"; if ( fStrings == NULL ) throw "missing symbol table"; fRelocBase = this->relocBase(); }