Узнать новые rva недокументированных функций.

Тема в разделе "WASM.BEGINNERS", создана пользователем Fduch, 4 май 2009.

  1. Fduch

    Fduch New Member

    Публикаций:
    0
    Регистрация:
    10 авг 2006
    Сообщения:
    13
    Имеется такая проблема. Есть код на с++ с забитой руками таблицей rva пары сотен функций одной библиотеки (uDWM.dll). Выглядит примерно так:
    Код (Text):
    1. typedef enum
    2. {
    3.     // names
    4.     rva_CDesktopManager__s_pDesktopManagerInstance                                       = 0x00030068,
    5.     rva_CDesktopManager__s_csDwmInstance                                 = 0x000300F0,
    6.  
    7.     // functions
    8.     rva_AccessibleObjectFromWindow                                                       = 0x000286EA,
    9.     rva_AreAllMarginsZero                                                                = 0x00008477,
    10.     rva_AssertW                                                                          = 0x00027FB6,
    11.     rva_AvCreateProcessHeap                                                              = 0x00018754,
    12.     rva_AvDestroyProcessHeap                                                             = 0x00027B6C,
    Я не очень хорошо разбираюсь в этом, но uDWM.dll экспортирует эти функции, как минимум без имён (а возможно, что и без ординалов (не знаю может ли такое быть)), так что программы, которые показывают экспорты, выводят пустой список. Код использует эти значения для доступа к данным и вызова функций напрямую. Выглядит это так:
    Код (Text):
    1. #define PE_RvaToVa(handle, rva)             ((void *)((DWORD)handle + (DWORD)rva))
    2.  
    3.     HANDLE  hUDWM = GetModuleHandle(_T("udwm.dll"));
    4.     CDesktopManager *pdm = *(CDesktopManager **)PE_RvaToVa(hUDWM, rva_CDesktopManager__s_pDesktopManagerInstance);
    5.     SuspendThread(pdm->hMessageLoopThread);
    Код (Text):
    1. DWORD   CBaseObject::UDWM_CallMethodEAX(void *thisObj, UDWM_RVAs methodRva, ...)
    2. {
    3.    DWORD retVal;
    4.    void *methodAddr = CBaseObject::UDWM_GetMethodAddr(methodRva);
    5.  
    6.    __asm
    7.    {
    8.     pushad
    9.  
    10.     mov  eax, [ebp + 4]     // get current ret addr
    11.     xor  ecx, ecx           // clear ecx
    12.     mov  cl, [eax + 2]      // read the add opcode parameter (which is actually the number of args * 4)
    13.     sub  cl, 8          // don't count thisptr and address
    14.     sub  esp, ecx           // reserve the new stack frame
    15.     shr  ecx, 2         // set the counter to the correct number of params
    16.     lea  esi, [methodRva + 4]   // set the source (the var args)
    17.     mov  edi, esp           // set the destination (the newly created stack frame)
    18.     rep  movsd          // copy
    19.     mov  eax, thisObj       // mov this
    20.     call methodAddr
    21.     mov  retVal, eax
    22.  
    23.     popad
    24.     }
    25.  
    26.    return (retVal);
    27. }
    28. int CResource::Initialize(MIL_RESOURCE_TYPE type, MIL_CHANNEL channel)
    29. {
    30.     return (UDWM_CallMethodEAX(this, rva_CResource_Initialize, type, channel));
    31. }
    Проблема: мне нужно получить таблицу этих rva_* констант для новой версии библиотеки. В идеале вообще научиться находить эти значения в рантайме. Как?
     
  2. Mika0x65

    Mika0x65 New Member

    Публикаций:
    0
    Регистрация:
    30 июл 2005
    Сообщения:
    1.384
    Каким-то образом dll должна что-то экспортировать. Либо по именам, либо по ординалам. Можно, конечно, предположить, что создатели библиотеки были ребятами с юмором и сделали свой экспорт, но это маловероятно. Ну или библиотека упакована, например.

    Т.к. информации маловато, то предположу, что RVA новой экспортов библиотеки надо получить тем же путем, как были получены RVA старой версии библиотеки :). Или просто выложите библиотеку куда-нибудь, можно будет посмотреть, что и как она экспортирует.

    P.S. А затачиваться на то, что сразу за вызовом идет очистка стека -- нехорошо. gcc, например, может очистку стека передвинуть намного дальше относительно вызова ф-ии.
     
  3. n0name

    n0name New Member

    Публикаций:
    0
    Регистрация:
    5 июн 2004
    Сообщения:
    4.336
    Адрес:
    Russia
    Очень часто плагинная система на этом и строится, что плагины запрашивают адреса неэкспортируемых функций.
     
  4. Fduch

    Fduch New Member

    Публикаций:
    0
    Регистрация:
    10 авг 2006
    Сообщения:
    13
    /Windws/System32/uDWM.dll - стандартная библиотека, входящая в Windows Vista и выше. В основном её использует /Windws/System32/dwm.exe (композитный оконный менеджер). Думаю, что здесь всё несложно. Библиотека неупакована.
    Это и хочется узнать =)
    Выкладываю четыре версии (6.0.6000.16386, 6.0.6001.18000, 6.0.6002.16670 и 6.1.7100.0), а также хедер с таблицей для 6.0.6000 : http://rapidshare.com/files/229006862/uDWM.rar.html
     
  5. Mika0x65

    Mika0x65 New Member

    Публикаций:
    0
    Регистрация:
    30 июл 2005
    Сообщения:
    1.384
    Посмотрел экспорт, экспортируется только три ф-ии, по ординалу. В самом худшем случае нужен реверс :). А как выглядит "CBaseObject::UDWM_GetMethodAddr"? А то не совсем понятно, зачем она нужна -- rva ф-ии и так известен, что там еще считать? Может, в ней какой-то намек есть, как получить адреса наиболее простым путем.
     
  6. Fduch

    Fduch New Member

    Публикаций:
    0
    Регистрация:
    10 авг 2006
    Сообщения:
    13
    Mika0x65

    К сожалению, CBaseObject::UDWM_GetMethodAddr - совсем неинтересная функция:
    Код (Text):
    1. HMODULE CBaseObject::hUDwm = GetModuleHandle(_T("uDWM.dll"));
    2.  
    3. void    *CBaseObject::UDWM_GetMethodAddr(UDWM_RVAs methodRva)
    4. {
    5.         // we know what we are doing
    6. #pragma warning( push )
    7. #pragma warning( disable : 4311 4312 )
    8.         return ((void *)((unsigned int)CBaseObject::hUDwm + (unsigned int)methodRva));
    9. #pragma warning( pop )
    10. }
    Пробовал дебажить dwm.exe. Он грузит uDWM.dll через LoadLibrary. Дебажить сложно, потому, что при брике интерфейс системы, очевидно, перестаёт работать.
     
  7. Mika0x65

    Mika0x65 New Member

    Публикаций:
    0
    Регистрация:
    30 июл 2005
    Сообщения:
    1.384
    Давайте посмотрим на dwm.exe (у меня его нет, выложите). Может что-то интересное есть в нем. И еще мне непонятна такая вещь: внутренние ф-ии могут быть скопилированы весьма "фривольно", например, ф-ия может ожидать адрес this не в ecx, как требует конвенция, а в esi. Вы это как-то учитываете в своем коде?
     
  8. bolkin

    bolkin New Member

    Публикаций:
    0
    Регистрация:
    5 июл 2005
    Сообщения:
    34
    Адрес:
    Israel
    Подгузил твою uDWM {6.0.6000.16386}.dll в Иду, получил список(в аттаче) очень похож на твой из .h
    Поскольку длл от микрософта, для нее есть паблик символы (.pdb), и большинство функций Ида вытягивает оттуда.
     
  9. Mika0x65

    Mika0x65 New Member

    Публикаций:
    0
    Регистрация:
    30 июл 2005
    Сообщения:
    1.384
    О, а мне IDA сказала, что символы скачала, а имен этих нет.
     
  10. bolkin

    bolkin New Member

    Публикаций:
    0
    Регистрация:
    5 июл 2005
    Сообщения:
    34
    Адрес:
    Israel
    Еще можно просто с Debugging Tools for Windows, правда все ли имена есть я не проверял.
    В аттаче лог того что получилось, а вкратце:


    symchk "uDWM {6.0.6000.16386}.dll" /s SRV*c:\sym*http://msdl.microsoft.com/download/symbols
    copy c:\sym\udwm.pdb\38D207C1D60E4414923F1941BA93CB752\udwm.pdb .
    dbh -v "C:\temp\uDWM {6.0.6000.16386}.dll"
    :srch globals
     
  11. Fduch

    Fduch New Member

    Публикаций:
    0
    Регистрация:
    10 авг 2006
    Сообщения:
    13
    bolkin, Mika0x65
    Огромное спасибо, dbh всё замечательно сдампил. Я правильно понимаю, что при отсутствии символов, получить адреса было бы намного сложнее?
     
  12. wasm_test

    wasm_test wasm test user

    Публикаций:
    0
    Регистрация:
    24 ноя 2006
    Сообщения:
    5.582
    Дебаж на виртуалке с помощью WinDbg
     
  13. bolkin

    bolkin New Member

    Публикаций:
    0
    Регистрация:
    5 июл 2005
    Сообщения:
    34
    Адрес:
    Israel
    Понадобилось бы много гаданий на кофейной гуще и реверса :)