Создаём форму весом 1,5 кб!

Discussion in 'С/С++, C#, Rust, Swift, Go, Java, Perl, Ruby' started by CraftR14, 26 Aug 2010.

Thread Status:
Not open for further replies.
  1. Jingo Bo

    Jingo Bo Member

    Joined:
    25 Oct 2009
    Messages:
    368
    Likes Received:
    51
    Reputations:
    7
    Загрузчик указывает, а берет из EXE, а в EXE это указывает компоновщик(linker) и адрес этот в нем можно менять.
     
  2. GRRRL Power

    GRRRL Power Moderator

    Joined:
    13 Jul 2010
    Messages:
    823
    Likes Received:
    185
    Reputations:
    84
    Для программиста, разрабатывающего софт на высокоуровневых языках, хороший ответ, больше вопросов не имею)
    Это значение - ImageBase в IMAGE_NT_HEADERS, правда, он изменяться может, если файл имеет таблицу перемещаемых элементов. В этом случае загрузчик может разместить файл по любому доступному адресу и скорректировать некоторые значения в памяти, руководствуясь этой таблицей, если этот адрес не равен ImageBase. Такое практически всегда происходит с dll-файлами.
     
    _________________________
    #22 GRRRL Power, 26 Aug 2010
    Last edited: 26 Aug 2010
  3. Redeemer

    Redeemer Member

    Joined:
    3 Jul 2010
    Messages:
    203
    Likes Received:
    24
    Reputations:
    1
    А как это противоречит моисм словам?

    Оно берется из ImageBase и почти всегда с ним совпадает. НО в редких случаях загрузчик может переместить модуль в памяти (поэтому он и называется Portable Executable) с использованием Relocation Table.

    P.S. Я не гуглю)
     
    1 person likes this.
  4. GRRRL Power

    GRRRL Power Moderator

    Joined:
    13 Jul 2010
    Messages:
    823
    Likes Received:
    185
    Reputations:
    84
    Ну, вы сказали, что нет вообще никакой структуры там, и в то же время там проекция PE. Противоречие есть)

    В предыдущем посте дописал, когда.
     
    _________________________
  5. Redeemer

    Redeemer Member

    Joined:
    3 Jul 2010
    Messages:
    203
    Likes Received:
    24
    Reputations:
    1
    Я искал в вашем вопросе подъ***у, поэтому в первую очередь подумал о рантаймовых структурах. А так конечно вы правы.

    Про DLL справедливо не всегда. Некоторые системные библиотеки грузятся всегда по одному адресу. К тому же (тут я могу ошибаться), существует способ явно указать загрузчику куда грузить модуль
     
  6. GRRRL Power

    GRRRL Power Moderator

    Joined:
    13 Jul 2010
    Messages:
    823
    Likes Received:
    185
    Reputations:
    84
    Чаще всего происходит перемещение dll, потому что первым грузится сам exe файл, а после него dll'ки, из которых он импортирует функции, и адрес 0x400000, который так все любят ставить как ImageBase, может быть уже занят. Ну или одна дллка загрузилась по некоторому адресу, а следующая за ней уже не может быть загружена по нему же. DLL всегда должны иметь таблицу перемещаемых элементов, чтобы 100% успешно загрузиться.

    Существует - просто записать в IMAGE_NT_HEADERS, что файл не имеет перемещаемых элементов, тогда загрузчик будет вынужден грузить файл по ImageBase)
     
    _________________________
  7. Redeemer

    Redeemer Member

    Joined:
    3 Jul 2010
    Messages:
    203
    Likes Received:
    24
    Reputations:
    1
    К моменту загрузки EXE в памяти уже присутствуют как минимум ntdll.dll и Kernel32.dll, из последней кстати и вызывается EntryPoint.

    Не, я где-то слышал именно про программный способ. Хотя, повторюсь, возможно я и ошибаюсь.
     
  8. GRRRL Power

    GRRRL Power Moderator

    Joined:
    13 Jul 2010
    Messages:
    823
    Likes Received:
    185
    Reputations:
    84
    Вот вывод программы, которая показывает список модулей по порядку их загрузки
    [​IMG]
    Первый всегда exe.
     
    _________________________
    #28 GRRRL Power, 26 Aug 2010
    Last edited: 26 Aug 2010
  9. Redeemer

    Redeemer Member

    Joined:
    3 Jul 2010
    Messages:
    203
    Likes Received:
    24
    Reputations:
    1
    Загрузчик вызывает для вашей программы LoadLibrary для всех импортируемых библиотек.
    Но для Kernel32.dll LoadLibrary возвратит адрес практически мгновенно, так как она уже загружена.
    Пруф

    UPD. По материалам этой статьи можно написать EXE у которого вообще не будет таблицы импорта.
     
    #29 Redeemer, 26 Aug 2010
    Last edited: 26 Aug 2010
  10. GRRRL Power

    GRRRL Power Moderator

    Joined:
    13 Jul 2010
    Messages:
    823
    Likes Received:
    185
    Reputations:
    84
    Хех, скриншот выше как раз сделал с MessageBox'а, выводимого программой без импорта)

    А список загруженных модулей по порядку загрузки взят из Process Environment Block.

    Ну так сначала же надо сам exe загрузить, вдруг там вообще структуры имеют недопустимые значения в полях, LoadLibrary заранее-то зачем делать)
     
    _________________________
    #30 GRRRL Power, 26 Aug 2010
    Last edited: 26 Aug 2010
  11. Redeemer

    Redeemer Member

    Joined:
    3 Jul 2010
    Messages:
    203
    Likes Received:
    24
    Reputations:
    1
    Значит не будете отрицать что кернел уже присутствует в памяти к моменту старта программы?

    Сначала загружается EXE, потом загрузчик проходит по таблице импорта, здесь все верно. Но сам загрузчик уже находится в памяти
     
  12. GRRRL Power

    GRRRL Power Moderator

    Joined:
    13 Jul 2010
    Messages:
    823
    Likes Received:
    185
    Reputations:
    84
    К моменту старта - присутствует конечно, к моменту загрузки в память его еще нет.
     
    _________________________
  13. Redeemer

    Redeemer Member

    Joined:
    3 Jul 2010
    Messages:
    203
    Likes Received:
    24
    Reputations:
    1
    kernel32.dll проецируется в адресное пространство всех процессов в системе, поэтому она там будет еще до загрузки.

    Мы уже ушли в глубокий оффтоп, давайте завязывать
     
  14. _nic

    _nic Elder - Старейшина

    Joined:
    5 May 2006
    Messages:
    651
    Likes Received:
    54
    Reputations:
    3
    Чем вам CreateWindow неугодило?
     
  15. GRRRL Power

    GRRRL Power Moderator

    Joined:
    13 Jul 2010
    Messages:
    823
    Likes Received:
    185
    Reputations:
    84
    Отпишу последнее слово)


    На васме том же вот здесь http://www.wasm.ru/forum/viewtopic.php?pid=375916 приведен кусочек кода:
    Code:
    NTSTATUS LdrpInitializeProcess(CONTEXT* Context, HMODULE SystemDllBase)
    {
        ...
        IMAGE_NT_HEADERS* NtHeader = RtlImageNtHeader(Peb->ImageBaseAddress);
        ...
        if (NtHeader->OptionalHeader.Subsystem == IMAGE_SUBSYSTEM_WINDOWS_GUI  ||
            NtHeader->OptionalHeader.Subsystem == IMAGE_SUBSYSTEM_WINDOWS_CUI)
        {
            status = LdrLoadDll(Kernel32DllName, &KernelHandle);
            if (SUCCEEDED(status))
            {
                LdrGetProcedureAddress(Kernel32Handle,  Kernel32ThreadInitThunkName, &Kernel32ThreadInitThunk);         // "BaseThreadInitThunk"
                LdrGetProcedureAddress(Kernel32Handle,  Kernel32BaseQueryModuleDataName, &Kernel32BaseQueryModuleData); // "BaseQueryModuleData"
            }
    #if NTDDI >= NTDDI_WIN7
            if (status == STATUS_DLL_NOT_FOUND)
                status = LdrLoadDll(KernelBaseDllName, &KernelHandle);
    #endif
            if (FAILED(status))
                ...
        }
        ...
    
    из которого видно, что kernel32 (или kernelbase) грузится только после проверки подсистемы нашего exe, который, соответственно, к этому моменту должен быть в памяти уже (RtlImageNtHeader как раз принимает значение HINSTANSE (HMODULE) нашего exe).

    И не всех процессов, а только с подсистемой IMAGE_SUBSYSTEM_WINDOWS_GUI или IMAGE_SUBSYSTEM_WINDOWS_CUI, как опять-таки видно из кода.
     
    _________________________
    1 person likes this.
  16. Redeemer

    Redeemer Member

    Joined:
    3 Jul 2010
    Messages:
    203
    Likes Received:
    24
    Reputations:
    1
    Был не прав, признаю. Перепутал с ntdll
     
  17. slesh

    slesh Elder - Старейшина

    Joined:
    5 Mar 2007
    Messages:
    2,704
    Likes Received:
    1,224
    Reputations:
    455
    Пля, народ ну вы даете. Начали за здравие закончили за упокой.

    2 GRRRL Power нах ты так дале полез? МОжет давай вообще полезим в Shadow SDT чтобы поглядеться что там делает CreateWindows? И подкрепим всё исходниками из WRK.

    А нехера, вы ошиблись. в w7 вместо kernel32 там торчит kernelbase.
    Заугукали флудить. Тему закрываю. Следующий раз по сношу все сообщения. Хочется пообсуждать идите в чат
     
    1 person likes this.
Loading...
Thread Status:
Not open for further replies.