![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
WriteConsoleInput [D7, WinXP]
Logo © (2005-05-31 08:47:00)Использую WriteConsoleInput.
Но почему то передается не буква "n", а буква "N".
И еще какой-то пробел после нее. Вместо Энтера знак равно.
Что может быть не так?
Еще не могу по русски писать в консоль.
Logo (2005-06-23 14:07:00) [1]Реально работает.
Единственное я немного подправил, чтобы ID можно было вводить русское.
Спасибо, alpet!
alpet (2005-06-23 13:20:00) [2]CreateFile и прочие закомментированные элементы можно удалить.
alpet (2005-06-23 13:19:00) [3]Блин, а задача интересной оказалось. Но как всегда помогло внимательное чтение справки. Вот держи и разбирай рабочий код, хотя я бы поискал для задачи исходники программы rsa.exe:
program redir;
{$APPTYPE CONSOLE}
uses Windows, Types, SysUtils;
var
SI: TStartupInfo;
PI: TProcessInformation;
function ChToOem (const s: string): string;
var p: array [0..255] of char;
begin
CharToOemBuff (PChar (s), p, Length (s) + 1);
result := p;
end;
procedure SendInputStr (const s: string);
var
r: TInputRecord;
n, num: dword;
ss, ls: string;
hstdi, hFile: THandle;
begin
ss := ChToOem (s);
ls := LowerCase (ss);
r.EventType := KEY_EVENT;
hFile := CreateFile ('con', GENERIC_WRITE, FILE_SHARE_WRITE, nil,
OPEN_ALWAYS, 0, 0);
//hstdi := GetStdHandle (STD_INPUT_HANDLE);
for n := 1 to Length (ss) do
with r.event do
begin
if (ls [n] = ss [n]) then
KeyEvent.dwControlKeyState := 0
else
KeyEvent.dwControlKeyState := SHIFT_PRESSED;
KeyEvent.AsciiChar := ss [n];
KeyEvent.UnicodeChar := WideChar (ss [n]);
KeyEvent.wRepeatCount := 0;
case ss [n] of
#13, #10: KeyEvent.wVirtualKeyCode := VK_RETURN;
#$30..#$39: KeyEvent.wVirtualKeyCode := ord (ss [n]);
else KeyEvent.wVirtualKeyCode := ord (UpCase (ss [n]));
end;
KeyEvent.wVirtualScanCode := MapVirtualKey (KeyEvent.wVirtualKeyCode, 0);
KeyEvent.bKeyDown := true;
//WriteFile (hFile, ss [n], 1, num, nil);
WriteConsoleInput (Si.hStdInput, r, 1, num);
r.Event.KeyEvent.bKeyDown := false;
WriteConsoleInput (Si.hStdInput, r, 1, num);
end;
CloseHandle (hFile);
end;
var n: dword;
begin
ZeroMemory(@SI, SizeOf(SI));
si.cb := sizeof (si);
si.hStdInput := GetStdHandle(STD_INPUT_HANDLE);
// SetConsoleMode (si.hStdInput, ENABLE_PROCESSED_OUTPUT);
chdir ('C:\temp\rsa\');
CreateProcess(Nil, 'C:\temp\rsa\RSAKEYS.EXE -kg 512 << con', Nil, Nil, True, 0, Nil, Nil, SI, PI);
// CreateProcess(Nil, 'C:\Windows\system32\cmd.exe', Nil, Nil, True, 0, Nil, Nil, SI, PI);
Sleep (1000);
SendInputStr ('AfxName1234'#13);
Sleep (200);
FlushConsoleInputBuffer (si.hStdInput);
SendInputStr ('PWDUNIVERSAL'#13);
Sleep (200);
FlushConsoleInputBuffer (si.hStdInput);
SendInputStr ('PWDUNIVERSAL'#13);
Sleep (200);
FlushConsoleInputBuffer (si.hStdInput);
n := 0;
while (WaitForSingleObject (pi.hProcess, random (200) + 10) = WAIT_TIMEOUT) and
(n < 10) do
begin
SendInputStr ('QWERTY');
inc (n);
end;
CloseHandle (pi.hProcess);
// WaitForSingleObject (pi.hProcess, INFINITE);
///TerminateProcess (pi.hProcess, 0); // not wait process
// FreeConsole;
// readln (input);
end.
Logo (2005-06-23 06:55:00) [4]Вот код. Он запускает прогу и выводит вместо 12345 пять букв A.
{$APPTYPE CONSOLE}
uses SysUtils, Windows;
var
SI: TStartupInfo;
PI: TProcessInformation;
function ChToOem (const s: string): string;
var p: array [0..255] of char;
begin
CharToOemBuff (PChar (s), p, Length (s) + 1);
result := p;
end;
procedure SendInputStr (const s: string);
var
r: TInputRecord;
n, num: dword;
ss: string;
hstdi: THandle;
begin
ss := ChToOem (s);
r.EventType := KEY_EVENT;
//hstdi := GetStdHandle (STD_INPUT_HANDLE);
for n := 1 to Length (ss) do
with r.event do
begin
KeyEvent.bKeyDown := true;
KeyEvent.AsciiChar := ss [n];
KeyEvent.wRepeatCount := 0;
KeyEvent.wVirtualKeyCode := 0;
KeyEvent.wVirtualScanCode := 0;
WriteConsoleInput (Si.hStdInput, r, 1, num);
r.Event.KeyEvent.bKeyDown := false;
WriteConsoleInput (Si.hStdInput, r, 1, num);
end;
end;
begin
ZeroMemory(@SI, SizeOf(SI));
si.hStdInput := GetStdHandle(STD_INPUT_HANDLE);
AllocConsole;
CreateProcess(Nil, 'C:\temp\rsa\RSAKEYS.EXE -kg 512', Nil, Nil, True, 0, Nil, Nil, SI, PI);
Sleep(1000);
SendInputStr ('12345');
Sleep(1000);
// CloseHandle(PI.hThread);
// CloseHandle(PI.hProcess);
// FreeConsole;
end.
alpet (2005-06-22 10:32:00) [5]Код представь пожайлуста весь.
Logo (2005-06-22 07:51:00) [6]будете смеяться, но не могу добиться передачи login и password через delphi приложение. Передаются не те символы которые посылаются.
alpet (2005-06-15 11:43:00) [7]C нажатиями клавиш через файл нечего передавать не удается, видимо используются функции для проверки соостояния клавы (kbhit ???) которые не обманываются с помощью перехвата ввода (можно попробывать SetKeyboardStatus, внедрив dll в пространство ntdvm процесса).
Вот какое содержимое файла 1.txt программа воспринимает в качестве логина и пары паролей.
login
password
password
Logo (2005-06-15 11:23:00) [8]Попробовал создал в том же дельфи консольное приложение которое readln-ом получает данные. подставил вместо rsakeys.exe и все замечательно работает!
где копать? может сама прога что-то криво воспринимает?
Logo (2005-06-15 06:22:00) [9]Будешь смеяться, но я не могу корректно даже логин ей передать через WriteConsoleInput().
Через перенаправление ввода логин и первый пароль в нее попадают, второй тоже попадает но получаю сообщение о несовпадении пар паролей :( хотя в файле 1.txt они явно одинаковые
Одна из функций - объединение ключей после которого и надо нажимать лишь кнопку 'N'. После этого случайные символы не нужны но эффект тот же - зависон консоли.
Спасибо, что пытаешься помочь. Это редко бывает в наше время ;)
alpet (2005-06-14 15:32:00) [10]1. С этого надо было начинать.
2. Программа нормально получает логин и пару паролей, но затыкается когда дело доходит до произвольного текста. Собственно надо понять что она использует для оценки нажатия клавиши, возможно и не stdinput.
Попробуй после ввода логина и паролей отправлять символы, чередуя их с случайной задержкой:
for n := 1 to 100 do
begin
WriteConsoleInput (...); // some char
Sleep (random (100) + 100);
end;
Logo (2005-06-14 15:20:00) [11]Прога здесь - http://botchallenge.com/u/RSAKEYS.EXE
Это что-то наподобие PGP.
Например, комманда: RSAKEYS.EXE -KG 512, котрую я вызываю.
потом запрашивает ID Пользователя. Надо ввести, например, Пупкин.
Затем пароль два раза одинаковый, затем нажатия произвольных кнопок. После чего должны появиться два файла pubkeys и seckeys.
Когда делаю перенаправлением ввода консоль виснет.
alpet (2005-06-14 14:09:00) [12]Хм... А пример того что в консоли получается можно увидеть? И как та же программа (proga.exe) работает через echo или < перенаправления?
Пример файл 1.txt
echo start
dir
cd c:\windows
Если запустить cmd.exe < 1.txt он будет выполнять комманды файла так как если бы их вводил пользователь.
Logo (2005-06-14 13:43:00) [13]2 alpet Help!
Твой пример действительно работает. Вызывается консоль и в ней пишется то, что туда засылается. Но вот когда вместо консоли подсовываю свою DOS программку, в нее начинает выводится какой то бред.
вот кусок вставленного кода в твой пример.
==== BEG ====
var
SI: TStartupInfo;
PI: TProcessInformation;
begin
ZeroMemory(@SI, SizeOf(SI));
si.hStdInput := GetStdHandle(STD_INPUT_HANDLE);
AllocConsole;
CreateProcess(Nil, 'proga.EXE', Nil, Nil, True, 0, Nil, Nil, SI, PI);
Sleep(1000);
SendInputStr ('Test ');
end.
==== END ====
alpet (2005-05-31 14:48:00) [14]VMcL © (31.05.05 14:16) [12]
1. Абсолютно с вами согласен. Быстрее на целых 0.2%
2. И тут верно, функция моя пригодна лишь только для ShortString переменных, длиной не более 255 символов.
VMcL (2005-05-31 14:16:00) [15]>> alpet © (31.05.05 13:15) [10]
Если интересует быстродействие, то самый рулез приводить не к PChar, а к Pointer.
>> alpet © (31.05.05 10:50) [5]
Строк длинее 255 символов не бывает?
function StringToOEM(const S: AnsiString): AnsiString;
var
Len: Integer;
begin
Len := Length(S);
SetLength(Result, Len);
if Len > 0 then
Win32Check(CharToOEM(PChar(S), PChar(Result)));
end;
Digitman (2005-05-31 13:47:00) [16]
> alpet © (31.05.05 13:15) [10]
о производительности речи не идет.
alpet (2005-05-31 13:15:00) [17]Компилятору не фиолетово. При использовании приведении типа, код генерируется несколько другой, хотя разницы в результате и не наблюдается (только что 30% разница в быстродействии - приведение меньше времени занимает, но кому сейчас это интересно).
Digitman (2005-05-31 11:34:00) [18]
> alpet © (31.05.05 11:12) [8]
> работать будет, только выглядит криво
да почему криво ?
на вкус и цвет, как известно, товарищей нет - кому удобней воспринимать PChar(AnsiStrVar), а кому и @AnsiStrVar[1] .. компилятору же фиолетово)
alpet (2005-05-31 11:12:00) [19]2 Digitman
Ну да работать будет, только выглядит криво...
alpet (2005-05-31 11:10:00) [20]Пример консольного приложения в котором это все работает:
{$APPTYPE CONSOLE}
uses SysUtils, Windows;
function ChToOem (const s: string): string;
var p: array [0..255] of char;
begin
CharToOemBuff (PChar (s), p, Length (s) + 1); // + \0
result := p;
end;
procedure SendInputStr (const s: string);
var
r: TInputRecord;
n, num: dword;
ss: string;
hstdi: THandle;
begin
ss := ChToOem (s);
r.EventType := KEY_EVENT;
hstdi := GetStdHandle (STD_INPUT_HANDLE);
for n := 1 to Length (ss) do
with r.event do
begin
KeyEvent.bKeyDown := true;
KeyEvent.AsciiChar := ss [n];
KeyEvent.wRepeatCount := 0;
KeyEvent.wVirtualKeyCode := 0;
KeyEvent.wVirtualScanCode := 0;
WriteConsoleInput (hstdi, r, 1, num);
r.Event.KeyEvent.bKeyDown := false;
WriteConsoleInput (hstdi, r, 1, num);
end;
end;
begin
SendInputStr ('Test ');
SendInputStr ('Тест');
readln;
end.