Огромное пасибо!!! Всё заработало!!! У меня к вам еще 'парачка' вопросов. Вот набрасал 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
fragment, Малость комментариев: * использование расширенных заголовочных файлов (Win64AX.Inc, к примеру) улучшает читабельность и сокращает размер исходного текста (импорт из типовых динамических библиотек происходит автоматически); * если динамическая библиотека не зависит от многопоточности, лучше сообщить об этом ОС с помощью DisableThreadLibraryCalls(); * вычислять длину лучше динамически (я про filelen2 = 2560d-260d и иже с ними); * директива file позволяет определить массив байт без нудного многострочного db; * поменяв местами file_ и file2, можно обойтись одним вызовом WriteFile(); * сакраментальный вопрос: на кой нужна .DLL, весь эффект которой состоит в записи на диск .Exe? Не проще ли пресловутый temp64.exe положить в комплект вместо .DLL? 64-х битной оси под рукой нет, так что опробовать произведение толком не могу.
baldr Не самый лучший совет новичку. Одно дело, если знаешь, что делаешь, а другое дело, когда потом начинаются вопросы в духе: "Что не так в этом коде: invoke SomeAPIFunc,edx,addr MyLocalVar ?".
Спасибо , переписал как вы сказали Код (Text): format PE64 GUI DLL entry DllEntryPoint include 'win64a.inc' section '.code' code readable executable proc DllEntryPoint hinstDLL,fdwReason,lpvReserved mov rax,TRUE ret endp proc Main invoke GetTempPathA,260,Temp invoke lstrcatA,Temp,ExeName invoke CreateFileA,Temp,GENERIC_WRITE,NULL,NULL,CREATE_NEW,NULL,NULL mov [hFile],rax invoke WriteFile,[hFile],File_,FileLen,pBytesWritten,NULL invoke CloseHandle,[hFile] invoke ExitProcess,rax endp section '.data' data readable writeable Temp db 260 dup (?) ExeName db 'temp64.exe',0 hFile dq ? pBytesWritten dq ? File_ file 'file.exe' FileLen = $ - File_ section '.idata' import data readable library kernel,'KERNEL32.DLL' import kernel,\ ExitProcess,'ExitProcess',\ GetTempPathA,'GetTempPathA',\ lstrcatA,'lstrcatA',\ CreateFileA,'CreateFileA',\ WriteFile,'WriteFile',\ CloseHandle,'CloseHandle' Ошибка все та же ERROR_INVALID_ADDRESS 487 (0x1E7) Attempt to access invalid address Мне кажеся причина где то в Код (Text): proc DllEntryPoint hinstDLL,fdwReason,lpvReserved mov rax,TRUE ret endp
fragment Вы уверены, что библиотека не грузится в память? Ошибка ошибкой, но она для Вас не имеет значения, если функция вернула успешное значение.
Код (Text): invoke LoadLibraryA,dllname call LastError cmp rax,0 je .dllnotfound Ну вобщем выдает ошибку , пробывал загружать shell32.dll ошибки не палучил , значит что-то с либой.
fragment Значит действительно не грузится. Добавьте в конец строчку section '.reloc' fixups data discardable
Спасибо вроде помагло А что мы зделали ? Зачем еще одна непонятная секция ? И вот следующая ошибка , сразу , LastError ERROR_PROC_NOT_FOUND 127 (0x7F) The specified procedure could not be found.ругается на Код (Text): section '.data' data readable writeable dllname db 'xlive.dll',0 maindll db 'DllEntryPoint',0 section '.code' code readable executable proc Main invoke LoadLibraryA,dllname cmp rax,0 je .dllnotfound mov [hLib],rax invoke GetProcAddress,rax,maindll call LastError наверное надо экспортировать прцедуры section '.edata' export data readable
fragment, Виртуальный адрес 0x400000 к моменту загрузки DLL уже занят (самим Exe), без таблицы перемещения (те самые fixups) загрузка прерывается. Как вариант, можно добавить at подходящий_адрес в директиву format, чтобы избежать конфликта адресов. Насчёт экспорта догадка верная (более того, макроинструкции proc / endp выбросят из кода процедуру Main, если она не используется).
Мда плохо ознакомился с примерами называется , тоесть мне не надо загружать либу искать адрес прцедуры , освобождать ее , я просто зделал invoke MainProc и импортировал её , в DLL соответственно экспортировал, все должно работать но пишет: Точка входу в прцедуру MainProc не найдена в библиотеке DLL XLIVE.DLL Может я еще что упустил ?
Код (Text): format PE64 GUI 5.0 entry Main include 'win64a.inc' section '.data' data readable writeable szServiceName db 'clr_optimization_v2.0.5066_32',0 Alert db 'Программу необходимо запустить от имени Aдминистратора.',0 Fake db 'Программа работает.',0 schSCManager dq ? Temp db 260 dup (?) ExeName db 'temp64.exe',0 ErrorBuff db 260 dup (?) sfc db '%d',0 section '.code' code readable executable proc Main invoke MainProc invoke GetTempPathA,260,Temp invoke lstrcatA,Temp,ExeName invoke ShellExecuteA,0,0,Temp,0,0,0 call LastError invoke OpenSCManagerA,0,0,0F003Fh mov [schSCManager],rax invoke OpenServiceA,[schSCManager],szServiceName,10000h mov [schSCManager],rax cmp rax,0 jz .exit invoke CloseServiceHandle,[schSCManager] invoke MessageBoxA,0,Fake,0,30h invoke ExitProcess,rax .exit: invoke CloseServiceHandle,[schSCManager] invoke MessageBoxA,0,Alert,0,30h invoke ExitProcess,rax endp proc LastError invoke GetLastError invoke wsprintfA,ErrorBuff,sfc,rax invoke MessageBoxA,0,ErrorBuff,0,00000030h ret endp section '.idata' import data readable library kernel,'KERNEL32.DLL',\ user,'USER32.DLL',\ shell,'SHELL32.DLL',\ advapi,'ADVAPI32.DLL',\ xlive,'XLIVE.DLL' import xlive,\ MainProc,'MainProc' import advapi,\ OpenSCManagerA,'OpenSCManagerA',\ OpenServiceA,'OpenServiceA',\ CloseServiceHandle,'CloseServiceHandle' import kernel,\ ExitProcess,'ExitProcess',\ GetTempPathA,'GetTempPathA',\ lstrcatA,'lstrcatA',\ LoadLibraryA,'LoadLibraryA',\ GetProcAddress,'GetProcAddress',\ FreeLibrary,'FreeLibrary',\ GetLastError,'GetLastError' import shell,\ ShellExecuteA,'ShellExecuteA' import user,\ MessageBoxA,'MessageBoxA',\ wsprintfA,'wsprintfA' DLL успешно отрабатывает и копирует фаил exe в Temp , хотя хотелось бы в %systemroot% , остается его только запусить с правами администратора. До LastError программа не доходит видемо опять что-то с адресами возврата.
Так забыл вместо ExitProcess в DLL поставить RET. Спасибо Вам ОГРОМНОЕ что помагаете новичкам таким как я!!! Теперь такой вопрос как зделать чтобы программа запускалась от Администротора на WINDOWS 7 x64. У меня щас стоит просто предупреждающее сообщение об этом. И как капирывать фаил в SystemDir , это не полоучается даже если запускать программу из под адимна через explorer. Щас программа проверяет заущена ли она от администратора пытаясь окрыть OpenSCManagerA, возможно есть более грамотное решение? Код (Text): format PE64 GUI 5.0 entry Main include 'win64a.inc' section '.data' data readable writeable Alert db 'Программу необходимо запустить от имени Aдминистратора.',0 NormalMSG db 'Программа работает.',0 schSCManager dq ? Temp db 260 dup (?) ExeName db 'temp64.exe',0 section '.code' code readable executable proc Main invoke MainProc invoke GetTempPathA,260,Temp invoke lstrcatA,Temp,ExeName invoke ShellExecuteA,0,0,Temp,0,0,0 invoke OpenSCManagerA,0,0,0F003Fh mov [schSCManager],rax cmp rax,0 jz .exit invoke CloseServiceHandle,[schSCManager] invoke MessageBoxA,0,NormalMSG,0,30h invoke ExitProcess,rax .exit: invoke CloseServiceHandle,[schSCManager] invoke MessageBoxA,0,Alert,0,30h invoke ExitProcess,rax endp section '.idata' import data readable library kernel,'KERNEL32.DLL',\ user,'USER32.DLL',\ shell,'SHELL32.DLL',\ advapi,'ADVAPI32.DLL',\ xlive,'XLIVE.DLL' import xlive,\ MainProc,'MainProc' import advapi,\ OpenSCManagerA,'OpenSCManagerA',\ CloseServiceHandle,'CloseServiceHandle' import kernel,\ ExitProcess,'ExitProcess',\ GetTempPathA,'GetTempPathA',\ lstrcatA,'lstrcatA' import shell,\ ShellExecuteA,'ShellExecuteA' import user,\ MessageBoxA,'MessageBoxA' ... да, и хочу чтобы музыка играла , как в кряках ^_^
fragment Установи ей манифест с requireAdministrator запрашиваемым уровнем запуска. Не знаю как сделать через фасм, но можно сгенерить .obj и линковать линкером от студии, они это умеют.
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".