[NSSRound#6 Team]void(V2)

最后更新于 2024-08-20 796 字 预计阅读时间: 4 分钟


PE64位,放入ida进入main函数逻辑很简单,输入flag,base64后进行比较,但是解出来是乱码

进入init数组中发现有函数在执行main前被调用

进入CDA函数发现fork了一个子进程

pid_t fork( void);

(pid_t 是一个宏定义,其实质是int 被定义在#includesys/types.h>中)

返回值: 若成功调用一次则返回两个值,子进程返回0,父进程返回子进程ID;否则,出错返回-1

上述代码中子进程执行ptrace,父进程执行AD7,ptrace是一个系统调用,可以使一个进程调式另一个进程,是gdb核心

#include <sys/ptrace.h>
long ptrace(enum __ptrace_request request, pid_t pid, void *addr, void *data);
  • enum __ptrace_request request:指示了 ptrace 要执行的命令。
  • pid_t pid:指示 ptrace 要跟踪的进程。
  • void *addr:指示要监控的内存地址。
  •  void *data:存放读取出的或者要写入的数据。

其中request包含

PTRACE_TRACEME本进程被其父进程所跟踪。其父进程应该希望跟踪子进程。
PTRACE_PEEKTEXT, PTRACE_PEEKDATA从内存地址中读取一个字节,内存地址由addr给出。
PTRACE_PEEKUSR从USER区域中读取一个字节,偏移量为addr。
PTRACE_POKETEXT, PTRACE_POKEDATA往内存地址中写入一个字节。内存地址由addr给出。
PTRACE_POKEUSR往USER区域中写入一个字节。偏移量为addr。
PTRACE_SYSCALL, PTRACE_CONT重新运行,SYSCALL遇到系统调用在遇到系统调用时将控制权给回父进程。
PTRACE_KILL杀掉子进程,使它退出。
PTRACE_SINGLESTEP设置单步执行标志
PTRACE_ATTACH跟踪指定pid 进程。
PTRACE_DETACH结束跟踪

关于ptrace反调试

1.进程如果执行ptrace(PT_DENY_ATTACH, 0, 0, 0);表示拒绝被调试,调试器无法调试该进程

2.当有调试器调试该进程时,执行到ptrace(PTRACE_TRACEME, 0, NULL, NULL)将有父进程调试但是由于一个进程仅能被一个进程调试,该进程已被调试器调试故返回-1结束进程

 if (ptrace(PTRACE_TRACEME, 0, NULL, NULL) == -1) {
        printf("Debugger detected!\n");
        return 1;
    }

AD7函数,waitpid函数会等待子进程运行结束或者有信号时返回,将等待进程的状态码保留在stat_loc中,当stat_loc!=127(中断)时退出,在子进程中只执行了ptrace(PTRACE_TRACEME, 0LL, 0LL, 0LL);没有发送任何信号,故AD7函数只是等待子进程退出后自己也退出

父进程没做什么,看子进程

 for ( i = 0; i <= 0; ++i )
    result = ((sub_55E78000095A + i + 7))(11LL, 13LL, 17LL);
  return result;

上述代码确实执行95A+7=961函数

操作的数组离base64码表很近并且BA-3f=5f正好对应base64码表,故在换码表

看init数组中的第二个函数执行95A+BF=A19改编码后的值

程序逻辑

父进程------->等待子进程结束后退出

子进程-------->改码表和编码值后进入main函数进行输入编码比较

故我们可以将此处nop掉得到单进程版本调试

就可以看到真实的码表和编码值

此作者没有提供个人介绍。
最后更新于 2024-08-20