// File: /workspace/github_c_makefile_star2_O0/hifi[P]whatever/whatever.c
// Function: main
int main(int argc, char **argv)
{
    pid_t pid;

    if (argc < 2)
        die("usage: %s <program> [args]\n", argv[0]);

    pid = fork();

    if (pid < 0)
        die("%s: failed to fork()\n", argv[0]);

    if (pid == 0) {
        /* child */
        ptrace(PTRACE_TRACEME, 0, NULL, NULL);
        execv(argv[1], argv+1);
        die("%s: failed to execv()", argv[0]);
    } else {
        /* parent */
        waitpid(pid, NULL, 0);
        ptrace(PTRACE_SETOPTIONS, pid, NULL, PTRACE_O_TRACESYSGOOD|PTRACE_O_TRACEFORK|PTRACE_O_TRACEEXEC);
        ptrace(PTRACE_SYSCALL, pid, NULL, NULL);

        while (1) {
            int status;
            pid_t trace_pid = waitpid(-1, &status, 0);

            if (trace_pid < 0) {
                kill(pid, SIGKILL);
                return 1;
            }

            if (WIFEXITED(status)) {
                if (trace_pid == pid)
                    break;

                continue;
            }

            if (WSTOPSIG(status) == (SIGTRAP|0x80)) {
                int syscall = ptrace(PTRACE_PEEKUSER, trace_pid, 8*ORIG_RAX, NULL);

                switch (syscall) {
                    case SYS_setresuid:
                    {
                        struct user_regs_struct regs;
                        ptrace(PTRACE_GETREGS, trace_pid, 0, &regs);

                        if (regs.rdi >= 0)
                            processes[trace_pid].ruid = regs.rdi;
                        if (regs.rsi >= 0)
                            processes[trace_pid].euid = regs.rsi;
                        if (regs.rdx >= 0)
                            processes[trace_pid].suid = regs.rdx;

                        ptrace(PTRACE_POKEUSER, trace_pid, 8*RAX, 0);
                        break;
                    }

                    case SYS_setresgid:
                    {
                        struct user_regs_struct regs;
                        ptrace(PTRACE_GETREGS, trace_pid, 0, &regs);

                        if (regs.rdi >= 0)
                            processes[trace_pid].rgid = regs.rdi;
                        if (regs.rsi >= 0)
                            processes[trace_pid].egid = regs.rsi;
                        if (regs.rdx >= 0)
                            processes[trace_pid].sgid = regs.rdx;

                        ptrace(PTRACE_POKEUSER, trace_pid, 8*RAX, 0);
                        break;
                    }

                    case SYS_getresuid:
                    {
                        struct user_regs_struct regs;
                        ptrace(PTRACE_GETREGS, trace_pid, 0, &regs);

                        if (regs.rdi > 0)
                            poke_short(trace_pid, regs.rdi, processes[trace_pid].ruid);

                        if (regs.rsi > 0)
                            poke_short(trace_pid, regs.rsi, processes[trace_pid].euid);

                        if (regs.rdx > 0)
                            poke_short(trace_pid, regs.rdx, processes[trace_pid].suid);

                        ptrace(PTRACE_POKEUSER, trace_pid, 8*RAX, 0);
                        break;
                    }

                    case SYS_getresgid:
                    {
                        struct user_regs_struct regs;
                        ptrace(PTRACE_GETREGS, trace_pid, 0, &regs);

                        if (regs.rdi > 0)
                            poke_short(trace_pid, regs.rdi, processes[trace_pid].rgid);

                        if (regs.rsi > 0)
                            poke_short(trace_pid, regs.rsi, processes[trace_pid].egid);

                        if (regs.rdx > 0)
                            poke_short(trace_pid, regs.rdx, processes[trace_pid].sgid);

                        ptrace(PTRACE_POKEUSER, trace_pid, 8*RAX, 0);
                        break;
                    }

                    case SYS_getuid:
                        ptrace(PTRACE_POKEUSER, trace_pid, 8*RAX, processes[trace_pid].ruid);
                        break;
                    case SYS_getgid:
                        ptrace(PTRACE_POKEUSER, trace_pid, 8*RAX, processes[trace_pid].rgid);
                        break;
                    case SYS_geteuid:
                        ptrace(PTRACE_POKEUSER, trace_pid, 8*RAX, processes[trace_pid].euid);
                        break;
                    case SYS_getegid:
                        ptrace(PTRACE_POKEUSER, trace_pid, 8*RAX, processes[trace_pid].egid);
                        break;

                    case SYS_getgroups:
                    case SYS_setgroups:
                    case SYS_chown:
                    case SYS_fchown:
                    case SYS_lchown:
                    case SYS_fchownat:
                    case SYS_setreuid:
                    case SYS_setregid:
                    case SYS_setuid:
                    case SYS_setgid:
                        ptrace(PTRACE_POKEUSER, trace_pid, 8*RAX, 0);
                    default:
                        break;
                }
            } else {
                /* fork */
                pid_t child_pid;
                ptrace(PTRACE_GETEVENTMSG, trace_pid, 0, &child_pid);
                /* blindly forcing all children to think they are root initially */
                memset(&processes[child_pid], 0, sizeof(struct who));
                ptrace(PTRACE_SETOPTIONS, child_pid, NULL, PTRACE_O_TRACESYSGOOD|PTRACE_O_TRACEFORK|PTRACE_O_TRACEEXEC);
            }

            ptrace(PTRACE_SYSCALL, trace_pid, NULL, NULL);
        }
    }

    return 0;
}

// Assembly:
subq $0x398, %rsp            # imm = 0x398
movl $0x0, 0x394(%rsp)
movl %edi, 0x390(%rsp)
movq %rsi, 0x388(%rsp)
cmpl $0x2, 0x390(%rsp)
jge 0x4016d4
movq 0x388(%rsp), %rax
movq (%rax), %rsi
leaq 0x97bdb(%rip), %rdi     # 0x4992a8
movb $0x0, %al
callq 0x401d60
callq 0x44ee40
movl %eax, 0x384(%rsp)
cmpl $0x0, 0x384(%rsp)
jge 0x401703
movq 0x388(%rsp), %rax
movq (%rax), %rsi
leaq 0x97bc8(%rip), %rdi     # 0x4992c4
movb $0x0, %al
callq 0x401d60
cmpl $0x0, 0x384(%rsp)
jne 0x40175a
xorl %esi, %esi
xorl %eax, %eax
movl %eax, %ecx
movl %esi, %edi
movq %rcx, %rdx
movb $0x0, %al
callq 0x450e90
movq 0x388(%rsp), %rax
movq 0x8(%rax), %rdi
movq 0x388(%rsp), %rsi
addq $0x8, %rsi
callq 0x44f840
movq 0x388(%rsp), %rax
movq (%rax), %rsi
leaq 0x97b8c(%rip), %rdi     # 0x4992da
movb $0x0, %al
callq 0x401d60
jmp 0x401d37
movl 0x384(%rsp), %edi
xorl %eax, %eax
movl %eax, %esi
xorl %edx, %edx
callq 0x44ed80
movl 0x384(%rsp), %esi
movl $0x4200, %edi           # imm = 0x4200
xorl %eax, %eax
movl %eax, %edx
movl $0x13, %ecx
movb $0x0, %al
callq 0x450e90
movl 0x384(%rsp), %esi
movl $0x18, %edi
xorl %eax, %eax
movl %eax, %ecx
movq %rcx, %rdx
movb $0x0, %al
callq 0x450e90
movl $0xffffffff, %edi       # imm = 0xFFFFFFFF
leaq 0x380(%rsp), %rsi
xorl %edx, %edx
callq 0x44ed80
movl %eax, 0x37c(%rsp)
cmpl $0x0, 0x37c(%rsp)
jge 0x4017e8
movl 0x384(%rsp), %edi
movl $0x9, %esi
callq 0x40a660
movl $0x1, 0x394(%rsp)
jmp 0x401d42
movl 0x380(%rsp), %eax
andl $0x7f, %eax
cmpl $0x0, %eax
jne 0x40180e
movl 0x37c(%rsp), %eax
cmpl 0x384(%rsp), %eax
jne 0x40180c
jmp 0x401d35
jmp 0x4017a2
movl 0x380(%rsp), %eax
andl $0xff00, %eax           # imm = 0xFF00
sarl $0x8, %eax
cmpl $0x85, %eax
jne 0x401cc4
movl 0x37c(%rsp), %esi
xorl %eax, %eax
movl %eax, %ecx
movl $0x3, %edi
movl $0x78, %edx
callq 0x450e90
movl %eax, 0x378(%rsp)
movl 0x378(%rsp), %eax
addl $-0x5c, %eax
movl %eax, %ecx
movq %rcx, 0x8(%rsp)
subl $0xa8, %eax
ja 0x401cc0
movq 0x8(%rsp), %rax
leaq 0x97793(%rip), %rcx     # 0x499004
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
movl 0x37c(%rsp), %esi
movl $0xc, %edi
xorl %edx, %edx
leaq 0x2a0(%rsp), %rcx
movb $0x0, %al
callq 0x450e90
cmpq $0x0, 0x310(%rsp)
jb 0x4018c4
movq 0x310(%rsp), %rax
movl %eax, %ecx
movslq 0x37c(%rsp), %rdx
leaq 0xc9a35(%rip), %rax     # 0x4cb2f0
imulq $0x18, %rdx, %rdx
addq %rdx, %rax
movl %ecx, (%rax)
cmpq $0x0, 0x308(%rsp)
jb 0x4018f2
movq 0x308(%rsp), %rax
movl %eax, %ecx
movslq 0x37c(%rsp), %rdx
leaq 0xc9a08(%rip), %rax     # 0x4cb2f0
imulq $0x18, %rdx, %rdx
addq %rdx, %rax
movl %ecx, 0x4(%rax)
cmpq $0x0, 0x300(%rsp)
jb 0x401920
movq 0x300(%rsp), %rax
movl %eax, %ecx
movslq 0x37c(%rsp), %rdx
leaq 0xc99da(%rip), %rax     # 0x4cb2f0
imulq $0x18, %rdx, %rdx
addq %rdx, %rax
movl %ecx, 0x8(%rax)
movl 0x37c(%rsp), %esi
movl $0x6, %edi
movl $0x50, %edx
xorl %ecx, %ecx
movb $0x0, %al
callq 0x450e90
jmp 0x401cc2
movl 0x37c(%rsp), %esi
movl $0xc, %edi
xorl %edx, %edx
leaq 0x1c8(%rsp), %rcx
movb $0x0, %al
callq 0x450e90
cmpq $0x0, 0x238(%rsp)
jb 0x40198a
movq 0x238(%rsp), %rax
movl %eax, %ecx
movslq 0x37c(%rsp), %rdx
leaq 0xc9970(%rip), %rax     # 0x4cb2f0
imulq $0x18, %rdx, %rdx
addq %rdx, %rax
movl %ecx, 0xc(%rax)
cmpq $0x0, 0x230(%rsp)
jb 0x4019b8
movq 0x230(%rsp), %rax
movl %eax, %ecx
movslq 0x37c(%rsp), %rdx
leaq 0xc9942(%rip), %rax     # 0x4cb2f0
imulq $0x18, %rdx, %rdx
addq %rdx, %rax
movl %ecx, 0x10(%rax)
cmpq $0x0, 0x228(%rsp)
jb 0x4019e6
movq 0x228(%rsp), %rax
movl %eax, %ecx
movslq 0x37c(%rsp), %rdx
leaq 0xc9914(%rip), %rax     # 0x4cb2f0
imulq $0x18, %rdx, %rdx
addq %rdx, %rax
movl %ecx, 0x14(%rax)
movl 0x37c(%rsp), %esi
movl $0x6, %edi
movl $0x50, %edx
xorl %ecx, %ecx
movb $0x0, %al
callq 0x450e90
jmp 0x401cc2
movl 0x37c(%rsp), %esi
movl $0xc, %edi
xorl %edx, %edx
leaq 0xf0(%rsp), %rcx
movb $0x0, %al
callq 0x450e90
cmpq $0x0, 0x160(%rsp)
jbe 0x401a5c
movl 0x37c(%rsp), %edi
movq 0x160(%rsp), %rsi
movslq 0x37c(%rsp), %rcx
leaq 0xc98a5(%rip), %rax     # 0x4cb2f0
imulq $0x18, %rcx, %rcx
addq %rcx, %rax
movl (%rax), %eax
movswl %ax, %edx
callq 0x401e30
cmpq $0x0, 0x158(%rsp)
jbe 0x401a97
movl 0x37c(%rsp), %edi
movq 0x158(%rsp), %rsi
movslq 0x37c(%rsp), %rcx
leaq 0xc986b(%rip), %rax     # 0x4cb2f0
imulq $0x18, %rcx, %rcx
addq %rcx, %rax
movl 0x4(%rax), %eax
movswl %ax, %edx
callq 0x401e30
cmpq $0x0, 0x150(%rsp)
jbe 0x401ad2
movl 0x37c(%rsp), %edi
movq 0x150(%rsp), %rsi
movslq 0x37c(%rsp), %rcx
leaq 0xc9830(%rip), %rax     # 0x4cb2f0
imulq $0x18, %rcx, %rcx
addq %rcx, %rax
movl 0x8(%rax), %eax
movswl %ax, %edx
callq 0x401e30
movl 0x37c(%rsp), %esi
movl $0x6, %edi
movl $0x50, %edx
xorl %ecx, %ecx
movb $0x0, %al
callq 0x450e90
jmp 0x401cc2
movl 0x37c(%rsp), %esi
movl $0xc, %edi
xorl %edx, %edx
leaq 0x18(%rsp), %rcx
movb $0x0, %al
callq 0x450e90
cmpq $0x0, 0x88(%rsp)
jbe 0x401b46
movl 0x37c(%rsp), %edi
movq 0x88(%rsp), %rsi
movslq 0x37c(%rsp), %rcx
leaq 0xc97bc(%rip), %rax     # 0x4cb2f0
imulq $0x18, %rcx, %rcx
addq %rcx, %rax
movl 0xc(%rax), %eax
movswl %ax, %edx
callq 0x401e30
cmpq $0x0, 0x80(%rsp)
jbe 0x401b81
movl 0x37c(%rsp), %edi
movq 0x80(%rsp), %rsi
movslq 0x37c(%rsp), %rcx
leaq 0xc9781(%rip), %rax     # 0x4cb2f0
imulq $0x18, %rcx, %rcx
addq %rcx, %rax
movl 0x10(%rax), %eax
movswl %ax, %edx
callq 0x401e30
cmpq $0x0, 0x78(%rsp)
jbe 0x401bb6
movl 0x37c(%rsp), %edi
movq 0x78(%rsp), %rsi
movslq 0x37c(%rsp), %rcx
leaq 0xc974c(%rip), %rax     # 0x4cb2f0
imulq $0x18, %rcx, %rcx
addq %rcx, %rax
movl 0x14(%rax), %eax
movswl %ax, %edx
callq 0x401e30
movl 0x37c(%rsp), %esi
movl $0x6, %edi
movl $0x50, %edx
xorl %ecx, %ecx
movb $0x0, %al
callq 0x450e90
jmp 0x401cc2
movl 0x37c(%rsp), %esi
movslq 0x37c(%rsp), %rcx
leaq 0xc9705(%rip), %rax     # 0x4cb2f0
imulq $0x18, %rcx, %rcx
addq %rcx, %rax
movl (%rax), %ecx
movl $0x6, %edi
movl $0x50, %edx
movb $0x0, %al
callq 0x450e90
jmp 0x401cc2
movl 0x37c(%rsp), %esi
movslq 0x37c(%rsp), %rcx
leaq 0xc96d0(%rip), %rax     # 0x4cb2f0
imulq $0x18, %rcx, %rcx
addq %rcx, %rax
movl 0xc(%rax), %ecx
movl $0x6, %edi
movl $0x50, %edx
movb $0x0, %al
callq 0x450e90
jmp 0x401cc2
movl 0x37c(%rsp), %esi
movslq 0x37c(%rsp), %rcx
leaq 0xc969a(%rip), %rax     # 0x4cb2f0
imulq $0x18, %rcx, %rcx
addq %rcx, %rax
movl 0x4(%rax), %ecx
movl $0x6, %edi
movl $0x50, %edx
movb $0x0, %al
callq 0x450e90
jmp 0x401cc2
movl 0x37c(%rsp), %esi
movslq 0x37c(%rsp), %rcx
leaq 0xc9667(%rip), %rax     # 0x4cb2f0
imulq $0x18, %rcx, %rcx
addq %rcx, %rax
movl 0x10(%rax), %ecx
movl $0x6, %edi
movl $0x50, %edx
movb $0x0, %al
callq 0x450e90
jmp 0x401cc2
movl 0x37c(%rsp), %esi
movl $0x6, %edi
movl $0x50, %edx
xorl %ecx, %ecx
movb $0x0, %al
callq 0x450e90
jmp 0x401cc2
jmp 0x401d16
movl 0x37c(%rsp), %esi
movl $0x4201, %edi           # imm = 0x4201
xorl %edx, %edx
leaq 0x14(%rsp), %rcx
movb $0x0, %al
callq 0x450e90
movslq 0x14(%rsp), %rax
leaq 0xc9606(%rip), %rdi     # 0x4cb2f0
imulq $0x18, %rax, %rax
addq %rax, %rdi
xorl %esi, %esi
movl $0x18, %edx
callq 0x401098
movl 0x14(%rsp), %esi
movl $0x4200, %edi           # imm = 0x4200
xorl %eax, %eax
movl %eax, %edx
movl $0x13, %ecx
movb $0x0, %al
callq 0x450e90
movl 0x37c(%rsp), %esi
movl $0x18, %edi
xorl %eax, %eax
movl %eax, %ecx
movq %rcx, %rdx
movb $0x0, %al
callq 0x450e90
jmp 0x4017a2
jmp 0x401d37
movl $0x0, 0x394(%rsp)
movl 0x394(%rsp), %eax
addq $0x398, %rsp            # imm = 0x398
retq
nopw %cs:(%rax,%rax)