Skip to content

Instantly share code, notes, and snippets.

@ahmz1833
Last active December 31, 2025 12:36
Show Gist options
  • Select an option

  • Save ahmz1833/5c8588d67372b71c31a6061c4313c5f0 to your computer and use it in GitHub Desktop.

Select an option

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)
/* * 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, &regs);
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, &regs);
}
}
return 0;
CRASH:
printf("[HARDWARE] SYSTEM HALTED.\n");
kill(child, SIGKILL);
return 1;
}
@ahmz1833
Copy link
Author

برای تست کد خودتان در سوال ۵ می‌توانید از این ابزار که به زبان سی نوشته شده استفاده کنید.
ابتدا به وسیله gcc این کد را به صورت کاملاً عادی Compile کنید. (فرض کنیم فایل اجرایی خروجی tester نام گیرد)
سپس کد اسمبلی خود را با روش همیشگی و معمول خود (از نوع no-libc) به فایل اجرایی تبدیل کنید. فرض کنیم نام فایل اجرایی شما output.elf باشد. سپس به‌وسیله دستور زیر می‌توانید تستر را اجرا کنید:

./tester ./output.elf

نکته: دقت کنید پاس شدن تست این کد به معنای گرفتن نمرهٔ کامل نیست. این کد تستر صرفا برای دیباگینگ شما و یک عملکرد ساده است. کد تستر اصلی سمت کوئرا موارد بیشتری (از جمله تمام شدن باطری) را چک می‌کند.

@OverShifted
Copy link

همچنین اگر به هر دلیلی مشکلی در اجرای برنامه‌ی ربات بوجود اومد، می‌شود با تغییر خط ‍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