LoadLibrary (ERROR_DLL_INIT_FAILED)

Тема в разделе "WASM.BEGINNERS", создана пользователем MaxOn, 15 ноя 2009.

  1. MaxOn

    MaxOn Member

    Публикаций:
    0
    Регистрация:
    8 фев 2009
    Сообщения:
    45
    елаю запуск файла с памяти,при заполнение импорта возникает проблема. Первым в Import descriptor'e kernel32 идет, он грузится нормально. все ок. Затем переходим к user32 , и LoadLibrary возвращает ERROR_DLL_INIT_FAILED.
    вот код процедуры заполнения импорта.
    Код (Text):
    1. proc FillImport pImportTable,pAllocedMemory
    2.     pusha
    3.     mov edx,[pImportTable]
    4.     add edx,[pAllocedMemory];edx - IMAGE_IMPORT_DSCRIPTOR.    
    5.  
    6.     _loop:
    7.         push edx
    8.        
    9.         mov edi,[edx+IMAGE_IMPORT_DESCRIPTOR.FirstThunk]
    10.         mov esi,[edx+IMAGE_IMPORT_DESCRIPTOR.OriginalFirstThunk]
    11.         test edi,edi;Если последний IMAGE_IMPORT_DESCRIPTOR
    12.         jz end_it
    13.         test esi,esi;если OriginalFirstThunk нулевой
    14.         jnz __ok
    15.         mov    esi,edi;То присвоить ему значение из FirstThunk
    16.        
    17.         __ok:
    18.             mov eax,[edx+IMAGE_IMPORT_DESCRIPTOR.Name1]
    19.             add eax,[pAllocedMemory];eax имя длл
    20.             add edi,[pAllocedMemory];сюда будем писать адреса функций
    21.             add esi,[pAllocedMemory];esi - VA массива IMAGE_THUNk_DATA
    22.            
    23.            
    24.             xcall LoadLibraryA,eax
    25.             push eax
    26.            
    27.             load_func_addres:
    28.                 lodsd;eax - RVA IMAGE_IMPORT_BY_NAME
    29.                 test eax,eax
    30.                 jz _goto_next_ImportDescriptor
    31.                 bt eax,31;если этот бит установлен,то импорт по ординалу
    32.                 jnz .no_ord
    33.                 and eax,0ffffh;Выделем из eax ординал функции
    34.                 jmp .getproc
    35.                
    36.                 .no_ord:
    37.                     add eax,[pAllocedMemory];eax - VA IMAGE_IMPORT_BY_NAME
    38.                     add eax,2;VA имени функции
    39.                    
    40.            
    41.                 .getproc:
    42.                    
    43.                
    44.     ;push ebp
    45.                     mov ecx,[esp]
    46.                     xcall GetProcAddress,ecx,eax
    47.     ;pop ebp
    48.                     stosd;Пишем адрес в FirstThunk
    49.             jmp load_func_addres                    
    50.                    
    51.     _goto_next_ImportDescriptor:
    52.    
    53.     pop eax
    54.     pop edx
    55.     add edx,20    
    56.     jmp _loop
    57.     end_it:
    58. ;pop eax    
    59.         pop edx
    60.         popa
    61.         ret
    62. endp
    подскажите,пожалуйста где косяк.
    PS xcall вызывает функу с учетом дельта смещения,оно в ebx
     
  2. FLASH300

    FLASH300 New Member

    Публикаций:
    0
    Регистрация:
    30 окт 2008
    Сообщения:
    72
    совсем не понятно откуда берется массив структур IMAGE_IMPORT_DESCRIPTOR STRUCT если это просто PE файл как есть то :RVA и смещение в файле не одно и тоже
     
  3. MaxOn

    MaxOn Member

    Публикаций:
    0
    Регистрация:
    8 фев 2009
    Сообщения:
    45
    ну в pImportTable передается указатель на таблицу импорта,из DataDirectory.
    ну я это знаю как бы.. И потом если kernel32 нормально грузится,функции в нем ищутся, значит все норм. Где-то еще ошибку допустил,но не могу понять где. msvcrt.dll тоже нормально загружается,а вот user32 почему то не хочет.
     
  4. dyn

    dyn New Member

    Публикаций:
    0
    Регистрация:
    30 окт 2009
    Сообщения:
    566
    MaxOn
    Юзай LoadLibraryExA(path, 0, 1)
     
  5. MaxOn

    MaxOn Member

    Публикаций:
    0
    Регистрация:
    8 фев 2009
    Сообщения:
    45
    dyn
    попробовал,длл вроде грузится,но GetProcAddress возвращает не тот адерс. Функция (MessageBox не вызвается). Код такойже как и в первом посте,поменял только LoadLibraryEx на LoadLibrary. Может стоит добавить,что процедура во время работы переносится за ImageBase+SizeofImage файла который загружаем
     
  6. dyn

    dyn New Member

    Публикаций:
    0
    Регистрация:
    30 окт 2009
    Сообщения:
    566
    код переноса покажи
     
  7. MaxOn

    MaxOn Member

    Публикаций:
    0
    Регистрация:
    8 фев 2009
    Сообщения:
    45
    Код (Text):
    1. mov esi,_file;esi указывает на файл
    2.  add    esi,[esi+3ch] ;peheader
    3.  mov    ecx,[esi+34h] ;ecx=image base
    4.  mov    edx,[esi+50h] ;edx=SizeOfImage
    5.  lea    edi,[edx+ecx];edi - imagebase+SizeOfImage
    6.  mov    esi,iSizeToAlloc;Размер загрузчика
    7.  add    esi,10000h
    8.  and    esi,0ffff0000h;округляем
    9.  @@:
    10.     add edi,10000h
    11.     invoke  VirtualAlloc,edi,esi,MEM_RESERVE+MEM_COMMIT,PAGE_EXECUTE_READWRITE;размещаем загрузчие за SizeofImage+ImageBase
    12.     test    eax,eax
    13.     jz  @b
    14.     mov ebp,eax
    15.  
    16.     mov esi,krnl32
    17.     mov edi,ebp
    18.   @@:;копируем адреса апи функций,необходимых загрузчику
    19.     lodsd
    20.     test    eax,eax
    21.     jz  @f
    22.     mov eax,[eax]
    23.     stosd
    24.     jmp @b
    25.    
    26.   @@:
    27.    
    28.     ;push ebp
    29.     mov esi,Execute
    30.     mov edi,ebp
    31.     mov ecx,iSizeToAlloc
    32.     rep movsb  ;копируем загрузчик вместе с файлом
    33.     ;pop ebp
    34.     jmp ebp
     
  8. MaxOn

    MaxOn Member

    Публикаций:
    0
    Регистрация:
    8 фев 2009
    Сообщения:
    45
    krnl указывает на таблицу апи вида func dd funcddr
     
  9. FLASH300

    FLASH300 New Member

    Публикаций:
    0
    Регистрация:
    30 окт 2008
    Сообщения:
    72
    боюсь даже спрашивать, но любопытно :)

    это как ? GetProcAddress возвращает либо 0 либо правильный адрес

    Код (Text):
    1. ....
    2. add esi,10000h
    3.  and    esi,0ffff0000h;округляем
    4.  @@:
    5.     add edi,10000h   ;<-----------------
    я так понимаю что виртуальный адрес новоиспеченного PE отличается от задуманного при компиляции

    короче есть туманное предположение и "выложу его сразу" (очень надеюсь что не обидишься)
    посмотри на опкоды этих знакомых переходов через которые ползают все вызовы, в секции кода (по крайний мере у меня по умолчанию все эгзешники так собираются)
    Код (Text):
    1. 0040104A   .- FF25 10204000   JMP DWORD PTR DS:[<&kernel32.ExitProcess>]        
    2. 00401050   $- FF25 00204000   JMP DWORD PTR DS:[<&kernel32.GetLastError>]      
    3. 00401056   $- FF25 04204000   JMP DWORD PTR DS:[<&kernel32.GetModuleHandleA>]  
    4. 0040105C   $- FF25 08204000   JMP DWORD PTR DS:[<&kernel32.GetProcAddress>]    
    5. 00401062   $- FF25 0C204000   JMP DWORD PTR DS:[<&kernel32.LoadLibraryExA>]
    это же жестко прописанные виртуальные адреса, и их тоже правишь ?