AIS3 pre-exam 2021 – blind


題目提供了 program 本身,source code 跟 docker file 但我完全懶得架

要求 4 個參數並做 system call

system call 能參考 Chromium OS 提供的 linux system call list


隨便丟個合法的 system call 進去

恩….沒有給出東西
回去看 source code

void make_a_syscall()
{
    unsigned long long rax, rdi, rsi, rdx;
    scanf("%llu %llu %llu %llu", &rax, &rdi, &rsi, &rdx);
    printf("hi");
    syscall(rax,rdi,rsi,rdx);
}

int main()
{
    setvbuf(stdin, 0, 2, 0);
    setvbuf(stdout, 0, 2, 0);
    puts("You can call a system call, then I will open the flag for you.");
    puts("Input: [rax] [rdi] [rsi] [rdx]");
    close(1);
    make_a_syscall();
    return 0;
    int fd = open("flag", O_RDONLY);
    fd = open("flag", O_RDONLY);
    printf("%d",fd);
    char flag[0x100];
    size_t flag_len = read(fd, flag, 0xff);
    write(1, flag, flag_len);
    return 0;
}Code language: JavaScript (javascript)

close(1) 看起來有點可疑
查了一下 close(int fd) 是拿來將 fstream 關閉的

 ref : Linux 系統程式設計 – fd 及 open()、close() 系統呼叫 

fd = 1 是 stdout ,所以 close(1) 就是將 stdout 關掉
那就得想辦法重新開啟,但一個 fstream 關掉就無法重新開啟,除非使用 open
但 open 沒辦法使用,因為 syscall 的三個 arg 都是 int,要傳字串進去什麼的不太可能
網路上查到重新開啟關閉的 stdout 能使用 dup() 的方式備份原 fstream 下來
但如果要保留 stdout 的話就得在 close 前 dup 一個 stdout 的備份
且後面的 write(1, flag, flag_len); 表示一定得寫到 stdout 裡

細數現有能用的 fstream 就只有 stdin / flag.txt / stderr
但寫進 stdin 與 flag.txt 蠢到家了
剩下 stderr
參考文章中有提到 dup 會使用 id 最小的 fd 來使用
因為已經 close(1) ,所以 fd = 1 的位置會空下來
因此 dup(stderr) 就能將 fd = 1 的位置換成 stderr
反正 stderr 跟 stdout 一個樣,也沒差到多少

dup 的 rax = 0x20 , rdi = stderr = 2
其他就填 0 吧
所以輸入就是 32 2 0 0