CTF_100.apk 代码记录

// 调用这个函数 进行反调试
__pid_t __fastcall sub_107C(int a1, int a2, int a3)
{
__pid_t PID; // r0
__pid_t v4; // r4
int v5; // r3
__pid_t v6; // r5
int v7; // r4
int v8[5]; // [sp+4h] [bp-14h] BYREF

v8[0] = a2;
v8[1] = a3;
PID = fork(); // 这与fork函数的特性有关。fork调用的一个奇妙之处就是它仅仅被调用一次,却能够返回两次,它可能有三种不同的返回值:
v4 = PID; // 1)在父进程中,fork返回新创建子进程的进程ID;
// 2)在子进程中,fork返回0;
// 3)如果出现错误,fork返回一个负值;
if ( PID >= 0 )
{
if ( !PID ) // 如果是在子进程中 那么PID的值等于0 if成立
{
wait(0); // wait(0)和wait()方法的实际意义是一样的,都表示在没有唤醒的情况下该线程一直处于等待状态
v6 = getppid(); // getppid返回父进程标识
v7 = ptrace(PTRACE_ATTACH, v6); // PTRACE_ATTACH,追踪指定pid的进程 附加父进程 应该是附加成功返回0 失败返回-1
if ( !v7 )
{
// 这里为什么要waitpid 就是因为尝试附加到PID指定的进程上 附加成功后
// 目标进程将处于挂起状态 此时被跟踪的进程将会发送SIGSTOP信号给跟踪者
// 跟踪者需要调用waitPID()以接受被跟踪进程传来的SIGSTOP信号
waitpid(v6, 0, 0); // 等待v6的子进程结束或者暂停 返回:如果成功,返回子进程的ID;如果option设置为WNOHANG,则为0;如果其他错误,则为-1
ptrace(PTRACE_CONT, v6, 0, 0); // 重新启动父进程
ptrace(PTRACE_DETACH, v6); // 结束跟踪
}
exit(v7); // 退出子进程
}
v8[0] = -1; // 然后父进程接着执行下面的流程
prctl(‘Yama’, PID); // 设置子线程的名字
prctl(4, 1); // PR_SET_DUMPABLE :arg2作为处理器标志dumpable被输入
kill(v4, 18); // 杀死子进程
waitpid(v4, v8, 0); // 对杀死子进程返回的信号进行处理 v8 储存返回的状态
PID = prctl(4, 0); // 1: 阻塞等待子进程
// 2: 回收子进程资源
// 3: 获取子进程结束状态:1)WIFEXITED()真
//
// WEXITSTATUS()获取子进程退出状态
//
// 2)WIFSIGNALED() 真
//
// WTERMSIG()获取导致子进程终止的信号的
v5 = v8[0];
if ( v8[0] )
v5 = 1;
dword_4004 = v5;
}
return PID;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值