1 คะแนน โดย GN⁺ 2024-10-08 | 1 ความคิดเห็น | แชร์ทาง WhatsApp
  • คอมมิตของ uBlock Origin ปรับเขียนโฟลว์ CNAME uncloaking ในการประมวลผลเครือข่ายของ Firefox ใหม่ และเปลี่ยนให้สะท้อน IP ที่ได้จากการค้นหา DNS ลงใน details.ip
  • แคช cnames Map เดิมถูกยกเลิก และแทนที่ด้วย ring buffer 256 รายการ ที่อิง dnsList, dnsDict, dnsWritePtr พร้อมแคช TTL 60000ms
  • การค้นหา DNS ใช้ browser.dns.resolve(hn, [ 'canonical_name' ]) และนำ canonicalName กับ addresses[0] ในผลลัพธ์มาใช้เป็น CNAME และ IP ตามลำดับ
  • การจัดการข้อยกเว้น CNAME ยังคงเงื่อนไข 1st-party, ignore list และ root document ไว้ และชื่อโฮสต์ที่เป็นที่อยู่ IPv4 หรือขึ้นต้นด้วย [ จะถูก ยกเว้นจากการค้นหาซ้ำ
  • เวอร์ชันขั้นต่ำของ Chromium เพิ่มเป็น 80.0, เวอร์ชันขั้นต่ำของ Opera เพิ่มเป็น 67.0 และลบค่าเริ่มต้น cnameMaxTTL ในการตั้งค่าที่ซ่อนอยู่

ปรับโครงสร้างแคช DNS ของ Firefox ใหม่

  • โค้ดที่เกี่ยวข้องกับ CNAME uncloaking ใน platform/firefox/vapi-background-ext.js เปลี่ยนจากโครงสร้างที่เน้น Map แบบ global ไปเป็นโครงสร้าง แคช DNS ภายในคลาส
  • แทนที่จะใช้สถานะ global cnameUncloakEnabled และ cnames Map เดิม จะจัดการแคชด้วยฟิลด์ต่อไปนี้
    • dnsList: ring buffer
    • dnsWritePtr: ตำแหน่งเขียนถัดไป
    • dnsMaxCount: สูงสุด 256
    • dnsDict: แมปจากชื่อโฮสต์ไปยังดัชนีของ ring buffer
    • dnsEntryTTL: 60000ms
  • ใน constructor จะเริ่มต้น canUncloakCnames และ cnameUncloakEnabled เป็น true

โฟลว์การประมวลผลคำขอ

  • onBeforeSuspendableRequest(details) ดึงชื่อโฮสต์จาก URL ของคำขอ แล้วตรวจสอบแคชก่อนด้วย dnsFromCache(hn)
  • หากรายการ DNS ที่แคชไว้มี ip จะตั้งค่าให้ details.ip
  • หากผลลัพธ์จากการเรียก super.onBeforeSuspendableRequest(details) ตามปกติจบลงด้วยการยกเลิกหรือ redirect เป็นต้น จะคืนผลลัพธ์นั้นตามเดิม
  • หากรายการ DNS ที่แคชไว้ไม่ใช่ Promise จะดำเนินการต่อด้วย onAfterDNSResolution(hn, details, dnsEntry)
  • หากไม่เข้าเงื่อนไขสำหรับการค้นหา DNS ซ้ำ หรือมี details.proxyInfo?.proxyDNS จะไม่ทำการประมวลผล DNS เพิ่มเติม

วิธีค้นหาและบันทึก DNS

  • dnsShouldResolve(hn) จะ ยกเว้นจากเป้าหมายการค้นหา DNS สำหรับชื่อโฮสต์ว่าง, ชื่อโฮสต์ที่ขึ้นต้นด้วย [ และรูปแบบที่อยู่ IPv4
  • dnsResolve(hn, details) ลงทะเบียนชื่อโฮสต์ไว้ที่ตำแหน่งปัจจุบันของ ring buffer แล้วเรียก dnsAPI.resolve(hn, [ 'canonical_name' ])
  • เมื่อค้นหาสำเร็จจะเรียก dnsToCache(hn, rec, details) และหากล้มเหลวจะเรียก dnsToCache(hn) เพื่อทิ้งรายการว่างไว้ในแคช
  • dnsToCache บันทึก hn และเวลาหมดอายุไว้ในรายการแคชใหม่
    • หาก cnameFromRecord คืนค่า จะบันทึกไว้ใน dnsEntry.cname
    • หาก ipFromRecord คืนค่า จะบันทึกไว้ใน dnsEntry.ip
  • dnsFromCache จะคืนค่ารายการแคชตามเดิมหากเป็น Promise และจะลบรายการที่หมดอายุออกจาก dnsList และ dnsDict

เงื่อนไขการสะท้อน CNAME และ IP

  • cnameFromRecord(hn, record, details) จะไม่คืนค่า CNAME หากไม่มี record.canonicalName หรือค่าเท่ากับชื่อโฮสต์เดิม
  • หากเปิด cnameIgnore1stParty จะยกเว้นกรณีที่โดเมนของ CNAME กับชื่อโฮสต์เดิมเหมือนกัน
  • หากมี cnameIgnoreList จะยกเว้น CNAME ที่ไม่แมตช์กับ regular expression นั้น
  • หากเปิด cnameIgnoreRootDocument จะยกเว้นเมื่อชื่อโฮสต์ของคำขอตรงกับชื่อโฮสต์ของ details.documentUrl || details.url
  • ipFromRecord(record) จะคืนค่าที่อยู่แรก addresses[0] เมื่อ record.addresses เป็น array และไม่ว่าง

การเขียน URL ใหม่และการกรองถัดไป

  • onAfterDNSResolution จะเขียน URL ใหม่ด้วย uncloakURL หากรายการ DNS มี CNAME และเปิด cnameUncloakEnabled
  • เมื่อเปลี่ยน URL จะเก็บ URL เดิมไว้ใน details.aliasURL และสะท้อน URL ใหม่ลงใน details.url
  • หากรายการ DNS มี IP และต่างจาก details.ip ปัจจุบัน จะอัปเดต details.ip
  • จะเรียก onBeforeSuspendableRequest(details) ของคลาสพื้นฐานอีกครั้งเฉพาะเมื่อเกิด การเขียน CNAME ใหม่ หรือการเปลี่ยน IP เท่านั้น
  • uncloakURL จะหาตำแหน่งชื่อโฮสต์ใน URL แล้วเปลี่ยนเป็น CNAME และจะต่อ URL ทั้งหมดหรือคงไว้ถึงช่วงต้นของ path เท่านั้นตามค่า cnameReplayFullURL

การเปลี่ยนแปลงการตั้งค่าและ manifest

  • ลบการจัดการ cnameMaxTTL ออกจาก setOptions
  • เมื่อเปลี่ยนตัวเลือก จะล้างแคช DNS ด้วย dnsList.fill(null) และ dnsDict.clear() แทนการรีเซ็ต cnames Map เดิม
  • ลบ cnameMaxTTL: 120 ออกจากค่าเริ่มต้นของการตั้งค่าที่ซ่อนอยู่ใน src/js/background.js
  • minimum_chrome_version ใน platform/chromium/manifest.json เปลี่ยนจาก 73.0 เป็น 80.0
  • minimum_opera_version ใน platform/opera/manifest.json เปลี่ยนจาก 60.0 เป็น 67.0

1 ความคิดเห็น

 
GN⁺ 2024-10-08
ความคิดเห็นจาก Hacker News
  • คิดว่าชื่อเรื่องน่าจะผิด uBlock Origin รองรับฟีเจอร์นี้มาหลายปีแล้ว เพียงแต่ทำได้เฉพาะบน Firefox เท่านั้น
    กรณีนี้ดูเหมือนเป็นการรีแฟกเตอร์โค้ดนั้นมากกว่าจะเป็นฟีเจอร์ใหม่ทั้งหมด

    • ตอนนี้ก็ยังรองรับ และเมื่อก่อนก็รองรับอยู่แล้ว :P
    • ดูเหมือนจะมากกว่าแค่การรีแฟกเตอร์ธรรมดา ตอนนี้น่าจะสามารถทำ การบล็อกตาม IP ได้ในขั้นตอนที่เร็วขึ้น ก่อนที่คำขอจริงจะถูกส่งออกไป
      แต่ก็ยังไม่สมบูรณ์แบบ เพราะเมื่อโดเมนหนึ่งมีหลาย IP ก็ไม่รู้ว่าเบราว์เซอร์จะเลือก IP ไหน
    • เปลี่ยนชื่อเรื่องกลับไปเป็นชื่อหน้าตามเดิมแล้ว ชื่อที่ส่งเข้ามาคือ “uBlock Origin supports filtering CNAME cloaking sites on Firefox now”
      ถ้ามีข้อเสนอชื่อที่แม่นยำและเป็นกลางกว่านี้ก็เปลี่ยนได้อีก แต่โดยทั่วไปคอมมิตบน GitHub ที่ไม่มีบริบทเพิ่มเติมมักไม่ค่อยเหมาะกับเธรด HN เท่าไร
  • ยังไม่ได้รับผลกระทบโดยตรง แต่ถ้า Chrome กำจัด uBO ออกไปจริง ๆ ก็ได้เริ่มปรับส่วนขยายของตัวเองให้ใช้กับ Firefox ได้แล้ว เพื่อให้ย้ายได้

    • ไม่ใช่เรื่อง “ถ้า” แต่เป็นเรื่อง “เมื่อไหร่” ตั้งแต่ปี 2020 ก็เป็นเรื่อง “เมื่อไหร่” อยู่แล้ว และมันกำลังจะเกิดขึ้นจริง
      น่าจะมาถึงภายในไม่กี่รุ่นถัดไป จึงควรเตรียมตัวไว้
    • กำลังย้ายครอบครัวไปใช้ Brave แทบไม่รู้สึกถึงความแตกต่าง และมั่นใจมากกว่าว่าเบราว์เซอร์จะยังสนับสนุนการกรองเนื้อหาที่ผู้ใช้เป็นศูนย์กลางต่อไป
    • ถูกนำออกไปแล้วใน Canary release
    • ไม่เข้าใจว่า “เขียนส่วนขยายใหม่สำหรับ Firefox” หมายถึงอะไร Firefox ก็ใช้ API เดียวกัน
      อย่างมากก็แค่เปลี่ยน background.service_worker เป็น background.scripts เท่านั้น พูดตรง ๆ คือเปลี่ยนแค่ชื่อคีย์
    • ขอถามเผื่อคนที่ไม่ค่อยรู้ว่า uBO คืออะไร และมันส่งผลต่อส่วนขยายส่วนใหญ่ยังไง?
  • uBlock Origin เป็นสิ่งที่ทำให้ Firefox ยอดเยี่ยมขึ้น และเป็นหนึ่งในเหตุผลสำคัญที่ใช้ Firefox แทน Chrome และอื่น ๆ
    มันทำให้อินเทอร์เน็ตอยู่ในสภาพที่ท่องเว็บได้จริง

    • ย้ายมาใช้ชุดนี้เมื่อหลายปีก่อน และไม่เคยเห็นเหตุผลที่จะย้ายออกเลย บนโทรศัพท์ Android ก็เช่นกัน นี่เป็นประสบการณ์เว็บบนมือถือแบบเดียวที่ผมเห็นว่าใช้ได้จริง
      ตลอดกว่า 10 ปี มีปัญหาการแสดงผลกับบางเว็บอยู่บ้าง แต่เว็บเหล่านั้นก็มีปัญหาบน Chrome เช่นกัน
      โดยส่วนตัวมองว่าโฆษณาเป็นเหมือนมะเร็งของสังคมยุคใหม่ มันผสมปนเปกันระหว่างคำโกหกสีขาว คำโกหกที่ไม่ใช่สีขาว และการชักใย แถมยังมีเงินมหาศาลไหลผ่าน จึงยิ่งไม่มีอะไรให้น่าเคารพเลย
    • จุดนั้นอาจเปลี่ยนไป เพราะ Mozilla กำลังกลายเป็น บริษัทโฆษณา
    • ลองใช้ทั้ง Brave และ Firefox แล้ว พูดตามตรงก็ไม่รู้สึกว่าต่างกันมากนัก แต่ยังชอบ Firefox มากกว่าเพราะปรัชญาและการมาจากองค์กรไม่แสวงหากำไร
      Brave ก็เป็นโปรเจกต์คุณภาพดี เลยใช้เป็นตัวสำรอง และบางครั้งก็ใช้ Vivaldi ปนด้วยเพราะการแบ่งหน้าต่างและการจัดการแท็บที่ดีกว่ามาก
  • CNAME cloaking หมายถึงการที่เว็บโฆษณาใช้ซับโดเมนที่สร้างแบบสุ่มซึ่งชี้ไปยัง wildcard record ใช่ไหม?

    • นั่นเป็นส่วนหนึ่ง
      โดยทั่วไปเมื่อเข้าชม contentsite.com โฆษณาจะถูกเสิร์ฟจาก adsite.com กฎบล็อกโฆษณาแค่บล็อก adsite.com โฆษณาก็จะไม่แสดง
      CNAME cloaking คือวิธีที่เว็บไซต์หลักทำให้ซับโดเมนอย่าง adsite.contentsite.com ชี้ไปยัง adsite.com แบบนี้ตัวบล็อกโฆษณาก็ต้องทำงานแทบเป็นไปไม่ได้ คือบล็อกซับโดเมนหลายล้านรายการที่ดูเหมือนเป็นของเว็บไซต์ปกติ
      เว็บไซต์ปกติยังสามารถเปลี่ยนซับโดเมนไปเรื่อย ๆ ได้ และตัวบล็อกโฆษณาก็ไม่มีทางรู้ว่าซับโดเมนไหนเป็นเนื้อหาปกติ และซับโดเมนไหนเป็นโฆษณา อีกทั้งเพราะเนื้อหาถูกเสิร์ฟจากโดเมนเดียวกัน จึงอาจเลี่ยงนโยบายคุกกี้บางอย่างเพื่อใช้ติดตามผู้ใช้ได้ดีขึ้นด้วย
      การอัปเดตครั้งนี้ทำให้สามารถตั้งกฎที่กรองตาม IP ที่ถูก resolve แล้วได้
    • ใช่ ผู้ให้บริการโฆษณาและวิเคราะห์ข้อมูลเริ่มใช้วิธีนี้เพื่อเลี่ยง การป้องกันคุกกี้ของบุคคลที่สาม
  • นี่เป็นตัวอย่างที่ดีว่า ทำไม Manifest V3 ถึงไม่ค่อยดี โดยนิยามแล้วมันทำสิ่งแบบนี้ไม่ได้ และ heuristic ที่อิงโค้ดขณะรันก็ทำไม่ได้เช่นกัน
    นี่คือการแข่งขันยกระดับกับผู้ลงโฆษณา และ Google เป็นพ่อค้าขายอาวุธให้ทั้งสองฝ่าย พวกเขาจะไม่ให้สิ่งที่ผู้ใช้ต้องใช้เพื่อชนะ

    • ไม่มีเหตุผลที่ API แบบประกาศของ Manifest V3 จะให้ฟีเจอร์แบบนี้ไม่ได้ ถ้าผมอ่านคอมมิตถูกต้อง มันอาจทำงานได้ดีกว่าด้วยซ้ำ โดยผสานเข้ากับ flow ของคำขอได้ดีขึ้นและบล็อกตาม IP address ที่จะถูกใช้จริง ก่อนจะส่งอะไรไปยังเซิร์ฟเวอร์จริง
      แน่นอนว่าทั้งหมดนี้ขึ้นอยู่กับว่าผู้ให้บริการเบราว์เซอร์ หรือก็คือ Google อยากเพิ่ม API นี้หรือไม่ การมี “โค้ดขณะรัน” เพื่อประมวลผลแบบ imperative ช่วยให้เกิดนวัตกรรมใน user space ได้ก่อนที่ผู้สร้างเบราว์เซอร์จะใส่การรองรับในตัว
    • ในเชิงเทคนิค Manifest V3 เองแยกจาก API ที่เบราว์เซอร์ให้กับส่วนขยาย ใน Firefox นั้น Manifest V3 รองรับร่วมกับ blocking web requests[1] ซึ่งเป็น API สำหรับการกรองที่มีมาก่อน “Manifest V3”
      ดังนั้นการบอกว่าฟีเจอร์บางอย่างเป็นไปไม่ได้ “โดยนิยาม” จึงไม่ถูกต้อง
      [1] https://blog.mozilla.org/addons/2022/05/18/manifest-v3-in-fi...
    • แค่ทิ้ง Chrome แล้วหันมาใช้ Firefox ก็พอ
  • การพราง CNAME ยกตัวอย่างเช่น สมมติว่าผู้ให้บริการ SaaS A ต้องการให้ซอฟต์แวร์ติดตามโฆษณาสุดเจ๋งแก่บริษัท Q
    ถ้าเป็นวิธีเดิม A ก็น่าจะบอกให้ Q แทรกสคริปต์ เช่น https://A-ads-tracking.example ลงในเว็บไซต์ของบริษัท Q ที่อยู่ที่ https://q-company.example
    จากนั้นในรายการบล็อกที่ uBlock Origin ใช้ ก็จะมีกฎประมาณว่า “บล็อกคำขอที่ไปยังโดเมน A-ads-tracking.example” แล้วโฆษณาก็จะถูกบล็อก
    การพราง CNAME คือวิธีที่ผู้ให้บริการ SaaS A ไม่ได้วางบริการติดตามโฆษณาไว้ที่โดเมน A-ads-tracking.example แต่ไปวางไว้ที่ที่อยู่ IP เฉพาะ เช่น 29.1.2.3 และส่วนสำคัญคือ SaaS A จะขอให้บริษัท Q สร้างซับโดเมนของ q-company.example แล้วให้เรคคอร์ด CNAME ของมันชี้ไปที่ 23.1.2.3 พร้อมตั้งชื่อที่ดูน่าเชื่อถืออย่าง media.q-company.example
    หลังจากบริษัท Q ตั้งค่า CNAME นั้นแล้วเพิ่มแท็กสคริปต์ media.q-company.example ลงในเว็บไซต์ SaaS A ก็จะสามารถติดตามผู้ใช้ทั้งหมดของไซต์นั้นได้ เพราะชั้นการเลี่ยงแบบนี้ ทำให้เกิดเกมแมวไล่จับหนูที่แทบไม่มีที่สิ้นสุดระหว่างเจ้าของบริษัท Q กับรายการบล็อกสาธารณะ
    ถ้าจะหลีกเลี่ยงปัญหานี้ ซอฟต์แวร์ที่รันส่วนขยายอย่าง uBlock Origin จำเป็นต้องมองเห็นไม่ใช่แค่โดเมนปลายทางของคำขอในเบราว์เซอร์ แต่รวมถึงที่อยู่ IP จริงของโดเมนนั้นด้วย คอมมิตนี้ดูเหมือนจะเกี่ยวกับการทำให้พฤติกรรมดังกล่าวเป็นไปได้ หรืออย่างน้อยก็ทำให้โค้ดส่วนนั้นทำงานได้ดีขึ้น

    • พูดให้แม่นคือไม่ใช่แบบนั้นเสียทีเดียว ตามชื่อเลย มันใช้ CNAME ซึ่งเป็นเรคคอร์ดที่ชี้ไปยังเรคคอร์ดอื่น ไม่ใช่เรคคอร์ด A ที่ชี้ไปยัง IP
      ตัวอย่างเช่น media.q-company.example เป็น CNAME ที่ชี้ไปยัง q-company.ads-tracking.example แล้วจากนั้น q-company.ads-tracking.example จึงมีเรคคอร์ด A ที่ให้ IP อีกที
      ไม่แน่ใจว่าเบราว์เซอร์ส่งชื่อ DNS ระหว่างทางให้ส่วนขยายหรือไม่ ดังนั้นเครื่องมืออย่าง uBlock อาจต้องพึ่งพารายการ IP แต่การกรองแบบอิง DNS อย่าง pihole สามารถบล็อกได้ง่าย ๆ ด้วยกฎสำหรับ ads-tracking.example
      ไม่ว่าอย่างไร การใช้ตัวบล็อกสิ่งประสงค์ร้ายทั้งแบบบนเบราว์เซอร์และแบบอิง DNS ควบคู่กันก็เป็นเรื่องดี
    • นี่แหละคือเหตุผลที่ในโหมดขั้นสูงของ uBlock ควร บล็อก JavaScript ทั้งหมด แล้วค่อย ๆ เพิ่มสคริปต์ที่มองเห็นลงใน allowlist จนกว่าไซต์จะทำงานได้ถูกต้อง
      มันช้าและพลาดได้ง่าย แต่พอชินแล้วก็สบายขึ้น และจะมีภูมิคุ้มกันต่อกลเม็ดไร้สาระแบบนี้อย่างสมบูรณ์
  • Chrome กำลังจะบล็อก uBO หรือเปล่า? ไม่ได้ตามสถานการณ์ล่าสุดตลอด
    เท่าที่รู้ ตอนนี้เขาอนุญาตคุกกี้บุคคลที่สามแล้ว ดังนั้นบางทีอาจเป็นไปได้ก็ได้

    • ไม่ได้บล็อกตัว uBO เอง แต่คือการออก API ปลั๊กอินใหม่ชื่อ Manifest V3 แล้วตัดฟีเจอร์ของเบราว์เซอร์ที่เคยทำให้ uBO ทำงานได้ออก
      กำลังตัด API หลักที่จำเป็นสำหรับให้ uBO ระบุว่าอะไรไม่ควรถูกโหลด แล้วทำให้สิ่งนั้นไม่ถูกโหลด
      Google อ้างว่าเป็นเพราะ “ประสิทธิภาพ” หรือ “ความปลอดภัย” แน่นอนว่า “ประสิทธิภาพ” หรือ “ความปลอดภัย” อย่างเดียวที่ได้รับผลกระทบจริง ๆ อย่างมากคือความสามารถในการระบุ ดัก และหยุดการดาวน์โหลดที่เป็นอันตรายหรือเกี่ยวกับโฆษณาก่อนที่มันจะเริ่มต้น
    • การไม่อัปเดตเบราว์เซอร์ก็อันตรายเหมือนกัน การ ย้ายไป Firefox เพื่อให้ได้ทั้งการอัปเดตและการรองรับ uBO เต็มรูปแบบย่อมดีกว่ามาก
    • เขาค่อย ๆ ทยอยถอดออกเป็นระยะยาว เพื่อเลี่ยงไม่ให้กระแสต่อต้านการผูกขาดเบราว์เซอร์ระเบิดขึ้นมาพร้อมกัน แต่กำหนดการนั้นเริ่มไปแล้วตั้งแต่เดือนมิถุนายน
      https://developer.chrome.com/docs/extensions/develop/migrate...
      https://www.bleepingcomputer.com/news/google/google-chrome-w...
    • ตอนนี้ uBlock Origin ยังอยู่ใน Chrome Web Store สำหรับเบราว์เซอร์ Chromium ที่รองรับ Manifest V2
      ถ้าใช้ Chromium เวอร์ชันที่รองรับเฉพาะ Manifest V3 ก็จะถูกซ่อนไว้
    • พูดตรง ๆ มีความเป็นไปได้สูงว่าจะขึ้นอยู่กับว่าสหรัฐฯ จะยังรักษารัฐบาลที่พร้อมลากบริษัทผูกขาดแบบโจ่งแจ้งขึ้นศาลต่อไปหรือไม่
  • ในเซิร์ฟเวอร์ DNS บางตัวมีฟีเจอร์ที่ทำงานเหมือน CNAME ที่เซิร์ฟเวอร์ resolve ให้แล้วไม่ใช่หรือ? คือผู้ดูแลใส่เรคคอร์ดที่ชี้ไปยังชื่อ DNS อื่น แต่ไคลเอนต์เห็นแค่เรคคอร์ด A หรือ AAAA เท่านั้นน่ะ

    • น่าจะหมายถึง ALIAS record
  • uBO มีฟีเจอร์นี้มาค่อนข้างนานแล้ว ตั้งแต่ 1.34.0 และใน advanced settings ก็มีตั้งแต่ 1.25.0
    https://github.com/gorhill/uBlock/wiki/Dashboard:-Settings#u...
    จำได้คร่าว ๆ ว่าน่าจะราวปี 2021

  • สถานะของ uBO บน Brave, Edge, Opera เป็นอย่างไรบ้าง?

    • ไม่ได้สนใจเบราว์เซอร์ proprietary สองตัวที่พูดถึงเท่าไร แต่ Brave จะรองรับ Manifest V2 บางส่วนให้นานที่สุดเท่าที่ทำได้ และจะรักษาความเข้ากันได้กับ uBO ไว้
      https://brave.com/blog/brave-shields-manifest-v3/
      อย่างไรก็ตาม ไม่จำเป็นถึงขั้นนั้น Brave มีตัวบล็อกโฆษณาในตัวที่ค่อนข้างทรงพลังอยู่แล้ว และเท่าที่ตรวจสอบครั้งล่าสุด มันถูกคอมไพล์เป็น native code จึงมีประสิทธิภาพสูงกว่า uBO และรองรับรายการโฆษณาเดียวกันได้ครบถ้วน