Last active
December 31, 2025 12:36
-
-
Save ahmz1833/5c8588d67372b71c31a6061c4313c5f0 to your computer and use it in GitHub Desktop.
Student Test Code for CSL-2025 (Exercise 7 - Q5 for Dr. Asadi and Exercise 2 - Q4 for Dr. Jahangir)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| /* * STUDENT TESTER | |
| * This simulates the hardware blindly. | |
| * Use this to verify your logic locally. | |
| */ | |
| #define _GNU_SOURCE | |
| #include <sys/ptrace.h> | |
| #include <sys/types.h> | |
| #include <sys/wait.h> | |
| #include <sys/user.h> | |
| #include <sys/uio.h> | |
| #include <unistd.h> | |
| #include <stdio.h> | |
| #include <stdlib.h> | |
| #include <string.h> | |
| // 0=Open, 1=Obstacle, 2=Target | |
| const int HIDDEN_MAP[] = {0, 0, 1, 0, 1, 0, 0, 0, 1, 0, 2}; | |
| const int MAP_SIZE = 11; | |
| void read_mem(pid_t child, unsigned long addr, char *buf, size_t len) { | |
| struct iovec local = {buf, len}; | |
| struct iovec remote = {(void *)addr, len}; | |
| process_vm_readv(child, &local, 1, &remote, 1, 0); | |
| } | |
| int main(int argc, char *argv[]) { | |
| if (argc < 2) { printf("Usage: %s <program>\n", argv[0]); return 1; } | |
| pid_t child = fork(); | |
| if (child == 0) { | |
| ptrace(PTRACE_TRACEME, 0, NULL, NULL); | |
| execl(argv[1], argv[1], NULL); | |
| exit(1); | |
| } else { | |
| int status, pos = 0; | |
| struct user_regs_struct regs; | |
| wait(&status); | |
| ptrace(PTRACE_SETOPTIONS, child, 0, PTRACE_O_EXITKILL); | |
| printf("[HARDWARE] Robot System Booting...\n"); | |
| while (1) { | |
| ptrace(PTRACE_SYSEMU, child, 0, 0); | |
| wait(&status); | |
| if (WIFEXITED(status) || WIFSIGNALED(status)) break; | |
| ptrace(PTRACE_GETREGS, child, 0, ®s); | |
| if (regs.orig_rax == 100) { // SYS_SCAN | |
| int val = (pos + 1 < MAP_SIZE) ? HIDDEN_MAP[pos + 1] : 0; | |
| regs.rax = val; | |
| } | |
| else if (regs.orig_rax == 101) { // SYS_MOVE | |
| int act = regs.rdi; | |
| int next = (pos + 1 < MAP_SIZE) ? HIDDEN_MAP[pos + 1] : -1; | |
| if (act == 0) { // Walk | |
| if (next == 0 || next == 2) { | |
| pos++; | |
| } else { | |
| printf("\n[HARDWARE] CRITICAL: COLLISION DETECTED.\n"); | |
| goto CRASH; | |
| } | |
| } else if (act == 1) { // Jump | |
| if (next == 1) { | |
| pos += 2; | |
| } else { | |
| printf("\n[HARDWARE] CRITICAL: ILLEGAL MANEUVER (JUMP ON FLAT).\n"); | |
| goto CRASH; | |
| } | |
| } | |
| regs.rax = 0; | |
| } | |
| else if (regs.orig_rax == 102) { // SYS_LOG | |
| char buf[20] = {0}; | |
| read_mem(child, regs.rdi, buf, regs.rsi < 19 ? regs.rsi : 19); | |
| if (HIDDEN_MAP[pos] == 2 && strncmp(buf, "MISSION OK", 10) == 0) { | |
| printf("\n[BASE STATION] Signal Received: \"%s\"\n", buf); | |
| printf("[HARDWARE] MISSION SUCCESSFUL.\n"); | |
| kill(child, SIGKILL); return 0; | |
| } | |
| else if (strncmp(buf, "LOW", 3) == 0) { | |
| printf("\n[BASE STATION] Signal Received: \"%s\"\n", buf); | |
| printf("[HARDWARE] SHUTDOWN CONFIRMED (Battery Depleted).\n"); | |
| kill(child, SIGKILL); return 0; | |
| } | |
| else { | |
| printf("\n[BASE STATION] Corrupted Packet or Wrong Coordinates.\n"); | |
| goto CRASH; | |
| } | |
| } | |
| else if (regs.orig_rax == 60) { | |
| printf("[HARDWARE] Manual Shutdown.\n"); | |
| break; | |
| } | |
| ptrace(PTRACE_SETREGS, child, 0, ®s); | |
| } | |
| } | |
| return 0; | |
| CRASH: | |
| printf("[HARDWARE] SYSTEM HALTED.\n"); | |
| kill(child, SIGKILL); | |
| return 1; | |
| } |
Author
همچنین اگر به هر دلیلی مشکلی در اجرای برنامهی ربات بوجود اومد، میشود با تغییر خط execl به این شکل از مشکل با خبر شد:
if (execl(argv[1], argv[1], NULL) == -1) {
perror("[HARDWARE] Failed to execute program");
}
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
برای تست کد خودتان در سوال ۵ میتوانید از این ابزار که به زبان سی نوشته شده استفاده کنید.
ابتدا به وسیله gcc این کد را به صورت کاملاً عادی Compile کنید. (فرض کنیم فایل اجرایی خروجی
testerنام گیرد)سپس کد اسمبلی خود را با روش همیشگی و معمول خود (از نوع no-libc) به فایل اجرایی تبدیل کنید. فرض کنیم نام فایل اجرایی شما
output.elfباشد. سپس بهوسیله دستور زیر میتوانید تستر را اجرا کنید:نکته: دقت کنید پاس شدن تست این کد به معنای گرفتن نمرهٔ کامل نیست. این کد تستر صرفا برای دیباگینگ شما و یک عملکرد ساده است. کد تستر اصلی سمت کوئرا موارد بیشتری (از جمله تمام شدن باطری) را چک میکند.