Доброго времени суток! такое дело: есть строка strng1 BYTE "ololo",0 создается файл invoke CreateFile,addr fn,GENERIC_WRITE,0,0,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,0 mov hFile,eax и строка пишется в файл invoke WriteFile,hFile,addr strng1,5,addr htemp,0 ... так вот мне надо чтобы при записи в файл строка шифровалась(ROL,ROR или XOR неважно,что то простенькое) а потом когда допустим у меня файл читался,расшифровывалось назад(это я так понял будет одна и та же функция выполняться). Никогда подобного в асме не делал,а переводить с высокоуровневых языков боян,так что прошу помощи.
Код шифровки при помощи xor можно вместить наверное в байт так 35. на MASM mov esi,offset strng1 mov edi,offset strng1 mov ecx,sizeof strng1 m1: lodsb xor al,30d ;30d - ключ шифрования stosb loop m1 Шифрует по байтно. Буфером хранения служит буфер источника, т.е. в strng1 находится шифруемая строка, после выполнения xor там же будет находится зашифрованная.
т.е. так: invoke CreateFile,addr fn,GENERIC_WRITE,0,0,CREATE_ALWAYS,FILE_ATTRIBUTE_ NORMAL,0 mov hFile,eax mov esi,offset strng1 mov edi,offset strng1 mov ecx,sizeof strng1 m1: lodsb xor al,30d ;30d - ключ шифрования stosb loop m1 invoke WriteFile,hFile,addr strng1,5,addr htemp,0 что то я не оч.въехал,почему xor al а не esi?...
Да, так. Смотри, принцип работы этого алгоритма таков: 1. В esi и edi заносишь адреса твое строки. Это нужно для команд stosb, lodsb. stosb - заносит младший байт из eax по адресу edi; edi = edi + 1; lodsb - заносит в eax один байт из адреса esi; esi = esi + 1; 2. В ecx заносится размер твоей строки. Это счетчик цикла, т.к. мы шифруем строку по одному байту. 3. При помощи lodsb загружаем в eax 1 байт твоей строки. Он находится в al. 4. Делаем xor этого байта. 5. При помощи stosb записываем зашифрованный байт из al туда, откуда читали его, т.к. esi = edi. 6. Повторяем тело цикла, пока не зашифруем все байты, т.е. пока ecx не будет равно нулю. P.S. Ключ не может быть больше, чем 0FFh. Ну это в данном примере, вед можно шифровать по 2 байта, и по 4. Так что не пытайся подставить туда 12345 и так далее.
эм..понятно,то что esi edi служат для работы со строками ето я знал и сразу спрошу тогда,это ж асм32,можно ж и другие регистры(ну там не ecx например а edx,в eax обычно возвр.результат выполнения функции)у меня с апи более-менее норм,а вот так еще сильно не разбираюсь,такая хрень где ax аккумулятор сх счетчик и т.п,в досовом асме была.
В смысле другие регистры? Ты можешь вообще не использовать stosb и lodsb - это хорошая оптимизация. Здесь используется именно eax потому, что разработчики архитектуры Intel процессоров сделали команды работы со строками через eax. И тут ничего не изменить. И вообще, eax, грубо говоря, это рабочий регистр. Через него "проходит" много чего, даже тот же результат любых WinAPI возвращается именно в eax. Можно сделать не оптимизированный вариант, он более легче для восприятия, но и кода больше, и выполняется он дольше (конечно на доли секунд, но тем не менее) mov eax,offset strng1 ;или lea eax,strng1 - абсолютно эквивалентно mov ecx,sizeof strng1 m1: mov dl,byte ptr [eax] xor dl,30d ;30d - ключ шифрования mov byte ptr [eax],dl inc eax loop m1 В этом варианте уже задействован регистр edx, и не тронуты esi и edi. Но, этот вариант с точки зрения АСМ просто, как бы так сказать, убогий.
угу...понятно,спасибо что откликнулся,не подскажешь где можно почитать конкретнее про назначение регистров?(а то я ток с апи знаком)если можно чтоб на русскомеще раз спс.,а и еще,если таких строк там порядка 10?как тогда?
Ой, извини, я там неправильно написал, оно зашифрует 1 байт, а дальше не будет. Спать хочу ну смотри, представим, что ты прочитал файл при помощи ReadFile. Ты передавал этой функции адрес буфера, куда поместить содержимое. А так же указатель на переменную, куда после выполнения, функция поместить число прочитанных байт. И просто делаешь вот так: mov esi,<адрес буфера> mov edi,<адрес буфера> mov ecx,<значение переменной, в которой количество прочитанных байт> m1: lodsb xor al,30d ;30d - ключ шифрования stosb loop m1 P.S. А по поводу книг, если хочешь серьезно заняться АСМ, то начинай программирование под Дос. Сам учился по Калашников "Ассемблер? Это просто".
да я просто хз что под дос писать,я ранее писал,там и с графикой работал,и с файлами тоже дело было,потом на win переключился,сдесь уже все по другому,и в win у меня еще кое что выходит..кстати нащет 10 строк,я имел ввиду такое: str1 BYTE "123",0 str2 BYTE "456",0 strN... как все эти строки разом записать,причем с новой строки каждую,не юзая 0dh,0ah? и чтоб каждая ксорилась,я так имел ввиду
Ну записать с новой строки каждую без "0dh,0ah" никак не получится. Это же ASCII коды перевода курсора на следующую строку, а так же перемещение каретки в начало строки. Что по поводу твоих 10-ти строк. Смотри, если ты их пишешь подряд, значит и в памяти они буду расположены так же. В твоем случае это будет выглядеть так: str1 BYTE "123",0 str2 BYTE "456",0 01 02 03 00 04 05 06 00 .... Текстовая строка, которая заканчивается нулевым байтом называется ASCIIZ. Так вот, что тебе мешает использовать все тот же алгоритм из второго поста? В esi и edi записываешь указатель на первую строку - str1. В ecx - сумма размеров всех строк включая нулевой байт в конце. И всё, в итоге получишь зашифрованные все 10 строк. Но тут есть одно НО, строки собьются, ибо при xor нуля получим не ноль, а значит не будет известно, где заканчивается ASCIIZ строка. Если же ты не хочешь, что бы строки сбились, потому что в будущем к ним нужно будет еще обращаться по имени, то одним из вариантов можно делать во время xor проверку на нулевой байт, и если он присутствует, то просто его пропустить. Это если у тебя много строк. В случае с парочкой, 2-4 например, можешь вынести код криптора в отдельную процедуру, и передавать через параметры начало ASCIIZ строк. Тогда тебе придется вызвать эту процедуру столько раз, сколько и строк. Хотя этот вариант идеально подходит для парочки строк большой длинны.
значить пробовал я на деле,с 1-й строкой работает прекрасно, но т.к. мне надо много строк,получается я так делал: crlf db 0dh,0ah,0 invoke CreateFile,addr fn,GENERIC_WRITE,0,0,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,0 mov hFile,eax mov esi,offset strng1 mov edi,offset strng1 mov ecx,sizeof strng1 m1: lodsb xor al,30d stosb loop m1 invoke WriteFile,hFile,addr strng1,50,addr htemp,0 invoke WriteFile,hFile,addr crlf,2,addr htemp,NULL (зашифровали 1-ю строку) mov esi,offset strng2 mov edi,offset strng2 mov ecx,sizeof strng2 m2: lodsb xor al,30d stosb loop m2 invoke WriteFile,hFile,addr strng2,10,addr htemp,0 (зашифровали вторую строку) а можно так что б сто раз не писать цикл?взять отдельно в процедуру?
Да, конечно. Не можно, а в таком случае даже нужно Code: Функция CryptXor(src:DWORD,sz:DWORD,xkey:DWORD); src - указатель на строку sz - размер строки xkey - [B]однобайтный[/B] ключ CryptXor proc src:DWORD,sz:DWORD,xkey:DWORD pusha mov esi,src mov edi,src mov ecx,sz xor eax,eax CryptXor_m1: lodsb xor eax,xkey stosb loop CryptXor_m1 popa ret CryptXor endp Пример использования: invoke CryptXor,addr str1,sizeof str1,44d либо push 44d push sizeof str1 push offset str1 call CryptXor
Ах да, и еще, когда ты определяешь размер строки через sizeof, то ноль тоже учитывается, потому после криптования потеряется конец строки. Нужно передать размер без нуля. mov eax,sizeof str1 dec eax invoke CryptXor,addr str1,eax,44d
Не думаю, что проще, ибо при изменение строки нужно будет заново пересчитывать длину, а так код сделает все за тебя Ну так возьми, и вместо sizeof str1 просто подставь свое значение. А в чем собственно вообще заключается твоя задача? Что-то ты выбрал какой-то метод нерациональный что-ли Кстати, для того, что бы использовать функцию CryptXor при помощи макроса invoke, нужно вначале программы, где делаешь инклуды, объявить прототип этой функции. Допиши просто Code: CryptXor PROTO :DWORD,:DWORD,:DWORD