Ассемблер.Криптография.

Discussion in 'С/С++, C#, Rust, Swift, Go, Java, Perl, Ruby' started by DooD, 28 Feb 2011.

  1. DooD

    DooD Elder - Старейшина

    Joined:
    30 Sep 2010
    Messages:
    1,168
    Likes Received:
    450
    Reputations:
    288
    Доброго времени суток!
    такое дело:
    есть строка
    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 неважно,что то простенькое)
    а потом когда допустим у меня файл читался,расшифровывалось назад(это я так понял будет одна и та же функция выполняться).
    Никогда подобного в асме не делал,а переводить с высокоуровневых языков боян,так что прошу помощи.
     
    #1 DooD, 28 Feb 2011
    Last edited: 28 Feb 2011
  2. Sams

    Sams Member

    Joined:
    18 Apr 2009
    Messages:
    247
    Likes Received:
    70
    Reputations:
    17
    Код шифровки при помощи 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 там же будет находится зашифрованная.
     
    #2 Sams, 28 Feb 2011
    Last edited: 28 Feb 2011
    1 person likes this.
  3. DooD

    DooD Elder - Старейшина

    Joined:
    30 Sep 2010
    Messages:
    1,168
    Likes Received:
    450
    Reputations:
    288
    т.е. так:
    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?...
     
  4. Sams

    Sams Member

    Joined:
    18 Apr 2009
    Messages:
    247
    Likes Received:
    70
    Reputations:
    17
    Да, так.

    Смотри, принцип работы этого алгоритма таков:
    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 и так далее.
     
    #4 Sams, 1 Mar 2011
    Last edited: 1 Mar 2011
    1 person likes this.
  5. DooD

    DooD Elder - Старейшина

    Joined:
    30 Sep 2010
    Messages:
    1,168
    Likes Received:
    450
    Reputations:
    288
    эм..понятно,то что esi edi служат для работы со строками ето я знал:) и сразу спрошу тогда,это ж асм32,можно ж и другие регистры(ну там не ecx например а edx,в eax обычно возвр.результат выполнения функции)у меня с апи более-менее норм,а вот так еще сильно не разбираюсь,такая хрень где ax аккумулятор сх счетчик и т.п,в досовом асме была.
     
    #5 DooD, 1 Mar 2011
    Last edited: 1 Mar 2011
    1 person likes this.
  6. Sams

    Sams Member

    Joined:
    18 Apr 2009
    Messages:
    247
    Likes Received:
    70
    Reputations:
    17
    В смысле другие регистры? Ты можешь вообще не использовать 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.
    Но, этот вариант с точки зрения АСМ просто, как бы так сказать, убогий.
     
    2 people like this.
  7. DooD

    DooD Elder - Старейшина

    Joined:
    30 Sep 2010
    Messages:
    1,168
    Likes Received:
    450
    Reputations:
    288
    угу...понятно,спасибо что откликнулся,не подскажешь где можно почитать конкретнее про назначение регистров?(а то я ток с апи знаком:))если можно чтоб на русском:)еще раз спс.,а и еще,если таких строк там порядка 10?как тогда?
     
    #7 DooD, 1 Mar 2011
    Last edited: 1 Mar 2011
  8. Sams

    Sams Member

    Joined:
    18 Apr 2009
    Messages:
    247
    Likes Received:
    70
    Reputations:
    17
    Ой, извини, я там неправильно написал, оно зашифрует 1 байт, а дальше не будет. Спать хочу :eek:

    ну смотри, представим, что ты прочитал файл при помощи ReadFile. Ты передавал этой функции адрес буфера, куда поместить содержимое. А так же указатель на переменную, куда после выполнения, функция поместить число прочитанных байт. И просто делаешь вот так:

    mov esi,<адрес буфера>
    mov edi,<адрес буфера>
    mov ecx,<значение переменной, в которой количество прочитанных байт>

    m1:
    lodsb
    xor al,30d ;30d - ключ шифрования
    stosb
    loop m1



    P.S. А по поводу книг, если хочешь серьезно заняться АСМ, то начинай программирование под Дос. Сам учился по Калашников "Ассемблер? Это просто".
     
    #8 Sams, 1 Mar 2011
    Last edited: 1 Mar 2011
    1 person likes this.
  9. DooD

    DooD Elder - Старейшина

    Joined:
    30 Sep 2010
    Messages:
    1,168
    Likes Received:
    450
    Reputations:
    288
    да я просто хз что под дос писать,я ранее писал,там и с графикой работал,и с файлами тоже дело было,потом на win переключился,сдесь уже все по другому,и в win у меня еще
    кое что выходит..кстати нащет 10 строк,я имел ввиду такое:
    str1 BYTE "123",0
    str2 BYTE "456",0
    strN...
    как все эти строки разом записать,причем с новой строки каждую,не юзая 0dh,0ah? и чтоб каждая ксорилась,я так имел ввиду:)
     
  10. Sams

    Sams Member

    Joined:
    18 Apr 2009
    Messages:
    247
    Likes Received:
    70
    Reputations:
    17
    Ну записать с новой строки каждую без "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 строк. Тогда тебе придется вызвать эту процедуру столько раз, сколько и строк. Хотя этот вариант идеально подходит для парочки строк большой длинны.
     
    #10 Sams, 1 Mar 2011
    Last edited: 1 Mar 2011
  11. DooD

    DooD Elder - Старейшина

    Joined:
    30 Sep 2010
    Messages:
    1,168
    Likes Received:
    450
    Reputations:
    288
    значить пробовал я на деле,с 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
    (зашифровали вторую строку)

    а можно так что б сто раз не писать цикл?взять отдельно в процедуру?
     
  12. Sams

    Sams Member

    Joined:
    18 Apr 2009
    Messages:
    247
    Likes Received:
    70
    Reputations:
    17
    Да, конечно. Не можно, а в таком случае даже нужно ;)

    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
     
    #12 Sams, 1 Mar 2011
    Last edited: 1 Mar 2011
  13. Sams

    Sams Member

    Joined:
    18 Apr 2009
    Messages:
    247
    Likes Received:
    70
    Reputations:
    17
    Ах да, и еще, когда ты определяешь размер строки через sizeof, то ноль тоже учитывается, потому после криптования потеряется конец строки. Нужно передать размер без нуля.

    mov eax,sizeof str1
    dec eax
    invoke CryptXor,addr str1,eax,44d
     
  14. DooD

    DooD Elder - Старейшина

    Joined:
    30 Sep 2010
    Messages:
    1,168
    Likes Received:
    450
    Reputations:
    288
    а если я не использую sizeof, а беру кол-во байтов в строке?
     
  15. Sams

    Sams Member

    Joined:
    18 Apr 2009
    Messages:
    247
    Likes Received:
    70
    Reputations:
    17
    В смысле берешь? Вручную сам подсчитываешь заранее что-ли?
     
  16. DooD

    DooD Elder - Старейшина

    Joined:
    30 Sep 2010
    Messages:
    1,168
    Likes Received:
    450
    Reputations:
    288
    ну да,я смотрю в notepad++ кол-во байт,и ставлю вручную....так проще чем sizeof'ом пользоваться..
     
  17. Sams

    Sams Member

    Joined:
    18 Apr 2009
    Messages:
    247
    Likes Received:
    70
    Reputations:
    17
    Не думаю, что проще, ибо при изменение строки нужно будет заново пересчитывать длину, а так код сделает все за тебя ;)
    Ну так возьми, и вместо sizeof str1 просто подставь свое значение.

    А в чем собственно вообще заключается твоя задача? Что-то ты выбрал какой-то метод нерациональный что-ли :confused:

    Кстати, для того, что бы использовать функцию CryptXor при помощи макроса invoke, нужно вначале программы, где делаешь инклуды, объявить прототип этой функции. Допиши просто
    Code:
    CryptXor PROTO :DWORD,:DWORD,:DWORD
     
    #17 Sams, 1 Mar 2011
    Last edited: 1 Mar 2011
  18. DooD

    DooD Elder - Старейшина

    Joined:
    30 Sep 2010
    Messages:
    1,168
    Likes Received:
    450
    Reputations:
    288
    ок,спс,попробую,напишу что вышло...
     
  19. DooD

    DooD Elder - Старейшина

    Joined:
    30 Sep 2010
    Messages:
    1,168
    Likes Received:
    450
    Reputations:
    288
    блин что то я не так походу делаю,бо не получается
     
  20. Sams

    Sams Member

    Joined:
    18 Apr 2009
    Messages:
    247
    Likes Received:
    70
    Reputations:
    17
    Запости свой исходник. Сейчас разберемся ;)