多次运行应用程序时不同的基本块数

逆向工程 动态分析 发电机
2021-06-17 00:25:16

我一直在测试 DynamoRio 和minblox来进行覆盖率分析,我有一个问题,当我在 ping.exe(不传递参数)上多次运行 bbcount 示例时,我得到了不同数量的基本块,我我没有改变任何东西。

bbcoverage/minblox 也会发生同样的情况,我得到不同的跟踪,例如运行 100 次,我只得到 44 条完全相同的跟踪,其他的则完全不同(额外的/丢失的块)。

我也尝试过这个微不足道的程序:

int main(int argc, char* argv[]) {
    return 0;
}

bbcount 仍然产生不同的输出,它可能变化较少,但仍然会:

Instrumentation results:
     14075 basic block executions
       528 basic blocks needed flag saving
      1109 basic blocks did not

Instrumentation results:
     14075 basic block executions
       529 basic blocks needed flag saving
      1108 basic blocks did not

Instrumentation results:
     14159 basic block executions
       529 basic blocks needed flag saving
      1108 basic blocks did not

这种行为是预期的吗?我正在禁用 ASLR 的 Windows 上进行测试(使用 EMET)。

1个回答

这种行为是意料之中的。

对于ping,执行跟踪很大程度上取决于任何给定运行的网络。如果一次 ping 在 0.1 ms 内成功,则不能保证下一次也会在同一时间内成功。

Ping 使用非阻塞 IO 通过网络接收数据报。这意味着它会在退出之前反复尝试。相应地,您将获得这些运行的不同执行跟踪。

作为参考,这里是从 ReactOS 获取的 ping的相关代码片段。

/* Expect to receive ICMP echo reply */
FD_ZERO(&Fds);
FD_SET(IcmpSock, &Fds);
Timeval.tv_sec  = Timeout / 1000;
Timeval.tv_usec = Timeout % 1000;

do {
    Status = select(0, &Fds, NULL, NULL, &Timeval);
    if ((Status != SOCKET_ERROR) && (Status != 0))
    {
        Length = sizeof(From);
        Status = recvfrom(IcmpSock, Buffer, Size, 0, &From, &Length);

#ifndef NDEBUG
        printf("Received packet\n");
        DisplayBuffer(Buffer, Status);
        printf("\n");
#endif /* !NDEBUG */
    }
    else
        LostCount++;
    if (Status == SOCKET_ERROR)
    {
        if (WSAGetLastError() != WSAETIMEDOUT)
        {
            FormatOutput(IDS_COULD_NOT_RECV, WSAGetLastError());
            GlobalFree(Buffer);
            return FALSE;
        }
        Status = 0;
    }

    if (Status == 0)
    {
        FormatOutput(IDS_REQUEST_TIMEOUT);
        GlobalFree(Buffer);
        return TRUE;
    }

} while (!DecodeResponse(Buffer, Status, (PSOCKADDR_IN)&From));