Юго, Чётко. Внатуре чётко. Киев, Так же, как и исходники Windows в пачку сигарет. *.asm - формат файла, содержащий исходный текст программы, написанной на языке ассемблера. Шеллкод - специфически написанный код, обладающий чудным свойством - базонезависимостью. Превращать тут надо не *.asm, а сам код. А ответит конкретно на такой вопрос сможет только тот человек, который может научить программировать на С++ за пару минут. Шеллкод - http://forum.antichat.ru/showpost.php?p=2887126&postcount=1183 Генерация шеллкода в виде бинарного потока в файл http://forum.antichat.ru/showpost.php?p=2891318&postcount=1192 P.S. Masm32
ASM и DLL Помогите! Объясните наконец, уже 6 часов бьюсь и не могу понять. Вот статья , про динамические библиатеки. Там есть процедура именно в dll PHP: TestHello proc invoke MessageBox,NULL,addr HelloMsg,addr AppName,MB_OK ret TestHello endp Так вот как мне туда передать целочисленный массив и выполнить над ним какие-небудь действия и вернуть обратно. И ещё я использую invoke LoadLibrary в основном приложении. Очень нуждаюсь в вашей помощи. Кстати вот ссылка на пример .
Почитай доки по синтаксису MASM. Там всё написано, и не придется 6 часов сидеть. Передаются аргументы так: PHP: TestHello proc arg1 :DWORD, arg2 :DWORD, arg3 :DWORD TestHello endp где arg1, arg2, arg3 - твои аргументы. Так как MASM32 - малотипизированный язык, в них можно совать и числа, и указатель на начало твоего целочисленного массива, и указатель на строку. Возвращать аргумент из функции можешь как угодно - например, в любом регистре (тогда ты сможешь вернуть 4 байта (DWORD)), либо вообще записывать возвращаемые данные по некоторому адресу, который передан функции. Прочитай про конвенции вызовов, и увидишь, каким условиям должны удовлетворять функции stdcall (такое соглашение используют практически все функции WinAPI). В stdcall значение возвращается через регистр eax.
Спасибо, немного продвинулся, но всё же, есть вопросы. Я отправляю в функцию размер масива и его самого PHP: ... push len push m call EAX ... Но ведь stdcall функция может возврашать только eax... Ступор Как мне передать мои данные это в функцию, изменить их, а затем вернуть обратно? PHP: Sum proc ;buf:DWORD push EBP mov EBP, ESP mov EСX, [EBP+8] ; здесь лежит мой размер (len) mov ebx, [EBP+12] ; здесь первый элемент массива (m) mov EAX,1 ; Это походу что вернёт моя функция... pop EBP ret Sum endp Пожалуйсто помогите разобраться, я из гугла уже n времени не вылезаю... Ещё вопрос могу ли я из динамической функции работать с регистром из своей программы, к примеру PHP: ... mov esi, OFFSET m ... Будет ли доступна для функции из библиотеки?
Ты можешь менять тот же самый массив, который передал в функцию. Ты можешь передать таким же образом второй массив, предварительно создав его в вызывающей функцию программе, а из дллки в него писать данные. Ты даже можешь создать в дллке массив (динамически выделить память), в него записать нужные данные, а адрес массива вернуть через eax, хотя это не очень хороший тон. Посмотри на любую winapi-функцию, возвращающую, скажем, строку, например, GetUserName. Они все принимают указатель на массив, который ты выделяешь в своей программе, и пишут в него данные. Динамическая библиотека, подгруженная в адресное пространство твоего процесса - это часть процесса, она может делать все, что угодно, в том числе, менять регистры вызывающей программы. Но если ты хочешь сделать так, чтобы твою дллку могли использовать все программы, создавай в ней функции с использованием какой-либо конвенции вызовов. Если это stdcall, то значение возвращай в eax, принимай значения через стек, и сохраняй значения регистров edi, esi и ebx (push edi, push esi, push ebx в начале кода функции и pop ebx, pop esi, pop edi в конце. Можно еще директиву uses масма32 использовать).
Да я понимаю, что это возможно, от части задачу я решил записав в стек размер массива и записав всё значение массива в регистр, перед вызовом функции PHP: ... push len mov esi, OFFSET m call EAX ... Т.е хотелось бы увидеть пример, как сделать так 1. Записываем в стек адрес массива 2. Получаем в dll этот адрес и начинаем, допустим увеличивать значения массива на 1, при этом я так понимаю, мы должны взять к примеру этот же регистр, загнав его в стек?! 3. Как через еах вернуть адрес уже изменённого масива?! 4. Получается что мою написаную dll не могут исползувать сразу несолько приложений, так для них всех регистр esi будет обшим? (Это наверное для вас самый нубский вопрос...) Я не могу найти ни одного примера в интернете с аргументами в процедуре dll и вообще как потом вернуть значение в EAX??? И как потом написать код допустим в Delphi для вызова данной функции, там же я не определяю в какой регистр я пишу? Пожалуйсто приведите пример. Очень прошу. Кстати вот моей функции в dll PHP: ... Sum proc push EBP mov EBP, ESP mov ecx, [EBP+8] ; Считываем из стека размер массива. mov edx,ecx dec ecx for_i: push ecx neg ecx add ecx, edx for_j: mov eax, [esi][ecx*4] mov ebx, [esi][ecx*4-4] cmp ebx, eax jg skip mov [esi][ecx*4], ebx mov [esi][ecx*4-4], eax skip: loop for_j pop ecx loop for_i pop EBP ret 4 Sum endp ...
Сейчас глупые вопросы пошли. Советую почитать, что такое вообще регистры, стек, куча и т.п. базовые вещи. Если мы передали в функцию (неважно, где эта функция, в dll, не в dll) АДРЕС массива и работаем с этим адресом изнутри функции, то мы работаем с тем самым массивом, который лежит где-то в памяти программы, которая вызвала функцию. Массив при этом НЕ дублируется, т.к. мы передали указатель на его начало. Адрес. Если мы не хотим, чтобы наш изначальный массив менялся, то делаем, например, так. Передаем два адреса в функцию: первый адрес - адрес массива с исходными данными, второй адрес - адрес массива с неопределенными данными, в который функция будет писать результат. Функция в цикле берет каждый элемент первого массива, делает с ним какие-то операции, а результат записывает во второй массив. На выходе у нас получается неизмененный исходный массив и заполненный нужными нам значениями второй. Пример не буду приводить, тут и так все очевидно. Соответственно, этот вопрос отпадает. Смогут, у каждого процесса свое адресное пространство, свои значения регистров, свой стек и своя куча. Ну только если ты принудительно не сделаешь некоторую секцию исполняемого файла shared.
И Снова Ассемблер+процедуры... И так вот кусок кода, приложения. PHP: ... incMass :DWORD, :DWORD mas DD 100 DUP(?) ln DD 0 ... Здесь код заполнения массива ... INVOKE incMass,mas,ln ; вызов функции из dll ... Собсвенно вот кусок dll кода, в кором я не пойму некорое вещи 1. Как передать этот массив в код, переписать его эл-ты на 1, и вернуть обратно??? PHP: ... incMass PROC m:DWORD, l:DWORD mov ecx,l lea esi,m mov ebx,1 start: mov [esi],ebx add esi,4 loop start ret incMass endp ... Эта процедура из dll у меня не работатет, и никак не могу найти информацию с подобным примером. Поправте пожалуйсто, если не трудно эту процедуру... И ещё как я понял если использовать CALL то аргументы передаються только через СТЕК??? Почему в длл кампилятор рунаеться на OFFSET?
что именно не работает?дебаггером пройдись.через стек если передавать то вызов колл-ом.если укажешь прототип то можно и через инвок вызывать.
Помогите пожалуйста дописать программу, сейчас она только считывает и выводит каждый элемент массива. Нужно обнулить все элементы массива, которые по модулю меньше 10 PHP: include 'win32ax.inc' .data array db 5,34,9,98,-3 ; массив array_len db $-array Caption db 'Результат.',0 buffer rb 20 .code start: xor eax,eax xor ecx, ecx mov cl, [array_len] mov edi, buffer mov esi, array m: xor eax,eax mov al,[esi] ; помещаем элемент массива в регистр al ; ; здесь надо заменить al нулем, если он по модулю меньше 10 ; call IntToStr ; Выводим элемент массива inc esi inc edi loop m mov [edi], byte 0 invoke MessageBox,0,buffer,Caption,MB_OK invoke ExitProcess,0 IntToStr: ;eax = number, ebx = base(основание системы счисления=10), edi = buffer(буфер для хранения строки ;результата) push eax ecx ebx edx xor ecx,ecx mov ebx, 10 .new: xor edx,edx div ebx push edx inc ecx test eax,eax jnz .new .loop: pop eax add al,30h mov [edi], al inc edi loop .loop mov al, byte ' ' mov [edi],al pop edx ebx ecx eax ret .end start
Возник вот такой вопросег о так называемых "регистрах процессора". Суть вопроса - регистры одни, или их несколько ? Т.е. при запуске двух приложений, соответственно есть два "блока" регистров. Допустим, в одном преложении eax = 5, а во втором - 10. Вообщем, обьясните, "сколько" их. Надеюсь, смысл ясен Заранее благодарю.
Регистры в процессоре одни. Один eax, один esi и т.д. На каждое ядро по одному. Операционная система занимается тем, что переключает контексты процессов и потоков, сохраняя состояние регистров процесса, который она приостанавливает, и восстанавливая регистры для того, который она запускает на выполнение.
Большое спасибо, прояснил. Подозревал, что это так, просто это стоило бы писать в обучалках ). Кстати, получается, отладчики в некотором смысле берут на себя то, что должна делать ось ?
Отладчики могут контролировать состояние памяти и регистров какого-либо процесса, переключением контекстов они не занимаются.
исключено. делаешь "Step by step" кода в отладчике - и видишь, как меняется содержание регистров. отладчики - не хирурги, а судебно-медицинские эксперты. фиксируют лишь изменения в памяти и регистрах, которые ты сам внёс, своим кодом.
вопрос как после создание файла invoke CreateFile,addr file,GENERIC_WRITE,0,0,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,0 записать с поле EDIT в файл file в моем случае поле вода пароля выглядит так dialogitem 'EDIT','',ID_PASS,55,11,110,12,WS_CHILD+WS_VISIBLE+ES_CENTER+WS_BORDER+ES_PASSWORD хоть не большой пример скиньте должен ли я еще использовать функцию записи invoke WriteFile
создается файл но туда не чего не записывается вот пример PHP: IF ax == BN_CLICKED invoke MessageBox,hWnd,addr TextButton1,0,MB_ICONINFORMATION invoke CreateFile,addr fname,GENERIC_WRITE,0,0,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,0 invoke GetWindowText, Edit1ID,ADDR buf,512 invoke WriteFile,fname,TextEdit1,Edit1ID,addr buf,512
смори Code: invoke GetWindowText,hwndEdit,addr buffer,512 Code: invoke GetWindowTextLength,hwndEdit получили длину текста. получили текст,ок. Code: invoke WriteFile,hFile,addr buffer,eax,addr htemp,0 записали.