Làm sao bạn biết nó đã hiệu quả?
Với mọi công cụ khác cùng loại, bạn không biết. Ứng dụng khởi động, hiển thị một ngày nào đó, và bạn đoán. Nhưng nó có thể đọc đồng hồ qua một đường mà không gì chặn được - và khi đó “bài kiểm thử đã qua” hoàn toàn vô nghĩa.
Thất bại không có triệu chứng
Một công cụ dịch chuyển thời gian bỏ sót một kênh sẽ không sập và không cảnh báo. Ứng dụng chỉ đơn giản đọc ngày thật qua một hàm mà không ai chặn, và cư xử đúng như nó sẽ cư xử vào bất kỳ buổi chiều bình thường nào. Bài kiểm thử xanh. Lỗi được phát hành.
RunAsDate trung thực về điều này trong tài liệu của chính nó - nó nói rằng nó “sẽ không ảnh hưởng đến các ứng dụng lấy ngày/giờ hiện tại từ một nguồn khác” - rồi để bạn tự tìm hiểu xem ứng dụng của bạn có thuộc nhóm đó không. Công cụ này coi chính câu đó là điều cần đo.
Một phiên thực sự báo cáo gì
Đầu ra thật, từ việc chạy công cụ trên một trong các đầu dò kiểm thử của chính dự án này - một đầu dò cố ý mở một kết nối mạng:
$ chrono run "...\pnet-x64.exe" --at 2038-01-19T03:14:07 --report session.txt Chrono Mock - session report target: C:\ChronoMock\tools\probes\bin\pnet-x64.exe verdict: WORKS - time substitution took effect (processes: 1) every process that read time saw the session clock session: fake clock reached 2038-01-19T03:14:10 real elapsed 3.4s, fake elapsed 3.4s exited: the target closed itself with code 0 covered channels (substituted, with call counts, 4 calls in all): - pid 9152: GetSystemTimeAsFileTime (1 call) - pid 9152: NtQuerySystemTime (3 calls) ... every other channel, including the ones never called observed channels (hooked but left real): - pid 9152: NtCreateUserProcess (0 calls) - pid 9152: connect (1 call) warnings: - the target opened a network connection - it may read time from a server, which no local hook can cover (source.network_at_start) requested: 2038-01-19T03:14:07 (zone +02:00 (host default), mode flow)
Hai khối cuối là điểm mấu chốt. Không có gì thất bại ở đây - kết luận là hoạt động - vậy mà báo cáo vẫn nói, không cần ai hỏi, rằng ứng dụng này đã nói chuyện với mạng trước khi xong việc, nên một hook cục bộ có thể chưa phải toàn bộ câu chuyện. Câu đó là sự khác biệt giữa một bài kiểm thử bạn có thể tin và một bài bạn không thể.
Bốn kết luận, và một mã thoát cho mỗi kết luận
Kết luận được đưa ra từ bên trong tiến trình đang chạy, trước khi bạn bắt đầu làm việc, và nó chính là mã thoát của công cụ để pipeline có thể rẽ nhánh theo nó.
| Kết luận | Mã thoát | Ý nghĩa |
|---|---|---|
| hoạt động | 0 | mọi tiến trình đọc giờ đều thấy đồng hồ của phiên |
| hoạt động một phần | 10 | một số kênh được bao phủ, một số thì không - các kênh chưa bao phủ được liệt kê |
| không hoạt động | 11 | việc thay thế không đến được các kênh then chốt |
| chưa xác định | 4 | không thể xác lập độ bao phủ - một câu “tôi không biết” trung thực |
Khi kết luận là “không hoạt động”, tiến trình bị dừng ngay lập tức, trước khi bạn kịp tương tác với nó. Kết luận không thể có trước lúc khởi chạy, vì nguồn chân lý duy nhất là một số đọc được lấy từ bên trong tiến trình đang chạy. Điều được đảm bảo là bạn biết sự thật trước khi bắt đầu làm việc - chứ không phải một lần khởi chạy chắc chắn thất bại sẽ không bao giờ xảy ra. Bạn có thể ghi đè và tiếp tục, và khi đó phiên được đánh dấu là không đáng tin ở mọi nơi nó xuất hiện, kể cả trong bất kỳ bằng chứng nào bạn xuất ra.
Các mã khác cho biết chính lần chạy đã hỏng chứ không phải việc thay thế - lỗi sử dụng, mục tiêu không khởi động được, lần chạy bị cắt ngang, một phiên khác đang chạy - và không mã nào là kết luận. Bảng đầy đủ nằm trong tài liệu tham khảo dòng lệnh.
Được bao phủ, được quan sát, không được bao phủ
Các kênh rơi vào ba nhóm, và nhóm ở giữa là nhóm thú vị.
- Được bao phủ - đã hook và thay thế. Ứng dụng hỏi, và nhận đồng hồ của phiên. Số lần gọi cho biết bao nhiêu lần.
- Được quan sát - bị chặn, được đếm và cố ý để nói sự thật. Ở đây có các lệnh chờ đối tượng, vì rút ngắn thời hạn chờ có thể giả một lần hết giờ trên handle thật, và bộ hẹn giờ đa phương tiện, vì co giãn nó sẽ làm lệch nhịp âm thanh và MIDI - cả hai được theo dõi khi phiên co giãn trục thời gian trôi qua. Kết nối mạng và một đường tạo tiến trình có mặt ở đây trong mọi phiên, vì chúng là bằng chứng, không phải đồng hồ. Bộ đếm độ phân giải cao không thuộc nhóm này: nó được để nguyên trừ khi bạn yêu cầu bằng
--scale-qpc, và khi đó nó được bao phủ. - Không được bao phủ - một kênh mà ứng dụng đã đọc mà việc thay thế không đến được. Đây là thứ biến một kết luận thành hoạt động một phần, và nó được liệt kê theo tên chứ không bị tóm tắt cho biến mất.
Số đếm bằng không cũng là thông tin: kênh đã được hook và ứng dụng chưa bao giờ hỏi. Đó là lý do báo cáo liệt kê chúng thay vì giấu đi.
Những gì kiểm toán không thể thấy
Báo cáo trung thực về độ bao phủ, nghĩa là cũng trung thực về chính biên giới của nó. Những thứ này được đọc mà không có lệnh gọi hàm nào để chặn, hoặc hoàn toàn bên ngoài tiến trình:
- đọc trực tiếp trang dữ liệu dùng chung ở chế độ người dùng - giá trị nằm trong bộ nhớ, nên không có gì để hook. Hiếm trong ứng dụng thông thường, phổ biến trong mã cấp phép và chống can thiệp
- lời gọi hệ thống trực tiếp bỏ qua các hàm xuất chuẩn - cùng mẫu đó
- giờ lấy được từ ngoài tiến trình, qua WMI, một máy chủ COM ngoài tiến trình hoặc RPC
- giờ từ mạng - tiêu đề HTTP
Date, NTP, một phản hồi API, hoặc đồng hồ riêng của một máy chủ cơ sở dữ liệu - giờ từ trình điều khiển nhân
Trường hợp mạng là trường hợp mà kiểm toán ít nhất có thể nhận ra, đó là lý do cảnh báo trong báo cáo ở trên tồn tại. Với phần còn lại, kết luận hoạt động có nghĩa là các kênh mà công cụ này thấy được đã được bao phủ - chứ không phải là không còn đường nào khác.
Trong một pipeline
--json xuất cùng các dữ kiện dưới dạng cho máy, --report ghi phiên bản cho
người ra tệp, và một phiên có kết luận khác hoạt động mở đầu tệp đó bằng biểu ngữ bằng
chứng không đáng tin thay vì chôn lời lưu ý ở cuối.
chrono run "C:\apps\test.exe" --at 2027-12-31T23:59:59 --json --report evidence.txt