powered by simpleCommunicator - 2.0.52     © 2025 Programmizd 02
Форумы / WinForms, .Net Framework [игнор отключен] [закрыт для гостей] / Передать массив байт через cmd без ошибок в общем случае как-то могу?
35 сообщений из 35, показаны все 2 страниц
Передать массив байт через cmd без ошибок в общем случае как-то могу?
    #39493400
Дмитрий77
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Юзер экспортирует сертификат из своего StoreLocation.CurrentUser
Код: vbnet
1.
2.
      Dim sb As Byte()
      sb = cert.Export(X509ContentType.Pkcs12, "12345")


Админ устанавливает этот сертификат в StoreLocation.LocalMachine (у юзера нет прав на это)
Код: vbnet
1.
2.
3.
4.
5.
6.
7.
    Dim newcert As X509Certificate2 = _
     New X509Certificate2(sb, "12345", _
     X509KeyStorageFlags.Exportable Or X509KeyStorageFlags.MachineKeySet Or X509KeyStorageFlags.PersistKeySet)
    Dim store As X509Store = New X509Store(StoreLocation.LocalMachine)
    store.Open(OpenFlags.ReadWrite)
    store.Add(newcert)
    store.Close()


Одним кодом под админом в общем случае делать нельзя, т.к. админ не обязательно совпадает с юзером и вытащить нужный сертификат (массив байтов cb) из хранилища юзера в общем случае не сможет.

Посему юзер запускает другое exe под админом (с запросом Elevated при старте второго exe естественно),
при этом должен передать ему этот самый экспортированный sb в качестве параметра, файла и т.п., чтоб второй exe его установил в локальное хранилище.

Через Named Shared Memory понял что не получится, потому что не смогу создать MapFile с /Global под юзером.

Самый простой вариант, сохранить cb в файл под юзером WriteAllBytes, а админ его прочтет ReadAllBytes (в заведомо известном месте, куда оба точно имеют доступ, %temp% не катит ибо могут не совпадать, но такое другое место допустим есть), потом файл удалить, но не люблю так делать.

Идея такая.
Юзер может запустить второй (админский) exe с командной строкой, передав в ней cb.
Длина cb конечно не маленькая но в 8000+ (макс. длина cmd) вроде с запасом укладывается.

Смущает только то что передать надо Byte() а cmd это String,
соотв. перекодирование туда-сюда означает Encoding. Понятно что одинаковая на обоих концах,
но не видится как good и хз что из этого выйдет.

Задача взята отсюда:
20666360
...
Рейтинг: 0 / 0
Передать массив байт через cmd без ошибок в общем случае как-то могу?
    #39493408
Фотография Cat2
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Модератор форума
Извините, но я счастлив, что у меня нет таких заморочек!
...
Рейтинг: 0 / 0
Передать массив байт через cmd без ошибок в общем случае как-то могу?
    #39493410
Фотография hVostt
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Дмитрий77,

Передать путь к файлу не судьба?

Чёто на ум приходит только присказка про жабу и гадюку
...
Рейтинг: 0 / 0
Передать массив байт через cmd без ошибок в общем случае как-то могу?
    #39493412
Дмитрий77
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
hVosttПередать путь к файлу не судьба?
Я про этот вариант упомянул:
авторСамый простой вариант, сохранить cb в файл под юзером WriteAllBytes, а админ его прочтет ReadAllBytes (в заведомо известном месте, куда оба точно имеют доступ, %temp% не катит ибо могут не совпадать, но такое другое место допустим есть), потом файл удалить, но не люблю так делать.
Файл как таковой изначально не существует (сертификат установлен в хранилище тек. юзера + содержит экспортируемые закрытые ключи, а не в виде PFX-файла). Перебросить "через файл" (экспорт в файл под юзером, импорт из файла под админом) - да, могу. Но не хочу( Чего из плодить). Хотел бы через файл, вопроса бы не задавал.
Вопрос задан в шапке темы и сформулирован вполне корректно.
Готов переформулировать:
Есть массив байт,
надо из него сделать String,
потом из String обратно массив байт.
(при этом, чтоб байты на выходе гарантированно не исказились).
Что непонятно в вопросе?
Просто начинаешь пояснять зачем, начинаются сказки про гадюку.
...
Рейтинг: 0 / 0
Передать массив байт через cmd без ошибок в общем случае как-то могу?
    #39493413
Фотография Изопропил
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Дмитрий77Смущает только то что передать надо Byte() а cmd это String,
соотв. перекодирование туда-сюда означает Encoding. Понятно что одинаковая на обоих концах,
но не видится как good и хз что из этого выйдет.

что может выйти из кодирования байтового массива в base64 кроме base64?

ХЗ? - круто.
...
Рейтинг: 0 / 0
Передать массив байт через cmd без ошибок в общем случае как-то могу?
    #39493414
Фотография Изопропил
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Дмитрий77Просто начинаешь пояснять зачем, начинаются сказки про гадюку.
можно вместо гадюки скушать любимый кактус
...
Рейтинг: 0 / 0
Передать массив байт через cmd без ошибок в общем случае как-то могу?
    #39493416
Дмитрий77
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Изопропил,

покажи как.

Еще ж наверно строку их HEX-ов сделать туда-сюда можно, типа как в реестре байты хранятся.
...
Рейтинг: 0 / 0
Передать массив байт через cmd без ошибок в общем случае как-то могу?
    #39493420
Фотография Изопропил
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
...
Рейтинг: 0 / 0
Передать массив байт через cmd без ошибок в общем случае как-то могу?
    #39493421
Дмитрий77
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Изопропилчто может выйти из кодирования байтового массива в base64 кроме base64?
А впрочем, спасибо, все получилось:

Код: vbnet
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
  Function main() As Integer
    main = 0

    If InStr(Command, "/InstallCertToLocal") > 0 Then 'устанавливает e-mail сертификат в LocalMachine и выходит
      Dim str_byte As String = GetSingleOptionFromStr(Command, "InstallCertToLocal")
      If InstallCertToLocalMachine(str_byte) Then
        Return 0
      Else
        Return 1 'код возврата, отличный от нуля означает ошибку
      End If
    End If

...


  Public Function ReInstallCertToLocalMachine(ByRef cert As X509Certificate2) As Boolean
    Try
      Dim sb As Byte()
      sb = cert.Export(X509ContentType.Pkcs12, "12345")


      Dim str_byte = Convert.ToBase64String(sb)
      If IsAdministrator() Then
        ReInstallCertToLocalMachine = InstallCertToLocalMachine(str_byte)
      Else
        Dim cmd_install As String = "/InstallCertToLocal=" & str_byte
        Dim eResult As ExecuteStatus _
         = ExecuteProcess(Application.ExecutablePath, ProcessWindowStyle.Normal, cmd_install, True)
        Select Case eResult
          Case ExecuteStatus.res_OK
            ReInstallCertToLocalMachine = True
          Case Else 'res_FAILED res_CANCEL (здесь не делаем разницы)
            ReInstallCertToLocalMachine = False
        End Select
      End If
    Catch
      Return False
    End Try
  End Function

  Public Function InstallCertToLocalMachine(ByVal the_bytestr As String) As Boolean
    'Выполняется AsAdmin
    Try

      Dim sb As Byte()
      sb = Convert.FromBase64String(the_bytestr)

      Dim newcert As X509Certificate2 = _
       New X509Certificate2(sb, "12345", _
       X509KeyStorageFlags.Exportable Or X509KeyStorageFlags.MachineKeySet Or X509KeyStorageFlags.PersistKeySet)
      Dim store As X509Store = New X509Store(StoreLocation.LocalMachine)
      store.Open(OpenFlags.ReadWrite)
      store.Add(newcert)
      store.Close()
      Return True
    Catch
      Return False
    End Try
  End Function



Проверил на всякий случай
Strings.Len(str_byte) на тесте дало 4090
(по сути это PFX файл)
Макс. длина cmd 8000+
Не рискую попасть на ограничение длины?
...
Рейтинг: 0 / 0
Передать массив байт через cmd без ошибок в общем случае как-то могу?
    #39493422
Фотография Изопропил
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Дмитрий77,

base64 добавляет 33%

lpCommandLine [in, out, optional]
The command line to be executed. The maximum length of this string is 32,768 characters, including the Unicode terminating null character.
...
Рейтинг: 0 / 0
Передать массив байт через cmd без ошибок в общем случае как-то могу?
    #39493424
Дмитрий77
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ИзопропилThe maximum length of this string is 32,768 characters, including the Unicode terminating null character.
Ну, я наверно не про ту cmd читал.
Тогда успокоил, все в шоколаде, такой длины думаю там неоткуда взяться.
Пошел оформлять это хозяйство в свою панель.
...
Рейтинг: 0 / 0
Передать массив байт через cmd без ошибок в общем случае как-то могу?
    #39493425
Фотография Изопропил
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Дмитрий77,

32768 - это из CreateProcess
...
Рейтинг: 0 / 0
Передать массив байт через cmd без ошибок в общем случае как-то могу?
    #39493429
Дмитрий77
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ИзопропилДмитрий77,
32768 - это из CreateProcess
Да понял я. Я видимо про cmd.exe читал.

У меня AsAdmin вот таким кодом вызывается, в варианте VB6 там был ShellExecuteEx, но думаю то же самое, т.е. 32768.
Код: vbnet
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
  Public Function ExecuteProcess(ByVal FilePath As String, _
   Optional ByVal nShow As ProcessWindowStyle = ProcessWindowStyle.Normal, _
   Optional lpParameters As String = vbNullString, _
   Optional LaunchElevated As Boolean = False, _
   Optional useDoEvent As Boolean = False) As ExecuteStatus

    'useDoEvent -использует цикл с DoEvent вместо WaitForSingleObject

    Dim ExecInfo As New ProcessStartInfo
    With ExecInfo
      .FileName = FilePath
      .WindowStyle = nShow
      .WorkingDirectory = IO.Path.GetDirectoryName(FilePath)
      .Arguments = lpParameters
      .UseShellExecute = True
      ' On Microsoft Windows Vista and later, one can use runas instead of Open, in order to execute the
      ' process as an elevated process. In that case, the user will be asked whether he or she wants to
      ' run the process as an administrator.
      If LaunchElevated = True Then
        .Verb = "runas"
      Else
        .Verb = "Open"
      End If
    End With

    Dim procExec As New Process
    Try
      procExec = Process.Start(ExecInfo)
    Catch
      Return ExecuteStatus.res_CANCEL
    End Try

    If useDoEvent Then
      Do While Not procExec.HasExited
        Application.DoEvents()
      Loop
    Else
      procExec.WaitForExit()
    End If
    If procExec.ExitCode = 0 Then
      Return ExecuteStatus.res_OK
    Else
      Return ExecuteStatus.res_FAILED
    End If
  End Function
...
Рейтинг: 0 / 0
Передать массив байт через cmd без ошибок в общем случае как-то могу?
    #39493442
Фотография hVostt
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Дмитрий77Я про этот вариант упомянул:
авторСамый простой вариант, сохранить cb в файл под юзером WriteAllBytes, а админ его прочтет ReadAllBytes (в заведомо известном месте, куда оба точно имеют доступ, %temp% не катит ибо могут не совпадать, но такое другое место допустим есть), потом файл удалить, но не люблю так делать.

Ты делаешь это в один момент времени, значит можешь удалить файл по окончанию процедуры.
Я проблемы не вижу в упор.

Дмитрий77Просто начинаешь пояснять зачем, начинаются сказки про гадюку.

Потому что не надо придумывать себе проблем, чтобы потом героически их решать. Сохранил в файл, передал путь к файлу и всё. Нет, это не наш путь, надо через одно место всё порешать.
...
Рейтинг: 0 / 0
Передать массив байт через cmd без ошибок в общем случае как-то могу?
    #39493445
Дмитрий77
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
hVostt,
ну вот че неймется?
я вопрос корректно задал, Изопропил корректно подсказал.
стоит раз в полгода зайти, сразу срач какой-то не по делу, то не так - это не так.

Просто блин когда файлы плодишь, потом в десятках мест надо проверять, что они удалились, и где нибудь забываешь.
>Сохранил в файл, передал путь к файлу и всё.
Файлопомойка это.
...
Рейтинг: 0 / 0
Передать массив байт через cmd без ошибок в общем случае как-то могу?
    #39493450
Фотография hVostt
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Дмитрий77,

Ну сам виноват, я увидел целую историю о том, как ты страдаешь фигнёй, вместо того, чтобы решать задачу по уму. Так что не обессудь.
...
Рейтинг: 0 / 0
Передать массив байт через cmd без ошибок в общем случае как-то могу?
    #39493451
Фотография hVostt
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Дмитрий77Файлопомойка это.

Файловая система это по своей сути файлопомойка. Зато у тебя никогда не пригорит по поводу, что какой-нибудь сертификат в base64 не влез в cmd с другими параметрами.
...
Рейтинг: 0 / 0
Передать массив байт через cmd без ошибок в общем случае как-то могу?
    #39493453
Дмитрий77
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
hVosttрешать задачу по уму.
По уму я решил.
20666326
20666360
То о чем идет речь здесь это тоже по уму. И решилось достаточно быстро и просто.

>Зато у тебя никогда не пригорит по поводу, что какой-нибудь сертификат в base64 не влез в cmd с другими параметрами
не пригорит, я такие операции делаю независимо с одним-двумя параметрами и они отработаны сто лет в обед.
ключевая ф-ция Function ExecuteProcess
смысл ее донельзя прост
когда требуется действо "AsAdmin", прога запускает другой экземпляр себя + cmd и этот экземпляр требует админа(через окно UAC).
main() анализирует cmd и при наличии /ключ= делает одну конкретную операцию и выходит. Основной экземпляр (запущенный в основном режиме под обычным пользователем) при этом ждет возврата результата (в случае если используется useDoEvent, может еще что-то делать при этом).

>как ты страдаешь фигнёй
это не фигня, это интересный рабочий вопрос, причем довольно быстро решаемый

фигня, это например написать 10 нехилых MsgBox-ов на английском, потом запихнуть этот текст в строковые переменные, перевести на русский и т.д.
фигня это писать справочную систему
фигня это писать обработку ошибок + красивый лог, хотя понимаешь что в 99,9% случаев ошибки там не будет и быть не может
на фигню уходит большая часть времени
без фигни к сожалению никак

но не простой вопрос на который давно получен быстрый ответ
...
Рейтинг: 0 / 0
Передать массив байт через cmd без ошибок в общем случае как-то могу?
    #39493468
Фотография hVostt
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Дмитрий77фигня это писать справочную систему

Всё верно.
Пусть люди прокачивают свои способности к телепатии.
Пусть разбираются методом тыка и матерятся всю дорогу.

Дмитрий77фигня это писать обработку ошибок + красивый лог, хотя понимаешь что в 99,9% случаев ошибки там не будет и быть не может

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

Хотя.. на этот момент способности к телепатии уже должны быть развиты, так это решает всё проблемы.

Дмитрий77на фигню уходит большая часть времени

Ну глядя на то, какой ты фигнёй страдаешь, вместо того, чтобы делом заниматься, это 100% верное утверждение


Дмитрий77но не простой вопрос на который давно получен быстрый ответ

Простой вопрос был бы такой: как мне мой byte[] перевести в строку и потом обратно?

Хотя, если бы ты смог его сформулировать таким образом, ты бы ответ нагуглил секунд за 10.
...
Рейтинг: 0 / 0
Передать массив байт через cmd без ошибок в общем случае как-то могу?
    #39493469
Фотография hVostt
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Дмитрий77,

Кстати, лучше уж передать твой сертификат не через параметры, а через входной поток.

Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
class Program
{
    static void Main(string[] args)
    {
        string s;
        while ((s = Console.ReadLine()) != null)
        {
            Console.WriteLine(s);
        }

    }
}



Пример:

Код: powershell
1.
2.
C:\...\ConsoleApplication1\bin\Debug>echo "Foo bar baz" | ConsoleApplication1.exe
"Foo bar baz"



Так ты можешь передавать данные гораздо больших размеров, чем позволено в командной строке, и просто сразу закрыть вопрос на любые непредвиденные ситуации.
...
Рейтинг: 0 / 0
Передать массив байт через cmd без ошибок в общем случае как-то могу?
    #39493470
Фотография hVostt
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Дмитрий77,

Ещё варианты:

System.Console.In.ReadToEnd()
Console.OpenStandardInput()


Пример запуска:
Код: powershell
1.
myprogram_export_certificate.exe | myprogram_import_certificate.exe /AsAdmin
...
Рейтинг: 0 / 0
Передать массив байт через cmd без ошибок в общем случае как-то могу?
    #39493503
Дмитрий77
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
hVosttДмитрий77фигня это писать справочную систему

Всё верно.
Пусть люди прокачивают свои способности к телепатии.
Пусть разбираются методом тыка и матерятся всю дорогу.
Да пишу я эти хэлпы в лучшем виде, не переживай.
Только 90% юзеров их не читают. Но все равно пишу, чтоб прога солидней выглядела.
Да и Вы, уважаемый, не читаете о чем люди пишут:
hVosttПростой вопрос был бы такой: как мне мой byte[] перевести в строку и потом обратно?

Хотя, если бы ты смог его сформулировать таким образом, ты бы ответ нагуглил секунд за 10.
Специально для Вас переформулировал, в 4-м посте сверху:
Готов переформулировать:
Есть массив байт,
надо из него сделать String,
потом из String обратно массив байт.
(при этом, чтоб байты на выходе гарантированно не исказились).
Не тоже самое, не? Но вы ж не читаете, чукча не читатель, чукча писатель.

Да насрать юзеру, через файл это сделано, через классический cmd или через мутный грязе-.Net о-поток.
И мне насрать, если честно.
Работает, отлично.

Просто ответ получен через 2 часа как вопрос задан,
а срач с гадюками продолжается еще +13 часов с момента как получен ответ, и видимо продолжится еще до послезавтра.

Я за это время уже все имплементировал, прострадал фигней с "10-ю Msgbox-ами " на русском, английском, китайском и суахили (шутю) и с вами успел "подискутировать".

Вот поэтому порой лучше погуглить 2 часа, а не 2 минуты, после того как дали оч. явную подсказку (за которой и пришел, а зачем еще на форум ходят?) Гадюк оно конечно можно игнорировать, но иногда тоже хочется погадючиться, время только уходит, а вот это обидно.

А то вот приходит кто-нибудь сюда из гуглопоиска,
вроде и вопрос поставлен, и ответ найден, а поди найди среди 100 постов, когда кругом одни гадюки среди кактусов ползают.
...
Рейтинг: 0 / 0
Передать массив байт через cmd без ошибок в общем случае как-то могу?
    #39493614
ART-CODE
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Командная строка легко перехватывается - начиная опцией в диспетчере задач "показать командную строку".
И заканчивая утилитами, которые это делают специально, я такую для себя написал и логирую всю активность процессов. Для контроля и анализа.

Поток немного сложнее перехватить, особенно если продумать защиту от перехвата потока (как это сделано в телнете например).
Если важна безопасность, конечно.
Ну и я бы не называл поток "мутным", на мой взляд это лучшее решение.
...
Рейтинг: 0 / 0
Передать массив байт через cmd без ошибок в общем случае как-то могу?
    #39493617
Фотография Изопропил
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ART-CODEПоток немного сложнее перехватить, особенно если продумать защиту от перехвата потока (как это сделано в телнете например).
чё в теленете сделано? пургу зачем гнать
...
Рейтинг: 0 / 0
Передать массив байт через cmd без ошибок в общем случае как-то могу?
    #39493626
ART-CODE
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Изопропил,
Я вернусь домой, сброшу тестовое приложение по перехвату ввода/вывода телнета.
Сам запустишь и увидишь.
...
Рейтинг: 0 / 0
Передать массив байт через cmd без ошибок в общем случае как-то могу?
    #39493637
Фотография Изопропил
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ART-CODEИзопропил,
Я вернусь домой, сброшу тестовое приложение по перехвату ввода/вывода телнета.
Сам запустишь и увидишь.
зачем мне какое-то приложение, мне Wireshark достаточно

PS надеюсь речь идёт о telnet в смысле RFC 854/5198
...
Рейтинг: 0 / 0
Передать массив байт через cmd без ошибок в общем случае как-то могу?
    #39493640
Фотография hVostt
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Изопропил,

Да всё равно потоки лучше, передавать сертификат в base64 в командной строки, совсем убогий костыль.
...
Рейтинг: 0 / 0
Передать массив байт через cmd без ошибок в общем случае как-то могу?
    #39493642
Фотография Изопропил
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
hVosttИзопропил,

Да всё равно потоки лучше, передавать сертификат в base64 в командной строки, совсем убогий костыль.
с этим я полностью согласен,

меня интересует мифическая "защита в телнете"
...
Рейтинг: 0 / 0
Передать массив байт через cmd без ошибок в общем случае как-то могу?
    #39493686
Дмитрий77
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ART-CODEКомандная строка легко перехватывается -
Террористами, вирусами. Госп..., как тяжело жить то стало.
А файл воруется. Да плевать.

Маслица подлить вам в костерок?
Никто еще не смотрел мой код (мы ж писатели) в котором устанавлен пароль на серт. "12345", а я и в продакшн так оставил, гы.
Счас начнется, пароль ненадежный, да и раздебажить .Net-exe-шник наверно можно.
Ну не надоело?
...
Рейтинг: 0 / 0
Передать массив байт через cmd без ошибок в общем случае как-то могу?
    #39493719
ART-CODE
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Дмитрий77 ,
ok, я Вас понял. Как хотите.
---
Отвечу для Изопропил
Все мои эксперименты с telnet.exe были в 2005 году.
Тогда я обнаружил, что ее поведение отличается от поведения обычных консольных программ,
таких как ftp.exe и cmd.exe
Но внешне - ее поведение такое же.
Я предположил, что используется некий механизм разрганичения прав на доступ к потокам программы.
Далее не углублялся.

А сейчас, пока писал - подумал, что раз ею можно управлять через отправку клавиатурных команд типа SendMessage,
то потоки могут вообще не использоваться как способ ввода.

эксперимент (C++Builder - консольное с vcl):
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
101.
102.
103.
104.
105.
106.
107.
108.
109.
110.
111.
112.
113.
114.
115.
116.
117.
118.
119.
120.
121.
122.
123.
124.
125.
126.
127.
128.
129.
130.
131.
132.
133.
134.
135.
136.
137.
138.
139.
140.
141.
142.
143.
144.
145.
146.
147.
148.
149.
150.
151.
152.
153.
154.
155.
156.
157.
158.
159.
160.
161.
162.
163.
164.
165.
166.
167.
168.
169.
170.
171.
172.
173.
174.
175.
176.
177.
178.
179.
180.
181.
182.
183.
184.
185.
186.
187.
188.
189.
190.
191.
192.
193.
194.
195.
196.
197.
198.
199.
200.
201.
202.
203.
204.
205.
206.
207.
208.
209.
210.
211.
212.
213.
214.
215.
216.
217.
218.
219.
220.
 #include <vcl.h>
#include <windows.h>

#pragma hdrstop
#pragma argsused

#include <tchar.h>
#include <stdio.h>
#include <conio.h>



bool IsWinNT()  //проверка запуска под NT
{
  OSVERSIONINFO osv;
  osv.dwOSVersionInfoSize = sizeof(osv);
  GetVersionEx(&osv);
  return (osv.dwPlatformId == VER_PLATFORM_WIN32_NT);
}

void  Log(AnsiString LogMessage)
{
OemToChar(LogMessage.c_str(),LogMessage.c_str());
  FILE * F;
  AnsiString LogFileName=ExtractFileName(Application->ExeName)+".log";

		 if((F=fopen(LogFileName.c_str(),"a+"))==NULL) return;
		 fwrite(LogMessage.c_str(),LogMessage.Length(),1,F);

         fclose(F);
}

void ErrorMessage(char *str)  //вывод подробной информации об ошибке
{

  LPVOID msg;

  FormatMessage(
    FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
    NULL,
    GetLastError(),
    MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // язык по умолчанию
    (LPTSTR) &msg,
    0,
	NULL
  );
  Log(String ((LPTSTR) &msg));
  printf("%s: %s\n",str,msg);
  LocalFree(msg);

}



#pragma argsused
int _tmain(int argc, _TCHAR* argv[])
{

//------------ CreateProcess и Anonymous Pipes------
#define bzero(a) memset(a,0,sizeof(a))

  char buf[1024];           //буфер ввода/вывода

  STARTUPINFO si;
  ZeroMemory(&si,sizeof(STARTUPINFO));
  SECURITY_ATTRIBUTES sa;
  SECURITY_DESCRIPTOR sd;        //структура security для пайпов
  PROCESS_INFORMATION pi;

  HANDLE newstdin,newstdout,read_stdout,write_stdin;  //дескрипторы
                                                      // пайпов


  if (IsWinNT())        //инициализация security для Windows NT
  {
    InitializeSecurityDescriptor(&sd,SECURITY_DESCRIPTOR_REVISION);
    SetSecurityDescriptorDacl(&sd, true, NULL, false);
    sa.lpSecurityDescriptor = &sd;
  }

  else sa.lpSecurityDescriptor = NULL;

  sa.nLength = sizeof(SECURITY_ATTRIBUTES);
  sa.bInheritHandle = true;       //разрешаем наследование дескрипторов


  if (!CreatePipe(&newstdin,&write_stdin,&sa,0))   //создаем пайп
                                                   // для stdin
  {
    ErrorMessage("CreatePipe");
    getch();
    return 0;
  }

  if (!CreatePipe(&read_stdout,&newstdout,&sa,0)) //создаем пайп
                                                  // для stdout
  {
    ErrorMessage("CreatePipe");
    getch();
    CloseHandle(newstdin);
    CloseHandle(write_stdin);
    return 0;
  }



  GetStartupInfo(&si);      //создаем startupinfo для
                            // дочернего процесса

  /*

  Параметр dwFlags сообщает функции CreateProcess
  как именно надо создать процесс.

  STARTF_USESTDHANDLES управляет полями hStd*.
  STARTF_USESHOWWINDOW управляет полем wShowWindow.

  */
  si.cb = sizeof (si);                                      //  STARTF_USESTDHANDLES|
  si.dwFlags =STARTF_USESTDHANDLES|STARTF_USESHOWWINDOW;
  si.wShowWindow =SW_HIDE;  // SW_SHOW   ;
  si.hStdOutput = newstdout;
  si.hStdError = newstdout;   //подменяем дескрипторы для
  si.hStdInput = newstdin;    // дочернего процесса
  si.lpDesktop=NULL;
  si.lpTitle = NULL;


  char app_spawn[] = "C:\\WINDOWS\\system32\\cmd.exe";

  //создаем дочерний процесс

  if (!CreateProcess(app_spawn,NULL,NULL,NULL,TRUE, NULL,
                      NULL ,NULL,&si,&pi))
 {
    ErrorMessage("CreateProcess");
    getch();
    CloseHandle(newstdin);
    CloseHandle(newstdout);
    CloseHandle(read_stdout);
    CloseHandle(write_stdin);
    return 0;
  }

  Log("\r\n__START__\r\n");

  unsigned long exit=0;  //код завершения процесса
  unsigned long bread;   //кол-во прочитанных байт
  unsigned long avail;   //кол-во доступных байт



  bzero(buf);

  for(;;)      //основной цикл программы
  {
    GetExitCodeProcess(pi.hProcess,&exit); //пока дочерний процесс
                                           // не закрыт
    if (exit != STILL_ACTIVE)
     break;

    PeekNamedPipe(read_stdout,buf,1023,&bread,&avail,NULL);

    //Проверяем, есть ли данные для чтения в stdout

    if (bread != 0)
    {
      bzero(buf);
      if (avail > 1023)
      {
        while (bread >= 1023)
        {
          ReadFile(read_stdout,buf,1023,&bread,NULL);  //читаем из
          Log(String ( buf));                                            // пайпа stdout
          printf("%s",buf);
          bzero(buf);
        }
      }

      else {
        ReadFile(read_stdout,buf,1023,&bread,NULL);
        Log(String ( buf));
        printf("%s",buf);
      }
    }

    if (kbhit())      //проверяем, введено ли что-нибудь с клавиатуры
    {
      bzero(buf);
      *buf = (char)getche();

      //printf("%c",*buf);
     Log(String ( buf));
      WriteFile(write_stdin,buf,1,&bread,NULL); //отправляем это
                                                // в stdin

     if (*buf == '\r' ||*buf == '\n' )
        {
        *buf = '\n';
        printf("%c",*buf);
        WriteFile(write_stdin,buf,1,&bread,NULL); //формирум конец
        Log(String ( buf));
         }                                          //строки, если нужно


    }
    Sleep(250);
  }

  CloseHandle(pi.hThread);
  CloseHandle(pi.hProcess);
  CloseHandle(newstdin);            //небольшая уборка за собой
  CloseHandle(newstdout);
  CloseHandle(read_stdout);
  CloseHandle(write_stdin);


  printf("PRESS ANY KEY TO EXIT - PIPE CATCHER PROCESS STOPPED");
  getch();
}


В этом коде жестко зашит вызов CMD.EXE, а наша программа перехватывает весь ее ввод/вывод
и пишет все в лог.
Не выключая программы - вызовите FTP.EXE и увидите, что теперь общаетесь с ней, можете передавать файлы на сервер и обратно, и все будет записано в лог.
А теперь выйдите из ftp.exe и запустите telnet.exe - облом.
Телнет стартовал, но связь с ним отсутствует по стандартным каналам ввода/вывода.
Либо он вообще не использует их, либо принудительно ограничивает доступ.
...
Рейтинг: 0 / 0
Передать массив байт через cmd без ошибок в общем случае как-то могу?
    #39493723
Дмитрий77
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ART-CODE,
бодался я когда-то с французами на тему неработающего перехвата, который как раз был очень нужен, но не работал:

Чтение результатов работы "упрямого" консольного приложения

Чтение результатов работы консольного приложения

Так, поностальгировал, возможно не в кассу.
...
Рейтинг: 0 / 0
Передать массив байт через cmd без ошибок в общем случае как-то могу?
    #39493757
Фотография hVostt
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Дмитрий77Маслица подлить вам в костерок?
Никто еще не смотрел мой код (мы ж писатели) в котором устанавлен пароль на серт. "12345", а я и в продакшн так оставил, гы.

Какие пароли ты ставишь на серт, к разработке не относится. Дело твоё.


Дмитрий77Счас начнется, пароль ненадежный, да и раздебажить .Net-exe-шник наверно можно.
Ну не надоело?

Не начнётся. Сказано было про убогость решения передачи серта через параметры командной строки.
...
Рейтинг: 0 / 0
Передать массив байт через cmd без ошибок в общем случае как-то могу?
    #39493838
Фотография Изопропил
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ART-CODEТелнет стартовал, но связь с ним отсутствует по стандартным каналам ввода/вывода.
Либо он вообще не использует их, либо принудительно ограничивает доступ.
это очевидно - ему ж терминал нужно эмулировать, на "доступ" насрать,
поэтому и использует консольные функции https://docs.microsoft.com/en-us/windows/console/console-functions
...
Рейтинг: 0 / 0
Передать массив байт через cmd без ошибок в общем случае как-то могу?
    #39493999
ART-CODE
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Изопропил,
Ваша правда.
Я ожидал такое поведение от какого-нибудь НортонКоммандера,
а про терминал, что-то не подумал, что может быть так.
...
Рейтинг: 0 / 0
Передать массив байт через cmd без ошибок в общем случае как-то могу?
    #39494002
ART-CODE
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Опечатка: про телнет имелось в виду.
...
Рейтинг: 0 / 0
35 сообщений из 35, показаны все 2 страниц
Форумы / WinForms, .Net Framework [игнор отключен] [закрыт для гостей] / Передать массив байт через cmd без ошибок в общем случае как-то могу?
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]