1. Если вы только начинаете программировать на ассемблере и не знаете с чего начать, тогда попробуйте среду разработки ASM Visual IDE
    (c) на правах рекламы
    Скрыть объявление

CryptUnprotectData error 87

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

  1. Demon13

    Demon13 New Member

    Публикаций:
    0
    Регистрация:
    16 ноя 2018
    Сообщения:
    23
    Здравствуйте, на просторах интернета я нашёл программу, которая зашифровывает и расшифровывает строку с помощью CryptProtectData и CryptUnprotectData. Я попробовал переписать её под 64 бита. Но в моей версии после выполнения CryptUnprotectData я получал ошибку 87(invalid_argument). В чём я ошибся?

    Оригинальная 32 битная программа:
    Код (ASM):
    1. include 'win32ax.inc'
    2. entry main
    3.  
    4. szData db 'paSSword',0
    5. DataSize = $ - szData
    6.  
    7. main:
    8.      mov [datain.pbData], szData
    9.      mov [datain.cbData], DataSize
    10.  
    11.      invoke CryptProtectData, datain, 0, 0, 0, 0, 0, dataout
    12.      cinvoke wsprintf,buf,PASS,[dataout.pbData]
    13.      invoke MessageBox,0,buf,cap,MB_OK
    14.  
    15.      invoke CryptUnprotectData, dataout, 0, 0, 0, 0, 0, datain
    16.      cinvoke wsprintf,buf,PASS,[datain.pbData]
    17.      invoke MessageBox,0,buf,cap,MB_OK
    18.  
    19.      invoke ExitProcess,0
    20.  
    21. section '.data' data readable writeable
    22.  struct DATA_BLOB
    23.     cbData   dd ?
    24.     pbData   dd ?
    25.    ends
    26.  datain      DATA_BLOB
    27.  dataout     DATA_BLOB
    28.  
    29.  cap      db 'Result',0
    30.  PASS     db 'Pass:  %s',10,13,0
    31.  buf      db  64  dup (?)
    32.  
    33. section '.idata' import data readable writeable
    34.  
    35.   library kernel32,'KERNEL32.DLL',\
    36.           user32,'USER32.DLL',\
    37.           Crypt32, 'Crypt32.dll'
    38.  
    39.   import Crypt32,\
    40.                    CryptUnprotectData, 'CryptUnprotectData',\
    41.                    CryptProtectData,'CryptProtectData'
    42.  
    43.   include 'api\kernel32.inc'
    44.   include 'api\user32.inc'
    Моя 64 битная программа:
    Код (ASM):
    1. format PE64 GUI
    2. include 'C:\FASM\INCLUDE\win64ax.inc'
    3. entry main
    4. szData db 'paSSword',0
    5. DataSize = $ - szData
    6. main:
    7.      mov [datain.pbData], szData
    8.      mov [datain.cbData], DataSize
    9.           sub rsp, 8
    10.      invoke CryptProtectData, datain, 0, 0, 0, 0, 0, dataout
    11.  
    12.      cinvoke wsprintf,buf,PASS,[dataout.pbData]
    13.      invoke MessageBox,0,buf,cap,MB_OK
    14.  
    15.      invoke SetLastError, 0
    16.      mov eax, [dataout.pbData]
    17.      invoke CryptUnprotectData, dataout, 0, 0, 0, 0, 0, datain
    18.      invoke GetLastError
    19.  
    20.      mov eax, [datain.pbData]
    21.      mov eax, [datain.cbData]
    22.  
    23.      cinvoke wsprintf,buf,PASS,[datain.pbData]
    24.      invoke MessageBox,0,buf,cap,MB_OK
    25.      invoke ExitProcess,0
    26.  
    27. section '.data' data readable writeable
    28.  struct DATA_BLOB
    29.     cbData   dd ?
    30.     pbData   dd ?
    31.    ends
    32.    
    33.  datain      DATA_BLOB
    34.  dataout     DATA_BLOB
    35.  cap      db 'Result',0
    36.  PASS     db 'Pass:  %s',10,13,0
    37.  buf      db  64  dup (?)
    38.  
    39. section '.idata' import data readable writeable
    40.  
    41.   library kernel32,'KERNEL32.DLL',\
    42.           user32,'USER32.DLL',\
    43.           Crypt32, 'Crypt32.dll'
    44.  
    45. import kernel32,\
    46.      GetLastError, 'GetLastError',\
    47.      SetLastError, 'SetLastError'
    48.  
    49.   import Crypt32,\
    50.                    CryptUnprotectData, 'CryptUnprotectData',\
    51.                    CryptProtectData,'CryptProtectData'
    52.  
    53.   include 'C:\FASM\INCLUDE\api\kernel32.inc'
    54.   include 'C:\FASM\INCLUDE\api\user32.inc'
     
    Последнее редактирование модератором: 25 июл 2019
  2. HESH

    HESH Member

    Публикаций:
    1
    Регистрация:
    20 мар 2008
    Сообщения:
    98
    Читаем описание функции CryptUnprotectData:

    DATA_BLOB *pDataIn - A pointer to a DATA_BLOB structure that holds the encrypted data. The DATA_BLOB structure's cbData member holds the length of the pbData member's byte string that contains the text to be encrypted.

    То есть в качестве аргумента должен передаваться УКАЗАТЕЛЬ на входную структуру DATA_BLOB (на выходную в том числе).

    Теперь, внимание, вопрос: как вы дали понять компилятору, что необходимо использовать именно указатель на структуру, а не структуру целиком?
    (Подсказка: для этих целей в языке ASMЪ предусмотрены ADDR и OFFSET)
    А вот куда их вставить - домашнее задание.

    P.S. Данную практику необходимо распространить на все вызываемые функции во избежание косяков (ЕБ**ЕЙ НЕВЕДОМОЙ Х**НИ) в будущем.
     
  3. Demon13

    Demon13 New Member

    Публикаций:
    0
    Регистрация:
    16 ноя 2018
    Сообщения:
    23
    HESH, возможно, я чего-то не понял и ошибаюсь, но в CryptProtect(Unprotect)Data передаётся именно указатель на начало этой структуры
    upload_2019-7-26_12-34-4.png
     
  4. HESH

    HESH Member

    Публикаций:
    1
    Регистрация:
    20 мар 2008
    Сообщения:
    98
    Ты все правильно понял, в функцию передается ИМЕННО УКАЗАТЕЛЬ на структуру, предварительно инициализированную. По скрину дебаггера видно, что первые 2 строки кода - инициализация этой структуры, но указатель на струкуру (судя по листингу она находится по адресу 401000) фигурирует только в инструкции mov rcx, 401000. В стек это значение перед вызовом функции CryptProtectData НЕ ПОПАДАЕТ ни через PUSH ни через mov qword [RSP+...], rcx и это не есть TRUE.
     
  5. Demon13

    Demon13 New Member

    Публикаций:
    0
    Регистрация:
    16 ноя 2018
    Сообщения:
    23
    HESH, По скрину чуть ниже видно, что в функцию передаётся указатель на выходную структуру(401008) командой mov qword ptr ss:[rsp+30], 401008
    --- Сообщение объединено, 26 июл 2019 ---
    HESH, а первое значение в функцию передаётся через rcx(fastcall). Или я чего-то не понимаю?
     
  6. HESH

    HESH Member

    Публикаций:
    1
    Регистрация:
    20 мар 2008
    Сообщения:
    98
    Не уверен, отладчика под рукой нету - только вечером точнее сказать смогу. Но если хочешь, попробуй зайти в тело функции и посмотреть, допустима ли передача аргумента через rcx или после пролога CryptProtectData читает входной аргумент из стека.

    [MS]: The __fastcall calling convention specifies that arguments to functions are to be passed in registers, when possible. This calling convention only applies to the x86 architecture.
     
  7. Demon13

    Demon13 New Member

    Публикаций:
    0
    Регистрация:
    16 ноя 2018
    Сообщения:
    23
    Посмотрел, допустимо через rcx, как обычный fastcall
     
  8. HESH

    HESH Member

    Публикаций:
    1
    Регистрация:
    20 мар 2008
    Сообщения:
    98
    Ок, тогда смотри, что ты имеешь в выходной структуре по результатам выполнения функции. Заполняется ли она, данные защищаются ? Если да - тогда иди к UnprotectData.
     
    Последнее редактирование: 26 июл 2019
  9. Demon13

    Demon13 New Member

    Публикаций:
    0
    Регистрация:
    16 ноя 2018
    Сообщения:
    23
    Довольно необычно, функция добавляет к указателю на структуру 8 байт(т.е переступает её) и сравнивает значение с нулём, после этого идёт устанавливать ошибку 87(invalid_argument)
     
  10. HESH

    HESH Member

    Публикаций:
    1
    Регистрация:
    20 мар 2008
    Сообщения:
    98
    У тебя структура DATA_BLOB имеет в своем составе 2 поля: размер данных и указатель на их начало. Ну если поле размера теоретически может иметь размер dword, то второе поле (указатель) в x64 обязан иметь размер QWORD, так что есть подозрение, что объявление самой структуры неверно. Если руководствоваться логикой, то размер этой структуры в x64 должен быть никак не меньше sizeof(dword)+ sizeof(qword). Скорее всего, структура имеет 2 поля по QWORD. Проверь объявление этой структуры в заголовочных файлах и попробуй назначить ее членам другие размеры, как я сказал ранее.
     
  11. Demon13

    Demon13 New Member

    Публикаций:
    0
    Регистрация:
    16 ноя 2018
    Сообщения:
    23
    Это помогло, большое спасибо
     
  12. HESH

    HESH Member

    Публикаций:
    1
    Регистрация:
    20 мар 2008
    Сообщения:
    98
    Нет проблем )

    Для этого есть кнопка )
     
    Demon13 нравится это.