Форум программистов, компьютерный форум CyberForum.ru

C++

Войти
Регистрация
Восстановить пароль
 
Рейтинг: Рейтинг темы: голосов - 9, средняя оценка - 4.89
soMan
0 / 0 / 0
Регистрация: 26.02.2012
Сообщений: 5
#1

SIGINT с OpenSSL - C++

26.02.2012, 20:17. Просмотров 1120. Ответов 6
Метки нет (Все метки)

Приветствую всех! Натыкаюсь в программе (обычная однопоточная консолька, делащая несколько запросиков) на SIGINT. Программа использует libCURL (+ OpenSSL + zlib). Натыкаюсь, только если использую соединение к защищенным ресурсам (HTTPS). Обращаясь только к HTTP процесс завершается нормально без ошибок.
Прогнал через профилирование в Dependency Walker и увидел две ошибки:
GetProcAddress(0x767F0000 [KERNEL32.DLL], "CloseToolhelp32Snapshot") called from "LIBEAY32.DLL" at address 0x630825C2 and returned NULL by thread 1 (127).
127 ошибка говорит нам, что такой функции нету в дллке. MSDN и исходники OpenSSL подсказывают, что эта функция используется на WinCe, при этом макросы для WinCe при сборке OpenSSL я не использовал. Вторая ошибка похожая, только с функцией _OPENSSL_isservice. Ее я решил пересобрав OpenSSL с макросом _WIN32_WINNT. Как решить первую не знаю. Насколько понимаю, эта ошибка и является причиной SIGINT.

А также:
- Без отладки и запуска вне IDE это выглядит как стандартное окошко ошибки винды после отработки программы.
- Все либы собирал самостоятельно из исходников.
- Юзал в программе ключи линкера -libgcc, -libstdc++ - ничего не изменилось.

Просьба, подскажите, куда копать или как решить данный вопрос.
Допинфо:
Компилятор: gcc 4.6.2 (MinGW)
IDE: Eclipse CDT 3.7.2
ОС: Win 7 Pro x86
Либы: libCURL 7.24.0, OpenSSL 1.0.0g, zlib 1.2.6
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
niXman
Эксперт C++
3134 / 1446 / 49
Регистрация: 09.08.2009
Сообщений: 3,441
Записей в блоге: 2
26.02.2012, 21:29     SIGINT с OpenSSL #2
посмотри, в kernel32.dll есть экспорт CloseToolhelp32Snapshot ?

Цитата Сообщение от soMan Посмотреть сообщение
пересобрав OpenSSL с макросом _WIN32_WINNT.
макросу _WIN32_WINNT нужно задать конкретное значение: http://msdn.microsoft.com/en-us/libr...(v=vs.85).aspx
soMan
0 / 0 / 0
Регистрация: 26.02.2012
Сообщений: 5
26.02.2012, 22:27  [ТС]     SIGINT с OpenSSL #3
посмотри, в kernel32.dll есть экспорт CloseToolhelp32Snapshot
Нету.
макросу _WIN32_WINNT нужно задать конкретное значение
Пересобирал с -D_WIN32_WINNT=0x602, а также с -D_WIN32_WINNT_WIN7 - стала появляться еще и предыдущая
GetProcAddress(0x00400000 [APP.EXE], "_OPENSSL_isservice") called from "LIBEAY32.DLL" at address 0x63001715 and returned NULL by thread 1
Кстати в INSTALL.W32 о _OPENSSL_isservice написано:
If you link with static OpenSSL libraries [those built with ms/nt.mak],
then you're expected to additionally link your application with
WS2_32.LIB, ADVAPI32.LIB, GDI32.LIB and USER32.LIB. Those developing
non-interactive service applications might feel concerned about linking
with the latter two, as they are justly associated with interactive
desktop, which is not available to service processes. The toolkit is
designed to detect in which context it's currently executed, GUI,
console app or service, and act accordingly, namely whether or not to
actually make GUI calls. Additionally those who wish to
/DELAYLOAD:GDI32.DLL and /DELAYLOAD:USER32.DLL and actually keep them
off service process should consider implementing and exporting from
.exe image in question own _OPENSSL_isservice not relying on USER32.DLL.
E.g., on Windows Vista and later you could:

C
1
2
3
4
5
6
7
__declspec(dllexport) __cdecl BOOL _OPENSSL_isservice(void)
{
    DWORD sess;
    if (ProcessIdToSessionId(GetCurrentProcessId(),&sess))
        return sess==0;
    return FALSE;
}
If you link with OpenSSL .DLLs, then you're expected to include into
your application code small "shim" snippet, which provides glue between
OpenSSL BIO layer and your compiler run-time. Look up OPENSSL_Applink
reference page for further details.
Не очень вот пойму, что же я все-таки должен сделать.
Makefile, по которому собирал.
niXman
Эксперт C++
3134 / 1446 / 49
Регистрация: 09.08.2009
Сообщений: 3,441
Записей в блоге: 2
26.02.2012, 22:54     SIGINT с OpenSSL #4
мои фантазии исчерпаны..
soMan
0 / 0 / 0
Регистрация: 26.02.2012
Сообщений: 5
26.02.2012, 23:03  [ТС]     SIGINT с OpenSSL #5
Приведу куски кода из исходничков, может, чем-нибудь помогут.
Юзание GetProcAddress(dll,"CreateToolhelp32Snapshot");
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
#include <tlhelp32.h>
#ifdef _WIN32_WCE
# define DLLNAME "TOOLHELP.DLL"
#else
# ifdef MODULEENTRY32
# undef MODULEENTRY32   /* unmask the ASCII version! */
# endif
# define DLLNAME "KERNEL32.DLL"
#endif
 
typedef HANDLE (WINAPI *CREATETOOLHELP32SNAPSHOT)(DWORD, DWORD);
typedef BOOL (WINAPI *CLOSETOOLHELP32SNAPSHOT)(HANDLE);
typedef BOOL (WINAPI *MODULE32)(HANDLE, MODULEENTRY32 *);
 
static int win32_pathbyaddr(void *addr,char *path,int sz)
    {
    HMODULE dll;
    HANDLE hModuleSnap = INVALID_HANDLE_VALUE; 
    MODULEENTRY32 me32; 
    CREATETOOLHELP32SNAPSHOT create_snap;
    CLOSETOOLHELP32SNAPSHOT  close_snap;
    MODULE32 module_first, module_next;
    int len;
 
    if (addr == NULL)
        {
        union   { int(*f)(void*,char*,int); void *p; } t =
            { win32_pathbyaddr };
        addr = t.p;
        }
 
    dll = LoadLibrary(TEXT(DLLNAME));
    if (dll == NULL)
        {
        DSOerr(DSO_F_WIN32_PATHBYADDR,DSO_R_UNSUPPORTED);
        return -1;
        }
 
    create_snap = (CREATETOOLHELP32SNAPSHOT)
        GetProcAddress(dll,"CreateToolhelp32Snapshot");
    if (create_snap == NULL)
        {
        FreeLibrary(dll);
        DSOerr(DSO_F_WIN32_PATHBYADDR,DSO_R_UNSUPPORTED);
        return -1;
        }
    /* We take the rest for granted... */
#ifdef _WIN32_WCE
    close_snap = (CLOSETOOLHELP32SNAPSHOT)
        GetProcAddress(dll,"CloseToolhelp32Snapshot");
#else
    close_snap = (CLOSETOOLHELP32SNAPSHOT)CloseHandle;
#endif
    module_first = (MODULE32)GetProcAddress(dll,"Module32First");
    module_next  = (MODULE32)GetProcAddress(dll,"Module32Next");
 
    hModuleSnap = (*create_snap)(TH32CS_SNAPMODULE,0); 
    if( hModuleSnap == INVALID_HANDLE_VALUE ) 
        { 
        FreeLibrary(dll);
        DSOerr(DSO_F_WIN32_PATHBYADDR,DSO_R_UNSUPPORTED);
        return -1;
        } 
 
    me32.dwSize = sizeof(me32); 
 
    if(!(*module_first)(hModuleSnap,&me32)) 
        { 
        (*close_snap)(hModuleSnap);
        FreeLibrary(dll);
        DSOerr(DSO_F_WIN32_PATHBYADDR,DSO_R_FAILURE);
        return -1;
        }
 
    do  { 
        if ((BYTE *)addr >= me32.modBaseAddr &&
            (BYTE *)addr <  me32.modBaseAddr+me32.modBaseSize)
            {
            (*close_snap)(hModuleSnap);
            FreeLibrary(dll);
#ifdef _WIN32_WCE
# if _WIN32_WCE >= 101
            return WideCharToMultiByte(CP_ACP,0,me32.szExePath,-1,
                            path,sz,NULL,NULL);
# else
            len = (int)wcslen(me32.szExePath);
            if (sz <= 0) return len+1;
            if (len >= sz) len=sz-1;
            for(i=0;i<len;i++)
                path[i] = (char)me32.szExePath[i];
            path[len++] = 0;
            return len;
# endif
#else
            len = (int)strlen(me32.szExePath);
            if (sz <= 0) return len+1;
            if (len >= sz) len=sz-1;
            memcpy(path,me32.szExePath,len);
            path[len++] = 0;
            return len;
#endif
            } 
        } while((*module_next)(hModuleSnap, &me32)); 
 
    (*close_snap)(hModuleSnap); 
    FreeLibrary(dll);
    return 0;
    }
Функция OPENSSL_isservice
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
#if defined(_WIN32_WINNT) && _WIN32_WINNT>=0x0333
int OPENSSL_isservice(void)
{ HWINSTA h;
  DWORD len;
  WCHAR *name;
  static union { void *p; int (*f)(void); } _OPENSSL_isservice = { NULL };
 
    if (_OPENSSL_isservice.p == NULL) {
    HANDLE h = GetModuleHandle(NULL);
    if (h != NULL)
        _OPENSSL_isservice.p = GetProcAddress(h,"_OPENSSL_isservice");
    if (_OPENSSL_isservice.p == NULL)
        _OPENSSL_isservice.p = (void *)-1;
    }
 
    if (_OPENSSL_isservice.p != (void *)-1)
    return (*_OPENSSL_isservice.f)();
 
    (void)GetDesktopWindow(); /* return value is ignored */
 
    h = GetProcessWindowStation();
    if (h==NULL) return -1;
 
    if (GetUserObjectInformationW (h,UOI_NAME,NULL,0,&len) ||
    GetLastError() != ERROR_INSUFFICIENT_BUFFER)
    return -1;
 
    if (len>512) return -1;     /* paranoia */
    len++,len&=~1;          /* paranoia */
    name=(WCHAR *)alloca(len+sizeof(WCHAR));
    if (!GetUserObjectInformationW (h,UOI_NAME,name,len,&len))
    return -1;
 
    len++,len&=~1;          /* paranoia */
    name[len/sizeof(WCHAR)]=L'\0';  /* paranoia */
#if 1
    /* This doesn't cover "interactive" services [working with real
     * WinSta0's] nor programs started non-interactively by Task
     * Scheduler [those are working with SAWinSta]. */
    if (wcsstr(name,L"Service-0x")) return 1;
#else
    /* This covers all non-interactive programs such as services. */
    if (!wcsstr(name,L"WinSta0"))   return 1;
#endif
    else                return 0;
}
#else
int OPENSSL_isservice(void) { return 0; }
#endif
niXman
Эксперт C++
3134 / 1446 / 49
Регистрация: 09.08.2009
Сообщений: 3,441
Записей в блоге: 2
27.02.2012, 02:12     SIGINT с OpenSSL #6
запутался... давай с начала.
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
27.02.2012, 13:17     SIGINT с OpenSSL
Еще ссылки по теме:

C++ сигналы SIGINT SIGABORT
SMTP клиент и OpenSSL C++
OpenSsl и bio интерфейс C++
Сборка OpenSSL под Windows
C++ OpenSSL & Module

Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
soMan
0 / 0 / 0
Регистрация: 26.02.2012
Сообщений: 5
27.02.2012, 13:17  [ТС]     SIGINT с OpenSSL #7
запутался... давай с начала.
Весь вопрос в том, что как побороть
GetProcAddress(0x767F0000 [KERNEL32.DLL], "CloseToolhelp32Snapshot") called from "LIBEAY32.DLL" at address 0x630825C2 and returned NULL by thread 1 (127).
Может, какие-то еще макросы не задал или еще что?
В таблице экспортов kernel32.dll нет такой функции.
Конфигурил в MSYS как configure threads shared zlib-dynamic mingw. Вот Makefile, в корне папки OpenSSL, который я и собираю.
Куски кода выше привел из исходникой самого OpenSSL. В одном из приведенных кусков и используется GetProcAddress(0x767F0000 [KERNEL32.DLL], "CloseToolhelp32Snapshot"), который вызывает у меня ошибку. При этом, если макрос _WINCE не задан при сборке, то библиотека, из которой пытаются достать эту функцию задана как KERNEL32.DLL. Вот, собственно и вся проблема, ноги которой пока не выяснил откуда растут.
Yandex
Объявления
27.02.2012, 13:17     SIGINT с OpenSSL
Ответ Создать тему
Опции темы

Текущее время: 11:56. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru