Локальные статические переменные не инициализируются, если приложение загружается как dll.C++

Программы на C++. Форум разработчиков
Ответить
Anonymous
 Локальные статические переменные не инициализируются, если приложение загружается как dll.

Сообщение Anonymous »

У нас есть sandbox.exe, app.exe и app.dll. Если пользователи хотят запустить приложение, не изолированное в песочнице, они запускают app.exe. Если пользователи хотят запустить приложение в «песочнице», они запускают sandbox.exe, который загружает app.dll. См., например, загрузочное приложение chrome.exe, которое загружает chrome.dll.
Теперь мы хотим уменьшить количество распространяемых файлов, удалить app.dll и LoadLibraryA("app.exe").
Известно, что

Если указанный модуль является исполняемым модулем, статический импорт не загружается; вместо этого модуль загружается как будто с помощью LoadLibraryEx с флагом DONT_RESOLVE_DLL_REFERENCES.

Итак, мы загружаем исполняемый модуль, загружаем его ссылки на dll и инициализируем IAT (таблицу адресов импорта). Загруженное приложение работает нормально до тех пор, пока не потребуется инициализировать локальную статическую переменную.

Код: Выделить всё

int F() {
static const int ret = GetLastError() + 1;  // non zero value
return ret;
}
Дизассемблирование неоптимизированного инициализатора:

Код: Выделить всё

int F() {
00007FF7C27EA680  push        rdi
00007FF7C27EA682  sub         rsp,60h
00007FF7C27EA686  lea         rdi,[rsp+40h]
00007FF7C27EA68B  mov         ecx,8
00007FF7C27EA690  mov         eax,0CCCCCCCCh
00007FF7C27EA695  rep stos    dword ptr [rdi]
00007FF7C27EA697  lea         rcx,[__8398B9A9_core-win@cc (07FF7C3033B4Dh)]
00007FF7C27EA69E  call        __CheckForDebuggerJustMyCode (07FF7C239D00Ch)
static const int ret = GetLastError() + 1;  // non zero value
00007FF7C27EA6A3  mov         eax,18Ch
00007FF7C27EA6A8  mov         eax,eax
00007FF7C27EA6AA  mov         ecx,dword ptr [_tls_index (07FF7C2FA4C7Ch)]
00007FF7C27EA6B0  mov         rdx,qword ptr gs:[58h]
00007FF7C27EA6B9  mov         rcx,qword ptr [rdx+rcx*8]
00007FF7C27EA6BD  mov         eax,dword ptr [rax+rcx]
00007FF7C27EA6C0  cmp         dword ptr [$TSS0 (07FF7C2FA2500h)],eax
00007FF7C27EA6C6  jle         F+77h (07FF7C27EA6F7h)
00007FF7C27EA6C8  lea         rcx,[$TSS0 (07FF7C2FA2500h)]
00007FF7C27EA6CF  call        _Init_thread_header (07FF7C2399D80h)
00007FF7C27EA6D4  cmp         dword ptr [$TSS0 (07FF7C2FA2500h)],0FFFFFFFFh
00007FF7C27EA6DB  jne         F+77h (07FF7C27EA6F7h)
00007FF7C27EA6DD  call        qword ptr [__imp_GetLastError (07FF7C301D110h)]
00007FF7C27EA6E2  inc         eax
00007FF7C27EA6E4  mov         dword ptr [ret (07FF7C2FA24FCh)],eax
00007FF7C27EA6EA  lea         rcx,[$TSS0 (07FF7C2FA2500h)]
00007FF7C27EA6F1  call        _Init_thread_footer (07FF7C239AA87h)
00007FF7C27EA6F6  nop
По неизвестной причине eax получает 0, а $TSS0 — правильный 0 при первом cmp. Таким образом, 0

Подробнее здесь: https://stackoverflow.com/questions/797 ... ded-as-dll
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «C++»