- Phép nhân số thực dấu phẩy động VU của PS2 có sai số tính toán 1 bit, nên với một số giá trị nhất định,
1 * Xcó thể khácX - Theo tài liệu hướng dẫn dành cho nhà phát triển VU,
X * 1được đảm bảo chính xác, nhưng1 * Xkhông có bảo đảm tương tự; khác biệt này trở thành tín hiệu phát hiện trình giả lập - Ví dụ dùng 129.5f, một trong các giá trị gây lỗi được tìm bằng brute force, để kiểm tra sự khác biệt hành vi giữa PS2 thật và trình giả lập
- Cách triển khai có cấu trúc đơn giản: trong chế độ macro VU0, nhân
129.5fvới1, rồi chỉ so sánh xem đầu vào ban đầu và kết quả có khác nhau hay không - PCSX2, Play!, DobieStation, hps2x64 hiện chưa mô phỏng hành vi này, và độ khó phát hiện được đánh giá là 1/5
Sai số 1 bit phát sinh trong phép nhân VU của PS2
- Phương pháp này là mục thứ hai trong loạt bài phát hiện trình giả lập PS2, và có thể dùng trong VU1, chế độ micro VU0, cũng như chế độ macro VU0
- Ví dụ sử dụng chế độ macro VU0 để đơn giản hóa triển khai
- Vì dùng VU0 như một coprocessor, có thể chạy trực tiếp từ EE CPU
- Không cần xử lý một chương trình VU riêng
- Trong tài liệu hướng dẫn dành cho nhà phát triển VU, các lệnh nhân như
MUL,MULicó chú thích rằng chúng có sai số tính toán 1 bit1 * Xcó thể khác giá trị gốcX- Nếu dùng
VF[fs]làm số bị nhân, độ chính xác của kết quả dạngX * 1được đảm bảo
- Chưa xác nhận chính xác vì sao bit bị mất
Giá trị phát hiện và cách triển khai
- Để phát hiện sai số này, cần một con số gây ra vấn đề; cách tìm kiếm dễ nhất là brute force
- Tác giả trước đây đã lập danh sách 250 số đầu tiên gây vấn đề theo bước 0.5, và công khai danh sách đó trên gist
- Mã ví dụ dùng 129.5f làm con số mục tiêu để phát hiện
- Dùng
QMTC2để đặt129.5fvàoVF1 - Dùng
VADDwđể tạo1trongVF2 - Dùng
VMULđể tínhVF1 = 1 * 129.5f - Dùng
QMFC2để đưa kết quả về phía EE và so sánh với đầu vào
- Dùng
- Giá trị trả về là
in[0] != out[0]; nếu giá trị gốc và kết quả phép nhân khác nhau thì coi như có tồn tại sai số phép nhân VU
Ảnh hưởng theo từng trình giả lập
- Hiện tại PCSX2, Play!, DobieStation, hps2x64 chưa mô phỏng hành vi phép nhân VU này của PS2
- Vì chỉ cần nhân một con số với
1rồi kiểm tra kết quả, độ khó của phương pháp phát hiện này ở mức 1/5
1 bình luận
Ý kiến trên Hacker News
ARM thật do có pipeline nên trong lúc thực thi ở PC và giải mã ở PC+4 thì sẽ đọc PC+8, vì vậy lệnh vừa ghi mới không được ảnh hưởng. Nếu là trình giả lập không mô phỏng pipeline phần cứng thì nó sẽ thực thi lệnh đó
Bài viết giải thích chi tiết hơn cùng nhiều kỹ thuật phá giả lập từ năm 2004: https://mgba.io//2014/12/28/classic-nes/
Có lẽ giá trị thanh ghi không được xác định trong vài chu kỳ. Viết mã assembly tối ưu sát nút cho kiểu chip này khá kinh khủng, như đang chơi một bản clone Zachtronics có gu tệ bất thường
Mãi về sau có người tìm ra một trường hợp biên khác không bị phát hiện, đó là lệnh chuỗi lặp tự ghi đè chính nó
https://silviocesare.wordpress.com/2009/02/02/anti-debugging...
x86 có cơ chế như vậy, nhưng không rõ cuối cùng nó có bị loại bỏ trong biến thể 64-bit hay không
Không chỉ phải biết mọi hành vi kỳ lạ của phần cứng và phần mềm gốc, mà còn phải tái hiện nguyên trạng dù chúng có quái dị đến đâu. Chỉ riêng việc đó đã khó, chưa kể còn phải tính đến tác động hiệu năng
Dùng JIT recompiler thì không thể hoàn toàn chính xác đến từng chu kỳ như phần cứng gốc, nhưng trừ khi mã game cố tình được viết để phá trình giả lập thì nhìn chung không thành vấn đề
Dolphin cũng từng phải xử lý sự cân bằng này khi một số game Wii thương mại chèn mã chống giả lập khai thác chi tiết hành vi bộ đệm của CPU Wii thật. Về lý thuyết, họ có thể giả lập cache của CPU thật để chạy game mượt mà, nhưng chi phí hiệu năng có lẽ sẽ khiến tốc độ chậm hơn khoảng 10 lần và không thể chơi nổi, nên họ chọn vá để né qua
https://dolphin-emu.org/blog/2017/02/01/dolphin-progress-rep...
Có vẻ gần như phải hiểu cả điện tử học lẫn ma thuật lập trình ở mức sâu
Khi mới bắt đầu, và thật ra phần lớn thời gian ngay cả lúc hoàn thành, bạn không cần hiểu thứ ma thuật sâu xa nào cả. Thường chỉ cần đọc đặc tả rồi triển khai đúng theo đó. Tất nhiên vẫn cần khả năng tổ chức cấu trúc mã để nó không thành mớ hỗn độn, nhưng đã có các mẫu phổ biến và sau khi làm một hai trình giả lập thì mọi thứ sẽ dễ hơn nhiều
Cũng hiếm khi cần phải hiểu điện tử học. Thứ được giả lập chỉ là hành vi. Khi phát hiện lỗi trong hành vi của phần cứng gốc, thường chỉ cần thêm xử lý đặc biệt vào trình giả lập. Kiến thức điện tử có thể giúp hiểu vì sao hành vi đó xuất hiện, nhưng điều đó gần với hứng thú lịch sử hơn là giá trị thực dụng
Dĩ nhiên vẫn có khó khăn riêng. Khi có vấn đề, bạn thường phải debug đồng thời ba thứ: hiểu biết về phần cứng, phần cài đặt của trình giả lập, và chính trò chơi đang được giả lập. Việc khoanh vùng nguyên nhân chính xác có thể rất khó. Dù vậy, cứ thử làm đại một bản trước đã. Không đẹp đẽ gì đâu, nhưng mọi trình giả lập đều đầy những xử lý đặc biệt để bằng cách nào đó làm cho game phổ biến chạy được. Nếu vài cú hack lộn xộn là đủ để game chạy, thì cứ làm vậy. Không nhất thiết phải cài đặt chính xác hành vi phần cứng gốc, miễn là làm cho game chạy được
CPU 8-bit là một cỗ máy trạng thái đơn giản chỉ có vài byte trạng thái, tức các thanh ghi. Nó đọc chương trình từng byte một, rồi bạn chỉ cần bắt chước CPU sẽ làm gì sau khi đọc byte đó. Đó là các phép toán rất đơn giản như cộng trừ số, hoặc đọc và lưu byte
http://www.6502.org/users/obelisk/6502/registers.html
http://www.6502.org/users/obelisk/6502/instructions.html
Trình giả lập CPU 6502 sẽ đọc vài byte tiếp theo của chương trình, diễn giải các byte đó thành lệnh, rồi thực thi lệnh. Trong quá trình này, nó cập nhật một vài thanh ghi hoặc bộ đếm của CPU, thực hiện phép toán số học hoặc bit, và nếu cần thì đọc hoặc lưu 1 byte dữ liệu từ vị trí này sang vị trí khác. Quy trình này được lặp lại trong một vòng lặp vô hạn
Đây là mô phỏng của chu kỳ lấy lệnh–giải mã–thực thi
https://en.wikipedia.org/wiki/Instruction_cycle
Trước đây tôi từng port một trình thông dịch 6502 từ UNIX sang Classic Macintosh để phát các tệp nhạc SID. Chỉ cần nó chạy đủ nhanh là được, nên độ chính xác theo chu kỳ xung nhịp không quan trọng
Nó hoạt động bằng cách gọi mã C từ trong trình thông dịch
Tôi vẫn muốn thử, nhưng không có thời gian
Ngoài ra thì bình luận anh em của @xcv123 nói rất đúng
Nếu một ngày nào đó việc tái tạo PS2 bằng FPGA trở nên khả thi, thì việc tìm ra cơ chế hành vi này xảy ra như thế nào sẽ là một dự án thú vị với ai đó
Không có gì đảm bảo rằng phiên bản PS2 trên FPGA sẽ không tái hiện lỗi giống hoặc tương tự
Số thực dấu phẩy động bằng phần mềm sẽ chậm, nhưng lời giải chung có lẽ sẽ theo trình giả lập PS2 của PS4: đưa vào danh sách trắng các đoạn mã cho phép dùng đường xử lý số thực dấu phẩy động bằng phần mềm theo từng trò chơi
Tôi mất quá lâu mới nhận ra đây là nói về PlayStation 2 chứ không phải cổng Personal System/2 dùng để kết nối chuột và bàn phím
Các từ viết tắt ba chữ cái thật sự có thể khiến việc suy ra ngữ cảnh trở nên rất khó. Chỉ cần nhập riêng từ viết tắt đó lên Google thì khá thường xuyên phần lớn kết quả hiện ra lại gần như không liên quan