Модераторы: Snowy, bartram, MetalFan, bems, Poseidon, Riply
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> DuplicateHandle() и чужие сокеты (\Device\Afd) 
:(
    Опции темы
ldr12
Дата 15.2.2007, 22:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 18
Регистрация: 9.2.2007

Репутация: 1
Всего: 1



Доброго времени суток.

Проблема такова: получаю список хендлов процесса с помощью NtQuerySystemInformation.

Выбираю из них файловые, а из них - сокеты. Делаю это, проверяя имя, ассоциированное с хендлом на соответствие строке \Device\Afd.

Но! Когда я хочу скопировать каждый из этих сокетов в свой процесс, то какой бы я хендл не выбрал - DuplicateHandle() возвращает всегда дескриптор на последнее открытое процессом подключение (тестировал на mirc.exe).

Как решить эту проблему? Или, быть может, есть более красивый способ получения сокетов процесса?

Код

...
ProcHandle := OpenProcess(PROCESS_DUP_HANDLE, False, PID);
...
if DuplicateHandle(ProcHandle, Info^.Information[Loop].Handle,
                         GetCurrentProcess, @CopiedHandle,
                         0, False, DUPLICATE_SAME_ACCESS) then
...
getpeername(CopiedHandle, r_sin, r_sin_len)
...

PM MAIL   Вверх
bartram
Дата 16.2.2007, 09:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Комодератор
Сообщений: 1606
Регистрация: 22.2.2004
Где: Russia, Samara

Репутация: 3
Всего: 29



А хендл у тебя вообще правильно копируется? Попробуй  для примера сравнить исходный хендл  с тем хендлом который ты уже скопировал

Добавлено @ 10:01 
приведи более полный код, попробую у себя проверить


--------------------
В каждом из нас спит гений, но с каждым днем все крепче ;-)
bartram.ru
Twitter
user posted image 

PM MAIL ICQ   Вверх
ldr12
Дата 16.2.2007, 22:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 18
Регистрация: 9.2.2007

Репутация: 1
Всего: 1



В том-то и дело, что неправильно smile Всегда копирует сокет к последнему подключению. 
А код вот он:
Обнаружил удивительное свойство - если убрать CloseHandle(), то выводиться будет все правильно. Интересно, отчего?

Memo1, Button1, Edit1

Код

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, Winsock;

type
  TForm1 = class(TForm)
    Memo1: TMemo;
    Button1: TButton;
    Edit1: TEdit;
    Label1: TLabel;
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

function ZwQuerySystemInformation(ASystemInformationClass: DWORD; ASystemInformation: Pointer;
  ASystemInformationLength: DWORD; AReturnLength: PCardinal): DWORD;
  stdcall; external 'ntdll.dll';

function ZwQueryObject(ObjectHandle, ObjectInformationClass: DWORD;
  ObjectInformation: Pointer; Length: DWORD; ReturnLength: PDWORD): DWORD;
  stdcall; external 'ntdll.dll';

const
  SYSTEM_HANDLE_INFORMATION = 16;

  STATUS_INFO_LENGTH_MISMATCH = $C0000004;
  STATUS_SUCCESS = $00000000;

  OB_TYPE_FILE_WIN2K = 26;
  OB_TYPE_FILE_WINXP = 28;

  OBJECT_NAME_INFORMATION = 1;

type
  TSYSTEM_HANDLE_INFORMATION = packed record
    ProcessId: DWORD;
    ObjectTypeNumber: Byte;
    Flags: Byte;
    Handle: Word;
    pObject: Pointer;
    GrantedAccess: DWORD;
  end;

  TSYSTEM_HANDLE_INFORMATION_EX = packed record
    NumberOfHandles: DWORD;
    Information: array [0..0] of TSYSTEM_HANDLE_INFORMATION;
  end;
  PSYSTEM_HANDLE_INFORMATION_EX = ^TSYSTEM_HANDLE_INFORMATION_EX;

  TUnicodeString = packed record
    Length: Word;
    MaximumLength: Word;
    Buffer: PWideChar;
  end;
  PUnicodeString = ^TUnicodeString;

implementation

{$R *.dfm}

function GetInfoTable(ATableType: DWORD; var ReturnLen: DWORD): Pointer;
var
  mSize: DWORD;
  mPtr: Pointer;
  St: DWORD;
  
begin
  Result := nil;
  mSize := $4000;

  repeat
    mPtr := VirtualAlloc(nil, mSize, MEM_COMMIT or MEM_RESERVE, PAGE_READWRITE);
    if mPtr = nil then
      Exit;

    St := ZwQuerySystemInformation(ATableType, mPtr, mSize, nil);

    if St = STATUS_INFO_LENGTH_MISMATCH then
    begin
      VirtualFree(mPtr, 0, MEM_RELEASE);
      mSize := mSize * 2;
      ReturnLen := mSize;
    end;
  until St <> STATUS_INFO_LENGTH_MISMATCH;

  if St = STATUS_SUCCESS then
    Result := mPtr else
    VirtualFree(mPtr, 0, MEM_RELEASE);
end;

procedure TForm1.Button1Click(Sender: TObject);
var
  Info: PSYSTEM_HANDLE_INFORMATION_EX;
  InfoSize, HandleNameLen, ObjectType, PID, hProcess, Loop, DstHandle, ReturnLen: DWORD;
  Version: TOSVersionInfo;
  HandleName: PUnicodeString;
  Filename: string;

  WSAData: TWSAData;

  r_sin: sockaddr_in;
  r_sin_len: Integer;

begin
  PID := StrToInt(Edit1.Text);
  hProcess := OpenProcess(PROCESS_DUP_HANDLE, False, PID);
  
  if hProcess = 0 then
  begin
    Memo1.Lines.Add('Process not accessible');
    Exit;
  end;

  Version.dwOSVersionInfoSize := SizeOf(TOSVersionInfo);
  GetVersionEx(Version);

  if Version.dwMajorVersion <> 5 then
  begin
    Memo1.Lines.Add('Unsupported Windows version');
    Exit;
  end;

  case Version.dwBuildNumber of
    2195: ObjectType := OB_TYPE_FILE_WIN2K;
    2600: ObjectType := OB_TYPE_FILE_WINXP;
  end;

  HandleNameLen := SizeOf(WideChar) * MAX_PATH;
  HandleName := VirtualAlloc(nil, SizeOf(TUnicodeString) + HandleNameLen,
                             MEM_COMMIT or MEM_RESERVE, PAGE_READWRITE);
  if HandleName = nil then
    Exit;
  HandleName^.MaximumLength := HandleNameLen;

  Info := GetInfoTable(SYSTEM_HANDLE_INFORMATION, InfoSize);

  if Info = nil then
  begin
    Memo1.Lines.Add('Cannot obtain system handle list');
    Exit;
  end;

  WSAStartup($202, WSAData);

  for Loop := 0 to Info^.NumberOfHandles - 1 do
    if Info^.Information[Loop].ProcessId = PID then
      if Info^.Information[Loop].ObjectTypeNumber = ObjectType then
        if DuplicateHandle(hProcess, Info^.Information[Loop].Handle,
                           GetCurrentProcess, @DstHandle,
                           0, False, DUPLICATE_SAME_ACCESS) then
        begin
          ZwQueryObject(DstHandle, OBJECT_NAME_INFORMATION, HandleName,
                        HandleNameLen, @ReturnLen);
          FileName := WideCharToString(HandleName^.Buffer);
                      
          if Pos('\Device\Afd', Filename) > 0 then
          begin
            r_sin_len := SizeOf(r_sin);
            FillChar(r_sin, SizeOf(r_sin), 0);
               
            if getpeername(DstHandle, r_sin, r_sin_len) = 0 then
              Memo1.Lines.Add('Addr: ' + inet_ntoa(r_sin.sin_addr) + ', Port: ' + IntToStr(ntohs(r_sin.sin_port)));
          end;

          CloseHandle(DstHandle);
        end;

  WSACleanup;

  VirtualFree(HandleName, SizeOf(TUnicodeString) + HandleNameLen, MEM_RELEASE);
  VirtualFree(Info, InfoSize, MEM_RELEASE);

  CloseHandle(hProcess);
end;

end.



Это сообщение отредактировал(а) ldr12 - 16.2.2007, 22:49
PM MAIL   Вверх
bartram
Дата 18.2.2007, 13:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Комодератор
Сообщений: 1606
Регистрация: 22.2.2004
Где: Russia, Samara

Репутация: 3
Всего: 29



ldr12, странно....
Первый раз запускаю - показывает
Второй раз запускаю без CloseHandle - показывает (тоже самое что и в первый раз)
И показывает все время локальный ip 127.0.0.1, хотя я в этот момент был подключен к инету....
Странно....посмотрю в чем проблема smile

Добавлено @ 13:13 
если без   CloseHandle(DstHandle); то все показывает, только убивает подключение с инетом у приложения на котором проверку проходит, но ip по прежнему локальный....


--------------------
В каждом из нас спит гений, но с каждым днем все крепче ;-)
bartram.ru
Twitter
user posted image 

PM MAIL ICQ   Вверх
ldr12
Дата 18.2.2007, 18:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 18
Регистрация: 9.2.2007

Репутация: 1
Всего: 1



Ага, убивает, все верно smile
Насчет локального ипа - еще интересней даже smile
У меня просто показывало последнее подключение вместо всех (т.е. 6 раз 65.54.11.234, допустим)

Windows 2000 SP4
PM MAIL   Вверх
bartram
Дата 18.2.2007, 19:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Комодератор
Сообщений: 1606
Регистрация: 22.2.2004
Где: Russia, Samara

Репутация: 3
Всего: 29



Цитата(ldr12 @  18.2.2007,  18:13 Найти цитируемый пост)
У меня просто показывало последнее подключение вместо всех (т.е. 6 раз 65.54.11.234, допустим)

У меня показывает локальный ip хотя я в инете сижу и у меня есть два разных ip один внешний, другой внутренний. Странно.
 Посмотрю ещё твой код более детально
 Тестил на WinXp Sp2.


Это сообщение отредактировал(а) bartram - 18.2.2007, 19:53


--------------------
В каждом из нас спит гений, но с каждым днем все крепче ;-)
bartram.ru
Twitter
user posted image 

PM MAIL ICQ   Вверх
ldr12
Дата 18.2.2007, 20:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 18
Регистрация: 9.2.2007

Репутация: 1
Всего: 1



Чтобы убедить себя в том, что исходные хендлы для копирования правильны (а я бы на твоем месте уже засомневался), попробуй заменить DUPLICATE_SAME_ACCESS на DUPLICATE_CLOSE_SOURCE и позапускать smile
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Delphi: WinAPI и системное программирование"
Snowybartram
MetalFanbems
PoseidonRrader
Riply

Запрещено:

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Литературу по Delphi обсуждаем здесь
  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь
  • 90% ответов на свои вопросы можно найти в DRKB (Delphi Russian Knowledge Base) - крупнейшем в рунете сборнике материалов по Дельфи
  • 99% ответов по WinAPI можно найти в MSDN Library, оставшиеся 1% здесь

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Snowy, bartram, MetalFan, bems, Poseidon, Rrader, Riply.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Delphi: WinAPI и системное программирование | Следующая тема »


 




[ Время генерации скрипта: 0.0662 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.