„BPROF:2dm” változatai közötti eltérés

A Miau Wiki wikiből
(Egyéb funkciók)
(Egyéb funkciók)
311. sor: 311. sor:
 
         var result = Bool()
 
         var result = Bool()
 
         // Load the CoreML model
 
         // Load the CoreML model
         guard let model = try? ProfaneClassifier_v3(configuration: .init()) else {
+
         guard let model = try? ProfaneClassifier_vX(configuration: .init()) else {
 
             fatalError("Failed to load CoreML model")
 
             fatalError("Failed to load CoreML model")
 
         }
 
         }
346. sor: 346. sor:
 
A második Swift programkód egy "SwearWordDetector" nevű osztályt definiál, amely szintén a CoreML keretrendszer használatával készült. Ez az osztály egy metódust tartalmaz, amely egy szöveg bemenetet kap, és visszatér egy logikai értékkel, amely megadja, hogy a szöveg tartalmaz-e káromkodó szavakat "SwearWords".
 
A második Swift programkód egy "SwearWordDetector" nevű osztályt definiál, amely szintén a CoreML keretrendszer használatával készült. Ez az osztály egy metódust tartalmaz, amely egy szöveg bemenetet kap, és visszatér egy logikai értékkel, amely megadja, hogy a szöveg tartalmaz-e káromkodó szavakat "SwearWords".
  
Az "isProfane" metódus először betölt egy ProfaneClassifier_v3 nevű modellt (amelyet szintén előzetesen a CoreML segítségével készítettek), majd használja ezt a modellt a bemeneti szöveg osztályozására. Az osztályozás eredményét ("profane" vagy "not profane") egy "ProfaneClassifier_v3Output" objektumban tárolja, majd visszaadja az osztályozás eredményétől függő logikai értéket.
+
Az "isProfane" metódus először betölt egy ProfaneClassifier_vX nevű modellt (amelyet szintén előzetesen a CoreML segítségével készítettek), majd használja ezt a modellt a bemeneti szöveg osztályozására. Az osztályozás eredményét ("profane" vagy "not profane") egy "ProfaneClassifier_v3Output" objektumban tárolja, majd visszaadja az osztályozás eredményétől függő logikai értéket.
  
 
CoreML betanítása:
 
CoreML betanítása:
378. sor: 378. sor:
 
A CoreML-es transfer learning algoritmus előnye, hogy jelentősen csökkentheti a modell tanításához szükséges adatmennyiséget és időt, mivel az előre tanított modell már rendelkezik valamennyi szükséges tudással. Ezenkívül a CoreML lehetővé teszi a modell finomhangolását az Apple eszközein, ami lehetővé teszi a felhasználói élmény javítását és a modell jobb teljesítményét.
 
A CoreML-es transfer learning algoritmus előnye, hogy jelentősen csökkentheti a modell tanításához szükséges adatmennyiséget és időt, mivel az előre tanított modell már rendelkezik valamennyi szükséges tudással. Ezenkívül a CoreML lehetővé teszi a modell finomhangolását az Apple eszközein, ami lehetővé teszi a felhasználói élmény javítását és a modell jobb teljesítményét.
  
* Majd végül az elkészült .mlmodel fájlt importáltam a szakdolgozat projektbe. Ezt a kódban "ProfaneClassifier_v3" -ként hívom meg.
+
* Majd végül az elkészült .mlmodel fájlt importáltam a szakdolgozat projektbe. Ezt a kódban "ProfaneClassifier_vX" -ként hívom meg.
  
 
Használata:
 
Használata:
388. sor: 388. sor:
 
Tehát a modell a "cat" szót a "NiceWords" címkével ilette
 
Tehát a modell a "cat" szót a "NiceWords" címkével ilette
  
A modellt többszöri nekifutással, különböző méretű tanítási halmazzal tanitottam, annak érdekében, hogy tudjambizonyítani a modell "okosodását", hasznosságát, fejlódését.<br>
+
A modellt többszöri nekifutással, különböző méretű tanítási halmazzal tanitottam, annak érdekében, hogy tudjambizonyítani a modell "okosodását", hasznosságát, fejlódését. Minden egyes újrataniítással, egy újabb verzót kapott a modell (ProfaneClassifier_v1 ... ProfaneClassifier_vX) <br>
 
Modell 1:<br>
 
Modell 1:<br>
 
2563 adattal tanítottam, maximum entropy algoritmussal<br>
 
2563 adattal tanítottam, maximum entropy algoritmussal<br>

A lap 2023. március 28., 13:33-kori változata

Ez a szócikk a "Rendszertervezés" tantárgy keretében keletkező dokumentum, mely része a szakdolgozat mellékleteinek. Tartalmazza a felhasznált technológia részletes leírását, informatikai felépítését. A dokumentum a reprodukálhatóság elősegítéséhez készült

Tartalomjegyzék

Szakdolgozat alrendszerei

  • GTS (Graphical Test Software), ez a tesztek lejátszására kifejlesztett szoftver
  • GTDS (Graphical Test Designer Software), ez a tesztek tervezésére kifejlesztett szoftver
  • Theme4GTS ,ez a témák létrehozására fejlesztett szoftver
  • Language4GTS ,ez a nyelvek létrehozására fejlesztett szoftver

Fogalmak

(potenciális változók a kódhoz)
  • puzzle: X-szer Y-os háló, melyben a sorfejléc (X) és oszlopfejléc (Y) attribútumok alapján kell elhelyezni az odaillő válaszkártyát
  • X(i): sorfejléc, mely megadja a válaszkártya1. attribútumát
  • Y(j): soszlopfejléc, mely megadja a válaszkártya2. attribútumát
  • válaszkártya(k): képkocka, melyet el kell helyezni a megfelelő kockájába a hálónak
  • megoldástér(i,j,k):
  • keretrendszer: puzzle megjelenítő szoftver
  • log: minden tevékenység (pl. egérmozgás, billentyű-leütés, billentyű-kombináció) feljegyzése egy fájlban, dátummal felcímkézve (vö. https://miau.my-x.hu/mediawiki/index.php/Excel-makro#Tanfolyami_vez.C3.A9r-feladatok)
  • kiértékelés: válaszkártyák helyének helyességének ellenőrzése
  • teszt:
  • hiba:
  • játék:
  • rendszer
  • réteg
  • modul
  • alrendszer
  • szoftver
  • licensz

Megrendelői kezdeményezés

Létezik egy 2DM-játék (https://miau.my-x.hu/miau/254/2dm_kemia_demo/), amelyben a feladat egy 3x3-as* hálóban különféle képeket elhelyezni az oszlop- és sor-fejlécek alapján. A létező 2DM-játék log-ja a vágólapra keletkezik a JavaScript lehetőségei mentén. Az új rendszerben a sebezhetőségek minimalizálása, csalás minden mennyiségű kizárása a cél.

Feladat:

  • Új játék tervezését és
  • futtatását támogató keretrendszer kialakítása úgy, hogy
  • a keretrendszer által olyan output kialakítása, mely a jelenlegi 2DM-megoldás által azonnal futtatható
  • adatbázis-alapú megoldás kialakítása (elemi logok és logelemzések exportálása)

Nem feladat:

  • online kollaboratív munka támogatása
  • elemi diagnózisok végső konklúzióvá formálása

Potenciális piaci helyzet:

  • Pályaalkalmassági vizsgálat
  • 10-50 2dm játék lefejlesztése
  • minden egyes játék logjának kiértékelése
  • elemi diagnózisok végső konklúzióvá formálása
  • (gyakorlással személyiségfejlesztés)
  • Teszt intézmény választása (pl.: tánciskola)

Jelenlegi 2DM játék

Struktúrája: A jelenleg már elkészült 2DM játék adatbeolvasását,adatstruktúráját ki kell nyomozni annak érdekében, hogy a dolgozatban készülő játék kompatibilis lehessen vele. Nyomozás lépései:

  1. https://www.cyotek.com/downloads/info/setup-cyowcopy-1.9.0.822-x86.exe alkalmazás segytségével letöltöttem a https://miau.my-x.hu/miau/271/2dm/ weboldal összes fájlját
  2. letöltött adatok megjelenítése
  3. ebből egyetlen egy 2DM-játékhoz tartozó objektumok (vö. *BLANK*): ???
  4. egy játékra egyszerűsített manuálisan lebutított saját lokális verzió tesztelése
  5. régi 2DM-játék által igényelt specifikációk véglegesítése
  6. egy régi 2DM-játék (értékes tartalommal történő) manuális előállítása a specifikációk alapján az új játék fejlesztője által
  7. manuálisan készített saját játék tesztelése
  8. ezen manuális saját játék új keretrendszerben való reprodukálása és az output tesztelése

Rendszer megrendelővel egyeztetett követelményei

Optimális (tesztelt)

iPhone 6S / iPhone 11

iOS 14.7.1 / iOS 15.5

Választott technológiák

  • Programnyelv:
    • mobil:
      • Swift
  • lokális adattárolás: JSON
  • publikus adattárolás: Firebase NoSQL adatbázis
  • Bevonni tervezett online szolgáltatások:
    • Általunk használandó:
      • ChatGPT
      • flowchart tervező
    • Általunk ajánlott:
      • nayuki.io/page/png-file-chunk-inspector
      • png/jpeg/gif ellenőrzése
      • helyesírásellenőrzés
      • szöveget tartalmazó kép helyesírás ellenőrzése
      • felolvasó robot esetén helyes-e a szöveg?
    • Ötletek

Vizuális követelmények

single Játéktervező nézetei

  • nyitó kép (1.vizuális réteg):
    • tartalom:
      • logó
      • pl: copyright @ 2023 Sipos
      • termék neve
      • verziószám
      • elérhetőségek
        • weboldal
        • telefon
        • email
        • ...
    • forma:
      • betűméret
      • stílus
      • nyelv (nyelvválasztó, 0. vizuális réteg?)
      • ...
    • funkcionalitás:
      • automatikusan betöltődik
      • X másodpercig látható
      • legalább az elérhetőség kijelölhető
      • a nyitó képet a menük egyik alpontja újra betölti (kapcsolatok)
  • ÁSZF/szerződés (2.vizuális réteg):
    • tartalom:
      • licensz típus
      • adatgyűjtés (GDPR)
        • játéktervező felel a GDPR általi nem érintettségért
        • log gyűjtés szabályrendszere. ezzel egyet kell értetni mind a játék tervezőt, mind a játék játszóját
      • copyright a képekre (felelősség játéktervező részéről, NEM a keretrendszer tervező részéről!)
      • halmazelméleti szabályok közlése a sor és oszlop fejlécre vonatkozóan
        • kihagyásmentesség (kihagyásmentességi chatGPT-teszt: pl. palacsinta-receptből kihagyott tojás esetén a meg-tudod-e-sütni-kérdésre nemleges válasz kell és az indoklás is logikus hiányrámutatást kell, hogy adjon)
        • átfedésmentesség (vö. halmazértelmezés chatGPT által: https://miau.my-x.hu/bprof/2023/chatgpt_sets.docx - a homogén halmazok (tortaszeleket) anomáliái felismertethetők, így a 2dm sor/oszlop-fejléc-tervezés chatGPT által is támogatható ) vö. https://www.youtube.com/watch?v=5cYYeuwYF_0
      • súgó elérhetősége
      • helyetérzékeny súgók elérhetősége
      • GYIK
    • forma
      • kiemelések
      • ugrópontok
        • email
        • weboldal
        • applikáción belüli ugrópont (pl.: helyetérzékeny súgók)
      • kijelölhetőségek
      • betűméret
      • betűstílus
    • funkcionalitás
      • ÁSZF archiválhatósága (letölthetősége ... )
      • súgók demója
      • ÁSZF accept/deny gomb/checkbox
      • Online adatbáziskapcsolat engedélyezése (ezt letiltva a felhasználó beszorítja magát a lokális adattérbe, ezt lehet később módosítani)
      • Accessibility nézet
        • színvakság
        • szoftveres felolvashatóság
        • élő billentyűkről szóló tájékoztatás
          • ne lehessen felesleges inputot megadni, engedélyezetlen eszközről
        • ...
  • Menü (3. vizuális réteg)
    • tartalom
      • szingle játék tervezése (egyenlőre 3x3)
        • ellenőrzési elemek:
          • játék adatfájljainak elérésének megadása (létezik-e az elérési útvonal)
          • kép fájl típusok megadása listából (png, jpg, gif ...)
            • képfájl tartalom azonosság ellenőrzése (fizikai azonosság, másolatok más néven való ellenőrzése)
            • hiba üzenet ha nincs pontosan 17 db megfelelő formátumú képállomány
            • maximum felbontás ellenőrzése (hiba üzenet ha a méret/arány nem megfelelő pl.: 400x400)
            • kép permission olvashatóságának (read,write,execute) ellenőrzése
            • kép formátum önazonosságának ellenőrzése ( attól még, hogy .png, valóban kép-e a kép)
            • felső fájl méret ellenőrzése
            • színpaletta egyenszilárdságának ellenőrzése
            • vízjelmentesség ellenőrzése
            • (törvényi előírásokat nem sértő tartalom garantálása)
            • könyvtár olvashatóságának ellenőrzése
            • kép fájl tartalmaz-e káros kódot?
            • kép fájl nevek nem tartalmazhatnak speciális karaktereket (ékezet szóköz , fájlnév 1-17ig stb)
            • képek stílusa egyezik-e? (pl.: mindegyik kép eliptikus...)
        • képek játékba integrálása
          • 17 soros összerendező táblázat (1-17ig előre kitöltve felülírhatóság mellett és a felhasználó ehhez fog alkalmazkodni)
            • lapozó kép (1)
            • bal felső sarok (2)
            • oszlop bal (3)
            • oszlop közép (4)
            • oszlop jobb (5)
            • sor felső (6)
            • sor közép (7)
            • sor alsó (8)
            • válaszkártyák (9-17)
      • multi játék tervezése (csak single alapon)
        • integrálandó játékok számának megadása (2-től N-ig)
        • N db alkönyvtár megadása abban a sorrendben, amiben a játékok integrálandók (ezek a könyvtárak a single játék tervezés eredményeinek kell hogy legyenek)
        • játéktervező szoftver névjegyének ellenőrzése könyvtáranként
      • lokális adatfájl betöltése
      • játék indítása
      • online adatfájlok elérése katalógusosan
      • beállítások elérése
        • tervezői beállítások
          • időlimites-e a játék
          • éles vagy próba játék (lehet újrapróbálni...)
          • tesztíró azonosítási módja (pl.: anonim, belső kód ...)
          • ....
    • forma
      • ellenőrzési elemekről olvasmányos,színes visszaigazolás
    • funkcionalitás
      • játéktervezés:
        • ellenőrzési lépések után a felhasználót a lépések sikerességéről tájékoztatva:
          • megfelelő játéktípus szükséges alkotórészeinek új alkönyvtárba másolása
          • 1-17 képfájlok másolat készítése,átnevezése
          • játékindítás fejajánlása

Játékot használó vizuális rétegei

....

Egyéb követelmények

Internet elérése szükséges a Kvíz Katalógus használatához, hiszen csatlakoznia kell a Firebase adatbázishoz. Lokális játékhoz az internetkapcsolat szükséges, mivel a megoldókulcsot a keretrendszer a Firebase adatbázisból nyeri ki. Ennek a módszernek az offline megoldását nem zárja ki a szakdolgozatíró, ám a megvalósítás nincs a szakdolgozat fókuszában

Egyéb funkciók

  • UI személyre szabása előre elkészített, akár a felhasználók által személyre szabott téma segítségével - (színvilág/színharmónia nem ellenőrzött, a téma tervezőjének kell figyelnie arra, hogy a felhasznált színek nem olvadnak egybe egymással)
  • nyelvek támogatása, akár a felhasználók által definiált szótár segítségével - (szótár helyessége nem ellenőrzött, nincs kizárva akár a halandzsa nyelv használata sem)
  • Kényes tartalom szűrése:
    • Grafikai
@available(iOS 12.0, *)
public class NSFWDetector {

   public static let shared = NSFWDetector()

   private let model: VNCoreMLModel

   public required init() {
       guard let model = try? VNCoreMLModel(for: NSFW(configuration: MLModelConfiguration()).model) else {
           fatalError("NSFW should always be a valid model")
       }
       self.model = model
   }

   /// The Result of an NSFW Detection
   ///
   /// - error: Detection was not successful
   /// - success: Detection was successful. `nsfwConfidence`: 0.0 for safe content - 1.0 for hardcore porn ;)
   public enum DetectionResult {
       case error(Error)
       case success(nsfwConfidence: Float)
   }

   public func check(image: UIImage, completion: @escaping (_ result: DetectionResult) -> Void) {

       // Create a requestHandler for the image
       let requestHandler: VNImageRequestHandler?
       if let cgImage = image.cgImage {
           requestHandler = VNImageRequestHandler(cgImage: cgImage, options: [:])
       } else if let ciImage = image.ciImage {
           requestHandler = VNImageRequestHandler(ciImage: ciImage, options: [:])
       } else {
           requestHandler = nil
       }

       self.check(requestHandler, completion: completion)
   }

   public func check(cvPixelbuffer: CVPixelBuffer, completion: @escaping (_ result: DetectionResult) -> Void) {

       let requestHandler = VNImageRequestHandler(cvPixelBuffer: cvPixelbuffer, options: [:])

       self.check(requestHandler, completion: completion)
   }
 }
 
 @available(iOS 12.0, *)
 private extension NSFWDetector {

   func check(_ requestHandler: VNImageRequestHandler?, completion: @escaping (_ result: DetectionResult) -> Void) {

       guard let requestHandler = requestHandler else {
           completion(.error(NSError(domain: "either cgImage or ciImage must be set inside of UIImage", code: 0, userInfo: nil)))
           return
       }

       /// The request that handles the detection completion
       let request = VNCoreMLRequest(model: self.model, completionHandler: { (request, error) in
           guard let observations = request.results as? [VNClassificationObservation], let observation = observations.first(where: { $0.identifier == "NSFW" }) else {
               completion(.error(NSError(domain: "Detection failed: No NSFW Observation found", code: 0, userInfo: nil)))

               return
           }

           completion(.success(nsfwConfidence: observation.confidence))
       })
       
       /// Start the actual detection
       do {
           try requestHandler.perform([request])
       } catch {
           completion(.error(NSError(domain: "Detection failed: No NSFW Observation found", code: 0, userInfo: nil)))
       }
   }
}


A NSFWDetector osztály felelős a kép ellenőrzéséért, és ezt a CoreML modellt használja a detektáláshoz. A VNCoreMLModel példányosítása során a modell konfigurációját állítják be, és elvégzik az inicializálást.

Az NSFWDetector osztály a következő metódusokkal rendelkezik:

check(image: UIImage, completion:): Az ellenőrzéshez egy UIImage objektumot adunk át, és a modell elvégzi a detektálást. Az eredményt egy DetectionResult típusú closure-on keresztül juttatja el, amely lehet error vagy success típusú. Az error típus hibát jelent, míg a success típusnál az nsfwConfidence érték határozza meg a detektált tartalom mértékét. check(cvPixelbuffer: CVPixelBuffer, completion:): Az ellenőrzéshez egy CVPixelBuffer objektumot adunk át, és a modell elvégzi a detektálást. Az eredményt egy DetectionResult típusú closure-on keresztül juttatja el. Az NSFW osztályban a detectNudity metódus használja az NSFWDetector osztályt, hogy eldöntse, hogy egy adott kép tartalmaz-e erotikus, vagy pornográf tartalmat. A metódus paraméterként egy URL objektumot kap, amelyen keresztül a képet betölti, majd átadja az NSFWDetector osztálynak, és a detektálás eredményét visszatéríti.

A print utasítások segítenek a programozónak, hogy lássa, hogy az ellenőrzés során milyen információk kerültek feldolgozásra, és ha bármilyen hiba merül fel, akkor segítségükkel azonosíthatja azt.

  • Szöveges
class SwearWordDetector {
   func isProfane(inputText: String) -> Bool{
       var result = Bool()
       // Load the CoreML model
       guard let model = try? ProfaneClassifier_vX(configuration: .init()) else {
           fatalError("Failed to load CoreML model")
       }
        
       // Define some input text to classify
        
       // Create an instance of ProfaneClassifierInput using the input text
       let input = ProfaneClassifier_v3Input(text: inputText)
        
       // Use the model to make a prediction
       guard let output = try? model.prediction(input: input) else {
           fatalError("Failed to make a prediction")
       }
       // Print the predicted label ("profane" or "not profane")
       print("Predicted label: \(output.label)")
        
       if output.label == "SwearWords" {
           result = true
       } else {
           result = false
       }
       return result
   }
}

magyarázat:

A SwearWordDetector osztály két fő metódust tartalmaz, amelyek az NSFW tartalom detektálására szolgálnak. Az első metódus "check(image:completion:)" egy UIImage objektumot kap bemenetként, és visszatér a detektálás eredményével, amely egy "DetectionResult" típusú felsorolás. Ez a felsorolás két lehetséges értéket tartalmaz: "error", ha a detektálás nem sikerült, és "success", ha a detektálás sikeres volt, és a tartalom NSFW.

A második metódus "check(cvPixelbuffer:completion:)" egy CVPixelBuffer objektumot használ a detektáláshoz, és ugyanazt a "DetectionResult" típusú eredményt adja vissza.

Az "NSFWDetector" osztály a VNCoreML keretrendszer segítségével működik. Ez az osztály betölt egy NSFW modellt (amelyet előzetesen a CoreML segítségével készítettek), majd az előbb említett két metódus használatával elvégzi az NSFW tartalom detektálását.

A második Swift programkód egy "SwearWordDetector" nevű osztályt definiál, amely szintén a CoreML keretrendszer használatával készült. Ez az osztály egy metódust tartalmaz, amely egy szöveg bemenetet kap, és visszatér egy logikai értékkel, amely megadja, hogy a szöveg tartalmaz-e káromkodó szavakat "SwearWords".

Az "isProfane" metódus először betölt egy ProfaneClassifier_vX nevű modellt (amelyet szintén előzetesen a CoreML segítségével készítettek), majd használja ezt a modellt a bemeneti szöveg osztályozására. Az osztályozás eredményét ("profane" vagy "not profane") egy "ProfaneClassifier_v3Output" objektumban tárolja, majd visszaadja az osztályozás eredményétől függő logikai értéket.

CoreML betanítása:

  • Minta adatok gyűjtése, felcímkézése
    • Összegyűjtöttem 2175 darab csúnya szót, magyar angol kínai és még 1-2 nyelven (nem tudom hogy miert ezeken a nyelveken, majd ezt kitalalom h miert igy)
    • Összegyűjtöttem 2456 darab biztosan nem csúnya szót, magyar angol kínai és még 1-2 nyelven (nem tudom hogy miert ezeken a nyelveken, majd ezt kitalalom h miert igy)
  • Ezeket mind elmentettem 1-1 .txt fájlba (fájl neve: csúnyaszóX.txt/szepszóX.txt, fájl tartalma: csúnyaszóX/szepszóX) az alábbi mappastruktúrába rendeztem:

- ML_mappa/

-- csunya_szavak_mappa/

--- csunyaszo1.txt

--- ...

--- csunyaszoX.txt

-- szep_szavak_mappa/

--- szepszo1.txt

--- ...

--- szepszoX.txt

  • odaadtam az ML_mappa a CoreML alkalmazásnak, amely feldolgozta, az általam felcímkézett szavakat, és elkészítette a modell fájlt.

transfer learning algoritmus: A CoreML-es transfer learning algoritmus egy olyan módszer, amely lehetővé teszi, hogy az Apple fejlesztők az előre tanított modelljeiket új problémák megoldására használják fel. Ennek lényege, hogy az előre tanított modell rétegeit át lehet hasznosítani a célproblémához, és csak a modell utolsó rétegeit kell finomhangolni az új feladathoz.

A CoreML-es transfer learning algoritmus előnye, hogy jelentősen csökkentheti a modell tanításához szükséges adatmennyiséget és időt, mivel az előre tanított modell már rendelkezik valamennyi szükséges tudással. Ezenkívül a CoreML lehetővé teszi a modell finomhangolását az Apple eszközein, ami lehetővé teszi a felhasználói élmény javítását és a modell jobb teljesítményét.

  • Majd végül az elkészült .mlmodel fájlt importáltam a szakdolgozat projektbe. Ezt a kódban "ProfaneClassifier_vX" -ként hívom meg.

Használata:

try swearDetector.isProfane(inputText: "cat") 

output:

false
Predicted label: NiceWords

Tehát a modell a "cat" szót a "NiceWords" címkével ilette

A modellt többszöri nekifutással, különböző méretű tanítási halmazzal tanitottam, annak érdekében, hogy tudjambizonyítani a modell "okosodását", hasznosságát, fejlódését. Minden egyes újrataniítással, egy újabb verzót kapott a modell (ProfaneClassifier_v1 ... ProfaneClassifier_vX)
Modell 1:
2563 adattal tanítottam, maximum entropy algoritmussal
...
Modell 2:
2563 adattal tanítottam, transfer learning algoritmussal
...
Modell 3:
4640 adattal tanítottam, maximum entropy algoritmussal
...
Modell 3:
4640 adattal tanítottam, transfer learning algoritmussal
MÉG ez nincs kész
... 4862 adattal tanítottam, transfer learning algoritmussal
MÉG ez nincs kész
...

Folyamatábrák

  • Puzzle tervezésének folyamatábrája:........
  • Puzzle megírásának folyamatábrája:........
  • Puzzle kiértékelésének folyamatábrája:........


https://miau.my-x.hu/miau/292/2dm_figures/ folyamatabrak lesznek

IT biztonsági kérdések

  • kulcsok tárolása a forráskódban?
    • nem a kódba fordítjuk bele a kulcsot, hanem valamilyen keychain szolgáltatásból nyeri ki
  • Hálózaton keresztül történő adatátvitel feltörhetősége
  • Logika nem a kliens,hanem a szerver oldalon kell, hogy tárolva legyen
  • Adatbázishoz való hozzáférés kiosztása
  • JSON alapú lokális adattárolás megfelelősége
  • régebbi verziójú keretrendszer használatának korlátozása, ezzel is csökkentve annak az esélyét, hogy egy már felefedezett sebezhetőségnek nem tesszük ki a felhasználót.
  • képekhez kötődő károkozási formák feltárása
  • kép eredeti (licensz kérdés nincs ha saját) vagy manipulált-e?
    • ...pdf url
    • elérési út alapján ellenőrizendő: létezik-e az objektum? (igen/nem)
      • nem = hibaüzenet a felhasználónak a helyes elérési útvonal kikényszerítésére
    • elérési útvonalban megadott fájl kiterjesztésének ellenőrzése (megfelel az előre fellistázott opcióknak/nem felel meg)
      • nem = hibaüzenet a felhasználónak a helyes kiterjesztés kikényszerítésére
    • elérési útvonalban megadott objektum jogosultságainak ellenőrzése (olvasható/nem olvasható)
      • nem = kérjük oldja fel, az olvashatóság korlátozását
    • a szóban forgó objektum megfelel-e a kiterjesztéshez kapcsolódó összes elvárásnak (igen/nem)
    • kép méret,harmónia, ellenőrzése
      • ezeknek a sorrendje?
        • először méret, legvégén a harmónia
        • szerintem rettentő mindegy
      • kép ne olvadjon bele a futtató környezetbe
      • színharmónia megítélése
        • skálázható
        • mondhatja a szoftver, hogy szerinte ez csúnya
  • SSL pinning (https://medium.com/trendyol-tech/securing-ios-applications-with-ssl-pinning-38d551945306 , https://www.kodeco.com/1484288-preventing-man-in-the-middle-attacks-in-ios-with-ssl-pinning)

Programnyelv

Több fajta programnyelvet kipróbáltam, ám legvégül IOS környezetben, Swift nyelvnél döntöttem. (https://miau.my-x.hu/mediawiki/index.php/BPROF:2dm#Swift) Felsorolom a kipróbált nyelveket, majd legvégül kifejtem a Swift fejezetet.

Desktop

https://www.freecodecamp.org/news/compiled-versus-interpreted-languages/#:~:text=Examples%20of%20pure%20compiled%20languages,Haskell%2C%20Rust%2C%20and%20Go.

Interpretált programnyelv

Az interpretált sorról sorra olvassák be a programot, és futtatnak le minden parancsot. Ezek a programnyelvek szignifikánsabban lassabbak, mint a fordított programnyelvek.
pl.: Python, Ruby

Fordított programnyelv

Közvetlenül a CPU-ba vannak írva, és ezért gyorsabban lehet futtatni öket, mint az interpretált nyelveken íródott programokat. Hátránya, hogy a fejlesztéskor minden változtatás futtatásakor rebuildelni kell a teljes programot.
Előnye, hogy mivel a CPU-ba vannak írva, nehezebb hozzáférni a forráskódhoz. pl.: C++, Rust, Go

Konklúzió: Nem lesz logika tárolva a frontendben, ez a későbbi alfejezetekben lesz kifejtve.

Mobil

Swift

Programozási nyelv:

/*Ide amit Rikk J. t.úr kért (OOP, output elemzés, hasznalt algoritmusok elemzese)*/

OOP:

sajat swift oop doksim*

Használt algoritmusok: ......


Ötlet gyűjtés:

IT biztonság normál felhasználós környezetben

SSL Pinning

Az SSL pingelés azt jelenti, hogy egy készülék teszteli, hogy egy másik számítógép vagy szerver SSL/TLS titkosítást használ-e az adatkapcsolatánál. Az SSL/TLS a Secure Sockets Layer/Transport Layer Security protokolljai, amelyek kétoldalú titkosítást biztosítanak a kommunikációhoz, így megakadályozzák az adatok illetéktelen hozzáférését vagy megváltoztatását.

Ez egy olyan módszer, amely megállapítja, hogy egy adott szerver milyen gyorsan és megbízhatóan reagál SSL kapcsolatokra.

Az IOS készülékek esetében az SSL pingelés általában egy olyan alkalmazás által történik, amely az adatkapcsolatokat kezeli, például egy böngésző vagy egy e-mail alkalmazás.

Az SSL pingelés eredményei segíthetnek az alkalmazásnak meghatározni, hogy melyik szerverrel lehet a legjobb kapcsolatot létesíteni, és így javíthatják az alkalmazás teljesítményét és a felhasználói élményt.

App Attest Service

Az App Attest Service az Apple által az iOS 14 és az újabb verziókban bevezetett szolgáltatás, amely lehetővé teszi az alkalmazások számára, hogy igazolják a biztonságos futásukat az Apple rendszerén belül.

Az App Attest Service a biztonsági kulcsokat és az Apple T2 chipjének használatával valósítja meg a biztonságos alkalmazások ellenőrzését.

E szolgáltatás segítségével az alkalmazások egyedi azonosítóval rendelkező igazolást kérhetnek az Apple-től, amely igazolja, hogy az adott alkalmazás hiteles és az Apple rendszerében fut.

Az igazolás tartalmazza a kulcsot, amelyet az alkalmazás felhasználhat az alkalmazás eredetiségének és biztonságosságának bizonyításához, például azonosításra szolgáló tokenek, a biztonságos kommunikációhoz használt titkosított kulcsok és egyéb funkciók esetén.

Az említett szolgáltatás segít az alkalmazásoknak biztosítani, hogy csak az eredeti, biztonságosan fejlesztett kód fut a rendszerben, és segíthet megelőzni az adathalászatot, a csalásokat és a biztonsági kockázatokat. Az alkalmazásfejlesztőknek azonban támogatniuk kell az App Attest Service használatát az alkalmazásukban, hogy maximális biztonságot érhessenek el.

Megfelelő logolási módszer

A fejlesztők debug üzeneteket használnak az alkalmazás működésének naplózására, amely nagyon hasznos a fejlesztési folyamat során. Amikor az alkalmazás fejlesztés alatt áll, általában naplózunk bizonyos információkat, hogy segítsük a fejlesztők munkáját. Azonban, ha ez az információ hackerek kezébe kerül, akkor kiemelhet bizalmas adatokat és az alkalmazás belső működését. Annak érdekében, hogy biztosak lehessünk abban, hogy az alkalmazás verziójának, amelyet az App Store-ba küldünk, nem naplózunk üzeneteket, egyszerűen csak ellenőrizzük, hogy az alkalmazás Debug módban van-e, és csak ebben az esetben naplózzuk az üzeneteket.

#if DEBUG
print("log")
#endif

Ez a módszer hasznos lehet a fejlesztők számára, akik a fejlesztés során szeretnék naplózni az üzeneteket, de nem szeretnék, hogy az üzenetek megjelenjenek a naplókban a végleges verzióban. Ez azonban nem biztosít teljes védelmet, mivel a DEBUG módban végzett tesztelés során az üzenetek továbbra is elérhetők lehetnek, ha a tesztelők hozzáférnek az alkalmazás logfájljaihoz.


Amikor a Swiftben történő naplózásról van szó, több lehetőség is rendelkezésre áll, mindegyiknek saját előnyei és hátrányai vannak.

  • print()

Ez a legegyszerűbb és leggyakrabban használt naplózási módszer Swiftben, de nem biztonságos, mivel az üzeneteket a konzolra naplózza, amelyet bárki elérhet, aki hozzáfér az eszközhöz vagy az alkalmazás naplóihoz.

  • NSLog()

Az NSLog() az Apple Cocoa keretrendszer által biztosított naplózási funkció, amely az üzeneteket a rendszer naplójába naplózza, amelyet bárki elérhet, aki hozzáfér az eszközhöz vagy az alkalmazás naplóihoz. Biztonságosabb, mint a print(), mert az naplók nem jelennek meg a konzolon, de így is érzékeny információkat naplóz plain text formátumban.

  • os_log()

Az os_log() egy biztonságosabb naplózási módszer Swiftben, amelyet az iOS 10-ben vezettek be, és az üzeneteket az egyesített naplózási rendszerbe naplózza. Biztonságosabb, mint a print() és az NSLog(), mert biztonságos adatbázist használ az naplók tárolására, és lehetővé teszi a fejlesztőknek, hogy megadjanak egy adatvédelmi szintet minden naplóüzenetnek.

Biztonsági szempontból az os_log() a legbiztonságosabb naplózási módszer Swiftben. Biztonságosabb és központosított helyet biztosít az üzenetek naplózására, és lehetővé teszi a fejlesztőknek, hogy beállítsák a naplóüzenetek adatvédelmi szintjét. Emellett támogatja az adatszerkezetes adatok naplózását és a naplóüzenetek szűrését bizonyos kritériumok alapján.

A naplózási módszer kiválasztása azonban az alkalmazás konkrét igényeitől függ. Ha egyszerű és gyors módra van szüksége az üzenetek naplózásához a fejlesztés során, akkor a print() is elegendő lehet. Ha olyan üzeneteket kell naplózni, amelyek érzékeny információkat tartalmaznak, akkor az os_log() lehet a legjobb választás.

Az os_log használatakor a Loggernek két kategóriája van: az osztály (subsystem) és a kategória (category).

Az osztály az alkalmazás összes részére vonatkozik, és lehetővé teszi a naplóbejegyzések szűrését. Az osztály segítségével az alkalmazás fejlesztői átláthatják, hogy melyik részénél jelentkezik probléma.

A kategória lehetővé teszi a naplóbejegyzések további csoportosítását. A kategóriákat általában az adott osztályon belüli folyamatokhoz rendelik. Például az "adatbázis" kategória az adatbázishoz kapcsolódó naplóbejegyzésekhez kapcsolódik, és segít a fejlesztőknek a hibakeresésben, ha az adatbázisból származó problémák merülnek fel.

Egy Logger példányt lehet létrehozni egy bizonyos osztály és kategória kombinációjával, amely segíti az üzenetek további csoportosítását és szűrését. A Logger osztály és kategória paramétereit a naplófájlok áttekintésére és az alkalmazás hibakeresésére is lehet használni.

Ennek eredményeképp, a keretrendszer minden fejlesztéssel kapcsolatos logolást az "os_log()" metódussal végzi.

Létrehozok különböző log kategóriákat, melynek segítségével meg tudom különböztetni a logokat. ez fontos, hiszen gyorsabb, tisztább, biztonságosabb log rendszert képez.

Kategóriák:

  • "ui": az alkalmazás felhasználói interfészével kapcsolatos log (pl.: Játék nézet sikeresen betöltve)
  • "database": az adatbázissal kapcsolatos log (pl.: sikertelen csatlakozás)
  • "gamePlay": a játék folyamatával kapcsolatos log (pl.: X képkocka a C;K pozícióra helyezve)
  • "network": ...
  • "security": ....
extension OSLog {
   private static let subsystem = "sipi.GTSios"
   
   static let network = OSLog(subsystem: subsystem, category: "network")
   static let database = OSLog(subsystem: subsystem, category: "database")
   static let ui = OSLog(subsystem: subsystem, category: "ui")
   static let gamePlay = OSLog(subsystem: subsystem, category: "gamePlay")
   static let security = OSLog(subsystem: subsystem, category: "security")
}

Példák:

os_log("kép pozíciók: ", log: .gamePlay, kepPoziciok)
os_log("Nem gomb megnyomva", log: .ui)

HTTPS használata

Az HTTPS protokoll használatára való kötelezéshez Swift alkalmazásban az alábbi lépésekkel lehet elérni:

Első lépésként a Info.plist fájlban engedélyezzük az alkalmazásnak, hogy hozzáférjen a biztonságos internetes erőforrásokhoz azáltal, hogy az alábbi kódrészletet hozzáadjuk a fájlhoz.

<key>NSAppTransportSecurity</key>
<dict>
   <key>NSAllowsArbitraryLoads</key>
   <false/>
   <key>NSExceptionDomains</key>
   <dict>
       <key>yourdomain.com</key>
       <dict>
           <key>NSExceptionRequiresForwardSecrecy</key>
           <true/>
           <key>NSIncludesSubdomains</key>
           <true/>
           <key>NSTemporaryExceptionAllowsInsecureHTTPLoads</key>
           <false/>
           <key>NSTemporaryExceptionMinimumTLSVersion</key>
           <string>TLSv1.2</string>
       </dict>
   </dict>
</dict>

A "yourdomain.com" helyett beírjuk a saját domain címünket.

A URLComponents segítségével létre hozzuk a URL-t, majd beállítjuk az https értéket a scheme tulajdonságon keresztül. Példa:

guard var components = URLComponents(string: "https://yourdomain.com") else {
   fatalError("Invalid URL")
}

A hálózati kérések elküldéséhez használjuk az URLSession-t, majd beállítjuk a requiresSecureHTTPS tulajdonságot true értékre. Példa:

let session = URLSession(configuration: .default, delegate: nil, delegateQueue: OperationQueue.main)
session.configuration.requiresSecureHTTPS = true
let task = session.dataTask(with: components.url!) { data, response, error in
   // A válasz kezelése
}
task.resume()
IT biztonság Root jogosultsággal kapcsolatban
Ezt még a tesztelő folyamatosan teszteli, és amint sikerül haladnia, a dolgozatíró is fogja frissíteni itt, a miauban.

Ezek az alap IOSSecuritySuite modul által támogatott biztonségi metódusok. Ezeket módosítani, kiegészíteni szükséges, mivel sikerült az alap metódusokat kijátszania a tesztelőnek.


Mivel ez egy komplikált függvénysorozat, ezért mindenek előtt szeretném ismertetni a függvény hívási hierarchiát:

  • checkJailbreak
    • amIJailbrokenWithFailMessage
      • amIJailbrokenWithFailMessage
        • performCheck
          • checkUrlSchemes
          • checkExistenceOfSuspiciousFiles
            • amIRunInEmulator
              • EmulatorChecker.amIRunInEmulator
              • checkCompile
              • checkRunTime
          • checkRestrictedDirectoriesWriteaable
          • checkSuspiciousFilesCanBeOpened
            • EmulatorChecker.amIRunInEmulator
            • checkCompile
            • checkRunTime
          • checkDYLD
  • findLoadedDylibs
    • findLoadedDylibs
    • findLoadedDylibs
  • amIReverseEngineered
    • amIReverseEngineered
      • checkExistenceOfSuspiciousFiles
      • checkDYLD
      • checkOpenedPorts
      • canOpenLocalConnection
      • swapBytesIfNeeded
    • checkPSelectedFlag
<key>LSApplicationQueriesSchemes</key>
<array>
   <string>undecimus</string>
   <string>sileo</string>
   <string>zbra</string>
   <string>filza</string>
   <string>activator</string>
</array>

Ez a fő függvény, amely több függvényt hív meg.

func checkJailbreak() -> Bool {
       let jailbreakStatus = IOSSecuritySuite.amIJailbrokenWithFailMessage()
       let findLoadedDylibs = IOSSecuritySuite.findLoadedDylibs()
       let amIReverseEngineered = IOSSecuritySuite.amIReverseEngineered()
       
       print("findLoadedDylibs: \(String(describing: findLoadedDylibs))")
       print("amIReverseEngineered: \(amIReverseEngineered)")
       
       if jailbreakStatus.jailbroken {
           print("This device is jailbroken")
           print("Because: \(jailbreakStatus.failMessage)")
           return true
       } else if amIReverseEngineered {
           print("IamReverseEngineered")
           return true
       } else {
           print("This device is not jailbroken")
           return false
       }
   }

Mit csinál a "checkJailbreak" nevű függvény?

A következőkben felbontom, hogy milyen komponensek vannak a "checkJailbreak" függvényben, minden alfüggvénnyel együtt. Ennek célja, hogy teljesen felfedjem a jailbreak detection rendszert.

  • függvény pontos helye: IOSSecuritySuite.amIJailbrokenWithFailMessage()
public static func amIJailbrokenWithFailMessage() -> (jailbroken: Bool, failMessage: String) {
       return JailbreakChecker.amIJailbrokenWithFailMessage()
   }

Mit csinál az "amIJailbrokenWithFailMessage" nevű függvény?

  • függvény pontos helye: JailbreakChecker.amIJailbrokenWithFailMessage()
static func amIJailbrokenWithFailMessage() -> (jailbroken: Bool, failMessage: String) {
       let status = performChecks()
       return (!status.passed, status.failMessage)
   }

Mit csinál a "performChecks" nevű függvény?

  • függvény pontos helye: JailbreakChecker.performChecks()
private static func performChecks() -> JailbreakStatus {
       var passed = true
       var failMessage = ""
       var result: CheckResult = (true, "")
       var failedChecks: [FailedCheckType] = []
       
       for check in FailedCheck.allCases {
           switch check {
           case .urlSchemes:
               result = checkURLSchemes()
           case .existenceOfSuspiciousFiles:
               result = checkExistenceOfSuspiciousFiles()
           case .suspiciousFilesCanBeOpened:
               result = checkSuspiciousFilesCanBeOpened()
           case .restrictedDirectoriesWriteable:
               result = checkRestrictedDirectoriesWriteable()
           case .fork:
               if !EmulatorChecker.amIRunInEmulator() {
                   result = checkFork()
               } else {
                   print("App run in the emulator, skipping the fork check.")
                   result = (true, "")
               }
           case .symbolicLinks:
               result = checkSymbolicLinks()
           case .dyld:
               result = checkDYLD()
           default:
               continue
           }

           passed = passed && result.passed

           if !result.passed {
               failedChecks.append((check: check, failMessage: result.failMessage))

               if !failMessage.isEmpty {
                   failMessage += ", "
               }
           }

           failMessage += result.failMessage
       }

       return JailbreakStatus(passed: passed, failMessage: failMessage, failedChecks: failedChecks)
   }


A függvényt JailbreakStatus típusú értékkel tér vissza, amelynek három eleme van: passed (egész szám, amely igaz vagy hamis értéket vesz fel), failMessage (szöveg) és failedChecks (FailedCheckType típusú tömb). A passed logikai érték megadja, hogy az összes ellenőrzés során sikeres volt-e, a failMessage tartalmazza az összes hibát, amelyet a tesztek során találtak, és a failedChecks pedig tartalmazza azokat a teszteket, amelyek során hiba történt.

A függvény kezdetén a változók inicializálódnak: passed igaz, failMessage üres sztring, result logikai értékből és szövegből álló tuple, amelynek kezdőértéke (true, ""), és failedChecks üres FailedCheckType tömb.

Ezután a függvény végigiterál az összes FailedCheck típusú értéken (FailedCheck egy enumeráció). Mindegyik tesztesetet végrehajtja a switch utasítással. Az első teszteset urlSchemes, és az checkURLSchemes() függvényt hívja meg. A következő teszteset existenceOfSuspiciousFiles, amely az checkExistenceOfSuspiciousFiles() függvényt hívja meg, és így tovább minden tesztesetre.

Minden teszteset eredménye (result) eltárolódik a passed és failMessage változókban. Ha az adott teszteset eredménye sikertelen, akkor hozzáadjuk a failedChecks tömbhöz, hogy az összes hibát nyomon követhessük. Ha az adott teszteset eredménye sikertelen, akkor hozzáadjuk az adott hibaüzenetet a failMessage változóhoz, amely tartalmazza az összes teszteset során talált hibákat.

Végül a függvény visszatér a JailbreakStatus értékével, amely tartalmazza az összes teszt eredményét.

Tesztesetek kibontva:

checkURLSchemes:

  • függvény pontos helye: JailbreakChecker.checkURLSchemes()
private static func checkURLSchemes() -> CheckResult {
       var flag: (passed: Bool, failMessage: String) = (true, "")
       let urlSchemes = [
           "undecimus://",
           "sileo://",
           "zbra://",
           "filza://",
           "activator://"
       ]

       if Thread.isMainThread {
           flag = canOpenUrlFromList(urlSchemes: urlSchemes)
       } else {
           let semaphore = DispatchSemaphore(value: 0)
           DispatchQueue.main.async {
               flag = canOpenUrlFromList(urlSchemes: urlSchemes)
               semaphore.signal()
           }
           semaphore.wait()
       }
       return flag
   }

Mit csinál a checkURLSchemes függvény?

Ez a függvény az URL sémák ellenőrzésére szolgál. Az URL sémák egy olyan azonosítók, amelyeket az alkalmazások használnak a külső forrásokkal való kommunikációhoz, például más alkalmazásokkal vagy webhelyekkel. A függvényben először létrehoz egy urlSchemes nevű tömböt, amely az ellenőrizni kívánt URL sémákat tartalmazza. Ezután ellenőrzi, hogy az aktuális szál a fő szál-e (Thread.isMainThread). Ha igen, akkor azonnal meghívja a canOpenUrlFromList függvényt a urlSchemes tömbön, és a függvény visszatérési értéke lesz a flag változó. Ha nem a fő szálban vagyunk, akkor létrehozunk egy szemafort (DispatchSemaphore), amely blokkolja a szálat, amíg a fő szál be nem fejezi a canOpenUrlFromList függvény hívását. Ezt azért teszi, mert a fő szálban kell hívni az URL sémák ellenőrzéséhez szükséges rendszeres függvényeket. Miután a függvény lefutott, a szemafor engedélyezi a folytatást, és visszatér a flag változóval. A flag változó egy (passed: Bool, failMessage: String) típusú tuple, amely két elemet tartalmaz. Az első elem egy bool érték, amely jelzi, hogy az URL sémák ellenőrzése sikeres volt-e vagy sem. A második elem egy string, amely egy hibaüzenetet tartalmaz, ha az ellenőrzés nem sikerült. A flag változó értékét a függvény végén adja vissza.

checkExistenceOfSuspiciousFiles:

  • függvény pontos helye: JailbreakChecker.checkExistenceOfSuspiciousFiles()
private static func checkExistenceOfSuspiciousFiles() -> CheckResult {
       var paths = [
           "/var/mobile/Library/Preferences/ABPattern", // A-Bypass
           "/usr/lib/ABDYLD.dylib", // A-Bypass,
           "/usr/lib/ABSubLoader.dylib", // A-Bypass
           "/usr/sbin/frida-server", // frida
           "/etc/apt/sources.list.d/electra.list", // electra
           "/etc/apt/sources.list.d/sileo.sources", // electra
           "/.bootstrapped_electra", // electra
           "/usr/lib/libjailbreak.dylib", // electra
           "/jb/lzma", // electra
           "/.cydia_no_stash", // unc0ver
           "/.installed_unc0ver", // unc0ver
           "/jb/offsets.plist", // unc0ver
           "/usr/share/jailbreak/injectme.plist", // unc0ver
           "/etc/apt/undecimus/undecimus.list", // unc0ver
           "/var/lib/dpkg/info/mobilesubstrate.md5sums", // unc0ver
           "/Library/MobileSubstrate/MobileSubstrate.dylib",
           "/jb/jailbreakd.plist", // unc0ver
           "/jb/amfid_payload.dylib", // unc0ver
           "/jb/libjailbreak.dylib", // unc0ver
           "/usr/libexec/cydia/firmware.sh",
           "/var/lib/cydia",
           "/etc/apt",
           "/private/var/lib/apt",
           "/private/var/Users/",
           "/var/log/apt",
           "/Applications/Cydia.app",
           "/private/var/stash",
           "/private/var/lib/apt/",
           "/private/var/lib/cydia",
           "/private/var/cache/apt/",
           "/private/var/log/syslog",
           "/private/var/tmp/cydia.log",
           "/Applications/Icy.app",
           "/Applications/MxTube.app",
           "/Applications/RockApp.app",
           "/Applications/blackra1n.app",
           "/Applications/SBSettings.app",
           "/Applications/FakeCarrier.app",
           "/Applications/WinterBoard.app",
           "/Applications/IntelliScreen.app",
           "/private/var/mobile/Library/SBSettings/Themes",
           "/Library/MobileSubstrate/CydiaSubstrate.dylib",
           "/System/Library/LaunchDaemons/com.ikey.bbot.plist",
           "/Library/MobileSubstrate/DynamicLibraries/Veency.plist",
           "/Library/MobileSubstrate/DynamicLibraries/LiveClock.plist",
           "/System/Library/LaunchDaemons/com.saurik.Cydia.Startup.plist",
           "/Applications/Sileo.app",
           "/var/binpack",
           "/Library/PreferenceBundles/LibertyPref.bundle",
           "/Library/PreferenceBundles/ShadowPreferences.bundle",
           "/Library/PreferenceBundles/ABypassPrefs.bundle",
           "/Library/PreferenceBundles/FlyJBPrefs.bundle",
           "/usr/lib/libhooker.dylib",
           "/usr/lib/libsubstitute.dylib",
           "/usr/lib/substrate",
           "/usr/lib/TweakInject",
           "/var/binpack/Applications/loader.app", // checkra1n
           "/Applications/FlyJB.app", // Fly JB X
           "/Applications/Zebra.app" // Zebra
       ]
       
       // These files can give false positive in the emulator
       if !EmulatorChecker.amIRunInEmulator() {
           paths += [
           "/bin/bash",
           "/usr/sbin/sshd",
           "/usr/libexec/ssh-keysign",
           "/bin/sh",
           "/etc/ssh/sshd_config",
           "/usr/libexec/sftp-server",
           "/usr/bin/ssh"
           ]
       }

       for path in paths {
           if FileManager.default.fileExists(atPath: path) {
               return (false, "Suspicious file exists: \(path)")
           }
       }

       return (true, "")
   }

A függvény egy ellenőrzést végez bizonyos fájlok meglétére az iOS rendszerben. Az ellenőrzés egy sor útvonalat vizsgál meg, és ha bármelyik fájl megtalálható az útvonalon, akkor a függvény hamis értékkel és az észlelt fájl elérési útjával tér vissza. Ha nincs találat, a függvény igaz értékkel tér vissza és üres stringgel. A függvény továbbá megvizsgálja, hogy az eszköz fut-e emulátorban, és ha nem, akkor további fájlokat vizsgál. Ha az emulátorban fut, akkor ezeket a fájlokat nem vizsgálja.

Összeszedtem, hogy miért ezeket a fájlokat keresi a kód:

  • "/var/mobile/Library/Preferences/ABPattern": A-Bypass jailbreak eszközhöz kapcsolódik, amely lehetővé teszi a különböző alkalmazásokból történő kibontakozást és a jailbreak védelme elleni védelmet.
  • "/usr/lib/ABDYLD.dylib": A-Bypass jailbreak eszközhöz kapcsolódik.
  • "/usr/lib/ABSubLoader.dylib": A-Bypass jailbreak eszközhöz kapcsolódik.
  • "/usr/sbin/frida-server": Frida nevű eszközhöz kapcsolódik, amely segít a rendszer elemzésében és biztonsági tesztek végzésében.
  • "/etc/apt/sources.list.d/electra.list": Electra jailbreak eszközhöz kapcsolódik, amely lehetővé teszi a jailbreakelést és az iOS rendszer módosításait.
  • "/etc/apt/sources.list.d/sileo.sources": Electra jailbreak eszközhöz kapcsolódik, amely a Sileo alkalmazáshoz tartozó forráslistákat tartalmazza.
  • "/.bootstrapped_electra": Electra jailbreak eszközhöz kapcsolódik, jelzi, hogy a jailbreak folyamat befejeződött.
  • "/usr/lib/libjailbreak.dylib": Electra jailbreak eszközhöz kapcsolódik.
  • "/jb/lzma": Electra jailbreak eszközhöz kapcsolódik, a jailbreak folyamat során használt adatokat tartalmazza.
  • "/.cydia_no_stash": unc0ver jailbreak eszközhöz kapcsolódik, amely bizonyos módosításokat hajt végre a jailbreakelés során.
  • "/.installed_unc0ver": unc0ver jailbreak eszközhöz kapcsolódik, amely jelzi, hogy az unc0ver jailbreak telepítve van.
  • "/jb/offsets.plist": unc0ver jailbreak eszközhöz kapcsolódik, az iOS rendszer által használt memóriaterületek eléréséhez szükséges információkat tartalmazza.
  • "/usr/share/jailbreak/injectme.plist": unc0ver jailbreak eszközhöz kapcsolódik, amely az iOS rendszer komponenseibe való injektáláshoz szükséges információkat tartalmazza.
  • "/etc/apt/undecimus/undecimus.list": unc0ver jailbreak eszközhöz kapcsolódik, amely a jailbreak folyamat során felhasznált forráslistákat tartalmazza.
  • "/var/lib/dpkg/info/mobilesubstrate.md5sums": Az Unc0ver nevű jailbreak-eszköz használt fájlja.
  • "/Library/MobileSubstrate/MobileSubstrate.dylib": Az Unc0ver nevű jailbreak-eszköz használt fájlja.
  • "/jb/jailbreakd.plist": Az Unc0ver nevű jailbreak-eszköz használt fájlja.
  • "/jb/amfid_payload.dylib": Az Unc0ver nevű jailbreak-eszköz használt fájlja.
  • "/jb/libjailbreak.dylib": Az Unc0ver nevű jailbreak-eszköz használt fájlja
  • "/usr/libexec/cydia/firmware.sh": A Cydia program által használt szkript, amely az iOS firmware verziószámát tartalmazza.
  • "/var/lib/cydia": A Cydia csomagkezelő által használt adatbázis.
  • "/etc/apt": Az Advanced Packaging Tool (APT) konfigurációs fájljai és forráslistái.
  • "/private/var/lib/apt": Az APT által használt tároló.
  • "/private/var/Users/": A felhasználói adatokat tartalmazó könyvtár.
  • "/var/log/apt": Az APT naplófájljai.
  • "/Applications/Cydia.app": A jailbreak után telepített, a Cydia csomagkezelőt tartalmazó alkalmazás.
  • "/private/var/stash": Az iOS rendszer fájljainak áthelyezett másolatai, amelyekkel a készülék tárhelyének optimalizálása érhető el.
  • "/private/var/lib/apt/": Az APT által használt adatbázis.
  • "/private/var/lib/cydia": A Cydia által használt adatbázis.
  • "/private/var/cache/apt/": Az APT által használt gyorsítótár.
  • "/private/var/log/syslog": A rendszer logfájlja.
  • "/private/var/tmp/cydia.log": A Cydia program naplófájlja.
  • "/Applications/Icy.app": Egy alternatív csomagkezelő alkalmazás a Cydia helyett.
  • "/Applications/MxTube.app": Egy alkalmazás, amely segítségével videókat tölthetünk le az internetről.
  • "/Applications/RockApp.app": Egy másik alternatív csomagkezelő alkalmazás a Cydia helyett.
  • "/Applications/blackra1n.app": Egy jailbreak eszköz.
  • "/Applications/SBSettings.app": Egy alkalmazás, amely lehetővé teszi a készülék beállításainak gyors elérését.
  • "/Applications/FakeCarrier.app": Egy alkalmazás, amely lehetővé teszi a hordozó nevének megváltoztatását.
  • "/Applications/WinterBoard.app": Egy alkalmazás, amely lehetővé teszi a készülék kinézetének testreszabását.
  • "/Applications/IntelliScreen.app": Egy alkalmazás, amely lehetővé teszi a készülék zárolt képernyőjén információ megjelenítését.
  • "/private/var/mobile/Library/SBSettings/Themes": A SBSettings alkalmazás témáit tartalmazó mappa.
  • "/Library/MobileSubstrate/CydiaSubstrate.dylib": Egy keretrendszer, amely lehetővé teszi a kiegészítők telepítését és
  • "/System/Library/LaunchDaemons/com.ikey.bbot.plist": ez egy plist fájl, amely egy indítási szkriptet tartalmaz, amely a rendszerindításkor fut. A com.ikey.bbot.plist fájl egy olyan adathalmozó program, amely egy adathalmozó botot futtat a rendszeren, hogy bizonyos műveleteket hajtson végre
  • "/Library/MobileSubstrate/DynamicLibraries/Veency.plist" és "/Library/MobileSubstrate/DynamicLibraries/LiveClock.plist": ezek olyan fájlok, amelyek az iOS rendszer módosítására szolgálnak, különösen az alkalmazások működésének módosítására. Az ilyen fájlokhoz gyakran hozzáadnak úgynevezett "tweak"-eket, amelyek módosítják a rendszer viselkedését.
  • "/System/Library/LaunchDaemons/com.saurik.Cydia.Startup.plist": ez a fájl egy indítási szkriptet tartalmaz, amely a Cydia nevű alkalmazást indítja el a rendszerindításkor.
  • "/Applications/Sileo.app": ez egy alternatív alkalmazásbolt, amely az iOS rendszeren fut, és lehetővé teszi az alkalmazások telepítését a jailbreakelt rendszerre.
  • "/var/binpack": ez egy mappa, amelyben a bináris fájlok találhatók, amelyek az iOS rendszer módosításához hasznosak lehetnek.
  • "/Library/PreferenceBundles/LibertyPref.bundle", "/Library/PreferenceBundles/ShadowPreferences.bundle", "/Library/PreferenceBundles/ABypassPrefs.bundle" és "/Library/PreferenceBundles/FlyJBPrefs.bundle": ezek az úgynevezett preference bundle-ök, amelyek az iOS rendszer beállításait módosítják.
  • "/usr/lib/libhooker.dylib", "/usr/lib/libsubstitute.dylib", "/usr/lib/substrate" és "/usr/lib/TweakInject": ezek a fájlok az iOS rendszer módosításához használt könyvtárak és fájlok.
  • "/var/binpack/Applications/loader.app": lehetővé teszi a Cydia és Sileo alternatív alkalmazásboltok használatát, valamint az olyan módosítások és eszközök használatát, amelyek csak jailbreakelt iOS rendszeren érhetők el
  • "/Applications/FlyJB.app": a FlyJB X jailbreak szoftverrel együttműködve használható. A FlyJB X lehetővé teszi a felhasználók számára a jailbreak módosításainak kezelését, valamint az iOS rendszer bizonyos beállításainak módosítását
  • "/Applications/Zebra.app": A Zebra alkalmazásbolt a Cydia és a Sileo alternatívája, amely lehetővé teszi a felhasználók számára az alkalmazások és az iOS rendszer módosításainak kezelését.

checkSuspiciousFilesCanBeOpened:

  • függvény pontos helye: JailbreakChecker.checkSuspiciousFilesCanBeOpened()
private static func checkSuspiciousFilesCanBeOpened() -> CheckResult {

       var paths = [
           "/.installed_unc0ver",
           "/.bootstrapped_electra",
           "/Applications/Cydia.app",
           "/Library/MobileSubstrate/MobileSubstrate.dylib",
           "/etc/apt",
           "/var/log/apt"
       ]
       
       // These files can give false positive in the emulator
       if !EmulatorChecker.amIRunInEmulator() {
           paths += [
           "/bin/bash",
           "/usr/sbin/sshd",
           "/usr/bin/ssh"
           ]
       }

       for path in paths {

           if FileManager.default.isReadableFile(atPath: path) {
               return (false, "Suspicious file can be opened: \(path)")
           }
       }

       return (true, "")
   }

Mit csinál ez a függvény?

Az a feladata, hogy ellenőrizze, hogy a programból elérhetőek-e bizonyos "gyanús" fájlok. A függvény az alábbiakat végzi el:

Definiálja a fájlok listáját, amelyeket ellenőrizni kell (pl. "/.installed_unc0ver", "/.bootstrapped_electra", stb.). Ha az ellenőrzés valamilyen okból a futtatott program futtatása esetén hamis pozitív eredményt adhat, akkor az ilyen fájlokat (pl. "/bin/bash", "/usr/sbin/sshd", stb.) csak akkor teszi hozzá a listához, ha a program nem fut emulatorban. Végigmegy a listán, és ellenőrzi, hogy a programból elérhető-e az adott fájl olvasása. Ha bármelyik fájl olvasható, akkor a függvény visszatér egy hamis értékkel és egy hibaüzenettel, amely jelzi, hogy az adott fájl elérhető. Ha egyetlen fájl sem olvasható, akkor a függvény visszatér egy igaz értékkel és egy üres hibaüzenettel. Ez a függvény nyilvánvalóan olyan helyzetekben hasznos, amikor az alkalmazásnak nem kell elérnie bizonyos fájlokat a rendszeren, és az ellenőrzés arra szolgál, hogy megakadályozza a programot a gyanús fájlok olvasásában, például azért, hogy ne lehessen jailbreak szoftvereket futtatni a készüléken.

checkRestrictedDirectoriesWriteable:

  • függvény pontos helye: JailbreakChecker.checkRestrictedDirectoriesWriteable()
private static func checkRestrictedDirectoriesWriteable() -> CheckResult {

       let paths = [
           "/",
           "/root/",
           "/private/",
           "/jb/"
       ]

       // If library won't be able to write to any restricted directory the return(false, ...) is never reached
       // because of catch{} statement
       for path in paths {
           do {
               let pathWithSomeRandom = path+UUID().uuidString
               try "AmIJailbroken?".write(toFile: pathWithSomeRandom, atomically: true, encoding: String.Encoding.utf8)
               try FileManager.default.removeItem(atPath: pathWithSomeRandom) // clean if succesfully written
               return (false, "Wrote to restricted path: \(path)")
           } catch {}
       }

       return (true, "")
   }

Mit csinál ez a függvény?

Ellenőrzi, hogy a program könyvtárai írhatóak-e a korlátozott könyvtárak közé. A függvény az alábbiakat végzi el:

Definiálja a könyvtárak listáját (pl. "/", "/root/", "/private/", "/jb/"). Végigmegy a listán, és megpróbál az egyes könyvtárakba írni egy véletlenszerű fájlt. Ha a fájlt sikerült írni az egyik könyvtárba, akkor azonnal visszatér egy hamis értékkel és egy hibaüzenettel, ami jelzi, hogy az írás sikeres volt. Ha az írás bármelyik könyvtárba nem sikerül, akkor a függvény visszatér az igaz értékkel és egy üres hibaüzenettel. Ez a függvény nyilvánvalóan olyan helyzetekben hasznos, amikor fontos, hogy a program ne írjon a korlátozott könyvtárakba. Ez például egy biztonsági ellenőrzéshez hasznos lehet, hogy megbizonyosodjon arról, hogy a program nem próbál meg olyan információkat elrejteni, amelyek nem tekinthetők nyilvánosnak.

checkFork:

  • függvény pontos helye: JailbreakChecker.checkFork()
private static func checkFork() -> CheckResult {

       let pointerToFork = UnsafeMutableRawPointer(bitPattern: -2)
       let forkPtr = dlsym(pointerToFork, "fork")
       typealias ForkType = @convention(c) () -> pid_t
       let fork = unsafeBitCast(forkPtr, to: ForkType.self)
       let forkResult = fork()

       if forkResult >= 0 {
           if forkResult > 0 {
               kill(forkResult, SIGTERM)
           }
           return (false, "Fork was able to create a new process (sandbox violation)")
       }

       return (true, "")
   }

Mit csinál ez a függvény?

Az a célja, hogy ellenőrizze, hogy a programból lehet-e új folyamatot indítani a fork rendszerhívással. A függvény a következőket teszi:

Létrehoz egy pointerToFork nevű mutatót, amely -2 bitminta értéket kap, és amelyre a dlsym függvény fog hivatkozni. A dlsym függvény az előzőleg létrehozott mutatóra hivatkozik a fork rendszerhívás címével, amelyet forkPtr változóba ment el. A forkPtr címet a ForkType típusú fork változóra konvertálja, amelynek típusa egy olyan C blokk, amely nem vesz át paramétereket, és egy pid_t típusú értéket ad vissza. Végül a függvény meghívja a fork függvényt, amely létrehoz egy új folyamatot. Ha a visszatérési érték pozitív, az azt jelenti, hogy a hívó folyamat az új folyamat szülője, és a függvény SIGTERM jelzést küld a gyermekfolyamatnak, majd visszatér egy hamis értékkel és egy hibaüzenettel, amely jelzi, hogy a függvény képes volt új folyamatot indítani. Ha a visszatérési érték negatív, az azt jelenti, hogy valamilyen hiba történt, és a függvény igaz értékkel tér vissza.

symbolicLinks:

  • függvény pontos helye: JailbreakChecker.checkSymbolicLinks()
private static func checkSymbolicLinks() -> CheckResult {

       let paths = [
           "/var/lib/undecimus/apt", // unc0ver
           "/Applications",
           "/Library/Ringtones",
           "/Library/Wallpaper",
           "/usr/arm-apple-darwin9",
           "/usr/include",
           "/usr/libexec",
           "/usr/share"
       ]

       for path in paths {
           do {
               let result = try FileManager.default.destinationOfSymbolicLink(atPath: path)
               if !result.isEmpty {
                   return (false, "Non standard symbolic link detected: \(path) points to \(result)")
               }
           } catch {}
       }

       return (true, "")
   }

Mit csinál ez a függvény?

ellenőrzi, hogy a rendszerben vannak-e nem szabványos szimbolikus linkek, amelyek a fájlok vagy könyvtárak helyett valamilyen más helyre mutatnak. A függvény a következőket teszi:

Definiál egy lista azokról a könyvtárakról és fájlokról, amelyek szimbolikus linkeket tartalmazhatnak. Végigmegy a lista összes elemén, és megpróbálja meghatározni az adott elem szimbolikus link célját a destinationOfSymbolicLink függvény segítségével. Ha az adott elem szimbolikus linket tartalmaz, és a célja nem üres, a függvény hamis értékkel és egy hibaüzenettel tér vissza, amely jelzi, hogy nem szabványos szimbolikus linket talált. Ha az adott elem nem tartalmaz

dyld:

  • függvény pontos helye: JailbreakChecker.checkDYLD()
   private static func checkDYLD() -> CheckResult {

       let suspiciousLibraries = [
           "SubstrateLoader.dylib",
           "SSLKillSwitch2.dylib",
           "SSLKillSwitch.dylib",
           "MobileSubstrate.dylib",
           "TweakInject.dylib",
           "CydiaSubstrate",
           "cynject",
           "CustomWidgetIcons",
           "PreferenceLoader",
           "RocketBootstrap",
           "WeeLoader",
           "/.file", // HideJB (2.1.1) changes full paths of the suspicious libraries to "/.file"
           "libhooker",
           "SubstrateInserter",
           "SubstrateBootstrap",
           "ABypass",
           "FlyJB",
           "Substitute",
           "Cephei",
           "Electra",
       ]

       for libraryIndex in 0..<_dyld_image_count() {

           // _dyld_get_image_name returns const char * that needs to be casted to Swift String
           guard let loadedLibrary = String(validatingUTF8: _dyld_get_image_name(libraryIndex)) else { continue }

           for suspiciousLibrary in suspiciousLibraries {
               if loadedLibrary.lowercased().contains(suspiciousLibrary.lowercased()) {
                   return (false, "Suspicious library loaded: \(loadedLibrary)")
               }
           }
       }

       return (true, "")
   }

Ez a függvény ellenőrzi, hogy az iOS eszköz rendszerében betöltött dinamikus könyvtárak között találhatóak-e bizonyos gyanús könyvtárak. A függvény egy listát használ, amely tartalmazza a gyanús könyvtárak neveit. A függvény végigmegy az összes betöltött dinamikus könyvtáron, és ellenőrzi, hogy a neve tartalmazza-e a gyanús könyvtárak nevét. Ha talál egy ilyen könyvtárat, akkor visszatér az eredménnyel, hogy talált egy gyanús könyvtárat. Ellenkező esetben a függvény visszatér az eredménnyel, hogy nem talált gyanús könyvtárat. A függvény célja, hogy megakadályozza az iOS eszközökön futó, nem kívánt, manipulatív szoftvereket.

OSSecuritySuite.findLoadedDylibs()

  • függvény pontos helye: IOSSecuritySuite.findLoadedDylibs()
static func findLoadedDylibs(_ target: IntegrityCheckerImageTarget = .default) -> [String]? {
       return IntegrityChecker.findLoadedDylibs(target)
   }

Mit csinál a "findLoadedDylibs" nevű függvény?

Meghívja a következő függvényt, az IntegrityChecker osztályból:

static func findLoadedDylibs(_ target: IntegrityCheckerImageTarget = .default) -> [String]? {
       switch target {
       case .custom(let imageName):
           return MachOParse(imageName: imageName).findLoadedDylibs()
       case .default:
           return MachOParse().findLoadedDylibs()
       }
   }

Mit csinál a "findLoadedDylibs" függvény?

A dinamikus könyvtárakat keresi egy adott célfolyamatban. A függvény egy opcionális IntegrityCheckerImageTarget típusú paramétert vár. A switch utasításban az IntegrityCheckerImageTarget típus értékétől függően a függvény két különböző esetben hajtódik végre. Az alapértelmezett esetben (case .default) a MachOParse objektumot példányosítjuk a default konstruktorral, és meghívjuk rajta a findLoadedDylibs() metódust, amely visszaadja az összes betöltött dinamikus könyvtárat a folyamatban. A másik esetben (case .custom(let imageName)) az adott imageName nevű fájlra hajtunk végre hasonló műveleteket, majd visszatérünk a talált dinamikus könyvtárak listájával. A visszatérési érték egy opcionális tömb típusú érték, amely tartalmazza a betöltött dinamikus könyvtárak neveit. Ha nincsenek betöltött dinamikus könyvtárak, akkor a függvény nil-t ad vissza.


IOSSecuritySuite.amIReverseEngineered()

public static func amIReverseEngineered() -> Bool {
       return ReverseEngineeringToolsChecker.amIReverseEngineered()
   }

Mit csinál az "amIReverseEngineered" nevű függvény?

static func amIReverseEngineered() -> Bool {
       return !performChecks().passed
   }

A függvény egyszerűen meghívja a performChecks() függvényt, amely visszaadja egy JailbreakStatus értéket, amely tartalmazza az alkalmazásban végrehajtott biztonsági ellenőrzések eredményeit. Az eredmény szerint, ha az összes ellenőrzés sikeres volt, és nincs biztonsági probléma, akkor a passed tulajdonság igaz értéket ad vissza, és az alkalmazás nem lett megfordítva.

A ! (negáció) operátorral azonban megfordítjuk az értéket, és ha bármelyik ellenőrzés megbukott, azaz az passed tulajdonság hamis értéket adott vissza, akkor a performChecks() függvényből visszatérő érték hamis lesz, mivel az alkalmazás nem teljesíti a biztonsági előírásokat. Ebben az esetben a amIReverseEngineered() függvény is hamis értékkel tér vissza, mivel a megfordítás (reverse engineering) előfeltétele a biztonsági ellenőrzések sikeres teljesítése. Így ha az amIReverseEngineered() függvény hamis értéket ad vissza, akkor az azt jelzi, hogy az alkalmazás nem lett megfordítva. Ellenkező esetben, ha igazat ad vissza, akkor az azt jelzi, hogy az alkalmazás meg van fordítva.


performChecks()

private static func performChecks() -> ReverseEngineeringToolsStatus {
       var passed = true
       var result: CheckResult = (true, "")
       var failedChecks: [FailedCheckType] = []
       
       for check in FailedCheck.allCases {
           switch check {
           case .existenceOfSuspiciousFiles:
               result = checkExistenceOfSuspiciousFiles()
           case .dyld:
               result = checkDYLD()
           case .openedPorts:
               result = checkOpenedPorts()
           case .pSelectFlag:
               result = checkPSelectFlag()
           default:
             continue
           }

           passed = passed && result.passed

           if !result.passed {
               failedChecks.append((check: check, failMessage: result.failMessage))
           }
       }

       return ReverseEngineeringToolsStatus(passed: passed, failedChecks: failedChecks)
   }

Mit csinál a "ReverseEngineeringToolsChecker" osztályban található "performChecks" függvény?

Az alkalmazásban keresi az olyan potenciális fordítási eszközök és technikák jelenlétét, amelyekkel az alkalmazást meg lehet fordítani (reverse engineering). A függvény neve performChecks, és nem vár paramétert.

A függvény egy üres ReverseEngineeringToolsStatus objektummal kezdődik, majd végrehajtja az összes definiált ellenőrzést a FailedCheck enumerációban. Az enumerációban definiált ellenőrzések a következők:

  • existenceOfSuspiciousFiles: Ellenőrzi az alkalmazásban lévő gyanús fájlok jelenlétét.
  • dyld: Ellenőrzi az alkalmazás dyld rendszerhívásait, amelyeket használhatnak a fordítási eszközök.
  • openedPorts: Ellenőrzi, hogy az alkalmazás nyitott-e hálózati portokat, amelyek lehetővé tehetik a támadók számára az alkalmazás kémkedését.
  • pSelectFlag: Ellenőrzi, hogy az alkalmazás használja-e a pselect() rendszerhívást, amelyet a fordítási eszközök használhatnak a hibakereséshez.

Az ellenőrzések végrehajtása során a függvény megvizsgálja az összes ellenőrzési eredményt, és ha az ellenőrzés sikeres, akkor az passed tulajdonságot igazra állítja, különben hamisra. Az összes sikeres ellenőrzés után az passed tulajdonsága igaz marad, különben hamis lesz.

Ha egy ellenőrzés nem sikerült, akkor a függvény hozzáadja az ellenőrzést a failedChecks tömbhöz. Ez azért fontos, mert az alkalmazás esetlegesen használhat olyan eszközöket, amelyek nem jelentenek kockázatot a biztonságra, és nem szeretnénk téves riasztást okozni.

Végül a függvény egy ReverseEngineeringToolsStatus objektumot ad vissza, amely tartalmazza az összes ellenőrzés eredményeit. Ha az összes ellenőrzés sikeres volt, akkor az passed tulajdonság igazra állítódik, különben hamisra. A failedChecks tömbben találhatók azok az ellenőrzések, amelyek nem voltak sikeresek, és ezt a ReverseEngineeringToolsStatus objektumot használják arra, hogy az alkalmazás megfelelően értékelje az alkalmazás biztonsági helyzetét, és megvédje azt a fordítási

Mi a ReverseEngineeringToolsStatus?

 ReverseEngineeringToolsStatus {
       let passed: Bool
       let failedChecks: [FailedCheckType]
   }

Ez az adattípus segít visszaadni az összes ellenőrzés eredményét a performChecks függvényben, hogy a függvény hívója könnyen ellenőrizhesse az eredményeket és választhatjon a megfelelő további műveletek közül.

'passed' egy logikai érték, amely azt jelzi, hogy az ellenőrzések átmentek-e vagy sem. 'failedChecks' egy [FailedCheckType] típusú tömb, amely azokat az ellenőrzéseket tartalmazza, amelyek nem mentek át, és a hibás üzenetüket.

Mi a FailedCheckType?

public typealias FailedCheckType = (check: FailedCheck, failMessage: String)
public enum FailedCheck: CaseIterable {
   case urlSchemes
   case existenceOfSuspiciousFiles
   case suspiciousFilesCanBeOpened
   case restrictedDirectoriesWriteable
   case fork
   case symbolicLinks
   case dyld
   case openedPorts
   case pSelectFlag
}


FailedCheckType - Egy típusaliasz, amely egy tuple-t definiál. A tuple két elemet tartalmaz: egy FailedCheck típusú értéket és egy szöveges üzenetet a hiba okának megadására. FailedCheck - Ez egy felsorolási típus (enum), amely tartalmazza azokat az ellenőrzéseket, amelyeket a kód végrehajt, hogy meghatározza, hogy az alkalmazás éppen visszafejtett állapotban van-e vagy sem. Minden enum eset (case) az adott ellenőrzési típus nevét tartalmazza, például urlSchemes, existenceOfSuspiciousFiles, dyld, stb. Ez az enum fontos szerepet játszik a performChecks függvényben, amely minden FailedCheck esetét végigmegy, és elvégzi az adott ellenőrzést. Ha az ellenőrzés nem sikerül, a függvény hozzáadja az adott FailedCheckType elemet a failedChecks tömbhöz.

Tesztelés

Ennek teszteléséhez szükség van egy Jailbreak-elt iOS eszközre. Ezt a lent megemlített tesztelő biztosítja.

A teszt eszköz specifikációjai:

  • Gyártó: Apple
  • Modell: iPhone 6S
  • IOS Verzió: 14.7.1
  • Jailbreak: checkra1n
  • checkra1n:

Exploit: checkm8

Hivatalosan támogatott eszközök és operációs rendszerek:

  • iPhone 4s
  • iPhone 5
  • iPhone 5c
  • iPad 2
  • iPad (3rd generation)
  • iPad (4th generation)
  • iPad mini (1st generation)
  • iPad Air (1st generation)
  • iPod touch (5th generation)
  • iOS 12.4.9 és korábbi
  • iOS 13 és korábbi
  • iOS 14 és korábbi

checkm8

A Checkm8 exploit egy hardveres sebezhetőséget használ ki, amely a bootrom-ban (indító rendszer) található a kijelölt Apple eszközökön. Az exploit általában egy speciális, manipulált USB kábel segítségével kerül az eszközre csatlakoztatásra.

A Checkm8 az érintett eszközökben lévő speciális lapkakészletet, az úgynevezett A5-től A11-ig terjedő chipkészleteket használja ki. A lapkakészletek egyik fontos eleme a bootrom, amely felelős az eszköz indításáért és biztonságos rendszerindításért.

Az exploit kihasználja a bootromban található biztonsági rést, és lehetővé teszi az eszközön a jailbreak-et, vagyis a kibontást, ami azt jelenti, hogy olyan szoftvereket és alkalmazásokat lehet futtatni az eszközön, amelyeket az Apple rendszeresen korlátoz.

A Checkm8 exploit egy "tethered" jailbreak, amely azt jelenti, hogy az eszköz minden újraindítása után újra be kell jelentkezni a jailbreak-be, amelyhez számítógépre van szükség. Az exploitnak azonban az előnye, hogy a készülék újraindítása után ismét elvégezhető a jailbreak, és nem szükséges a sebezhetőség újbóli kihasználása.

Tesztelt metódusok:

  • SSL Pinning

Az SSL pingelés azt jelenti, hogy egy készülék teszteli, hogy egy másik számítógép vagy szerver SSL/TLS titkosítást használ-e az adatkapcsolatánál. Az SSL/TLS a Secure Sockets Layer/Transport Layer Security protokolljai, amelyek kétoldalú titkosítást biztosítanak a kommunikációhoz, így megakadályozzák az adatok illetéktelen hozzáférését vagy megváltoztatását.

Az SSL pingelés egy olyan módszer, amely megállapítja, hogy egy adott szerver milyen gyorsan és megbízhatóan reagál SSL kapcsolatokra. Az IOS készülékek esetében az SSL pingelés általában egy olyan alkalmazás által történik, amely az adatkapcsolatokat kezeli, például egy böngésző vagy egy e-mail alkalmazás. Az SSL pingelés eredményei segíthetnek az alkalmazásnak meghatározni, hogy melyik szerverrel lehet a legjobb kapcsolatot létesíteni, és így javíthatják az alkalmazás teljesítményét és a felhasználói élményt.

  • App Attest Service

Az App Attest Service az Apple által az iOS 14 és az újabb verziókban bevezetett szolgáltatás, amely lehetővé teszi az alkalmazások számára, hogy igazolják a biztonságos futásukat az Apple rendszerén belül. Az App Attest Service a biztonsági kulcsokat és az Apple T2 chipjének használatával valósítja meg a biztonságos alkalmazások ellenőrzését.

Az App Attest Service szolgáltatás segítségével az alkalmazások egyedi azonosítóval rendelkező igazolást kérhetnek az Apple-től, amely igazolja, hogy az adott alkalmazás hiteles és az Apple rendszerében fut. Az igazolás tartalmazza a kulcsot, amelyet az alkalmazás felhasználhat az alkalmazás eredetiségének és biztonságosságának bizonyításához, például azonosításra szolgáló tokenek, a biztonságos kommunikációhoz használt titkosított kulcsok és egyéb funkciók esetén.

Az App Attest Service segít az alkalmazásoknak biztosítani, hogy csak az eredeti, biztonságosan fejlesztett kód fut a rendszerben, és segíthet megelőzni az adathalászatot, a csalásokat és a biztonsági kockázatokat. Az alkalmazásfejlesztőknek azonban támogatniuk kell az App Attest Service használatát az alkalmazásukban, hogy maximális biztonságot érhessenek el.

  • Hide current view on applicationWillResignActive
  • Prevent Logging in Production, ...
  • Function Hooking

A "function hooking" olyan technika, amely lehetővé teszi, hogy a programozó megváltoztassa egy program futás közbeni működését azáltal, hogy megváltoztatja annak függvényhívásait. A Swift programozási nyelvben ez azt jelenti, hogy a programozó a program futása közben hozzáadhat kódot egy függvényhívás előtt vagy után, hogy megváltoztassa a függvény eredményét vagy működését.

A function hooking általában olyan rendszerszintű programokban használatos, amelyek a rendszerhívásokat módosítják, de néhány esetben a fejlesztők is használhatják, például hibakereséshez vagy teszteléshez.

A Swiftben a function hooking megvalósítása az alacsony szintű C funkciók használatával lehetséges, például a dlsym() és dlopen() függvényekkel. A function hooking azonban erős függőséget mutat a rendszerbeli struktúrákra, és általában nem ajánlott átlagos fejlesztőknek, mivel hibákat és instabilitást okozhat a rendszerben.

  • Módosítások az alkalmazásban

Az IOSSecuritySuite egy harmadik féltől származó keretrendszer, amelyet az alkalmazás biztonságának javítására lehet használni. A fenti kódrészletek azt ellenőrzik, hogy az alkalmazásunkat manipulálták-e.

Ha hozzá szeretnénk adni az alkalmazásunkhoz, akkor először importálnunk kell az IOSSecuritySuite keretrendszert a projektünkbe. Ezután az alkalmazásunkban meg kell hívni a fenti függvényeket, amelyek visszatérnek egy eredmény struktúrával, amely tartalmazza a baszogatás eredményét.

A kód szerint az első függvény (amITampered) ellenőrzi, hogy az alkalmazásunkat manipulálták-e az adott bundleID-vel, mobileProvision-nel és machO fájl SHA256 hash-jével. Az eredmény egy result logikai érték, amely megmondja, hogy az alkalmazásunkat manipulálták-e vagy sem.

A második függvény (getMachOFileHashValue) visszaadja az adott Mach-O fájl SHA256 hash-jét. Az első példa custom paramétere az IOSSecuritySuite keretrendszer saját Mach-O fájlját használja. Az eredmény alapján az alkalmazásunkat manipulálták-e vagy sem.

A harmadik függvény (a példában kommentként megjegyezve) ellenőrzi az alkalmazásunk saját hash-értékét, amelyet a szerverről lehet lekérni.

Fontos megjegyezni, hogy az IOSSecuritySuite csak egy eszköz az alkalmazás biztonságának javítására. Az alkalmazás biztonságának javítása érdekében többféle eszközt kell használni, beleértve a kódellenőrzést, a titkosítást és az egyéb biztonsági mechanizmusokat.


if IOSSecuritySuite.amITampered([.bundleID("biz.securing.FrameworkClientApp"),
   .mobileProvision("2976c70b56e9ae1e2c8e8b231bf6b0cff12bbbd0a593f21846d9a004dd181be3"),
   .machO("IOSSecuritySuite", "6d8d460b9a4ee6c0f378e30f137cebaf2ce12bf31a2eef3729c36889158aa7fc")]).result {
   print("módosítottak")
}
else {
   print("nem módosítottak.")
}

if let hashValue = IOSSecuritySuite.getMachOFileHashValue(.custom("IOSSecuritySuite")), hashValue == "6d8d460b9a4ee6c0f378e30f137cebaf2ce12bf31a2eef3729c36889158aa7fc" {
   print("nem módosítottak.")
}
else {
   print("módosítottak.")
}

if let hashValue = IOSSecuritySuite.getMachOFileHashValue(.default), hashValue == "your-application-executable-hash-value" {
   print("nem módosítottak semmit.")
}
else {
   print("módosítottak.")
}

IT Bizonság tesztelése

Tesztelés elvégzője: Jkv3 , aki nem a szakdolgozat készítője. A tesztelő által készített teszt eredményeket a szakdolgozat készítője feldolgozta és implementálta a szükséges kódot.

https://canijailbreak.com

IOS-es fájlkezelővel megnyitotta az alkalmazás tartalmát:

IMG-állományok (ZIP): https://miau.my-x.hu/miau/292/2dm_figures/GTS%20ios%20app%20ITB%20k.zip 
  • IMG_0001.png , IMG_0010.png, firebase_url.png

A firebase adatbázis url-je. Az urlt nem lehet megnyitni böngészőből, ehhez a tulajdonos (jelen esetben a dolgozatíró) Google azonosítójával kell bejelentkezni a firebase szolgáltatásba.

  • IMG_003.png

Az alkalmazást ki lehet bontani egy szoftver segítségével. A szoftver megjeleníti az alkalmazáson belüli függvényeket, fájlok neveit, fontosabb kódrészleteket.

  • IMG_0005.png

Itt megtalálható minden alkalmazás fájl. Nyelvi fájlok (Localizable.strings) , Property list fájlok (.plist), és egyéb, az app futtatásához szükséges fájlok.

  • IMG_0006.png , IMG_007.png, IMG_008.png

Ez a nyelvi fájl. Itt deklarálódik, hogy melyik kifejezés éppen melyik nyelven miként jelenjen meg.

  • IMG_009.png

Ez maga az alkalmazás konfigurációs fájlja. Itt az érzékeny adat az “EMAIL” és “PASSWORD” mezőkben található. Ezt a dolgozatíró szánt szándékkal készítette így, mivel ez is egy módszer, egy alkalmazásbeli kulcs tárolásra.

Van rá lehetőség más módon tárolni ezeket a kulcsokat, elképzelhető, hogy a későbbiekben megváltozik a dolgozatban használt technológia.

https://www.securing.pl/en/the-secure-way-to-store-secrets-on-ios-devices/

“This also can be hacked if the hacker can have access to the archive file of our iOS. But this can be only shared with the people inside the company only, so I may not see this as a high threat.”

- https://medium.com/@karthianandhanit/how-to-securely-handle-the-third-party-keys-in-ios-adc6266efc1f

A teszt elvégzője szeretné hangsúlyozni, hogy ezekhez az adatokhoz való hozzáférés az IOS rendszerben mezei felhasználó számára nem kivitelezhető, root jogosultság, személyre szabott boot loader, kernel patchelés és még sok minden szükséges. Rengeteg ember foglalkozik ezzel (ki hobbi/ki professzionális szinten), hogy az éppen aktuális IOS-t “jailbreak”-eljék. Sem a teszt elvégzőjének, sem a dolgozatírónak nem ez volt a célja.


Jailbreak detection blocking https://ios.cfw.guide/blocking-jailbreak-detection/ https://www.reddit.com/r/jailbreak_/comments/qjr9h2/whats_the_best_jailbreak_detection_bypass_ios_144/

Keresnii kell egy olyan csomagot (tweak) amivel sikerül a jailbreak detectiont megtörni. Ennek a lényege,hogy újabb biztonsági rést fedezhessen fel a tesztelő, amit a dolgozatíró ledokumentálhat és befoltozhat.

  • A "A-Bypass" tweak: nem sikerult a jailbreak bypass
  • B "Liberty Lite" tweak: nem sikerült a jb bypass
  • C "Shadow" tweak:
    • C1 Alap konfigurációval, bypass letiltásával nem indul el az app
    • C2 Alap konfigurációval, bypassal elindul az app, sikerül a bypass.
      • konfiguráció:
        • Enable Shadow
        • Hooking Library: Default
          • irányítja az alkalmazási kód megvalósításához használt módszereket. Néhány hooking könyvtár lehetővé teheti a kikerülés javítását, de hatással lehet az alkalmazás stabilitására is.
        • Essential Hooks/File System -> bekapcsolva
          • ...mit jelent ez...
        • Essential Hooks/Dynamic Libraries -> bekapcsolva
          • ...mit jelent ez...
        • Essential Hooks/Environment Variables -> bekapcsolva
          • ...mit jelent ez...
      • log:

2023-02-21 11:45:43.944912+0100 GTSios[4366:30352] isPathRestricted: restricted: /Applications/Cydia.app 2023-02-21 11:45:43.948361+0100 GTSios[4366:30352] isPathRestricted: allowed: /Applications 2023-02-21 11:45:43.948458+0100 GTSios[4366:30352] isPathRestricted: allowed: /Applications 2023-02-21 11:45:43.948613+0100 GTSios[4366:30352] isPathRestricted: allowed: /Library/Ringtones 2023-02-21 11:45:43.948676+0100 GTSios[4366:30352] isPathRestricted: allowed: /Library/Ringtones 2023-02-21 11:45:43.948838+0100 GTSios[4366:30352] isPathRestricted: allowed: /Library/Wallpaper 2023-02-21 11:45:43.948896+0100 GTSios[4366:30352] isPathRestricted: allowed: /Library/Wallpaper 2023-02-21 11:45:43.949182+0100 GTSios[4366:30352] isPathRestricted: allowed: /usr/libexec 2023-02-21 11:45:43.949301+0100 GTSios[4366:30352] isPathRestricted: allowed: /usr/libexec 2023-02-21 11:45:43.949515+0100 GTSios[4366:30352] isPathRestricted: allowed: /usr/share 2023-02-21 11:45:43.949579+0100 GTSios[4366:30352] isPathRestricted: allowed: /usr/share

Tesztelt prorgamnyelvek

C#

Feltörése C# visszafejtése JetBrains dotPeek szoftver segítségével: https://miau.my-x.hu/mediawiki/index.php/BPROF:Csharp_Visszafejt%C3%A9se


Ruby

Mivel nem fordított nyelv, ezért a kódot nem lehet "elrejteni". A program egy *.rb fájl lenne, és ezt kellene futtatni egy interpreter segítségével. Emiatt a Ruby programnyelv használatát elvetem (a szakdolgozat GUI részének megvalósításához)

Feltörése

Nincs szükség rá,mivel magát a script fájlt futtattam le


Rust

Fordított programnyelv, tehát IT biztonsági szempontból megfelelő.


Logika tárolása

A keretrendszer logikáját nem maga a kliens,hanem a szervernek kell kezelnie. Ezzel csökkentve a játék sebezhetőségéneinek lehetőségét.

Backend

Itt kell a logikát tárolni. (azaz,hogy a képkockák jo helyen vannak -e) firebase cloud functions lenne a legkézennfekvőbb megoldás, ám ez fizetős. Feladat: megfelelő backed service-t találni ami ingyenes

Lista lehetséges backend service-kről:

  • heroku.com (fizetős)
  • aws
  • vercel

Kiválasztott opció: vercel

Indoklás: ingyenes. Teljesen Swift nyelvben lehet írni, ami könnyíti a Swiftben írt keretrendszerrel való kapcsolatot.

Frontend

.....

licenszelés

A szoftver licensszel való védése már egy erős IT biztonsági lépés.

ki kaphat licenszt?

Ingyen kellene adni, mert nem tartom reálisnak, hogy a tanárok/iskolák erre költenének. -> önkormányzatoknak kellene ezeket managelni?

Licensz tárolása adatbázisban (Firebase)

_______________________________
| licensz tulaj | licensz kód |
###############################
| ............. | ........... |
¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯

Amelyik kód bent van az adatbázisban a megfelelő rekordokkal, az hozzáférhet a programhoz

licensz generálása

Szerveren° futtatandó scriptnek kellene kérésre generálnia licensz kulcsokat, és azokat eltárolni a Firebase-s adatbázisban

° milyen szerveren?

licensz archiválása

licensz árazása

Lokális adattárolás

Nem éppen megfelelő az alkalmazás adatait JSON fájlokban tárolni. pl.: .db fájlban tárolni? https://learn.microsoft.com/en-us/windows/apps/design/app-settings/store-and-retrieve-app-data

Szoftverben használt csomagok és azok licenszeik

......

Log rendszer

A rendszer minden felhasználói tevékenységet feljegyez mind fejlesztési, mind a csalás elkerülése érdekében. A teszt fejlesztője megmondhatja, hogy mennyire kell szigorúan venni a szabályokat:

  • minden csalás tiltott, első attrocitás esetén a teszt lezárul, a log elkészül
  • csalások nincsenek engedélyezve, ám nem zár le a keretrendszer, csak logolja, hogy ez és ez történt
  • szabadon lehet csalni
  • beállíthatjuk, hogy mit vegyen csak figyelembe a rendszer. (indoklása: pl moodlen feltöltött anyagokat lehet használni, de más internetes keresést stb... nem)

Jelenleg logolható

  • app minimalizálása, bezárása, puzzle elindítása
  • játék során képkártyák húzása, elhelyezett pozíciójuk

Tervezett funkciók

  • internet használat elemzés (van-e esetleg olyan kulcsszavú keresés, mint amilyen szavak/kifejezések vannak az éppen aktív puzzle fájljaiban?)
  • egérmozgás elemzés (mennyire határozott a teszt író -> túl nagy határozottság akár azt is jelentheti, hogy valahonnan megszerezte a megoldásokat a teszthez ?)
  • ismert közösségi,csevegésre használt alkalmazások meg vannak-e nyitva (Messenger,Discord,facebook.com,Skype,Teams stb), ezek csalásra adhatnak lehetőséget
  • külső meghajtók vannak-e csatolva
  • adat mozgatás történt-e a számítógépen a teszt írása közben (x lokációról y lokációra való fájl mozgás)
  • operációs rendszerre telepített képfelismerési program detektálása
  • távolról van-e vezérelve a gép
  • képernyőkép készítésének logolása
  • automatikus egér mozgató (ha van ilyen, https://2b2t.miraheze.org/wiki/Baritone) auto clicker detektálása
  • ...

Log elemzés

ez is olyan fontos lesz mint az ITB stb.....

Rendszerspecifikáció

Ajánlott irodalom/demo/minta: http://centroszet.hu/tananyag/ - pl. http://centroszet.hu/tananyag/szervezes2/615_rszletes_rendszerterv.html 

Logikai rendszerterv

Fizikai rendszerterv

Program specifikáció

A követekző alfejezetben fogom összegyűjteni a program különféle specifikációját

User interface

Választott UI technológia

UIKit

Az UIKit az Apple által kifejlesztett keretrendszer az iOS alkalmazásokhoz, amelyeket iPhone, iPad és iPod Touch készülékeken futtatnak. Az UIKit lehetővé teszi az alkalmazások felhasználói felületének (UI) fejlesztését, amely az alkalmazások vizuális és interaktív aspektusait foglalja magában. Az UIKit tartalmaz egy sor előre elkészített UI elemeket, amelyeket könnyen hozzá lehet adni az alkalmazásokhoz, például gombokat, címkéket, képeket, szövegeket és sok más elemet. Az UIKit további funkciói közé tartozik az animációk és átmenetek, a szövegszerkesztés, az értesítések, az interakciók és az adatkezelés. Az UIKit egy nagyon hasznos eszköz az iOS alkalmazások fejlesztéséhez, és az iOS fejlesztők általánosan használt keretrendszerek közé tartozik.

Alternatívák

SwiftUI

A SwiftUI az Apple által kifejlesztett keretrendszer, amely lehetővé teszi az alkalmazások gyors és egyszerű felhasználói felületének (UI) kialakítását az iOS, az iPadOS, a macOS, a watchOS és a tvOS operációs rendszerekhez. A SwiftUI egy deklaratív programozási megközelítést kínál, amely lehetővé teszi az alkalmazások UI-jának kódolását egy egyszerű és intuitív módon. Az alkalmazás UI-ját előzetesen definiált építőelemekkel lehet létrehozni, amelyeket egyszerűen be lehet illeszteni a kódba, és a SwiftUI automatikusan megjeleníti az alkalmazásban.

A SwiftUI lehetővé teszi a fejlesztők számára az alkalmazások UI-jának gyors és hatékony tervezését és testreszabását. Az építőelemek sokfélesége lehetővé teszi az egyedi és összetett UI-k létrehozását. Az alkalmazások kódjának egyszerűsége és olvashatósága miatt az alkalmazások fejlesztése és karbantartása is gyorsabb és hatékonyabb lehet a SwiftUI használatával.

A Swift és a SwiftUI kiegészítik egymást, mivel a Swift lehetővé teszi a hatékony kódírást, míg a SwiftUI lehetővé teszi a gyors és egyszerű UI kialakítást. Az együtt használatuk lehetővé teszi az alkalmazások fejlesztőinek a hatékony, olvasható és testre szabható alkalmazások kódolását, és a gyors és egyszerű alkalmazások UI-jának kialakítását az Apple platformokra.

Adattárolás

Adatvagyon gazdálkodás fizikai megvalósulása

  • JSON (nevezéktan, életciklus):
    • Input (Betöltendő játékfájl)
    • Output (Lejátszott játék kimenete)
    • Log
  • Firebase adatbázis:
    • játék log
      • nicknévvel
      • loggal
      • késleltetés nélküli
      • késleltetéssel való adatfeltöltés
        • X időintervallumonkénti adatfeltöltés ( X = ..... )
        • keretrendszer indításonkénti publikálatlan eredmények ellenőrzése, és feltöltése
        • internetkapcsolat logok elkészítése
        • a tervező általi nyitóleosztással mindenkor
    • adatbázis nélkül (nincs engedélyezve a keretrendszer számára az internet kapcsolat):
      • nicknév nélkül
      • log nélkül
      • gyakorló játék
      • véletlenszerű induló leosztással
    • Alkalmazás rendszerlog:
      • pl.: Firebase Analytics
      • konfiguráció
        • X nevű user beállításai
        • anonim user esetén alap konfig (nem az utolsó beállítások)

Eredeti, elvetett ötlet

Githubon organizációban tárolt adatok. Hozzáfárés engedélyezése esetén lehetett ide publikálni repositorykat. Ez se informatikailag, se IT biztonságilag nem volt megfelelő ötlet, ám nem kellett adatbázist fenntartani hozzá.

Lokális adattárolás választott formája

  • A JSON fájlok egyszerű olvashatósága, értelmezhetősége miatt bárki létre tud hozni saját témát, nyelv sémát.
  • Alternatív megoldások:
    • MessagePack or CBOR
    • SQLite

Ez a saját téma/nyelvi csomag létrehozásának segítségül is szolgáló leírás.

  • A keretrendszer az adatokat .json fájlokban tárolja. Ezek
    • a beállítási adatok (kiválasztott téma illetve nyelv),

Unrestricted adattárolás választott formája

Firebase adatbázis Adatbázis jogosultságai Csak megfelelő ID-val lehet elérni az adatbázist, melyet az alkalmazás tárol. Ezt megfelelően kell tárolni, hogy ne lehessen kinyerni a forráskódból, Az ID csak az áruház adatait tároló adatrészhez kap olvasási jogosultságot. Ehhez létre hoztam egy usert, mely be fog jelentkezni minden kliensen read jogosultsággal:

https://miau.my-x.hu/mediawiki/images/6/6e/FirebaseAuthUser.png

Ez így néz ki a Firebase jogosultság szerkesztőben:

{
 "rules": {
   "quizCatalog": {
     ".read": "auth.uid === 'Létrehozott Firebase Auth user ID-ja'" 
   }
 }
}

Első megoldás:

ezt egy "FirebaseAPIKey.xcconfig" fájlban tárolom el a következő módon:

EMAIL = "..."
PASSWOWRD = "...."

majd így tárolom el az alkalmazásom 'Info.plist" fájljában:

....
<key>EMAIL</key>
<string>$(EMAIL)</string>
<key>PASSWORD</key>
<string>$(PASSWORD)</string>
....

Bejelnkezni pedig ezzel a metódussal tud az alkalmazás:

if let firebaseEmail = Bundle.main.infoDictionary?["EMAIL"] as? String {
  if let firebasePassword = Bundle.main.infoDictionary?["PASSWORD"] as? String {
     Auth.auth().signIn(withEmail: firebaseEmail, password: firebasePassword) { (result, error) in
        if let error = error {
           print("Error signing in: \(error)")
           return
        }
        guard let userId = result?.user.uid else {
           print("No user ID found")
           return
        }
     }
  }
}

Az email és jelszó tárolásátaz alkalmazásban a Config.xcconfig fájl segítségével tudjuk biztonságosan eltárolni.

Probléma:Az ID-t csak új alkalmazás verzó publiklásával tudom módosítani, ám mezei felhasználó nem tud hozzáférni ehhez a kódhoz. Amennyiben a Config.xcconfig publikussá válik, a usernevet és jelszót is meg kell változtatni, mely egy uj alkalmazasverzio kiadasával élesíthető

Megoldás: Firebase Remote Config használata. Ennek segítségével semmilyen szinten nem kell beégetnem felhasználónevet vagy jelszód a szoftverbe, ezeket a Firebaseból nyeri ki.

       let remoteConfig = RemoteConfig.remoteConfig()
       let settings = RemoteConfigSettings()
       settings.minimumFetchInterval = 0
       remoteConfig.configSettings = settings
       
       remoteConfig.fetchAndActivate { (status, error) in
           if let error = error {
               print("Err setingup remote config: \(error.localizedDescription)")
           }
           switch status {
           case .successFetchedFromRemote, .successUsingPreFetchedData:
               let configDataEmail = RemoteConfig.remoteConfig()["EMAIL"].stringValue
               print(configDataEmail!)
               let configDataPassword = RemoteConfig.remoteConfig()["PASSWORD"].stringValue
               print(configDataPassword!)
               
               self.signInWithFirebase(eeee: configDataEmail!,pwww: configDataPassword!)
           case .error:
               print("Error fetching remote config")
           }
           //0: .successFetchedFromRemote
           //1: .successUsingPreFetchedData
           //2: .error
           print("Remote config status: \(status.rawValue)")
           
       }

Az ITB további fejlesztése érdekében készülhetne script, ami intervallumonként változtatná a felhasználónév-jelszó párost

Konfiguráció

A rendszer konfigurálható paramétereit json fájlokban tároljuk, melyek a rendszer különböző életciklusaiban kerülnek betöltésre.

Nyelv fájl

A statikus szövegeket a rendszerben kiválasztott nyelvnek megfelelő fájlból nyeri ki. Támogatott nyelvek: magyar, angol, német, görög, olasz,lengyel,orosz,spanyol. (ChatGPT segítségével több nyelvre is le lehet fordítani, ám lehet nem a legmegfelelőbb módszer, ellenőrizni kell)

"load_file" = "Fájl betöltése";
"start_test" = "Kvíz elkezdése";
"home" = "Kezdőlap";
 "settings" = "Beállítások";
"marketplace" = "Áruház";
"identifier" = "Azonosító (Neptun, Kréta, email stb...)";
"save" = "Mentés";
"json_property_list" = "JSON lista nézet";
"loading" = "Betöltés...";
"file_downloaded" = "Fájl letöltve!";
"done" = "Kész";
"yes"="Igen";
"no"="Nem";
"score"= "Pont táblázat";
"confirm" = "Megerősítés";
"confirm_prompt" = "Biztosan meg akarod szakítani a játékot?";

Tesztadatok

A tesztfolyamat adatok betöltése után lép életbe. Az elérési útvonalnak a publikált képekre kell mutatni.

(kérdés, válasz lehetőségek)

{
"puzzles": [
   {
     "solutionAccessKey":"12",
     "question": "Ide írjuk a kérdést",
     "correctGridOrder": {
       "1": "www.urlA.valami/kep1.png",
       "2": "www.urlB.valami/kep2.png",
       "3": "www.urlC.valami/kep3.png",
       "4": "www.urlD.valami/kep4.png",
       "5": "www.urlE.valami/kep5.png",
       "6": "www.urlF.valami/kep6.png",
       "7": "www.urlG.valami/kep7.png",
       "8": "www.urlH.valami/kep8.png",
       "9": "www.urlI.valami/kep9.png"
     },
       "sorFejlec1": "leves",
       "sorFejlec2": "főétel",
       "sorFejlec3": "desszert",
       "oszlopFejlec1": "Magyar",
       "oszlopFejlec2": "Görögország",
       "oszlopFejlec3": "Olasz"
     }
]
}

Esetleges többletadat figyelmen kívül hagyása, ez esetben csak az 1-9ig felsorolt adatokat, és a "question" kulcsban megadott adatokat fogja figyelembe venni a rendszer.

Hibaelhárítás

(note: milyen funkciok vannak amik segitenek a hibaelharitasban)

A log megjelenítése a felhasználónak. Log automatikus kielemzése (pár alap esetet tudok előre definiálni, pl.: rossz json struktura, rossz fajlkiterjesztes stb), és tanács adás a felhasználónak, hogy vajon mi történt, és mit tudna tenni, hogy legközelebb ne történhessen meg ilyen eset. A szoftver kísérletet tehet a hiba automatikus kijavítására ezekben az esetekben:

  • hibás .json fájl struktúra -> amennyiben logikus hiba van (hiányzik "," ":" "{" karakter), pótolni tudja azokat. Természetesen tudomást ad a felhasználónak, hogy nem feltétlen a kívánt adat lett előállítva.
  • Amennyiben olyan eset áll elő, ami nem pre-definiált, akkor support kontaktálás (email)
  • ...

Előredefiniált hibák:

  • ...
  • ...

Perzisztencia

Egy konfig fájlba vannak írva a külön beállítások (nyelv, téma), tehát ezek perzisztensek. A teszt írása közben készülő, sérülésmentes logfájl segítségével (a teszt tervező engedélyével) vissza lehet állítani a folyamat utoljára elmentett állapotát, akár rendszer újraindulás után is

Tesztelés

Ebben a fejezetben fogom leírni mind a belső (saját magam/KJE-n belüli) mind a külső (.......) tesztelési folyamatokat, észrevételeket, eredményeket.

Belső tesztelés

A keretrendszer megvalósításakor intézményen belüli, és kívüli személyeket felkértünk a tesztelésre. Kiosztott jogosultságokkal belső tesztelés folytatódott intézményen belül, melynek segítségével több hibát is felfedeztünk. privat kanban boardon (majd elkészül)


Github Actions szolgáltatás segítségével minden egyes Branch Merge (vö.: https://www.w3schools.com/git/git_branch_merge.asp?remote=github) alkalmával tesztelendő a kód, ezen és ezen szempontokból (ezek a logikai szempontok, ezekből még nem tudjuk, hogy miket lehet megvalósítani):

  • Projekt buildelhetőségének tesztelés:
    • A program le tud futni, nincs benne hiba
    • ...
  • Játék játszhatóságának tesztelése
    • Sikerült adatot betölteni
    • Van output a játékból

Nem szempont:

  • Tartalmi ellenőrzés

Mivel ez csupán forráskód, ezért nem szükséges a szakdolgozatíró saját magának írt kódot ellenőrizni tartalmi szempontból, hiszen nem publikus

Projekt buildelhetőségének tesztelés

GitHub action fájl: .......

Github Action kód magyarázat

Alap konfiguráció

Ez az alap konfig, még nem a kódot teszteli, hanem megmondja, hogy mit kell/mit nem kell testtelni. a Github Action action neve ......

Forráskód tesztelése

Itt kezdődik a prejekt testz

Játék játszhatóságának tesztelése

Készülnie kell egy Unit tesztelő algoritmusnak, mely tudni fogja a keretrendszerek paramétereit, argumentumjait, és ennek megfelelően megpróbálja mind valid, mind invalid adatokkal feltölteni a keretrendzsert. Ennek eredményeaképpen látni fogjuk, hogy milyen inputra milyen output fog keletkezni, és felfedhetőek lesznek az inkonzisztens adatok által létrehozott hibák is.


Kód tesztelés

mvfodinm

Külső tesztelés

Publikus tesztelés, ezen a kanban boardon kell gyűjteni a problémákat a projekttel kapcsolatban: https://github.com/users/SiposPtr/projects/2

Fejlesztői saját 2DM-játékok

Hogyan nézzen ki egy lefejlesztendő játék, amennyiben a fejlesztő kézzel, és nem az erre megadott alrendszert (GTDS) használja.

1. játék

  • X=3
    • X1= oszlop1
    • X2= oszlop2
    • X3= oszlop3
  • Y=3
    • Y1= sor1
    • Y2= sor2
    • Y3= sor3
  • válaszkártyák (9=3*3)
    • VK1= kép1-nek a lokális elérési útvonala
    • VK2= kép2-nek a lokális elérési útvonala
    • VK3= ...
    • VK4= ...
    • VK5= ...
    • VK6= ...
    • VK7= ...
    • VK8= ...
    • VK9= kép9-nek a lokális elérési útvonala
  • Maga a feladat megfogalmazása

i. játék

  • X>3
  • Y>3
  • X<>Y

Teszt katalógus

A katalógus a Firebase adatbázist fetcheli, és jeleníti meg.

A katalógus a GTS alrendszer része, mivel:

  • a tesztírónak elég egy alkalmazást tudnia használni
  • a teszt megírása amúgy is a GTS rendszerben fog történni, így kézenfekvő a kvízek letöltése onnan, ahol a kvízt két-három kattintással később le is lehet játszani

Saját teszt publikálása

https://miau.my-x.hu/mediawiki/index.php/BPROF:2dm_q1

Üzleti hasznosítás

Lényegében iskoláknak készült, hogy a tanulókat számon kérjék stb.................

Kapcsolódó wiki-oldalak