Явное и не явное подключение библиотек

Тема в разделе "WASM.BEGINNERS", создана пользователем assch, 23 апр 2017.

  1. assch

    assch Member

    Публикаций:
    0
    Регистрация:
    17 мар 2011
    Сообщения:
    192
    Прочитал одну статью - "Использование DLL в программе на Visual C++"

    http://rsdn.org/article/baseserv/dlluse.xml

    Про явное и не явное подключение библиотек к программному проекту
    ну и расказано про относительные минусы и плюсы этих подключений

    Про неявное подключение библиотек к проекту всё понятно
    этот принцип используется и в masm32 и в C++
    то есть линкеру передается обьектный файл
    в котором прописаны файлы линковки с библиотеками импорта
    эти файлы линковки обычно имеет расширение - .lib

    Меня заинтересовало явное подключение библиотек
    при котором используются две функции LoadLibraryA и GetProcAddress

    Ну предположим что все остальные API функции в проекте
    можно подключить с помощью этого тандема функций
    то есть как бы использовать явное подключение
    этих библиотечных функций

    Но как быть с самими этими функциями LoadLibraryA и GetProcAddress
    ведь их то в проекте придётся подключать не явно
    то есть через файл линковки - Kernel.lib

    Или всё таки существует какой нибудь способ эти две функции
    тоже как то пристегнуть к проекту явным способом
    не используя файл линковки - Kernel.lib

    Кто в теме не подскажите
     
  2. rmn

    rmn Well-Known Member

    Публикаций:
    0
    Регистрация:
    23 ноя 2004
    Сообщения:
    2.329
    Из PEB узнать базовый адрес kernel32.dll в памяти и найти адреса этих двух функций в ее таблице экспорта.
     
  3. assch

    assch Member

    Публикаций:
    0
    Регистрация:
    17 мар 2011
    Сообщения:
    192
    Честно говоря не понял что такое - РЕВ
     
  4. yashechka

    yashechka Ростовский фанат Нарвахи

    Публикаций:
    90
    Регистрация:
    2 янв 2012
    Сообщения:
    1.449
    Адрес:
    Россия
    Код (ASM):
    1. ; By SIGSEGV
    2. [BITS 32]
    3. pushad
    4. call CodeStart
    5. CodeStart:
    6.     pop ebp
    7.     sub ebp,CodeStart   ; delta offset shit
    8.     mov ebx, [FS : 0x30]   ; get a pointer to the PEB
    9.     mov ebx, [ebx + 0x0C]   ; get PEB->Ldr
    10.     mov ebx, [ebx + 0x14]   ; get PEB->Ldr.InMemoryOrderModuleList.Flink (1st entry)
    11.     mov ebx, [ebx]   ; 2nd Entry
    12.     mov ebx, [ebx]   ; 3rd Entry
    13.     mov ebx, [ebx + 0x10]   ; Get Kernel32 Base
    14.     mov [ebp+dwKernelBase] , ebx
    15.     add ebx, [ebx+0x3C] ; Start of PE header
    16.     mov ebx, [ebx+0x78] ; RVA of export dir
    17.     add ebx, [ebp+dwKernelBase]  ; VA of export dir
    18.     mov [ebp+dwExportDirectory] , ebx
    19.     lea edx,[ebp+api_GetProcAddress]
    20.     mov ecx,[ebp+len_GetProcAddress]
    21.     call GetFunctionAddress
    22.     mov [ebp+AGetProcAddressA] , eax
    23.     lea edx,[ebp+api_LoadLibrary]
    24.     push edx
    25.     push dword [ebp+dwKernelBase]
    26.     call eax
    27.     mov [ebp+ALoadLibraryA] , eax
    28.     lea edx , [ebp+szUser32]
    29.     push edx
    30.     call eax
    31.     lea edx , [ebp+api_MessageBoxA]
    32.     push edx
    33.     push eax
    34.     mov ebx,[ebp+AGetProcAddressA]
    35.     call ebx
    36.     mov [ebp+AMessageBoxAA] , eax
    37.     push 0
    38.     lea edx,[ebp+szTitle]
    39.     push edx
    40.     lea edx,[ebp+szMsg]
    41.     push edx
    42.     push 0
    43.     call eax
    44.     popad
    45.     push 0xBBBBBBBB   ;OEP
    46.     retn
    47. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
    48. ;     <<<<< GetFunctionAddress >>>>>>                                          ;
    49. ;    Extracts Function Address From Export Directory and returns it in eax      ;
    50. ;    Parameters :  Function name in edx , Length in ecx                       ;
    51. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
    52. GetFunctionAddress:
    53.     push ebx
    54.     push esi
    55.     push edi
    56.     mov esi, [ebp+dwExportDirectory]
    57.     mov esi, [esi+0x20] ;RVA of ENT
    58.     add esi, [ebp+dwKernelBase]  ;VA of ENT
    59.     xor ebx,ebx
    60.     cld
    61.     looper:
    62.           inc ebx
    63.           lodsd
    64.           add eax , [ebp+dwKernelBase]   ;eax now points to the string of a function
    65.           push esi      ;preserve it for the outer loop
    66.           mov esi,eax
    67.           mov edi,edx
    68.           cld
    69.           push ecx
    70.           repe cmpsb
    71.           pop ecx
    72.           pop esi
    73.           jne looper
    74.           dec ebx
    75.           mov eax,[ebp+dwExportDirectory]
    76.           mov eax,[eax+0x24]       ;RVA of EOT
    77.           add eax,[ebp+dwKernelBase]     ;VA of EOT
    78.           movzx eax , word [ebx*2+eax]  ;eax now holds the ordinal of our function
    79.           mov ebx,[ebp+dwExportDirectory]
    80.           mov ebx,[ebx+0x1C]       ;RVA of EAT
    81.           add ebx,[ebp+dwKernelBase]     ;VA of EAT
    82.           mov ebx,[eax*4+ebx]
    83.           add ebx,[ebp+dwKernelBase]
    84.           mov eax,ebx
    85.         pop edi
    86.         pop esi
    87.         pop ebx
    88.         ret
    89. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
    90. ;   Data Shit                   ;
    91. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
    92. szTitle:              db      "Yo !",0
    93. szMsg:              db  "GreeTz From SIGSEGV",0
    94. szUser32            db    "User32.dll",0
    95. AGetProcAddressA:           dd    0
    96. api_GetProcAddress:         db    "GetProcAddress"
    97. len_GetProcAddress:         dd    $-api_GetProcAddress
    98. ALoadLibraryA:          dd    0
    99. api_LoadLibrary:        db    "LoadLibraryA",0
    100. AMessageBoxAA:          dd    0
    101. api_MessageBoxA:        db    "MessageBoxA",0
    102. dwKernelBase:           dd    0
    103. dwExportDirectory:          dd    0
     
    Коцит и assch нравится это.
  5. assch

    assch Member

    Публикаций:
    0
    Регистрация:
    17 мар 2011
    Сообщения:
    192
    Спасибо yashechka, попробую разобратся
     
  6. assch

    assch Member

    Публикаций:
    0
    Регистрация:
    17 мар 2011
    Сообщения:
    192
    Переписал под синтаксис - masm32

    Код (ASM):
    1. .data
    2. szTitle                db    "Yo !",0
    3. szMsg                  db    "GreeTz From SIGSEGV",0
    4. szUser32               db    "User32.dll",0
    5. api_LoadLibrary        db    "LoadLibraryA",0
    6. api_GetProcAddress     db    "GetProcAddress"
    7. api_MessageBoxA        db    "MessageBoxA",0
    8. ;----------------------------------------
    9. AGetProcAddressA       dd    0
    10. len_GetProcAddress     dd    $-api_GetProcAddress
    11. ALoadLibraryA          dd    0
    12. AMessageBoxAA          dd    0
    13. dwKernelBase           dd    0
    14. dwExportDirectory      dd    0
    15. .code
    16. ;========================================
    17. pushad
    18. call CodeStart
    19. CodeStart:
    20.     pop ebp
    21.     sub ebp,CodeStart   ; delta offset shit
    22.     mov ebx, [FS : 30h]   ; get a pointer to the PEB
    23.     mov ebx, [ebx + 0Ch]   ; get PEB->Ldr
    24.     mov ebx, [ebx + 14h]   ; get PEB->Ldr.InMemoryOrderModuleList.Flink (1st entry)
    25.     mov ebx, [ebx]   ; 2nd Entry
    26.     mov ebx, [ebx]   ; 3rd Entry
    27.     mov ebx, [ebx + 10h]   ; Get Kernel32 Base
    28.     mov [ebp+dwKernelBase] , ebx
    29.     add ebx, [ebx+3Ch] ; Start of PE header
    30.     mov ebx, [ebx+78h] ; RVA of export dir
    31.     add ebx, [ebp+dwKernelBase]  ; VA of export dir
    32.     mov [ebp+dwExportDirectory] , ebx
    33.     lea edx,[ebp+api_GetProcAddress]
    34.     mov ecx,[ebp+len_GetProcAddress]
    35.     call GetFunctionAddress
    36.     mov [ebp+AGetProcAddressA] , eax
    37.     lea edx,[ebp+api_LoadLibrary]
    38.     push edx
    39.     push dword ptr[ebp+dwKernelBase]
    40.     call eax
    41.     mov [ebp+ALoadLibraryA] , eax
    42.     lea edx , [ebp+szUser32]
    43.     push edx
    44.     call eax
    45.     lea edx , [ebp+api_MessageBoxA]
    46.     push edx
    47.     push eax
    48.     mov ebx,[ebp+AGetProcAddressA]
    49.     call ebx
    50.     mov [ebp+AMessageBoxAA] , eax
    51.     push 0
    52.     lea edx,[ebp+szTitle]
    53.     push edx
    54.     lea edx,[ebp+szMsg]
    55.     push edx
    56.     push 0
    57.     call eax
    58.     popad
    59.     push 0BBBBBBBBh   ;OEP
    60.     retn
    61. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
    62. ;     <<<<< GetFunctionAddress >>>>>>                                          ;
    63. ;    Extracts Function Address From Export Directory and returns it in eax      ;
    64. ;    Parameters :  Function name in edx , Length in ecx                       ;
    65. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
    66. GetFunctionAddress:
    67.     push ebx
    68.     push esi
    69.     push edi
    70.     mov esi, [ebp+dwExportDirectory]
    71.     mov esi, [esi+20h] ;RVA of ENT
    72.     add esi, [ebp+dwKernelBase]  ;VA of ENT
    73.     xor ebx,ebx
    74.     cld
    75.     looper:
    76.           inc ebx
    77.           lodsd
    78.           add eax , [ebp+dwKernelBase]   ;eax now points to the string of a function
    79.           push esi      ;preserve it for the outer loop
    80.           mov esi,eax
    81.           mov edi,edx
    82.           cld
    83.           push ecx
    84.           repe cmpsb
    85.           pop ecx
    86.           pop esi
    87.           jne looper
    88.           dec ebx
    89.           mov eax,[ebp+dwExportDirectory]
    90.           mov eax,[eax+24h]       ;RVA of EOT
    91.           add eax,[ebp+dwKernelBase]     ;VA of EOT
    92.           movzx eax , word ptr [ebx*2+eax]  ;eax now holds the ordinal of our function
    93.           mov ebx,[ebp+dwExportDirectory]
    94.           mov ebx,[ebx+1Ch]       ;RVA of EAT
    95.           add ebx,[ebp+dwKernelBase]     ;VA of EAT
    96.           mov ebx,[eax*4+ebx]
    97.           add ebx,[ebp+dwKernelBase]
    98.           mov eax,ebx
    99.         pop edi
    100.         pop esi
    101.         pop ebx
    102.         ret
    но в строке
    Код (ASM):
    1. mov ebx, [FS : 30h]   ; get a pointer to the PEB
    компилятор выдал ошибку
    Код (Text):
    1. error A2108:use of register assumed to ERROR
    Не подскажите как правильно прописать эту строчку правильно под синтаксисом - masm32

    Прошу прощения что прописал код не в специальном окне
    просто я не знаю как это делается, то есть как вставлять код в окно для кодинга
     
  7. rmn

    rmn Well-Known Member

    Публикаций:
    0
    Регистрация:
    23 ноя 2004
    Сообщения:
    2.329
    Код (ASM):
    1.  
    2. assume fs:nothing
    3. mov ebx, fs:[30h]
    4.  
     
  8. rmn

    rmn Well-Known Member

    Публикаций:
    0
    Регистрация:
    23 ноя 2004
    Сообщения:
    2.329
    [сode=аsm]
    ...
    [/соdе]
    Модеры, запилите уже кнопочку "Код" на панели, чтобы при нажатии весь выделенный текст в теги оборачивался.
     
    sl0n и assch нравится это.
  9. assch

    assch Member

    Публикаций:
    0
    Регистрация:
    17 мар 2011
    Сообщения:
    192
    Спасибо rmn, за подсказку синтаксиса
    Там кажется дальше по коду как то нужно будет освободить регистр - ebx или - fs
    а может быть я что то путаю
    короче буду вспоминать и дальше разбиратся с кодом

    За подсказку про теги для кода отдельное спасибо
    Честно говоря для меня это тоже удивительно
    Для уважаемого форума это мягко говоря более чем странно
     
    Последнее редактирование: 23 апр 2017
  10. assch

    assch Member

    Публикаций:
    0
    Регистрация:
    17 мар 2011
    Сообщения:
    192
    Ещё раз собрал код под синтаксис - masm32
    Вместо меток засунул код в функции

    Подставил теги но видно не правильно
    так что опять извиняюсь

    Код (ASM):
    1.  
    2. ;========================================
    3. .data
    4. szTitle                db    "Yo !",0
    5. szMsg                  db    "GreeTz From SIGSEGV",0
    6. szUser32               db    "User32.dll",0
    7. api_LoadLibrary        db    "LoadLibraryA",0
    8. api_GetProcAddress     db    "GetProcAddress"
    9. api_MessageBoxA        db    "MessageBoxA",0
    10. ;----------------------------------------
    11. AGetProcAddressA       dd    0
    12. len_GetProcAddress     dd    $-api_GetProcAddress
    13. ALoadLibraryA          dd    0
    14. AMessageBoxAA          dd    0
    15. dwKernelBase           dd    0
    16. dwExportDirectory      dd    0
    17. ;========================================
    18. .code
    19. call CodeStart
    20. push 0
    21. call ExitProcess
    22. ;========================================
    23. CodeStart proc
    24. ;----------------------------------------
    25. pushad
    26.     assume fs:nothing
    27.     mov ebx, fs:[30h]      ;48 get a pointer to the PEB
    28.     mov ebx, [ebx + 0Ch]   ;12 get PEB->Ldr
    29.     mov ebx, [ebx + 14h]   ;20 get PEB->Ldr.InMemoryOrderModuleList.Flink (1st entry)
    30.     mov ebx, [ebx]   ; 2nd Entry
    31.     mov ebx, [ebx]   ; 3rd Entry
    32.     mov ebx, [ebx + 10h]   ;16 Get Kernel32 Base
    33.     mov dwKernelBase , ebx
    34.     add ebx, [ebx+3Ch] ;60 Start of PE header
    35.     mov ebx, [ebx+78h] ;120 RVA of export dir
    36.     add ebx, dwKernelBase  ; VA of export dir
    37.     mov dwExportDirectory , ebx
    38.     lea edx,api_GetProcAddress
    39.     mov ecx,len_GetProcAddress
    40.  
    41. call GetFunctionAddress
    42.  
    43.     mov AGetProcAddressA , eax
    44.     lea edx,api_LoadLibrary
    45.     push edx
    46.     push dwKernelBase
    47.     call eax
    48.     mov ALoadLibraryA , eax
    49.     lea edx , szUser32
    50.     push edx
    51.     call eax
    52.     lea edx , api_MessageBoxA
    53.     push edx
    54.     push eax
    55.     mov ebx,AGetProcAddressA
    56.     call ebx
    57.     mov AMessageBoxAA , eax
    58.     push 0
    59.     lea edx,szTitle
    60.     push edx
    61.     lea edx,szMsg
    62.     push edx
    63.     push 0
    64.     call eax
    65. popad
    66. ;----------------------------------------
    67. ret
    68. CodeStart endp
    69. ;========================================
    70. GetFunctionAddress proc
    71. ;----------------------------------------
    72. push ebx
    73. push esi
    74. push edi
    75.     mov esi, dwExportDirectory
    76.     mov esi, [esi+20h] ;32 RVA of ENT
    77.     add esi, dwKernelBase  ;VA of ENT
    78.     xor ebx,ebx
    79.     cld
    80.     looper:
    81.           inc ebx
    82.           lodsd
    83.           add eax , dwKernelBase   ;eax now points to the string of a function
    84.           push esi      ;preserve it for the outer loop
    85.           mov esi,eax
    86.           mov edi,edx
    87.           cld
    88.           push ecx
    89.           repe cmpsb
    90.           pop ecx
    91.           pop esi
    92.           jne looper
    93.           dec ebx
    94.           mov eax,dwExportDirectory
    95.           mov eax,[eax+24h]       ;36 RVA of EOT
    96.           add eax,dwKernelBase     ;VA of EOT
    97.           movzx eax , word ptr [ebx*2+eax]  ;eax now holds the ordinal of our function
    98.           mov ebx,dwExportDirectory
    99.           mov ebx,[ebx+1Ch]       ;28 RVA of EAT
    100.           add ebx,dwKernelBase     ;VA of EAT
    101.           mov ebx,[eax*4+ebx]
    102.           add ebx,dwKernelBase
    103.           mov eax,ebx
    104. pop edi
    105. pop esi
    106. pop ebx
    107. ;----------------------------------------
    108. ret
    109. GetFunctionAddress endp
    110. ;========================================
    111.  
    Компилятор собирает без проблем
    но при запуске программа вылетает с ошибкой
    Ошибка происходит в функции - GetFunctionAddress
    в том месте где должно происходить копирование
    а точнее в этом месте - repe cmpsb
    я так думаю что копирование должно быть определённое количество единиц
    а на самом деле копирование или уходит в бесконечность
    или идёт переполнение подставленного отрезка памяти
    Скорее всего ошибка в данных которыми пользуется эта функция
    то есть ошибка где то в начале функции - CodeStart

    Код (ASM):
    1.  
    2.    assume fs:nothing
    3.     mov ebx, fs:[30h]      ;48 get a pointer to the PEB
    4.     mov ebx, [ebx + 0Ch]   ;12 get PEB->Ldr
    5.     mov ebx, [ebx + 14h]   ;20 get PEB->Ldr.InMemoryOrderModuleList.Flink (1st entry)
    6.     mov ebx, [ebx]   ; 2nd Entry
    7.     mov ebx, [ebx]   ; 3rd Entry
    8.     mov ebx, [ebx + 10h]   ;16 Get Kernel32 Base
    9.     mov dwKernelBase , ebx
    10.     add ebx, [ebx+3Ch] ;60 Start of PE header
    11.     mov ebx, [ebx+78h] ;120 RVA of export dir
    12.     add ebx, dwKernelBase  ; VA of export dir
    13.     mov dwExportDirectory , ebx
    14.     lea edx,api_GetProcAddress
    15.     mov ecx,len_GetProcAddress
    16. call GetFunctionAddress
    17.  
    С большой долей вероятности я где то неправильно что то записал
    Кто может определить эту ошибку или ошибки
    помогите пожалуйста
     
    Последнее редактирование: 23 апр 2017
  11. assch

    assch Member

    Публикаций:
    0
    Регистрация:
    17 мар 2011
    Сообщения:
    192
    Хотел ещё написать про теги но не успел по времени

    Путём эксперемента выяснил что код нужно прописывать между этими тегами

    [сode=аsm]
    ...
    [/соdе]

    но только в тегах нужно писать буквы в большом регистре
     
  12. Indy_

    Indy_ Well-Known Member

    Публикаций:
    4
    Регистрация:
    29 апр 2011
    Сообщения:
    4.775
    Код (Text):
    1.  push 0xBBBBBBBB   ;OEP
    2. retn
    3.  
    Думаете получится прыгнуть в кернел память - да невозможно.
     
  13. rmn

    rmn Well-Known Member

    Публикаций:
    0
    Регистрация:
    23 ноя 2004
    Сообщения:
    2.329
    Indy_,
    Это ж placeholder. Туда запишется адрес oep, когда образ настроится.
     
  14. assch

    assch Member

    Публикаций:
    0
    Регистрация:
    17 мар 2011
    Сообщения:
    192
    Судя по коду должен сработать - Месаджбокс
    Я так полагаю если код взят от куда то значит он там работал
     
    Последнее редактирование: 23 апр 2017
  15. assch

    assch Member

    Публикаций:
    0
    Регистрация:
    17 мар 2011
    Сообщения:
    192
    После анализа нашёл ошибку которую я допустил
    основной код в моём посте № 10 правильный
    только сегмент данных нужно изменить
    вместо моего прописанного сегмента данных
    Код (ASM):
    1.  
    2. ;========================================
    3. .data
    4. szTitle                db    "Yo !",0
    5. szMsg                  db    "GreeTz From SIGSEGV",0
    6. szUser32               db    "User32.dll",0
    7. api_LoadLibrary        db    "LoadLibraryA",0
    8. api_GetProcAddress     db    "GetProcAddress"
    9. api_MessageBoxA        db    "MessageBoxA",0
    10. ;----------------------------------------
    11. AGetProcAddressA       dd    0
    12. len_GetProcAddress     dd    $-api_GetProcAddress
    13. ALoadLibraryA          dd    0
    14. AMessageBoxAA          dd    0
    15. dwKernelBase           dd    0
    16. dwExportDirectory      dd    0
    17. ;========================================
    18.  
    нужно прописать этот сегмент по другому
    то есть так как это было прописано в посте № 4 у yashechka,
    Код (ASM):
    1.  
    2. ;========================================
    3. .data
    4. szTitle              db   "Yo !",0
    5. szMsg                db   "GreeTz From SIGSEGV",0
    6. szUser32             db   "User32.dll",0
    7. AGetProcAddressA     dd   0
    8. api_GetProcAddress   db   "GetProcAddress"
    9. len_GetProcAddress   dd   $-api_GetProcAddress
    10. ALoadLibraryA        dd   0
    11. api_LoadLibrary      db   "LoadLibraryA",0
    12. AMessageBoxAA        dd   0
    13. api_MessageBoxA      db   "MessageBoxA",0
    14. dwKernelBase         dd   0
    15. dwExportDirectory    dd   0
    16. .code
    17. ;========================================
    18.  
    Всё дело в обязательном тандеме переменных
    Код (ASM):
    1.  
    2. api_GetProcAddress   db   "GetProcAddress"
    3. len_GetProcAddress   dd   $-api_GetProcAddress
    4.  
    здесь можно обратить внимание
    что инициализация переменной - len_GetProcAddress
    происходит с помощью оператора - $
    то есть адрес минус прошлый адрес
    получается число символов в имени - "GetProcAddress"
    и это число соответственно равно - 14

    Так что пример работает отлично
    Ещё раз спасибо за этот пример - yashechka,

    Ну и всем конечно тоже большое спасибо за участие