информационная безопасность
без паники и всерьез
 подробно о проектеRambler's Top100
Портрет посетителяГде водятся OGRыСтрашный баг в Windows
BugTraq.Ru
Русский BugTraq
 Анализ криптографических сетевых... 
 Модель надежности двухузлового... 
 Специальные марковские модели надежности... 
 Phrack #70/0x46 
 Возможно, Facebook наступил на... 
 50 лет электронной почте 
главная обзор RSN блог библиотека закон бред форум dnet о проекте
bugtraq.ru / форум / programming
Имя Пароль
ФОРУМ
все доски
FAQ
IRC
новые сообщения
site updates
guestbook
beginners
sysadmin
programming
operating systems
theory
web building
software
hardware
networking
law
hacking
gadgets
job
dnet
humor
miscellaneous
scrap
регистрация





Легенда:
  новое сообщение
  закрытая нитка
  новое сообщение
  в закрытой нитке
  старое сообщение
  • Напоминаю, что масса вопросов по функционированию форума снимается после прочтения его описания.
  • Новичкам также крайне полезно ознакомиться с данным документом.
В паскале разберёшься? Кину тебе пример кода, который запускает Regedit и переводит его на нужную ветку в его TreeView. 07.12.06 06:37  Число просмотров: 3649
Автор: HandleX <Александр М.> Статус: The Elderman
<"чистая" ссылка> <обсуждение закрыто>

Procedure ShowServiceRegKey(aServiceName: String; FormWnd: HWND);
Type
  TRemoteBuff = Record
    Item: TTVITEM;
    aStr: Packed Array[0..820] Of Char;
  End;
  pRemoteBuff = ^TRemoteBuff;

  Function GetSFieldCount(aStr: String; Delimiter: Char = #9): DWORD;
  Var TempP: PChar;
  Begin
    TempP := PChar(aStr);
    If aStr = '' Then Result := 0
    Else Result := 1;
    While TempP^ <> #0 Do
    Begin
      If TempP^ = Delimiter Then
        Inc(Result);
      Inc(TempP);
    End;
  End;

  Function GetSField(aStr: String; anIndex: DWord; Delimiter: Char = #9): String;
  Var
    TempP: PChar;
    Counter: DWORD;
    Ind1, Ind2: Integer;
  Begin
    Counter := 0;
    Result := '';
    TempP := PChar(aStr);
    Ind1 := -1; Ind2 := -1;
    While TempP^ <> #0 Do
    Begin
      If TempP^ = Delimiter Then Inc(Counter);
      If Counter = anIndex Then
        If Ind1 = -1 Then
          Ind1 := TempP - PChar(aStr);
      If Counter > anIndex Then
      Begin
        Ind2 := TempP - PChar(aStr);
        Break;
      End;
      Inc(TempP);
    End;
    If TempP^ = #0 Then
      Ind2 := StrEnd(PChar(aStr)) - PChar(aStr);
    If Ind1 <> 0 Then Inc(Ind1);
    Result := Copy(aStr, Ind1 + 1, Ind2 - Ind1)
  End;

  Procedure ConnectHostToRegedit(aRegMainWnd: HWND; aHostName: String);

    Function GetChildEditControl(aParent: HWND): HWND;
      Function EnumProc(aHwnd: HWND; RetValue: PDWORD): BOOL; StdCall;
      Var aBuff: String[255];
      Begin
        SetLength(aBuff, GetClassName(aHwnd, @aBuff[1], 254));

        If (OSVersion.dwMajorVersion >= 5) And (OSVersion.dwMinorVersion >= 1) Then Result := Not (aBuff = 'RichEdit20W')
        Else Result := Not (aBuff = 'Edit');

        If Not Result Then
          RetValue^ := aHwnd;
      End;
    Begin
      EnumChildWindows(aParent, @EnumProc, DWORD(@Result));
    End;

    Function GetWindowClass(aWnd: HWND): String;
    Begin
      SetLength(Result, 255);
      SetLength(Result, GetClassName(aWnd, PChar(Result), Length(Result)));
    End;

  Var
    fWnd, eWnd: HWND;
    mHndl, subMenu: HMENU;
    mID: Integer;
  begin
    If aRegMainWnd = 0 Then Exit;

    mHndl := GetMenu(aRegMainWnd);
    Win32Check(mHndl <> 0);

    subMenu := GetSubMenu(mHndl, 0);
    Win32Check(SubMenu <> 0);

    If (OSVersion.dwMajorVersion >= 5) And (OSVersion.dwMinorVersion >= 1) Then mID := GetMenuItemID(SubMenu, 6)
    Else mID := GetMenuItemID(SubMenu, 3);
    Win32Check(mID > 0);

    Win32Check(PostMessage(aRegMainWnd, WM_COMMAND, mID, 0));

    Repeat
      fWnd := GetForegroundWindow;
      Sleep(50);
    Until Pos('#', GetWIndowClass(fWnd)) <> 0;

    Win32Check(fWnd <> 0);

    eWnd := GetChildEditControl(fWnd);
    Win32Check(eWnd <> 0);

    Win32Check(SendMessage(eWnd, WM_SETTEXT, 0, DWORD(PChar(aHostName))) <> 0);

    SendMessage(fWnd, WM_KEYDOWN, 13, 0);
    SendMessage(fWnd, WM_KEYUP, 13, 0);

  End;

  Function MakeFintInAnotherProcess(aProcess: THandle; aRemBuff: PRemoteBuff; aHwnd: HWND; aKey: String): Boolean;

    Procedure WriteStrToBuff(aStr: String);
    Var
      aSrc: Pointer;
      aSize, Written: DWORD;
    Begin
      aSrc := PChar(aStr);
      aSize := Length(aStr) + 1;
      If aSize > High(aRemBuff.aStr) Then
        Raise Exception.Create('String is too long!');
      Win32Check(WriteProcessMemory(aProcess, @aRemBuff^.aStr, aSrc, aSize, Written));
      Win32Check(Written = aSize);
    End;

    Function ReadStrFromBuff: String;
    Var Readed: DWORD;
    Begin
      SetLength(Result, High(aRemBuff.aStr));
      Win32Check(ReadProcessMemory(aProcess, @aRemBuff.aStr, PChar(Result), High(aRemBuff.aStr), Readed));
      Win32Check(Readed = High(aRemBuff.aStr));
      SetLength(Result, StrLen(PChar(Result)));
    End;

    Function ReadStrFromAddr(anAddr: Pointer): String;
    Var
      Readed: DWORD;
      Buff: Char;
      pTemp: Pointer;
    Begin
      pTemp := anAddr;
      Result := '';
      Repeat
        Win32Check(ReadProcessMemory(aProcess, pTemp, @Buff, 1, Readed));
        Win32Check(Readed = 1);
        If Buff <> #0 Then
          Result := Result + Buff;
        Inc(DWORD(pTemp));
      Until Buff = #0;
    End;

    Procedure WriteItemToBuff(Const Item: TTVITEM);
    Var Written: DWORD;
    Begin
      Win32Check(WriteProcessMemory(aProcess, aRemBuff, @Item, SizeOf(Item), Written));
      Win32Check(Written = SizeOf(Item));
    End;

    Procedure ReadItemFromBuff(Var Item: TTVITEM);
    Var Readed: DWORD;
    Begin
      Win32Check(ReadProcessMemory(aProcess, aRemBuff, @Item, SizeOf(Item), Readed));
      Win32Check(Readed = SizeOf(Item));
    End;

    Function GetItemText(anItem: THandle): String;
    Var ItemParams: TTVITEM;
    Begin
      ZeroMemory(@ItemParams, SizeOf(ItemParams));
      ItemParams.mask := TVIF_TEXT;
      ItemParams.hItem := HTREEITEM(anItem);
      ItemParams.pszText := @aRemBuff.aStr;
      ItemParams.cchTextMax := 400;
      WriteItemToBuff(ItemParams);
      Win32Check(TreeView_GetItem(aHwnd, aRemBuff.Item));
      ReadItemFromBuff(ItemParams);
      If ItemParams.pszText = Nil Then Result := ''
      Else
        If ItemParams.pszText = @aRemBuff.aStr Then Result := ReadStrFromBuff
        Else Result := ReadStrFromAddr(ItemParams.pszText);
    End;

    Function FindChild(aParent: THandle; aText: String): THandle;
    Var
      anItem: THandle;
      Compares: Integer;
      TempStr: String;
    Begin
      Result := 0;
      anItem := DWORD(TreeView_GetNextItem(aHwnd, HTREEITEM(aParent), TVGN_CHILD));
      If anItem = 0 Then Exit;
      Repeat
        TempStr := GetItemText(anItem);
        Compares := AnsiCompareStr(aText, TempStr);
        If Compares = 0 Then Break;
        anItem := DWORD(TreeView_GetNextSibling(aHwnd, HTREEITEM(anItem)));
      Until anItem = 0;
      If Compares = 0 Then Result := anItem;
    End;

    Function FindNextItem(fromItem: THandle; aText: String): THandle;
    Var
      anItem: THandle;
      Compares: Integer;
      TempStr: String;
    Begin
      Result := 0;
      anItem := fromItem;
      If anItem = 0 Then Exit;
      Compares := -1;
      Repeat
        anItem := SendMessage(aHwnd, TVM_GETNEXTITEM, TVGN_NEXT, anItem);
        If anItem = 0 Then Break;
        TempStr := GetItemText(anItem);
        Compares := AnsiCompareText(aText, TempStr);
      Until Compares = 0;
      If Compares = 0 Then Result := anItem;
    End;

  Var
    anItem, TempItem: THandle;
    J, Max: Integer;
    TempStr: String;
  Begin

    Max := GetSFieldCount(aKey, '\') - 1;
    Result := Max >= 0;
    If Not Result Then Exit;

    anItem := DWORD(TreeView_GetRoot(aHwnd));
    Result := anItem <> 0;
    If Not Result Then Exit;

    If (MainForm.HostName <> '') AND (UpperCase(MainForm.HostName) <> UpperCase(LocalHostName)) Then
    Begin
      ConnectHostToRegedit(GetParent(aHwnd), MainForm.HostName);
      Repeat
        Sleep(100);
        TempItem := FindNextItem(DWORD(TreeView_GetRoot(aHwnd)), MainForm.HostName);
      Until TempItem <> 0;
      anItem := TempItem;
      Result := anItem <> 0;
      If Not Result Then Exit;
    End;

    Result := TreeView_Expand(aHwnd, HTREEITEM(anItem), TVE_EXPAND);
    If Not Result Then Exit;

    For J := 0 To Max Do
    Begin
      TempStr := GetSField(aKey, J, '\');
      anItem := FindChild(anItem, TempStr);
      Result := anItem <> 0;
      If Not Result Then Exit;
      TreeView_Expand(aHwnd, HTREEITEM(anItem), TVE_EXPAND);
      If J = Max Then
        Result := TreeView_SelectItem(aHwnd, HTREEITEM(anItem)) <> HTREEITEM(0);
    End;

  End;

  Function GetWindowProcessIDByTopmostWindowClass(aClass: String; Var aWnd: HWND): DWORD;
  begin
    Result := 0;
    aWnd := FindWindow(PChar(aClass), Nil);
    If aWnd = 0 Then Exit;
    GetWindowThreadProcessID(aWnd, @Result);
  End;

  Function GetChildTreeView(aParent: HWND): HWND;
    Function EnumProc(aHwnd: HWND; RetValue: PDWORD): BOOL; StdCall;
    Var aBuff: String[255];
    Begin
      SetLength(aBuff, GetClassName(aHwnd, @aBuff[1], 254));
      Result := Not (aBuff = 'SysTreeView32');
      If Not Result Then
        RetValue^ := aHwnd;
    End;
  Begin
    EnumChildWindows(aParent, @EnumProc, DWORD(@Result));
  End;

  Function ShellExecuteAndWaitForIdle(ExePath: String): THandle;
  Var anInfo: TShellExecuteInfo;
  Begin
    ZeroMemory(@anInfo, SizeOf(anInfo));
    anInfo.cbSize := SizeOf(anInfo);
    anInfo.fMask := SEE_MASK_NOCLOSEPROCESS;
    anInfo.Wnd := FormWnd;
    anInfo.lpVerb := 'Open';
    anInfo.lpFile := PChar(ExePath);
    anInfo.nShow := SW_SHOWNORMAL;
    If Not ShellExecuteEx(@anInfo) Then Abort;
    Result := anInfo.hProcess;
    Win32Check(WaitForInputIdle(Result, INFINITE) <> $FFFFFFFF);
  End;

Var
  pID, pHndl: THandle;
  rBuff: PRemoteBuff;
  aHwnd: HWND;
Begin
  pHndl := 0;
  pID := GetWindowProcessIDByTopmostWindowClass('RegEdit_RegEdit', aHwnd);
  If pId = 0 Then
    If GetLastError = ERROR_FILE_NOT_FOUND Then
    Begin
      pHndl := ShellExecuteAndWaitForIdle('regedit.exe');
      pID := GetWindowProcessIDByTopmostWindowClass('RegEdit_RegEdit', aHwnd);
      Win32Check(pID <> 0);
    End Else RaiseLastWin32Error
  Else pHndl := OpenProcess(PROCESS_ALL_ACCESS, False, pID);
  Win32Check(pHndl <> 0);
  Try
    If IsIconic(aHwnd) Then ShowWindow(aHwnd, SW_Restore);
    SetForegroundWindow(aHwnd);

    aHwnd := GetChildTreeView(aHwnd);
    Win32Check(aHwnd <> 0);

    rBuff := VirtualAllocEx(pHndl, Nil, SizeOf(rBuff), MEM_COMMIT, PAGE_READWRITE);
    Win32Check(rBuff <> Nil);
    Try
      If Not MakeFintInAnotherProcess(pHndl, rBuff, aHwnd, 'HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\' + aServiceName) Then
        Raise Exception.Create('Error dialing with Regedit ;-)');
    Finally
      Win32Check(VirtualFreeEx(pHndl, rBuff, 0, MEM_RELEASE) <> Nil);
    End;
  Finally
    CloseHandle(pHndl);
  End;
End;

---
<programming> Поиск 








Rambler's Top100
Рейтинг@Mail.ru


  Copyright © 2001-2021 Dmitry Leonov   Page build time: 0 s   Design: Vadim Derkach