Как отлаживать 32-х битный код в 64-битной системе

Тема в разделе "WASM.X64", создана пользователем lhc645, 22 май 2010.

  1. lhc645

    lhc645 New Member

    Публикаций:
    0
    Регистрация:
    9 авг 2009
    Сообщения:
    106
    Как отлаживать 32-х битный код в 64-битной системе.

    В связи с возникновением вопросов о работе 32-х битного кода в 64-битной системе создана эта тема.
    Общий обзор wow64 есть в msdn

    "Running 32-bit Applications"

    Краткий очерк.
    К 32-х битному процессу, работающему в 64-битной ОС подгружаются 32-х битные dll из директории SysWow64. Внутри 32-битной ntdll каждый вызов системного сервиса выглядит примерно так

    Код (Text):
    1. .text:7D61CF22 _NtCreateThread@32 proc near            ; CODE XREF: RtlCreateUserThread(x,x,x,x,x,x,x,x,x,x)+FBp
    2. .text:7D61CF22                                         ; DATA XREF: .text:off_7D612068o
    3. .text:7D61CF22
    4. .text:7D61CF22 arg_0           = byte ptr  4
    5. .text:7D61CF22
    6. .text:7D61CF22                 mov     eax, 4Bh        ; NtCreateThread
    7. .text:7D61CF27                 xor     ecx, ecx
    8. .text:7D61CF29                 lea     edx, [esp+arg_0]
    9. .text:7D61CF2D                 call    large dword ptr fs:0C0h
    10. .text:7D61CF34                 retn    20h
    11. .text:7D61CF34 _NtCreateThread@32 endp
    Переход осуществляется по адресу fs:0C0h. Здесь лежит межсегментный переход на wow64cpu!CpupReturnFromSimulatedCode.
    После этого выполняется уже 64 битный код.Далее управление передается Wow64SystemServiceEx, а та, в свою очередь выбирает из нескольких таблиц

    sdwhnt32JumpTable (сервисы)
    sdwhbaseJumpTable (csr)

    следующие 2 таблицы эспортируются wow64win.dll

    sdwhconJumpTable (консоль)
    sdwhwin32JumpTable (gdi и user)

    а потом переходит на нужный сервис из той или иной таблицы.

    Вызов функций/сервисов

    Обработчики для вызовов сервисов внутри wow64.dll и wow64win.dll имеют приставку wh+имя сервиса.

    Для sdwhnt32JumpTable

    Код (Text):
    1. ...
    2. whNtAddAtom
    3. whNtAlertThread
    4. whNtCreateThread
    5. whNtCreateThreadEx
    6. whNtCreateUserProcess
    7. ...
    sdwhbaseJumpTable

    Код (Text):
    1. whNtWow64CsrBasepSoundSentryNotification                                        
    2. whNtWow64CsrBasepRefreshIniFileMapping
    3. whNtWow64CsrBasepDefineDosDevice
    4. whNtWow64CsrBasepGetTempFile
    5. whNtWow64CsrBasepCreateProcess
    6. whNtWow64CsrBasepExitProcess
    7. whNtWow64CsrBasepCreateThread
    8. ...
    sdwhconJumpTable

    Код (Text):
    1. whOpenConsoleWInternal
    2. whReadConsoleInternal
    3. whWriteConsoleInternal
    4. whCloseConsoleHandle
    5. whDuplicateConsoleHandle
    6. whGetConsoleHandleInformation
    7. ...
    sdwhwin32JumpTable

    Код (Text):
    1. whNtUserPeekMessage
    2. whNtUserCallOneParam
    3. whNtUserGetKeyState
    4. whNtUserInvalidateRect
    5. whNtUserCallNoParam
    6. whNtUserGetMessage
    7. whNtUserMessageCall
    8. whNtGdiBitBlt
    9. whNtGdiGetCharSet
    10. whNtUserGetDC
    11. whNtGdiSelectBitmap
    12. ...
    и так далее.

    Этих функций нет в экспорте, но они есть в символах. Следовательно, для отладки вашего приложения вам понадобятся символы для ОС и Windbg x64. Если возникает вопрос почему та или иная функция в wow64 работает не так, как в 32-битной ОС нужно сначала трейсить эти функции (windbg прекрасно подходит для этих целей).


    Скорее всего тема будет полезна в этом разделе, поэтому прошу закрепить.
     
  2. lhc645

    lhc645 New Member

    Публикаций:
    0
    Регистрация:
    9 авг 2009
    Сообщения:
    106
    Вывод таблиц обработчиков wow64 и wow64cpu

    Для просмотра содержимого *JumpTable в windbg можно использовать команду x.

    Несколько примеров.

    1) Будут выведены все функции начинающиеся с whNtUser из wow64win.dll

    Код (Text):
    1. x wow64win!whNtUser*
    2) Все функции из wow64, начинающиеся с whNt

    Код (Text):
    1. x wow64!whNt*
    3) Функции wow64win, начинающиеся с wh имеющие в названии Console

    Код (Text):
    1. x wow64win!wh*Console*
    Возможность логирования wow64

    В wow64.dll предусмотрена возможность загрузки dll логировщика wow64log.dll. Ей должны экспортироваться 4 функции

    Wow64LogInitialize
    Wow64LogSystemService
    Wow64LogMessageArgList
    Wow64LogTerminate

    Для отладки это может быть также очень полезно. Логировщик вызывается время выполнения wh* обработчиков и некоторых других внутренних функций.
    В стандартной поставке винды этой либы нет, но написать свой логировщик труда не составит.
     
  3. madshus

    madshus New Member

    Публикаций:
    0
    Регистрация:
    21 май 2009
    Сообщения:
    10
    Доброго внемени суток! Прошу прощения, если вопрос чайницкий, но сходу не смог найти ничего путного. Есть программа, работающая под WOW64. С ее отладкой проблем не возникает, однако если программа подгружает в свое адресное пространство dll, и эта dll попадает в старшие виртуальные адреса (> 00000000`7FFFFFFF) возникает некоторое неудобство. Можно поставить в ней точку останова - отладчик всплывает:
    Код (Text):
    1. 0:011> !wow64exts.sw
    2. Switched to 32bit mode
    3. 0:011:x86> g
    4. (1064.b78): WOW64 breakpoint - code 4000001f (first chance)
    5. First chance exceptions are reported before any exception handling.
    6. This exception may be expected and handled.
    7. fc84adb0 ??              ???
    и даже слушается команд трассировки (если удалить бряк)
    Код (Text):
    1. 0:011:x86> bd 1
    2. 0:011:x86> p
    3. fc84adb1 ??              ???
    4. 0:011:x86> p
    5. fc84adb2 ??              ???
    однако, как видно, напрочь отказвается читать и декодировать код, хотя декодировать все же можно
    Код (Text):
    1. 0:011:x86> u %fc84adb2
    2. mydll+0x2ebdb2:
    3. fc84adb2 57              push    edi
    4. fc84adb3 55              push    ebp
    5. fc84adb4 83ec08          sub     esp,8
    Может, кто сталкивался? Как бороться? Заранее благодарен.