curl_easy_perform缓冲区溢出

时间:2015-10-21 10:10:53

标签: c++ windows curl buffer-overflow

我的问题是,在我的程序的一部分中,双变量在一台特定(虚拟)计算机(而不是任何其他计算机)上被错误地设置为2.71179e-308。没有崩溃或类似的事情。经过大量工作后,我将问题缩小到调用curl_easy_perform(调用与所述变量没有其他连接)。如果我伪造curl_easy_perform调用并在执行之前返回,则不修改变量。

我的第一个想法是回调写入功能存在一些问题,但看起来很长很难看,我找不到任何错误,用空函数替换它仍然没有帮助错误。 / p>

我的第二个想法是,在使用之前,我的卷曲设置字符串可能超出了范围,但在我的卷曲版本(7.43.0)中,它们应该由curl本身复制和存储。

现在我处于斗智斗勇的状态,所以转向SO以寻找可能出错的某种暗示。这是我用于所有通信的类的代码;

部首:

#include <string>

class HTTPClient
{
public:
    enum Verb
    {
        V_GET,
        V_POST,
        V_PUT,
        V_DELETE,
    };

    // Constructor is not thread safe. Make sure to initialize in main thread.
    HTTPClient(const std::string& userAgent, const std::string& certPath, const std::string& cookieFile, const std::string& proxy = "");
    ~HTTPClient(void);

    int MakeRequest(Verb verb, const std::string& url, int& responseCode, std::string& response);

private:

    static size_t WriteFunction(void *ptr, size_t size, size_t nmemb, void *custom);

    void* m_curl;
};

来源:

#include "HTTPClient.h"
#include <curl/curl.h>

HTTPClient::HTTPClient(const std::string& userAgent, const std::string& certPath, const std::string& cookieFile, const std::string& proxy)
{
    curl_global_init(CURL_GLOBAL_DEFAULT);
    m_curl = curl_easy_init();

    if (m_curl)
    {
        // Indicate where the certificate is located
        curl_easy_setopt(m_curl, CURLOPT_CAINFO, certPath.c_str());

        // Indicate where the cookie file is located
        curl_easy_setopt(m_curl, CURLOPT_COOKIEFILE, cookieFile.c_str());
        curl_easy_setopt(m_curl, CURLOPT_COOKIEJAR, cookieFile.c_str());

        // Set user agent
        curl_easy_setopt(m_curl, CURLOPT_USERAGENT, userAgent.c_str());

        // Set the response function
        curl_easy_setopt(m_curl, CURLOPT_WRITEFUNCTION, &HTTPClient::WriteFunction);

        // Set proxy if specified
        if (!proxy.empty())
            curl_easy_setopt(m_curl, CURLOPT_PROXY, proxy.c_str());
    }
}


HTTPClient::~HTTPClient(void)
{
    if (m_curl)
        curl_easy_cleanup(m_curl);
    curl_global_cleanup();
}

int HTTPClient::MakeRequest(Verb verb, const std::string& url, int& responseCode, std::string& response)
{
    std::string protocol, server, path, parameters;

    if (!m_curl)
        return CURLE_FAILED_INIT;

    // Set response data
    response.clear();
    curl_easy_setopt(m_curl, CURLOPT_WRITEDATA, &response);

    switch (verb)
    {
    case V_GET:
        curl_easy_setopt(m_curl, CURLOPT_CUSTOMREQUEST, "GET"); 
        curl_easy_setopt(m_curl, CURLOPT_URL, url.c_str());
    break;

    // Other cases removed for brevity
    }

    // Execute command
    CURLcode res = curl_easy_perform(m_curl); // <-- When this executes the variable gets damaged

    // Get response code
    long code;
    curl_easy_getinfo(m_curl, CURLINFO_RESPONSE_CODE, &code);
    responseCode = code;

    return res;
}

size_t HTTPClient::WriteFunction(void *ptr, size_t size, size_t nmemb, void *custom)
{
    size_t full_size = size * nmemb;
    std::string* p_response = reinterpret_cast<std::string*>(custom);

    p_response->reserve(full_size);
    for (size_t i=0; i<full_size; ++i)
    {
        char c = reinterpret_cast<char*>(ptr)[i];
        p_response->push_back(c);
    }

    return full_size;
}

修改 我现在已经使用WinDbg进行了测试,并且发现了几乎所发生的事情(但不是如何解决问题)。

被删除的double是在mmx7寄存器中的发布版本中。然后,在调用curl_easy_perform之前但在WriteFunction调用curl_easy_perform之前,它不会被更改。

除了编译我自己的curl版本以便我可以更深入地调试我不知道如何解决这个问题。

0 个答案:

没有答案