我在使用 _popen(const char *, const char *)
时遇到问题
我正在尝试使用 awk 从 adb 获取信息,但我的程序在第二次 _popen 调用时崩溃(该方法被调用两次)。
这是有问题的代码(sysinf_getvalue()
在主程序中被多次调用)。
丑陋的代码
int deviceadbinfowritten = 0;
int devicebootloaderinfowritten = 0;
int adbinit = 0;
int initadb()
{
if(!adbinit)
{
system("adb kill-server && adb start-server");
adbinit = 1;
}
return 0;
}
int sysinfo_getadbinfofile()
{
if(!deviceadbinfowritten)
{
system("echo Please connect your device && adb wait-for-device && adb.exe shell getprop > deviceinfo");
deviceadbinfowritten = 1;
}
return 0;
}
int sysinfo_getbootloaderinfofile()
{
if(!devicebootloaderinfowritten)
{
system("adb wait-for-device && adb reboot bootloader && fastboot getvar all > bootloaderinfo && fastboot reboot");
devicebootloaderinfowritten = 1;
}
return 0;
}
char *sysinfo_getvalue(char *key, int bootloader)
{
initadb();
if(bootloader) sysinfo_getbootloaderinfofile();
else sysinfo_getadbinfofile();
char *file = (bootloader)?"bootloaderinfo":"deviceinfo";
char *command = malloc(sizeof(char) * (strlen("awk.exe -F\":\" \" { print $2 }\" < ") + strlen(key) + (bootloader)?0:2 + strlen(file)));
char *adbkey = malloc((strlen(key)+2)* (sizeof(char)));
if(!bootloader) sprintf(adbkey, "/%s/", key);
sprintf(command, "awk.exe -F\":\" \"%s { print $2 }\" < %s", ((bootloader)?key:adbkey), file);
printf("%s\n", command);
char *pointer = exe(command);
if(!bootloader)
{
pointer += 2;
pointer[strlen(pointer)-3] = 0;
}
return pointer;
}
char *exe(char *exe)
{
char buffer[1024];
FILE *f;
printf("debug %s\n", exe);
f = _popen(exe, "r");
printf("debug\n");
char *res = NULL;
printf("debug\n");
if (f == NULL) {
printf("[-] Failed to run command\n" );
return NULL;
}
printf("debug\n");
while (fgets(buffer, sizeof(buffer), f) != NULL) {
if(res == NULL) {res = malloc(strlen(buffer) * sizeof(char)); strcpy(res, buffer);}
else {res = realloc(res, strlen(res) * sizeof(char) + sizeof(buffer));sprintf(res, "%s%s", res, buffer);}
}
printf("debug\n");
_pclose(f);
return res;
}
注意:如果我使用提供的相同字符串在主程序中直接调用 exe()
,则 _popen 不会崩溃。
注意 2:调试器显示 "warning: HEAP[program.exe]:
警告:002D2EC0 处的堆 block 已在 002D2EC9 处修改,过去请求的大小为 1"
最佳答案
看起来好像您缺少为 0 终止符分配空间。
这是每个字符数组需要的最后一个附加字节,如果用作字符串以通过值为 NUL
(十进制 0
)的字符指示字符串的结尾。
至少这一行:
char *command = malloc(sizeof(char) * (strlen("awk.exe -F\":\" \" { print $2 }\" < ") + strlen(key) + (bootloader)?0:2 + strlen(file)));
再分配一个字符:
char *command = malloc(
sizeof(char) * (
strlen("awk.exe -F\":\" \" { print $2 }\" < ") +
strlen(key) +
(bootloader)?0:2 + strlen(file)) +
1
)
);
(对于此类问题,我没有检查您代码中字符数组的所有分配/分配。)
关于调用多个 _popen 失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14424141/