Nano Hash - криптовалюты, майнинг, программирование

Как изменить режим вывода консоли с помощью SetConsoleMode в powershell?

Я пытаюсь изменить режим консоли Windows для вывода (CONOUT$) с помощью Windows API и SetConsoleMode вызывает. Поэтому я изменил сценарий PowerShell на основе ConinMode.ps1 ( и который работает для ввода), чтобы сделать это. Чтение прекрасно работает с обоими ConoutMode.exe и мой скрипт и возвращает:

# .\ConoutMode.exe
mode: 0x3
ENABLE_PROCESSED_OUTPUT            0x0001 ON
ENABLE_WRAP_AT_EOL_OUTPUT          0x0002 ON
ENABLE_VIRTUAL_TERMINAL_PROCESSING 0x0004 off   <====
DISABLE_NEWLINE_AUTO_RETURN        0x0008 off
ENABLE_LVB_GRID_WORLDWIDE          0x0010 off

# .\ConoutMode.ps1
OK! GetConsoleWindow handle  :  0x1F06D6
Console Input  Mode (CONIN)  :  0x21f
Console Output Mode (CONOUT) :  0x3

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

В PowerShell:

# .\ConoutMode.exe set 0x000f
error: SetConsoleMode failed (is stdout a console?)

# .\ConoutMode.ps1 -Mode 7
OK! GetConsoleWindow handle  :  0x1F06D6
old (out) mode: 0x3
SetConsoleMode (out) failed (is stdout a console?)
At C:\cygwin64\home\emix\win_esc_test\ConoutMode.ps1:112 char:9
+         throw "SetConsoleMode (out) failed (is stdout a console?)"
+         ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo          : OperationStopped: (SetConsoleMode ...out a console?):String) [], RuntimeException
+ FullyQualifiedErrorId : SetConsoleMode (out) failed (is stdout a console?)

Вот мой ConoutMode.ps1 скрипт целиком:

param (
    [int] $Mode
)

$signature = @'
[DllImport("kernel32.dll", SetLastError=true)]
public static extern IntPtr GetConsoleWindow();

[DllImport("kernel32.dll", SetLastError = true)]
public static extern IntPtr GetStdHandle(int nStdHandle);

[DllImport("kernel32.dll", SetLastError = true)]
public static extern uint GetConsoleMode(IntPtr hConsoleHandle, out uint lpMode);

[DllImport("kernel32.dll", SetLastError = true)]
public static extern uint SetConsoleMode(IntPtr hConsoleHandle, uint dwMode);

public const int STD_INPUT_HANDLE  = -10;
public const int STD_OUTPUT_HANDLE = -11;

public const int  ENABLE_PROCESSED_OUTPUT            = 0x0001;
public const int  ENABLE_WRAP_AT_EOL_OUTPUT          = 0x0002;
public const int  ENABLE_VIRTUAL_TERMINAL_PROCESSING = 0x0004;
public const int  DISABLE_NEWLINE_AUTO_RETURN        = 0x0008;
public const int  ENABLE_LVB_GRID_WORLDWIDE          = 0x0010;
'@
#----------------------------------------------------------
$WinAPI = Add-Type -MemberDefinition $signature -Name WinAPI -Namespace ConoutMode -PassThru
#$WinAPI = Add-Type -MemberDefinition $signature -Name WinAPI -Namespace IdentifyConsoleWindow -PassThru

$hwnd = $WinAPI::GetConsoleWindow()
if ($hwnd -eq 0) {
    throw "Error: GetConsoleWindow returned NULL."
} 
echo "OK! GetConsoleWindow handle  :  0x$($hwnd.ToString("X"))"

function GetConIn {
    $ret = $WinAPI::GetStdHandle($WinAPI::STD_INPUT_HANDLE)
    if ($ret -eq -1) {
        throw "Error: cannot get stdin handle"
    }
    return $ret
}

function GetConOut {
    $ret = $WinAPI::GetStdHandle($WinAPI::STD_OUTPUT_HANDLE)
    if ($ret -eq -1) {
        throw "Error: cannot get stdout handle"
    }
    return $ret
}

function GetConInMode { #GetCOnsoleMode
    $conin = GetConIn
    $mode = 0
    $ret = $WinAPI::GetConsoleMode($conin, [ref]$mode)
    if ($ret -eq 0) {
        throw "GetConsoleMode (in) failed (is stdin a console?)"
    }
    return $mode
}

function GetConOutMode {
    $conout = GetConOut
    $mode   = 0
    $ret    = $WinAPI::GetConsoleMode($conout, [ref]$mode)
    if ($ret -eq 0) {
        throw "GetConsoleMode (out) failed (is stdout a console?)"
    }
    return $mode
}

function SetConInMode($mode) {
    $conin = GetConIn
    $ret = $WinAPI::SetConsoleMode($conin, $mode)
    if ($ret -eq 0) {
        throw "SetConsoleMode (in) failed (is stdin a console?)"
    }
}

function SetConOutMode($mode) {
    #$conout = GetConOut
    # Different tack:
    $conout = $hwnd
    $ret = $WinAPI::SetConsoleMode($conout, $mode)
    if ($ret -eq 0) {
        throw "SetConsoleMode (out) failed (is stdout a console?)"
    }
}

#----------------------------------------------------------
# MAIN
#----------------------------------------------------------
$oldInMode  = GetConInMode
$oldOutMode = GetConOutMode

$newMode = $oldOutMode
$doit = $false

if ($PSBoundParameters.ContainsKey("Mode")) {
    $newMode = $Mode
    $doit = $true
}

if ($doit) {
    echo "old (out) mode: 0x$($oldOutMode.ToString("x"))"
    SetConOutMode $newMode
    $newMode = GetConOutMode
    echo "new (out) mode: 0x$($newMode.ToString("x"))"
} else {
    echo "Console Input  Mode (CONIN)  :  0x$($oldInMode.ToString("x"))"
    echo "Console Output Mode (CONOUT) :  0x$($oldOutMode.ToString("x"))"
}

Итак, в конце концов, я хочу включить ENABLE_VIRTUAL_TERMINAL_PROCESSING для консоли.

Система, которую я использую для этого:

---------------------------------------------------------
  PowerShell Version    : 6.1.1
  OS Name               : Microsoft Windows 8.1 (64-bit)
  OS Version            : 6.3.9600  [2018-11-16 00:50:01]
  OS BuildLabEx         : 9600.19179
  OS HAL                : 6.3.9600.18969
  OS Kernel             : 6.3.9600.18217
  OS UBR                : 19182
  -------------------------------------------------------
  with Privilege        : Administrator
  -------------------------------------------------------
  ExecutionPolicy :
        MachinePolicy   : Undefined
        UserPolicy      : Undefined
        Process         : Undefined
        CurrentUser     : Undefined
        LocalMachine    : Bypass

  Console Settings:
      Type              : ConsoleHost
      OutputEncoding    : Unicode (UTF-8)
      Color Capability  : 23
      Registry VT Level : 1
      CodePage (input)  : 437
      CodePage (output) : 437

Я также включил элемент реестра: HKCU:\Console\VirtualTerminalLevel, как указано в другом месте.


Вопрос: Как включить этот бит/флаг с помощью PowerShell?

Некоторые вещи, о которых я могу думать, могут быть неправильными:

  • Я, конечно, неправильно понимаю, как это работает...
  • У меня могут быть неправильные разрешения писать в консоль? (Как установить?)
  • #P10# <блочная цитата> #P11#
  • Возможно, при выполнении скрипта создается новый выходной буфер? (Что делать?)

  • Возможно, мне придется создать новый буфер?
  • Возможно, мне придется создать новую консоль?

Похожие вопросы и ссылки:


  • Мне кажется, что вы используете неправильный дескриптор при вызове SetConsoleMode. GetConsoleWindow против GetStdHandle 13.12.2018
  • Пробовал и то, и другое. 13.12.2018
  • Что сообщил GetLastError? Кроме того, отредактируйте свой вопрос и удалите GetConsoleWindow, использование этой функции никогда не будет правильным. 14.12.2018
  • @ Андерс Извини, я не понимаю, что ты имеешь в виду. Последняя ошибка показана выше. Если есть другой способ, ИДК как его читать. И GetConsoleWindow я просто смотрел, есть ли другие окна как здесь. 14.12.2018
  • exploit-monday.com/2016/01/ или blogs.technet.microsoft.com/heyscriptingguy/2013/06/25/ 14.12.2018
  • Если я все сделал правильно, то получил: System.ComponentModel.Win32Exception (203): The system could not find the environment option that was entered. 14.12.2018

Ответы:


1

Я экспериментировал с этим сам в течение нескольких дней и понял несколько вещей. По-видимому, PowerShell включает обработку виртуального терминала при запуске. Однако он снова отключает его, когда запускает исполняемый файл, а затем снова включает его, когда исполняемый файл выходит. Это означает, что любой исполняемый файл, требующий обработки виртуального терминала, должен включать его сам или вызываться через программу-оболочку, которая включает его, а затем передает stdin/stdout/stderr на терминал. Что касается того, как вообще написать такую ​​программу, я не знаю.

14.12.2020
Новые материалы

Кластеризация: более глубокий взгляд
Кластеризация — это метод обучения без учителя, в котором мы пытаемся найти группы в наборе данных на основе некоторых известных или неизвестных свойств, которые могут существовать. Независимо от..

Как написать эффективное резюме
Предложения по дизайну и макету, чтобы представить себя профессионально Вам не позвонили на собеседование после того, как вы несколько раз подали заявку на работу своей мечты? У вас может..

Частный метод Python: улучшение инкапсуляции и безопасности
Введение Python — универсальный и мощный язык программирования, известный своей простотой и удобством использования. Одной из ключевых особенностей, отличающих Python от других языков, является..

Как я автоматизирую тестирование с помощью Jest
Шутка для победы, когда дело касается автоматизации тестирования Одной очень важной частью разработки программного обеспечения является автоматизация тестирования, поскольку она создает..

Работа с векторными символическими архитектурами, часть 4 (искусственный интеллект)
Hyperseed: неконтролируемое обучение с векторными символическими архитектурами (arXiv) Автор: Евгений Осипов , Сачин Кахавала , Диланта Хапутантри , Тимал Кемпития , Дасвин Де Сильва ,..

Понимание расстояния Вассерштейна: мощная метрика в машинном обучении
В обширной области машинного обучения часто возникает необходимость сравнивать и измерять различия между распределениями вероятностей. Традиционные метрики расстояния, такие как евклидово..

Обеспечение масштабируемости LLM: облачный анализ с помощью AWS Fargate и Copilot
В динамичной области искусственного интеллекта все большее распространение получают модели больших языков (LLM). Они жизненно важны для различных приложений, таких как интеллектуальные..