วิธีเปรียบเทียบไฟล์ไบนารีบน Linux
เผยแพร่แล้ว: 2022-08-20คุณจะตรวจสอบได้อย่างไรว่าไบนารี Linux สองตัวเหมือนกันหรือไม่ หากเป็นไฟล์ปฏิบัติการ ความแตกต่างใดๆ อาจหมายถึงพฤติกรรมที่ไม่พึงประสงค์หรือเป็นอันตราย นี่เป็นวิธีที่ง่ายที่สุดในการตรวจสอบว่ามีความแตกต่างกันหรือไม่
การเปรียบเทียบไฟล์ไบนารี
Linux มีวิธีมากมายในการเปรียบเทียบและวิเคราะห์ไฟล์ข้อความ คำสั่ง diff
จะเปรียบเทียบสองไฟล์สำหรับคุณ และเน้นความแตกต่าง มันสามารถให้สองสามบรรทัดที่ด้านใดด้านหนึ่งของการเปลี่ยนแปลงเพื่อให้บริบทรอบบรรทัดที่เปลี่ยนแปลง และคำสั่ง colordiff
จะเพิ่มสีเพื่อให้แยกวิเคราะห์ความแตกต่างทางสายตาได้ง่ายยิ่งขึ้น
นักพัฒนาและผู้เขียนใช้ diff
เพื่อเน้นความแตกต่างระหว่างไฟล์ซอร์สโค้ดของโปรแกรมเวอร์ชันต่างๆ หรือข้อความร่าง ทำได้ง่ายและรวดเร็ว และคุณไม่จำเป็นต้องมีทักษะทางเทคนิคใดๆ เพื่อดูความแตกต่างระหว่างสตริงข้อความ
ในโลกของไฟล์ไบนารี สิ่งต่างๆ ไม่ได้เรียบง่ายนัก ไฟล์ไบนารีไม่ได้ประกอบด้วยข้อความธรรมดา ประกอบด้วยหลายไบต์ที่มีค่าตัวเลข หากเป็นไฟล์บีบอัด เช่น ไฟล์เก็บถาวร TAR หรือไฟล์ ZIP ค่าเหล่านั้นจะแสดงไฟล์บีบอัดที่จัดเก็บไว้ในไฟล์เก็บถาวร พร้อมด้วยตารางสัญลักษณ์ที่จำเป็นสำหรับการคลายการบีบอัดและแตกไฟล์
หากไฟล์ไบนารีเป็นไฟล์เรียกทำงาน ค่าตัวเลขของไบต์ของไฟล์จะถูกตีความเช่นคำสั่งรหัสเครื่องสำหรับ CPU, เมตาดาต้า, เลเบล หรือข้อมูลที่เข้ารหัส การเปลี่ยนแปลงไฟล์ไบนารีหรือไฟล์ไลบรารีมีแนวโน้มที่จะนำไปสู่ความแตกต่างในการทำงานเมื่อไบนารีดำเนินการหรือใช้โดยแอปพลิเคชันอื่น
ง่ายต่อการปลอมแปลงวันที่และเวลาของการสร้างหรือแก้ไขไฟล์ นั่นหมายความว่าอาจมีไฟล์สองเวอร์ชันที่มีชื่อเดียวกัน ขนาดไฟล์—หากการเปลี่ยนแปลงแทนที่ไบต์เนื้อหาที่มีอยู่สำหรับไบต์—และการประทับวันที่ และถึงกระนั้น ไฟล์ใดไฟล์หนึ่งอาจมีการเปลี่ยนแปลง
อัลกอริทึมแฮชที่ปลอดภัย
อัลกอริทึมแฮชที่ปลอดภัยคืออัลกอริธึมที่ใช้คณิตศาสตร์ มันสร้างค่า 64 บิตโดยการสแกนไบต์ทั้งหมดในไฟล์และใช้การแปลงทางคณิตศาสตร์เพื่อสร้างค่าแฮช ในวันใด ๆ ไฟล์เดียวกันจะสร้างแฮชเดียวกันเสมอ แม้แต่ความแตกต่างแบบหนึ่งไบต์ก็จะส่งผลให้มีแฮชที่แตกต่างกันอย่างสิ้นเชิง
คุณมักจะเห็นแฮชของไฟล์แสดงอยู่บนหน้าดาวน์โหลด คุณควรสร้างแฮชสำหรับไฟล์เมื่อคุณดาวน์โหลดไฟล์แล้ว หากแตกต่างจากแฮชที่แสดงบนเว็บเพจ แสดงว่าไฟล์ถูกบุกรุก มีการดัดแปลงและแทนที่ไฟล์ของแท้—เพื่อให้ผู้คนดาวน์โหลดไฟล์ที่เสียหาย—หรือได้รับความเสียหายระหว่างการขนส่ง
ในคอมพิวเตอร์ทดสอบของเรา เรามีไฟล์เดียวกันสองชุด นั่นคือไลบรารีที่ใช้ร่วมกัน ไฟล์ถูกเปลี่ยนชื่อเพื่อให้สามารถอยู่ในไดเร็กทอรีเดียวกัน ตามทฤษฎีแล้วไฟล์เหล่านี้ควรเหมือนกัน ท้ายที่สุด พวกเขาควรจะเป็นเวอร์ชันเดียวกันของไลบรารีที่ใช้ร่วมกัน
ls -l *.so
ไฟล์มีขนาดเท่ากัน ประทับวันที่เหมือนกัน และประทับเวลาเดียวกัน สำหรับผู้สังเกตแบบสบาย ๆ พวกเขาดูเหมือนจะเหมือนกัน ลองใช้คำสั่ง sha256sum
และสร้างแฮชสำหรับแต่ละไฟล์
sha256sum binary_file1.so
sha256sum binary_file2.so
แฮชต่างกันโดยสิ้นเชิง ซึ่งแสดงให้เห็นชัดเจนว่ามีความแตกต่างระหว่างสองไฟล์ หากเว็บไซต์แสดงแฮชของไฟล์ของแท้ คุณสามารถทิ้งไฟล์ที่ไม่ตรงกันได้
ค้นหาความแตกต่าง
หากคุณต้องการดูการเปลี่ยนแปลง ก็มีวิธีทำเช่นนั้นเช่นกัน คุณไม่จำเป็นต้องสามารถถอดรหัสไฟล์ได้ หรือต้องเข้าใจแอสเซมบลีหรือโค้ดเครื่องเพียงเพื่อดูการแก้ไข การทำความเข้าใจความ หมาย ของการเปลี่ยนแปลงเหล่านั้น และจุดประสงค์ของการเปลี่ยนแปลงนั้น แน่นอนว่าต้องอาศัยความรู้ด้านเทคนิคที่ลึกซึ้งยิ่งขึ้น แต่การรู้ว่าการเปลี่ยนแปลงนั้นสำคัญเพียงใดก็สามารถบ่งบอกถึงสิ่งที่เกิดขึ้นกับไฟล์ได้
หากเราใช้ diff
กับไฟล์ไบนารีสองไฟล์ เราจะได้รับการตอบสนองที่ไม่ค่อยดีนัก
diff binary_file1.so binary_file2.so
เรารู้แล้วว่าไฟล์ต่างกัน มาลองกัน cmp
cmp binary_file1.so binary_file2.so
สิ่งนี้บอกเราเพิ่มเติมเล็กน้อย ไบต์แรกที่ต่างกันระหว่างสองไฟล์คือไบต์หมายเลข 13451 นั่นคือ นับจากจุดเริ่มต้นของไฟล์ไบนารี ไบต์ 13451 จะแตกต่างกันในไฟล์ไบนารีสองไฟล์ ดังนั้น 13451 จึงเป็นออฟเซ็ตของความแตกต่างแรก ตั้งแต่เริ่มต้นไฟล์
โดยบังเอิญตลอดทั้งไฟล์จะมีไบต์ที่มีค่าเลขฐานสิบหกเป็น 0x10 นี่คือค่าที่ Linux ใช้ในไฟล์ข้อความเป็นอักขระสิ้นสุดบรรทัด คำสั่ง cmp
พบ 131 ไบต์ด้วยค่านี้ระหว่างการเริ่มต้นของไฟล์ไบนารีและตำแหน่งของความแตกต่างแรก มันเลยคิดว่าอยู่ในบรรทัดที่ 132 มันไม่ได้มีความหมายอะไรเลยในบริบทนี้
หากเราเพิ่มตัวเลือก -l
(verbose) เราจะเริ่มได้รับข้อมูลที่เป็นประโยชน์
cmp -l binary_file1.so binary_file2.so
ไบต์ที่แตกต่างกันทั้งหมดจะแสดงรายการ หมายเลขไบต์หรือออฟเซ็ต ค่าจากไฟล์แรก และค่าจากไฟล์ที่สองจะแสดงขึ้น โดยมีหนึ่งไบต์ต่อบรรทัดของเอาต์พุต
ค่าไบต์จะแสดงเป็นเลขฐานแปด แทนที่จะเป็นรูปแบบเลขฐานสิบหกปกติที่ใช้กับไฟล์ไบนารี อย่างไรก็ตาม เราได้เรียนรู้อย่างอื่น ไบต์ที่เปลี่ยนแปลงทั้งหมดอยู่ในลำดับที่ต่อเนื่องกัน ออฟเซ็ตของพวกเขาจะเพิ่มขึ้นทีละหนึ่งสำหรับแต่ละไบต์
เครื่องมือ hexdump
จะดัมพ์ไฟล์ไบนารีไปที่หน้าต่างเทอร์มินัล หากเราใช้ตัวเลือก -C
(ตามรูปแบบบัญญัติ) เอาต์พุตจะแสดงรายการออฟเซ็ตแต่ละบรรทัด ค่าของ 16 ไบต์ที่ออฟเซ็ตนั้น และ—หากมีหนึ่งรายการ— การแสดง ASCII ของค่าไบต์
hexdump -C binary_file1.so
เราสามารถใช้เอาต์พุตจาก hexdump
เป็นอินพุตเพื่อ diff
ปล่อยให้ diff
ทำงานราวกับว่ากำลังอ่านไฟล์ข้อความสองไฟล์
diff <(hexdump binary_file1.so) <(hexdump binary_file2.so)
diff
ค้นหาบรรทัดที่แตกต่างกันและแสดงค่าไบต์ฐานสิบหกจากไฟล์แรกเหนือค่าจากไฟล์ที่สอง ออฟเซ็ตของบรรทัดแรกคือ 0x3480 หรือ 13440 เป็นทศนิยม ก่อนหน้านี้ cmp
บอกเราว่าการเปลี่ยนแปลงครั้งแรกเกิดขึ้นที่ไบต์ 13451 ซึ่งก็คือ 0x348B ที่จริงตรงกับสิ่งที่เราเห็นที่นี่
เอาต์พุตจาก diff
อยู่ในบล็อกสองไบต์ ไบต์คู่แรกคือไบต์ 0 และ 1 จากออฟเซ็ต 0x3480 บล็อกที่สองเก็บไบต์ 2 และ 3 จากออฟเซ็ต บล็อก 6 จะเก็บไบต์ 0xA และ 0xB หรือ 10 และ 11 เป็นทศนิยม นั่นคือไบต์ 13450 และ 13451 และเราจะเห็นว่าเป็นไบต์แรกที่แตกต่างกัน ไบต์ห้าคู่แรกจะเหมือนกันในทั้งสองไฟล์
อย่างไรก็ตาม เนื่องจาก diff
ถูกนับจากศูนย์ฐาน ดังนั้น cmp
ที่เรียกใช้ 13451 จะเป็น ไบต์ 13540 ถึง diff
และเพื่อให้เกิดความสับสนยิ่งขึ้น ลำดับไบต์ในแต่ละบล็อกแบบสองไบต์จะกลับรายการด้วย diff
จริงๆ แล้ว ไบต์จะเรียงตามลำดับนี้: 1 และ 0, 3 และ 2, 5 และ 4, 7 และ 6 เป็นต้น
คำสั่งนี้มีราคาแพงในการคำนวณด้วย — สอง hexdumps
และ diff
ทั้งหมดในคราวเดียว— โดยเฉพาะอย่างยิ่งหากไฟล์ที่เปรียบเทียบมีขนาดใหญ่
แต่ถ้า hexdump -C
สามารถส่งไฟล์ไบนารีเวอร์ชัน ASCII ไปยังหน้าต่างเทอร์มินัล ทำไมเราไม่เปลี่ยนเส้นทางเอาต์พุตไปยังไฟล์ข้อความ แล้วเปรียบเทียบไฟล์ข้อความทั้งสองกับ diff
hexdump -C binary_file1.so > binary1.txt
hexdump -C binary_file2.so > binary2.txt
diff binary1.txt binary2.txt
ความแตกต่างระหว่างสองไฟล์จะแสดงในสารสกัดสั้น ๆ สองไฟล์ มีการแสดง ASCII เคียงข้างพวกเขา จะมีคู่ของสารสกัดสำหรับแต่ละความแตกต่างระหว่างไฟล์ ในตัวอย่างนี้ มีความแตกต่างเพียงอย่างเดียว
ไม่เป็นไร แต่จะดีกว่าไหมถ้ามีบางอย่างที่ทำเพื่อคุณ
VBinDiff
โปรแกรม VBinDiff สามารถติดตั้งได้จากที่เก็บปกติสำหรับการกระจายหลักทั้งหมด ในการติดตั้งบน Ubuntu ให้ใช้คำสั่งนี้:
sudo apt ติดตั้ง vbindiff
ใน Fedora คุณต้องพิมพ์:
sudo dnf ติดตั้ง vbindiff
ผู้ใช้ Manjaro ต้องใช้ pacman
sudo pacman -Sy vbindiff
ในการใช้โปรแกรม ให้ส่งชื่อของไฟล์ไบนารีสองไฟล์บนบรรทัดคำสั่ง
vbindiff binary_file1.so binary_file2.so
แอปพลิเคชันที่ใช้เทอร์มินัลจะเปิดขึ้น โดยแสดงทั้งสองไฟล์ในมุมมองแบบเลื่อน
คุณสามารถใช้ล้อเลื่อนของเมาส์หรือปุ่ม "UpArrow", "DownArrow", "Home", "End", "PageUp" และ "PageDown" เพื่อเลื่อนดูไฟล์ต่างๆ ทั้งสองไฟล์จะเลื่อน
กดปุ่ม "Enter" เพื่อข้ามไปที่ความแตกต่างแรก ความแตกต่างถูกเน้นในทั้งสองไฟล์
หากมีความแตกต่างมากขึ้น การกด "Enter" จะแสดงความแตกต่างถัดไป การกด "q" หรือ "Esc" จะเป็นการออกจากโปรแกรม
อะไรคือความแตกต่าง?
หากคุณกำลังทำงานกับคอมพิวเตอร์ที่เป็นของบุคคลอื่น และคุณไม่ได้รับอนุญาตให้ติดตั้งแพ็คเกจใดๆ คุณสามารถใช้ cmp
, diff
และ hexdump
หากคุณต้องการจับภาพผลลัพธ์สำหรับการประมวลผลเพิ่มเติม เครื่องมือเหล่านี้ก็เป็นเครื่องมือที่ใช้ได้เช่นกัน
แต่ถ้าคุณได้รับอนุญาตให้ติดตั้งแพ็คเกจ VBinDiff จะทำให้เวิร์กโฟลว์ของคุณง่ายขึ้นและเร็วขึ้น และที่จริงแล้ว การใช้ VBinDiff กับไฟล์ไบนารีไฟล์เดียวเป็นวิธีที่ง่ายและสะดวกในการเรียกดูไฟล์ไบนารี ซึ่งเป็นโบนัสที่ดี
ที่เกี่ยวข้อง: วิธีดูภายในไฟล์ไบนารีจากบรรทัดคำสั่ง Linux