2011-02-03 3 views
0

누구든지이 기능에서 문제를 찾을 수 있습니까? 내 응용 프로그램에서 여러 요청을하고 첫 요청이 SSL을 사용하는 경우 응용 프로그램이 일부 컴퓨터에서 충돌합니다 (광산 4 컴퓨터 + VM웨어에서는 충돌없이 정상적으로 작동 함). 여기wininet에 문제가 있습니다.

코드

char Buffer[1024]; 
DWORD dwRead; 
string data; 

string Request(string method, string host, string file, string headers, 
       string post, bool debug, bool SSL) 
{ 
    HINTERNET hSession, hDownload, hRequest; 
    DWORD flag; 
    DWORD port; 

    data.empty(); 

    //SSL or not + flag :) 
    if (SSL) 
    { 
     port = INTERNET_DEFAULT_HTTPS_PORT; 
     flag = INTERNET_FLAG_SECURE; // FLAG_SECURE 
    } 
    else 
    { 
     port = INTERNET_DEFAULT_HTTP_PORT; 
     flag = INTERNET_FLAG_RELOAD; //FLAG_RELOAD 
    } 

    char * postdata; 
    postdata = new char[post.size() + 1]; 
    strcpy(postdata, post.c_str()); 
    char * headersdata; 
    headersdata = new char[headers.size() + 1]; 
    strcpy(headersdata, headers.c_str()); 

    //Actual request 
    hSession 
      = InternetOpen(
        "Mozilla/5.0 (Windows; U; Windows NT 6.1; sl; rv:1.9.2.11) Gecko/20101012 Firefox/3.6.11", 
        INTERNET_OPEN_TYPE_DIRECT, NULL, NULL, 0); 
    if (hSession) 
    { 
     hDownload = InternetConnect(hSession, host.c_str(), port, NULL, NULL, 
       INTERNET_SERVICE_HTTP, 0, 0); 
     if (hDownload) 
     { 
      hRequest = HttpOpenRequest(hDownload, method.c_str(), file.c_str(), 
        "HTTP/1.1", NULL, NULL, flag, 0); 
      if (hRequest) 
      { 
       if (strlen(headersdata) && strlen(postdata)) 
       { 
        HttpSendRequest(hRequest, headersdata, strlen(headersdata), 
          postdata, strlen(postdata)); 
       } 
       else 
       { 
        HttpSendRequest(hRequest, NULL, 0, NULL, 0); 
       } 
      } 
     } 
    } 
    //Writing HTML response in data buffer 
    while (InternetReadFile(hRequest, Buffer, sizeof(Buffer), &dwRead)) 
    { 
     if (dwRead == 0) 
     { 
      break; 
     } 
     Buffer[dwRead] = 0; 
     data += Buffer; 
    } 

    //Debug :) 
    if (debug) 
    { 
     ofstream dbgfile; 
     dbgfile.open("debug.html"); 
     dbgfile << data; 
     dbgfile.close(); 
    } 

    //Close handles 
    InternetCloseHandle(hSession); 
    InternetCloseHandle(hDownload); 
    InternetCloseHandle(hRequest); 

    return data; 
} 

감사합니다.

+0

충돌이 발생할 때 어떤 오류가 발생합니까? 액세스 위반? 다른 오류 코드가 있습니까? –

+0

오류 **이 응용 프로그램은 비정상적인 방식으로 종료하도록 런타임을 요청했습니다 ** ** 너무 나쁘면 디버깅 할 수 없습니다. ( – pwnu91

+0

원격 디버깅을 시도 할 수 있습니다 ... – smerlin

답변

0

우선, 버퍼 오버플로가 Buffer입니다.

는이 라인을 고려

while (InternetReadFile(hRequest, Buffer, sizeof(Buffer), &dwRead)) 

Buffer[dwRead] = 0; 

당신은 전 라인에 sizeof(Buffer)로 dwNumberOfBytesToRead 매개 변수를 전달하기 때문에

dwRead의 최대 값은 sizeof(Buffer)입니다. 이러한 경우가 발생하면 후자의 행은 Buffer 끝에서 1 바이트를 씁니다. 런타임 보안 검사를 사용하도록 설정하지 않은 경우 데이터 레이아웃을 사용하면 충돌이 발생할 가능성이 낮아집니다 (하지만 그럴 가능성이 있습니다!). 충돌 메시지를 설명 할 수는 없습니다.

또한 "이 응용 프로그램은 비정상적인 방식으로 프로그램을 종료하도록 요청했습니다."메시지가 assert() 또는 Microsoft 구현시 terminate()으로 표시됩니다. (나는 현재 MSVC를 사용할 수 없으며 그것을 확인할 수 없다). 나는이 코드의 어느 하나에 대한 이유를 보지 않는다. 따라서 만약 그것이 Buffer 오버플로가 아니라면 다른 곳에서도 찾아 보라.

+0

그것을 고정 :) 하지만 여전히 문제를 해결하지 ... ... ( 나는 그것이 일부 기계에서만 충돌하는 이유를 모르겠다 모든 ... – pwnu91

0

제거하려고 strlen 함수 : 함수가 조금 더 안전 할 것이다이 경우

HttpSendRequest(hRequest, &headers.front(), headers.size(), 
       &post.front(), post.size()); 

.

어쨌든 Crash Dump Analysis을 사용해보십시오. 이 경우 '일부 컴퓨터'에서 가져온 크래시 덤프에서 콜 스택을 확인할 수 있습니다.