3 คะแนน โดย GN⁺ 2023-09-25 | 3 ความคิดเห็น | แชร์ทาง WhatsApp
  • ชุด Rust crate ที่ทำให้สามารถพัฒนา Windows Drivers ด้วย Rust ได้ โดยมีเป้าหมายเพื่อรองรับโมเดลการพัฒนาไดรเวอร์ WDM และ WDF
  • องค์ประกอบหลักประกอบด้วย wdk-build สำหรับการตั้งค่าการบิลด์ WDK, wdk-sys สำหรับ FFI bindings โดยตรงกับ WDK API, wdk สำหรับ bindings ของ WDK API ที่ปลอดภัยและเป็นธรรมชาติ, wdk-panic สำหรับ panic handler, wdk-alloc สำหรับรองรับ alloc และ wdk-macros ซึ่งเป็นชุดแมโครที่ช่วยให้ใช้งาน bindings โดยตรงของ wdk-sys ได้สะดวกขึ้น
  • สร้างขึ้นโดยคำนึงถึงการรองรับไดรเวอร์ WDM, KMDF, UMDF และ Win32 Services รวมถึงรองรับ WDF ทุกเวอร์ชันที่รวมอยู่ใน WDK 22H2 ขึ้นไป
  • crate ที่เผยแพร่บน crates.io ปัจจุบันรองรับเพียง KMDF v1.33 เท่านั้น ส่วน bindings ขององค์ประกอบอื่นสามารถสร้างได้โดย clone windows-drivers-rs แล้วแก้ไขการตั้งค่า build.rs ของ wdk-sys
  • ลำดับการใช้งานประกอบด้วยการสร้างแพ็กเกจ Cargo แบบ lib, เพิ่ม dependency wdk-build, wdk, wdk-sys, wdk-alloc, wdk-panic, ตั้งค่า cdylib, กำหนดค่า WDK metadata, เรียก wdk_build::configure_wdk_binary_build() ใน build.rs, เพิ่ม DriverEntry และรัน cargo make
    • สำหรับ crate แบบ Kernel Mode อย่างไดรเวอร์ KMDF และ WDM จำเป็นต้องตั้งค่า panic strategy เป็น abort, ใช้ #![no_std] และตั้งค่า panic handler
    • หากต้องการใช้โมดูล alloc ของ Rust standard library จำเป็นต้องตั้งค่า global allocator เป็น wdk_alloc::WdkAllocator
  • ข้อกำหนดในการบิลด์คือ libclang สำหรับ bindgen, cargo-make สำหรับงานหลังการบิลด์ และสภาพแวดล้อม WDK ที่ใช้งานได้ โดยวิธีที่แนะนำคือเข้าใช้งาน eWDK developer prompt
  • cargo make จะบิลด์และแพ็กเกจไดรเวอร์โดยอัตโนมัติเป็นค่าเริ่มต้น และผลลัพธ์คือแพ็กเกจไดรเวอร์ที่เซ็นลายเซ็นแล้วพร้อมไฟล์ WDRLocalTestCert.cer ซึ่งจะถูกสร้างไว้ใต้ target/<Cargo profile>/package หรือเส้นทางของ target architecture
  • รองรับการส่งอาร์กิวเมนต์อย่าง cargo make default --target <TARGET TRIPLE>, --release, --features <FEATURES>, +<TOOLCHAIN> และสามารถเปิดใช้งานการตรวจสอบลายเซ็นของไฟล์ .sys และ .cat ที่สร้างขึ้นได้ด้วยการตั้งค่า WDK_BUILD_ENABLE_SIGNTOOL_VERIFY=true
  • ส่วนขยาย Cargo ใหม่ cargo-wdk อยู่ในสถานะ Preview และกำลังพัฒนาเพื่อมาแทน cargo-make ในฐานะเครื่องมือแนะนำสำหรับการบิลด์ไดรเวอร์ Rust
  • มีตัวอย่างขั้นต่ำสำหรับ WDM, KMDF, UMDF อยู่ใน examples directory และสามารถดูตัวอย่างการสร้างไดรเวอร์ได้ที่ Windows-rust-driver-samples
  • โครงการยังอยู่ในระยะเริ่มต้นของการพัฒนา และยังไม่แนะนำสำหรับ production use

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

 
GN⁺ 2023-09-25
ความคิดเห็นจาก Hacker News
  • สำหรับคนที่จำไม่ได้ Mark Russinovich ก่อนจะขึ้นมารับตำแหน่งต่อจากหัวหน้าและถูกพูดถึงในฐานะผู้ท้าชิง CEO คนถัดไปของ MSFT เขาเคยบริหารบริษัทเครื่องมือซอฟต์แวร์และที่ปรึกษาเคอร์เนล NT ที่วิศวกรใน Redmond ไปเรียนการพัฒนาเคอร์เนล NT กัน
    เขายังเป็นคนค้นพบฟีเจอร์ปกป้องไฟล์อย่าง DRM rootkit ของ Sony, rootkit ของ Symantec และจับได้ว่า Best Buy ละเมิดลิขสิทธิ์ ERD Commander
    ตอนปี 2014 ที่ลบบัญชี LinkedIn ไป ตอนนี้ก็เสียดายนิดหน่อย เป็นบัญชีที่ทั้ง Valley และ Mark เป็น connection ระดับ 1 กัน แต่ความไม่เป็นที่รู้จักมากนักก็มีอิสระและความคล่องตัวอยู่เหมือนกัน เพลงเร็กเกของ Desmond Dekker ที่บอกว่าการคุยโวว่าทำอะไรมาบ้าง หาเงินได้เท่าไร และรู้จักใครนั้นไร้ความหมาย ชื่อเพลงอะไรนะ

    • Apple ก็น่าจะเคยทำเรื่องคล้าย ๆ กัน เอกสารภายในของ Apple เทียบกับ หนังสือของ Jonathan Levin แล้วไม่เท่าไร ว่ากันว่า Apple ซื้อหนังสือพวกนั้นให้วิศวกร OS อยู่บ่อย ๆ
      น่าสนใจทีเดียวที่บริษัทระดับนั้น ทั้งที่มีข้อได้เปรียบมากกว่ามากอย่างซอร์สโค้ดจริงและการเข้าถึงวิศวกร กลับทำเรื่องแบบนี้เองได้ไม่ค่อยดี บุคคลที่สามเหล่านี้ อย่างน้อย Levin ก็ต้องพึ่งพา วิศวกรรมย้อนกลับ เป็นส่วนใหญ่
      https://newosxbook.com
    • พูดถึงเขาแล้วจะไม่พูดถึง Sysinternals ไม่ได้ ผมพึ่งพาชุดเครื่องมือนั้นในการทำงานทุกวัน
      ถ้าคิดว่าแทบทุกบริษัททั่วโลกที่ใช้ Windows อย่างน้อยก็ใช้เครื่องมือ Sysinternals สักตัวหนึ่ง อิทธิพลของ Sysinternals อาจมากกว่า Azure เองด้วยซ้ำ
    • เครื่องมือ Sysinternals ควรถูกติดตั้งมาเป็นค่าเริ่มต้นใน Windows ทุกเครื่อง ในสภาพแวดล้อมของผมมันจำเป็นมาก และเวลาไปซ่อมหรือดีบักคอมพิวเตอร์ของเพื่อน ถ้าไม่มีมันก็รู้สึกขาดมากจริง ๆ
      นั่นคงเป็นเหตุผลที่ MSFT acquihire Mark Russinovich กับทีมของเขาไม่ใช่หรือ
    • เขาเป็นโปรแกรมเมอร์ที่ดี แต่พออ่านหนังสือของเขาแล้ว ดูไม่น่าจะเป็น CEO ที่ดี
      ความประทับใจจากหนังสือเล่มแรกคือเขามองโลกแบบขาวดำสุด ๆ
  • ทวีตต้นทาง: https://twitter.com/markrussinovich/status/17057307039574058...

  • /s เจ๋งดี แต่สิ่งนี้ ไม่ค่อยเป็น Rust:
    pub struct QueueContext {
    buffer: PVOID,
    length: usize,
    timer: wdf::Timer,
    current_request: WDFREQUEST,
    current_status: NTSTATUS,
    spin_lock: wdf::SpinLock,
    }

    • ส่วนใหญ่ของพวกนั้นสุดท้ายก็ชี้ไปที่ ชนิดจำนวนเต็มสำหรับ FFI เพราะ API ไดรเวอร์ Windows ใช้แบบนั้น
      เวลาเขียนไดรเวอร์ Rust ในเคอร์เนล Linux ก็มีปัญหาคล้ายกัน และโปรเจกต์อื่นที่ต้องทำงานร่วมกับ C ก็เช่นกัน
      ชนิดอย่าง NTSTATUS มีเอกสารประกอบค่อนข้างเยอะ ต่างจาก C หรือ C++ ใน Rust ไม่สามารถยัดค่าจำนวนเต็มเข้าไปเป็นค่า enum ได้ตรง ๆ จะสร้างคลาส wrapper แล้วบังคับให้ cast ทุกครั้งก็ได้ แต่แบบนั้นโค้ดครึ่งหนึ่งคงกลายเป็น .into() และอาจเพิ่ม overhead ให้ไดรเวอร์ด้วย
      เท่าที่ดู ยกเว้น void* สำหรับ buffer แล้ว ค่า enum พวกนี้ไม่ได้ถูกตั้งค่าหรือเปลี่ยน แต่ถูกอ่านอย่างเดียว สำหรับ NTSTATUS ใช้บล็อก match {} ก็น่าจะพอ WDFREQUEST เป็น handle ดังนั้นนอกจากเปลี่ยนไปเป็น handle อื่นชนิดเดียวกัน ก็แทบไม่มีอะไรให้ทำมากนัก
      Timer และ SpinLock ถูกเปลี่ยนเป็น อ็อบเจ็กต์แบบ Rust ที่ห่อการเรียกไลบรารี unsafe ไว้ข้างในแล้ว นอกนั้นยังไม่ค่อยเห็นวิธีทำให้โค้ดนี้เป็น Rust มากขึ้นโดยไม่แบกภาระด้านประสิทธิภาพมากนัก
    • ถ้าจะกำจัดสิ่งนั้น คงต้องเขียนใหม่ทั้งหมด
  • รู้ไหมว่าอะไรดีกว่านั้น? การเขียนไดรเวอร์อุปกรณ์ด้วยภาษาที่จัดการหน่วยความจำให้ เช่น C#

    • Microsoft กำลังผลักโค้ดออกไปยัง user space มากขึ้นเรื่อย ๆ การเปลี่ยนแปลงล่าสุดคือบังคับให้ผู้ผลิตพรินเตอร์ใช้แอปพรินเตอร์ UWP แทนไดรเวอร์ เมื่อต้องการเพิ่มฟีเจอร์เฉพาะให้พรินเตอร์ แอปแบบนี้มักเขียนด้วยภาษาอย่าง C#
      ผมเห็นด้วยกับการตัดสินใจของ Microsoft ว่าทางที่ดีที่สุดคือให้โค้ดของผู้ผลิตทำงานในเคอร์เนลให้น้อยลง แทนที่จะทำให้เคอร์เนลเข้าถึงได้ง่ายขึ้น C# ไม่เหมาะกับสถานการณ์อย่าง “อยากเข้าถึงบัฟเฟอร์บางตัว แต่ยังไม่ได้ page in และฉันอยู่ใน interrupt handler” ดังนั้นการรัน garbage collector ในเคอร์เนลโดยไม่มีบั๊กจึงดูแทบเป็นไปไม่ได้
    • ไม่แน่ใจว่ามันจะดีกว่าจริงไหม ผมไม่มีประสบการณ์พัฒนาไดรเวอร์ แต่ไดรเวอร์อุปกรณ์เป็นองค์ประกอบแกนกลางระดับต่ำของระบบปฏิบัติการที่กำลังทำงานอยู่ จึงดูไม่ค่อยเข้ากับวิธีที่ garbage collection จะหยุดการทำงานตามกำหนดเวลาของตัวเอง
    • ไม่อยากให้เมาส์กระตุกเพราะไดรเวอร์หยุดไปเพื่อรัน garbage collector
    • Microsoft เคยลองแล้วแต่ล้มเหลวอย่างยับเยิน ผมไม่คิดว่าพวกเขาเคยบอกเหตุผล แต่ผมเดาว่าบนฮาร์ดแวร์ช่วงต้นทศวรรษ 2000 garbage collection คงทำให้เกิดการหยุดชะงักบ่อยเกินไป
    • แม้ใช้ C++ การเขียนไดรเวอร์อุปกรณ์พร้อมรักษาความสามารถในการเขียน เคอร์เนลไดรเวอร์ที่สามารถถูก page ได้ ก็ยังยากมาก
      ไดรเวอร์อาจต้องเข้าถึงหน่วยความจำในจังหวะที่เกิด page fault ไม่ได้ เช่น ระหว่าง interrupt handler จึงต้องควบคุมความพร้อมใช้งานของหน่วยความจำอย่างเข้มงวดมาก ภาษาและ runtime ของ C# อย่างน้อยก็ต้องเพิ่มความสามารถในการจัดการเรื่องนี้อย่างชัดเจน
 
bungker 2023-11-30

ขอเสริมเพราะดูเหมือนว่าสิ่งนี้จะถูกประเมินค่าต่ำไปเล็กน้อย Russinovich เป็นคนที่สร้างเอกสารและเครื่องมือจำนวนมากเกี่ยวกับเคอร์เนลของ Windows ในบรรดานักพัฒนาที่ทำงานเกี่ยวกับเคอร์เนลของ Windows (รวมถึงนักพัฒนาที่สร้างรูทคิท) คงแทบไม่มีใครที่ไม่ได้ศึกษาโดยดูจากข้อมูลหรือเอกสารของ Russinovich

 
botplaysdice 2023-12-01

ได้ยินข่าวว่ากำลังเขียนเคอร์เนล Windows ใหม่ด้วย Rust อยู่เหมือนกัน ในที่สุด SDK สำหรับไดรเวอร์ก็เริ่มออกมาแล้วสินะ อีกไม่นานคงจะมีประกาศให้สร้างไดรเวอร์ด้วย Rust ตั้งแต่ปี 20XX เป็นต้นไปแน่ๆ