Не могу получить экспортную функцию

Тема в разделе "WASM.WIN32", создана пользователем sanny, 17 ноя 2019.

  1. TrashGen

    TrashGen ТрещГен

    Публикаций:
    0
    Регистрация:
    15 мар 2011
    Сообщения:
    1.173
    Адрес:
    подполье
    какой мудень написал такой дров, который грузит длл прозрачно от загрузчика и дажэ не возращает вызывающему коду базу её загрузки?
     
  2. sanny

    sanny Member

    Публикаций:
    0
    Регистрация:
    28 сен 2018
    Сообщения:
    42
    HMODULE дров возвращает, только GetProcAddres мне 0 возвращает при попытке получить экспортные функции с загруженной дровом длл)
    --- Сообщение объединено, 18 ноя 2019 ---
    Не получается у меня взять адрес функции класса в длл мейн :dntknw: крч безнадежен я походу..
     
  3. TrashGen

    TrashGen ТрещГен

    Публикаций:
    0
    Регистрация:
    15 мар 2011
    Сообщения:
    1.173
    Адрес:
    подполье
    Если надо, для x32 весьма которкая функа поиска функций по именам и базе модуля уже запиленная в виде числового массива, только пара аргументов передается через регистры, что впрочем не мешает при х32 сделать ассемблерную вставку и оформить функцию в виде hex-массива
    Код (ASM):
    1.  
    2. ;#####################################################
    3.             NTDLL_BASE        equ     0b
    4.             KERNEL_BASE     equ     1b
    5.             FIND_ADDR        equ        00b
    6.             FIND_SERVICE    equ        10b
    7.             SEARCH_HASH        equ        000b
    8.             SEARCH_NAME        equ        100b
    9.          
    10.             LIB_NAME             equ 2
    11.             END_IMPORT_TABLE     equ -1
    12.          
    13. FindAddrFunc:    ;    find_flag:dword, ;base_image - edx ; eax - hash or name
    14.     ; поиск номера сервиса в нтдлл или адреса функи в
    15.     ; нтдлл или кернел32
    16.     ; по хешу имени функи или по имени функи
    17.     ; или же поиск оной же буйни по базе имиджа
    18.     ;-------------------------------------------------
    19.     ; in:  
    20.     ;    dword(find_flag):
    21.     ;        0     - ntdll base
    22.     ;        1     - kernel32 base
    23.     ;        00     - addr func
    24.     ;        10     - No service (ntdll base)
    25.     ;        000 - hash find    (edi - hash)
    26.     ;        100 - name find (edi - offset name)
    27.     ;        edi    - hash func or offset
    28.     ;    dword(base_image):
    29.     ;        address base of image dll to search or NULL
    30.     ; out:  
    31.     ;        eax - addr func or number of service
    32. ;#####################################################
    33.  
    --------РЕЗАТЬ ЗДЕСЬ-------
    Код (ASM):
    1.  
    2. FindAddrFunc:
    3. db 00bh, 0c0h, 00fh, 084h, 0ach, 000h, 000h, 000h, 060h, 033h, 0ffh, 087h, 07ch, 024h, 01ch, 092h
    4. db 00bh, 0c0h, 075h, 01eh, 064h, 0ffh, 035h, 030h, 000h, 000h, 000h, 058h, 08bh, 040h, 00ch, 08bh
    5. db 070h, 00ch, 0adh, 08bh, 070h, 018h, 096h, 0f6h, 044h, 024h, 024h, 001h, 074h, 004h, 0adh, 08bh
    6. db 040h, 018h, 08bh, 0d8h, 08bh, 040h, 03ch, 003h, 0c3h, 08bh, 040h, 078h, 003h, 0c3h, 08bh, 048h
    7. db 014h, 08dh, 050h, 01ch, 08bh, 070h, 020h, 003h, 0f3h, 08bh, 068h, 010h, 0adh, 003h, 0c3h, 056h
    8. db 052h, 033h, 0d2h, 096h, 0f6h, 044h, 024h, 02ch, 004h, 074h, 017h, 092h, 057h, 040h, 080h, 03ch
    9. db 006h, 000h, 075h, 0f9h, 040h, 091h, 0f3h, 0a6h, 05fh, 091h, 00bh, 0c0h, 075h, 002h, 08bh, 0d7h
    10. db 0ebh, 012h, 0f8h, 0ach, 002h, 0d0h, 0c1h, 0c2h, 004h, 081h, 0f2h, 046h, 075h, 043h, 06bh, 080h
    11. db 03eh, 000h, 075h, 0efh, 092h, 05ah, 05eh, 03bh, 0c7h, 075h, 021h, 08bh, 042h, 008h, 003h, 0c3h
    12. db 02bh, 06ah, 0f4h, 066h, 08bh, 02ch, 068h, 08bh, 002h, 003h, 0c3h, 08bh, 004h, 0a8h, 003h, 0c3h
    13. db 0f6h, 044h, 024h, 024h, 002h, 074h, 003h, 08bh, 040h, 001h, 0ebh, 003h, 045h, 0e2h, 09dh, 087h
    14. db 044h, 024h, 01ch, 061h, 0c2h, 004h, 000h
    15.  
    --------РЕЗАТЬ ЗДЕСЬ-------

    пример вызова:
    Код (ASM):
    1.  
    2. msg db "MessageBoxA",0
    3. load db "LoadLibraryA",0
    4. user db "user32.dll",0
    5. start:
    6.    mov eax,offset load
    7.    xor edx,edx
    8.    push KERNEL_BASE or FIND_ADDR or SEARCH_NAME
    9.    call FindAddrFunc
    10.    push offset user
    11.    call eax
    12.  
    13.    xchg    edx,eax ;     edx = hModule
    14.    mov    eax,offset msg  ;     eax = funk name
    15.    push    FIND_ADDR or SEARCH_NAME ;   стековый аргумент функции флаги
    16.    call    FindAddrFunc
    17.  
    18.    ret
    19. end start
     
  4. Indy_

    Indy_ Well-Known Member

    Публикаций:
    4
    Регистрация:
    29 апр 2011
    Сообщения:
    4.775
    RamMerLabs,

    > можно назначить фиксированный ординал нужной функции и искать по номеру, а не по имени.

    О чём вы говорите, экспорт происходит по имени всегда. Номера не используются в нт.

    TrashGen,

    > в коде этой библиотеки и всё сделают релоки

    Бред. У тс есть дров, он инжектит в процесс стаб(не ясно какой), далее он запускает плюсовую нагрузку. Пытается вызвать загрузочные апи и они фейлят, так как модуля нет. Толку от твоего указателя, если модуля в базах нет.
    --- Сообщение объединено, 18 ноя 2019 ---
    TrashGen,

    > db 00bh, 0c0h,

    Ему на скрипте нужно, а не нэйтив.
     
  5. ormoulu

    ormoulu Well-Known Member

    Публикаций:
    0
    Регистрация:
    24 янв 2011
    Сообщения:
    1.208
    Как функция экспортируется?

    Адрес должен браться чем-то типа void* p = (void*)MyClass::MyMethod, если он не приватный, не виртуальный и не инлайновый.
     
  6. Indy_

    Indy_ Well-Known Member

    Публикаций:
    4
    Регистрация:
    29 апр 2011
    Сообщения:
    4.775
    ormoulu,

    Может проще адрес возврата взять и выровнить поинтер на границу, 64к это гранулярность для модулей ?
     
  7. ormoulu

    ormoulu Well-Known Member

    Публикаций:
    0
    Регистрация:
    24 янв 2011
    Сообщения:
    1.208
    Что-то сомневаюсь, что в случае ТС это проще.
     
  8. TrashGen

    TrashGen ТрещГен

    Публикаций:
    0
    Регистрация:
    15 мар 2011
    Сообщения:
    1.173
    Адрес:
    подполье
    было есчо и FindAddrFunc64, но увы, не найдено ужэ, да ине нужно ужэ тожэ (мне, например)
    Indy_, а чо дров грузя библиотеку буттобы релоки не фиксит шоле от базы? ну там не то вобщемта надо

    короч в дллмейне кинуть куданить в разделяемую память, в пайп или есчо хз куда указатель на структуру с адресами нужных из либы функций, а адреса этих функций записать в структуру (все это заебенить в глобальных переменных той же библиотеки) в том же дллмейне. вопрос только чем передать это в процесс там способов должно быть куда больше двух-трех
     
  9. ormoulu

    ormoulu Well-Known Member

    Публикаций:
    0
    Регистрация:
    24 янв 2011
    Сообщения:
    1.208
    Вообще не очень понятно, что именно ТС нужно и как эту функцию планируется вызывать. В процессе уже существует какая-то функциональность, существующий код пытается найти процедуру через GetModuleHandle/GetProcAddress и обламывается? Или что.
     
  10. TrashGen

    TrashGen ТрещГен

    Публикаций:
    0
    Регистрация:
    15 мар 2011
    Сообщения:
    1.173
    Адрес:
    подполье
    да. паходу он в процессе перехватовает GetProcAddress и в перехватчике ему нужно найти адреса из либы, гружонной дровом
    --- Сообщение объединено, 18 ноя 2019 ---
    под х32 кодес там выше могу перепилить его в сишный вид с передачей параметров в стеке, только незнаю зачем мне это нужно^^
     
  11. Indy_

    Indy_ Well-Known Member

    Публикаций:
    4
    Регистрация:
    29 апр 2011
    Сообщения:
    4.775
    TrashGen,

    > грузя библиотеку буттобы релоки не фиксит шоле от базы?

    Нет по описанию тс следует что есть некий стаб, который подтягивает окружение.

    > короч в дллмейне кинуть куданить в разделяемую память

    Он купил решение и не может внести изменения, в то что есть. Ему парсер экспорта нужен на плюсах, зачем усложнять. ТС лень искать в гугле, мне тоже, это его трудности.
     
  12. ormoulu

    ormoulu Well-Known Member

    Публикаций:
    0
    Регистрация:
    24 янв 2011
    Сообщения:
    1.208
    Тогда сканить память на предмет наличия либы, или в DllMain получать адрес и сохранять куда-то в Tls, что-то в этом роде.
    А длл не может повторно сама себя загрузить уже традиционным способом?
    --- Сообщение объединено, 18 ноя 2019 ---
    Ну да вобщем-то, старый надежный способ. Придется чутка покопаться.
     
  13. TrashGen

    TrashGen ТрещГен

    Публикаций:
    0
    Регистрация:
    15 мар 2011
    Сообщения:
    1.173
    Адрес:
    подполье

    sanny

    , говорите короч где воще работает именно ВАШ КОД В КОТОРОМ ВСЁ ПРОИСХОДИТ в перехвате GetProcAddress, вызываемой основным модулем программы? чем вы ставите перехват? где находится код перехватчика?
     
  14. Indy_

    Indy_ Well-Known Member

    Публикаций:
    4
    Регистрация:
    29 апр 2011
    Сообщения:
    4.775
    ormoulu,

    > А длл не может повторно сама себя загрузить уже традиционным способом?

    Нет. Есть куча проверок в загрузчике, главная в виде ядерного сервиса NtAreMappedFilesTheSame - он проверяет два поинтера на один файл.
     
    ormoulu нравится это.
  15. TrashGen

    TrashGen ТрещГен

    Публикаций:
    0
    Регистрация:
    15 мар 2011
    Сообщения:
    1.173
    Адрес:
    подполье
    Indy_, но вы же не знаете КАК дров грузит либу. А то действительно было бы проще загрузить повторно найти адреса стандартным способом и найти разность баз загрузки
    --- Сообщение объединено, 18 ноя 2019 ---
    как то, наверное, так
    addrFunc = ((GetProcAddress(LoadLibrary("ololo.dll"),"func_name")-hModule); /где hModule-значение которое возращает дров для загруженной им ololo.dll
     
  16. sanny

    sanny Member

    Публикаций:
    0
    Регистрация:
    28 сен 2018
    Сообщения:
    42
    Наверно не совсем понятно что я имел в виду без примеров кода. Давайте сначала.
    Экспортные функции моего класса:
    Код (C):
    1.  
    2. // UnrealScript intrinsics.
    3.     #define DECLARE_FUNCTION(func) void func( FFrame& TheStack, RESULT_DECL );
    4.  
    5. class NEWAGE_API UNewAgeAPI : public UObject
    6. {
    7. public:
    8.     DECLARE_FUNCTION(execSetScItem);
    9. }
    Когда я внедряю длл в процесс - он запускает цепочку своих функций которые в конечном итоге сходятся сюда:

    Код (C):
    1. void* UPackage::GetDllExport( const TCHAR* ExportName, UBOOL Checked )
    2. {
    3.     guard(UPackage::GetDllExport);
    4.     void* Result;
    5.     #if !__STATIC_LINK
    6.     if( !DllHandle )
    7.     {
    8.         if( Checked && !ParseParam(appCmdLine(),TEXT("nobind")) )
    9.             appErrorf( LocalizeError(TEXT("NotDll"),TEXT("Core")), GetName(), ExportName );
    10.         Result = NULL;
    11.     }
    12.     else
    13.     #endif
    14.     {
    15.         #if __STATIC_LINK
    16.         Result = FindNative( (TCHAR*) ExportName );
    17.         #else
    18.         Result = appGetDllExport( DllHandle, ExportName );
    19.         #endif
    20.         if( !Result && Checked && !ParseParam(appCmdLine(),TEXT("nobind")) )
    21.             appErrorf( LocalizeError(TEXT("NotInDll"),TEXT("Core")), ExportName, GetName() );
    22.         if( Result )
    23.             debugfSlow( NAME_DevBind, TEXT("Found %s in %s%s"), ExportName, GetName(), DLLEXT );
    24.      
    25.     }
    26.     return Result;
    27.     unguard;
    28. }
    29.  
    вызывается в итоге этот участок: Result = appGetDllExport( DllHandle, ExportName );
    Код (C):
    1. //
    2. // Lookup the address of a DLL function.
    3. //
    4. CORE_API void* appGetDllExport( void* DllHandle, const TCHAR* ProcName )
    5. {
    6.     guard(appGetDllExport);
    7.     check(DllHandle);
    8.     check(ProcName);
    9.  
    10. #ifdef _XBOX
    11.     return NULL;
    12. #else
    13.     return (void*)GetProcAddress( (HMODULE)DllHandle, TCHAR_TO_ANSI(ProcName) );
    14. #endif
    15.  
    16.     unguard;
    17. }
    18.  
    Итог:
    Когда я длл внедряю самым обычным способом (или даже подтянуть LoadLibrary) - все работает, Result = appGetDllExport( DllHandle, ExportName ) - результат получен функция работает.
    Когда я внедряю дровом - Result = appGetDllExport( DllHandle, ExportName ) - Result == NULL и соответственно error.
     

    Вложения:

  17. TrashGen

    TrashGen ТрещГен

    Публикаций:
    0
    Регистрация:
    15 мар 2011
    Сообщения:
    1.173
    Адрес:
    подполье
    перед
    #else
    return (void*)GetProcAddress( (HMODULE)DllHandle, TCHAR_TO_ANSI(ProcName) );
    #endif
    попробуйте загрузить длл еще раз с помощью LoadLibrary
    если загрузится, то находите смещение функции (адрес функции минус база загруженной либы) и прибавляйте его к адресу базы, которую возвращает драйвер
     
  18. sanny

    sanny Member

    Публикаций:
    0
    Регистрация:
    28 сен 2018
    Сообщения:
    42
    Функцию void* UPackage::GetDllExport( const TCHAR* ExportName, UBOOL Checked ) я хукнул у себя в длл (которую внедряю) и мог бы в Result передать адрес своей функции например, но как?
    --- Сообщение объединено, 18 ноя 2019 ---
    Меня тогда защита процесса пошлет в лес :dntknw:
     
  19. ormoulu

    ormoulu Well-Known Member

    Публикаций:
    0
    Регистрация:
    24 янв 2011
    Сообщения:
    1.208
    Что у вас в аргументах appGetDllExport на момент вызова?
     
  20. sanny

    sanny Member

    Публикаций:
    0
    Регистрация:
    28 сен 2018
    Сообщения:
    42
    2 последние функции - не мои, они захардкожены в длл, но первую я могу хукнуть, точнее уже хукнул