过去一周我一直在尝试解决一个兵棋推演——我得到了一个程序,需要找到正确的输入(通常是格式错误的、恶意的或其他)才能让它执行我想要的代码。我一直在努力解决以下问题,想看看这里是否有人有建议或想法可以尝试。代码如下
unsigned long long passcode = 0xbadc0dedecadeull, code = 0, v;
int finished = 0;
void* tryAllCodes(void* ptr) {
char** codes = (char**) ptr;
while(*++codes) {
printf(".");
v = strtoull(*codes, 0, 16); // v is stored in ebx:ecx
code = (v != passcode)? v : 0;
}
finished = 1;
}
int main(int argc, char** argv) {
char *args[] = { "/bin/sh", 0};
pthread_t t;
pthread_create(&t, NULL, tryAllCodes, argv);
while(!finished)
if(code == passcode) { // code is stored in ebx:ecx
printf("Win!\n");
execve(*args, args, 0);
}
pthread_join(t, NULL);
return 0;
}
我相信这里存在竞争条件,因为在访问变量代码时没有互斥锁,我已经通过在 tryAllCodes 函数中使用 gdb 设置断点并让主线程继续运行来实现它。我相信这是因为 v 和 code 在检查它们的值时存储在其中的寄存器是相同的,所以如果上下文跳出 tryAllCodes 并且 v 在它被清零之前设置为密码,我会进入 win 块。不幸的是,我需要在不使用调试器的情况下获得相同的行为 - 所以我的问题是我利用竞争条件的方法似乎正确,还是我忽略了其他一些东西?如果是这样,linux 上有没有办法让线程更频繁地执行?我在 tryAllCodes 线程上尝试了 renice,但它似乎只是导致程序在主循环中旋转。
谢谢一堆