Форум программистов «Весельчак У»
  *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: [1]   Вниз
  Печать  
Автор Тема: изменение DCB у занятого com порта перехватом SetCommState  (Прочитано 14733 раз)
0 Пользователей и 1 Гость смотрят эту тему.
Grusha
Новенький

ru
Offline Offline

« : 16-12-2010 08:29 » 

мне нужно изменять скорость и четность у открытого, другой программой, com порта.
Делаю перехват функций CreateFileW и SetCommState,CreateFileW чтобы узнать хендл порта, через SetCommState собираюсь менять DCB.Buadrate, пока хочу просто зафиксировать момент установки параметров.

Dll перехвата взята из примера с перехватом Messagebox'ов, и она работает с Messagebox и CreateFileW, а с SetCommState в  result:= SetCommState(pPort,DCB), результат false.
Подскажите, пожалуйста, где тут ошибка и как ее исправить?
Код:
//----------------------------------------------------------------------------------
type
 OldCode = packed record
  One: dword;
  two: word;
 end;


far_jmp = packed record
  PuhsOp: byte;
  PushArg: pointer;
  RetOp: byte;
 end;

var
 hhPort:HWND;

 Jmp_CreateFileW, Jmp_SetCommState: far_jmp;
 Old_CreateFileW, Old_SetCommState: OldCode;

 CreateFileW_Adr, SetCommState_Adr: pointer;

//-----------------------------------------------------------------------------
function New_CreateFileW(  lpFileName:LPCWSTR;
                         dwDesiredAccess:DWORD;
                             dwShareMode:DWORD;
                    lpSecurityAttributes:PSecurityAttributes;
                   dwCreationDisposition:DWORD;
                    dwFlagsAndAttributes:DWORD;
                           hTemplateFile:HWND):HWND;stdcall
var
 Written: dword;
begin
  WriteProcessMemory(INVALID_HANDLE_VALUE, CreateFileW_Adr,
                     @Old_CreateFileW, SizeOf(OldCode), Written);
   
  Result := CreateFileW(lpFileName,dwDesiredAccess, dwShareMode,lpSecurityAttributes,
                                                               dwCreationDisposition,
                                                                dwFlagsAndAttributes,
                                                                      hTemplateFile);
 
  if   lpFileName='COM1' then
   begin
      MessageBox(0, 'COM1', '', 0);
      hhPort:=Result;
   end;
   
  WriteProcessMemory(INVALID_HANDLE_VALUE, CreateFileW_Adr,
                     @Jmp_CreateFileW, SizeOf(far_jmp), Written);
//-------------------------------------------------------------------------
function New_SetCommState(pPort:HWND; DCB:_DCB):LongBool; stdcall;
var
 Written: dword;
 wDCB:_DCB;
begin
 WriteProcessMemory(INVALID_HANDLE_VALUE, SetCommState_Adr,
                     @Old_SetCommState, SizeOf(OldCode), Written);

{здесь,pPort =hhPort, DCB.baudrate выдает непонятное число ,а GEtCommState(pPort,wDCB) в wDCB.baudrate установленную скорость 19200
}
  result:= SetCommState(pPort,DCB);

//? здесь result=false

   WriteProcessMemory(INVALID_HANDLE_VALUE, SetCommState_Adr,
                     @Jmp_SetCommState, SizeOf(far_jmp), Written);

end;
//----------------------------------------------------------------------
Procedure SetHook();
var
 hkernel32: dword;
 Bytes: dword;

begin
   hkernel32 := GetModuleHandle('kernel32.dll');

  CreateFileW_Adr  := GetProcAddress(hkernel32, 'CreateFileW');
  SetCommState_Adr  := GetProcAddress(hkernel32, 'SetCommState');

  ReadProcessMemory(INVALID_HANDLE_VALUE, CreateFileW_Adr, @Old_CreateFileW, SizeOf(OldCode), Bytes);
  ReadProcessMemory(INVALID_HANDLE_VALUE, SetCommState_Adr, @Old_SetCommState, SizeOf(OldCode), Bytes);

  Jmp_CreateFileW.PuhsOp  := $68;
  Jmp_CreateFileW.PushArg := @New_CreateFileW ;
  Jmp_CreateFileW.RetOp   := $C3;

  Jmp_SetCommState.PuhsOp  := $68;
  Jmp_SetCommState.PushArg := @New_SetCommState;
  Jmp_SetCommState.RetOp   := $C3;

  WriteProcessMemory(INVALID_HANDLE_VALUE, CreateFileW_Adr, @Jmp_CreateFileW, SizeOf(far_jmp), Bytes);
  WriteProcessMemory(INVALID_HANDLE_VALUE, SetCommState_Adr, @Jmp_SetCommState, SizeOf(far_jmp), Bytes);
end;

Записан
zubr
Модератор

by
Offline Offline
Пол: Мужской

« Ответ #1 : 16-12-2010 09:11 » 

А почему ты считаешь, что функция SetCommState не может выдавать False? Сделай вывод в лог-файл и смотри что и в каких процессах выдает данная функция.
Записан
Grusha
Новенький

ru
Offline Offline

« Ответ #2 : 16-12-2010 09:45 » 

я же прописываю, pPort:HWND; DCB:_DCB,  те же параметры что у исходной функции, ничего не меняю, вот и не понимаю почему false, мне кажется что в таком виде, перехвата вообще недолжно быть заметно,
хендл принадлежит нужному com порту,
и еще если сделать замену, вот так, как я предполагал меня подменять скорость

Код:
// в функции New_SetCommState после WriteProcessMemory(....

GetCommState(pPort,wDCB);

wDCB.BaudRate:= 19200;
wDCB.ByteSize:= 8;
wDCB.Parity:=NOPARITY;
wDCB.StopBits := ONESTOPBIT;


result:= SetCommState(pPort,wDCB);


то результат true, но программа которая открывает com порт, просто закрывается с ошибкой

"Access violation at address 0048B482 in module 'Com.exe'. Read of address 48B600F2"

Com.exe эта та программа которая открывает и опрашивает com порт.

"Сделай вывод в лог-файл и смотри что и в каких процессах выдает данная функция." как это сделать и что это даст объясните пожалуйста
Записан
zubr
Модератор

by
Offline Offline
Пол: Мужской

« Ответ #3 : 16-12-2010 10:44 » 

Честно говоря я вообще ничего не понял. Ты перехват делаешь в своем процессе или чужом? В какой системе сие действо происходит?
Если ты рабоатешь с чужим процессом, то как ты можешь определить что выдает перехватываемая функция, не используя лог-файл? Использовать для этой цели MessageBox - это очень кривое решение.
Записан
Grusha
Новенький

ru
Offline Offline

« Ответ #4 : 16-12-2010 11:59 » 

приведу весь код, может так будет понятней

AdvBox32.dll
Код:
//----------------------------------------------------------------------------------
library AdvBox32;

uses
  Windows,SysUtils;

type
 OldCode = packed record
  One: dword;
  two: word;
 end;


far_jmp = packed record
  PuhsOp: byte;
  PushArg: pointer;
  RetOp: byte;
 end;

var
 hhPort:HWND;

 Jmp_CreateFileW, Jmp_SetCommState: far_jmp;
 Old_CreateFileW, Old_SetCommState: OldCode;

 CreateFileW_Adr, SetCommState_Adr: pointer;

//-----------------------------------------------------------------------------
function New_CreateFileW(  lpFileName:LPCWSTR;
                         dwDesiredAccess:DWORD;
                             dwShareMode:DWORD;
                    lpSecurityAttributes:PSecurityAttributes;
                   dwCreationDisposition:DWORD;
                    dwFlagsAndAttributes:DWORD;
                           hTemplateFile:HWND):HWND;stdcall
var
 Written: dword;
begin
  WriteProcessMemory(INVALID_HANDLE_VALUE, CreateFileW_Adr,
                     @Old_CreateFileW, SizeOf(OldCode), Written);
    
  Result := CreateFileW(lpFileName,dwDesiredAccess, dwShareMode,lpSecurityAttributes,
                                                               dwCreationDisposition,
                                                                dwFlagsAndAttributes,
                                                                      hTemplateFile);
 
  if   lpFileName='COM1' then
   begin
      MessageBox(0, 'COM1', '', 0);
      hhPort:=Result;
   end;
  
  WriteProcessMemory(INVALID_HANDLE_VALUE, CreateFileW_Adr,
                     @Jmp_CreateFileW, SizeOf(far_jmp), Written);
//-------------------------------------------------------------------------
function New_SetCommState(pPort:HWND; DCB:_DCB):LongBool; stdcall;
var
 Written: dword;
 wDCB:_DCB;
begin
 WriteProcessMemory(INVALID_HANDLE_VALUE, SetCommState_Adr,
                     @Old_SetCommState, SizeOf(OldCode), Written);

{здесь,pPort =hhPort, DCB.baudrate выдает непонятное число ,а GEtCommState(pPort,wDCB) в wDCB.baudrate установленную скорость 19200
}
  result:= SetCommState(pPort,DCB);

//? здесь result=false

   WriteProcessMemory(INVALID_HANDLE_VALUE, SetCommState_Adr,
                     @Jmp_SetCommState, SizeOf(far_jmp), Written);

end;
//----------------------------------------------------------------------
//*******************************************************************************
Procedure SetHook();
var
 hkernel32: dword;
 Bytes: dword;

begin
   hkernel32 := GetModuleHandle('kernel32.dll');

  CreateFileW_Adr  := GetProcAddress(hkernel32, 'CreateFileW');
  SetCommState_Adr  := GetProcAddress(hkernel32, 'SetCommState');

  ReadProcessMemory(INVALID_HANDLE_VALUE, CreateFileW_Adr, @Old_CreateFileW, SizeOf(OldCode), Bytes);
  ReadProcessMemory(INVALID_HANDLE_VALUE, SetCommState_Adr, @Old_SetCommState, SizeOf(OldCode), Bytes);

  Jmp_CreateFileW.PuhsOp  := $68;
  Jmp_CreateFileW.PushArg := @New_CreateFileW ;
  Jmp_CreateFileW.RetOp   := $C3;

  Jmp_SetCommState.PuhsOp  := $68;
  Jmp_SetCommState.PushArg := @New_SetCommState;
  Jmp_SetCommState.RetOp   := $C3;

  WriteProcessMemory(INVALID_HANDLE_VALUE, CreateFileW_Adr, @Jmp_CreateFileW, SizeOf(far_jmp), Bytes);
  WriteProcessMemory(INVALID_HANDLE_VALUE, SetCommState_Adr, @Jmp_SetCommState, SizeOf(far_jmp), Bytes);
end;
//*******************************************************************************
Procedure Unhook();
var
 Bytes: dword;
begin
  WriteProcessMemory(INVALID_HANDLE_VALUE, SetCommState_Adr, @Old_SetCommState, SizeOf(OldCode), Bytes);
  WriteProcessMemory(INVALID_HANDLE_VALUE, CreateFileW_Adr, @Old_CreateFileW, SizeOf(OldCode), Bytes);
end;


//*******************************************************************************
Function MessageProc(code : integer; wParam : word;
                    lParam : longint) : longint; stdcall;
begin
 CallNextHookEx(0, Code, wParam, lparam);
 Result := 0;
end;
//*******************************************************************************
Procedure SetGlobalHookProc();
begin
 SetWindowsHookEx(WH_GETMESSAGE, @MessageProc, HInstance, 0);
 Sleep(INFINITE);
end;
//*******************************************************************************

Procedure SetGlobalHook();
var
 hMutex: dword;
 TrId: dword;
begin
 hMutex := CreateMutex(nil, false, 'AdvareHook');
 if GetLastError = 0 then
 CreateThread(nil, 0, @SetGlobalHookProc, nil, 0, TrId) else
 CloseHandle(hMutex);
end;

//*******************************************************************************
procedure DLLEntryPoint(dwReason: DWord);
begin
  case dwReason of
    DLL_PROCESS_ATTACH: begin
                          SetGlobalHook();
                          ii:=0;
                          Randomize();
                          SetHook()
                        end;
    DLL_PROCESS_DETACH: UnHook();
  end;
end;

//*******************************************************************************
begin
 DllProc := @DLLEntryPoint;
 DLLEntryPoint(DLL_PROCESS_ATTACH);
end.

и exe файл

AdvBox.exe
Код:
program AdwareBox;

uses
  Windows;

begin
 LoadLibrary('AdvBox32.dll');
 SLEEP(INFINITE);
end.



перехват в чужом процессе "com.exe", в windows xp,

про лог вы имеете ввиду, что нужно после снятия перехвата, сделать создание файла и запись туда значения pPort и DCB? , не особо понимю что это даст, и чем плох message box, но попробую сделать, других вариантов просто нет,
спасибо
« Последнее редактирование: 16-12-2010 12:36 от Джон » Записан
zubr
Модератор

by
Offline Offline
Пол: Мужской

« Ответ #5 : 16-12-2010 13:34 » 

Судя по всему прототип функции SetCommState не правильный. Я понимаю, что ты его взял из Borlandского модуля Windows, но к сожалению, я уже неоднократно замечал ошибки в прототипах функций.
Если верить MSDN, то прототип данной функции должен быть: function SetCommState(hFile: THandle; lpDCB: PDCB): BOOL; stdcall;
Записан
Grusha
Новенький

ru
Offline Offline

« Ответ #6 : 20-12-2010 06:13 » 

все работает, спасибо

вот в таком виде

Код:

function New_SetCommState(pPort:THandle;
                          p_DCB:PDCB):BOOL; stdcall;

var
  Written: dword;
   n_PDCB: _DCB;
 adr_PDCB: PDCB;
 
begin
 WriteProcessMemory(INVALID_HANDLE_VALUE, SetCommState_Adr,
                     @Old_SetCommState, SizeOf(OldCode), Written);
 //---------------------------------------------------------------

  adr_PDCB:=p_DCB;
  n_PDCB:= adr_PDCB^;

  if hhPort= pPort then
    begin
       n_PDCB.BaudRate :=9600;
       n_PDCB.Parity :=1;
    end;

   Result:= SetCommState(pPort,n_PDCB);

  //---------------------------------------------------------------
   WriteProcessMemory(INVALID_HANDLE_VALUE, SetCommState_Adr,
                     @Jmp_SetCommState, SizeOf(far_jmp), Written);
  //---------------------------------------------------------------
end;
Записан
Страниц: [1]   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines