问题描述:

I am having a problem with _popen(const char *, const char *)

I'm trying to use awk to get infos from adb but my program crashes at the second _popen call (the method is called twice).

Here is the problematic code (sysinf_getvalue() is called multiple times in the main).


Ugly code

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;

}

NOTE : If I directly call exe() in the main with the same string supplied _popen doesn't crash.

NOTE 2 : Debugger says "warning: HEAP[program.exe]:

warning: Heap block at 002D2EC0 modified at 002D2EC9 past requested size of 1"

网友答案:

It looks as if you are missing to allocate room for the 0-terminator.

That is the one last additional byte every character array needs if used as string to indicate the end of the string by a character of value NUL (decimal 0).

At least this line:

char *command = malloc(sizeof(char) * (strlen("awk.exe -F\":\" \" { print $2 }\" < ") + strlen(key) + (bootloader)?0:2 + strlen(file)));

shall allocate one character more:

char *command = malloc(
  sizeof(char) * (
    strlen("awk.exe -F\":\" \" { print $2 }\" < ") + 
    strlen(key) + 
    (bootloader)?0:2 + strlen(file)) + 
    1
  )
);

(I did not check all allocations/delcaration of character arrays in your code, for issues like this.)

网友答案:

I found out in this link C++ system() not working when there are spaces in two different parameters that you need to encapsulate all your system calls with quotes if you want them to work properly. For example in my code I need to use exe("\"mycommand\""); instead of exe("mycommand");

相关阅读:
Top