Sources.RU Magazine Поиск по журналу
 

Ссылки

Автор: x2er0

Все прекрасно видели пароли, которые отображаются в виде звезд, например, пароли для DialUp'a. Можно ли уведеть, что скрывается за этими звездами, а если можно, то КАК?! Мы рассмотрим ситуацию с Windows 98.

Создадим небольшое приложение на Delphi. На форму положим 2 Edit'a и 1 Button. Для первого Edit'a свойство PasswordChar, в IDE, установим в '*'. Т.е. теперь все что мы пишем в данном Edit'e будет отображаться звездочками. По нажатию кнопки во второй Edit постараемся вывести, то что написано в первом, но в более читабельном виде.

Приступим...

С помощью EM_GETPASSWORDCHAR мы проверим, действительноли тутто, что нам надо. Ну а далее дело техники - обыкновенный WM_GETTEXT для получения текста.

procedure TForm1.Button1Click(Sender: TObject);
Var
  SecretText: PChar;
  Len: Integer;
begin
 If SendMessage(Edit1.Handle, EM_GETPASSWORDCHAR, 0, 0) <> 0 Then
 Begin
    Len := Length(Edit1.Text) + 1;
    GetMem(SecretText, Len);
     try
       SendMessage(Edit1.Handle, WM_GETTEXT, Len, Integer(SecretText));
       Edit2.Text := String(SecretText);
     finally
       FreeMem(SecretText);
     end;
 End;
end;

Вот и все секреты....

Этот способ, в Win98, прокатывал со всеми звездами, но в линейке NT он не работает...

Давайте посмотрим как можно подсмотреть что же скрывается за звездочками в более старших версииях ОС, например, Windows XP. Метод описанный для Win98 в данном случае не прокатывает, по-этому будем пробовать что-то другое... Т.к. сама ОС без проблем может взять этот пароль, то нам надо как-то представиться этой самой ОС. Мы попробуем представиться эксплорером и от его имени попросим, с помощью все того же WM_GETTEXT, показать нам наши звездочки. Что бы нам стать частью эксплорера нам необходимо попасть в его АП (адресное пространство). Это можно делать несолькими способами, мы попробуем через WriteProcessMemory() и CreateRemoteThread().

зы: в данном примере Handle окна с паролем я нахжу не программно, а с помощью утилитки WinSpy, т.к. для примера нам этого хватит!

Вот код:

unit Unit1;

interface

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

type
  TForm1 = class(TForm)
    Button1: TButton;
    Edit1: TEdit;
    procedure Button1Click(Sender: TObject);
  private
    function IsNt: boolean;
    function OptHdrOffSet(ptr: LongInt): DWORD;
    function SpawnThreadNT(pszProcess: PChar; g_hModule: HMODULE; EntryPoint: pointer): boolean;
  public
  end;

var
  Form1: TForm1;

implementation
 Uses tlhelp32;
{$R *.dfm}

function TForm1.IsNt: boolean;
var
  osvi: OSVERSIONINFO;
begin
  osvi.dwOSVersionInfoSize := sizeof(OSVERSIONINFO);
  If (not GetVersionEx(osvi)) Then
  Begin
    Result := FALSE;
    Exit;
  End;

  If(osvi.dwPlatformId <> VER_PLATFORM_WIN32_NT) Then
     result := FALSE
  Else
     result := TRUE;
end;

function TForm1.OptHdrOffSet(ptr: Integer): DWORD;
begin
  Result := PImageOptionalHeader(
                    int64(ptr) +
                    PImageDosHeader(ptr)._lfanew +
                    sizeof(DWORD) +
                    sizeof(IMAGE_FILE_HEADER)).SizeOfImage;
end;


function TForm1.SpawnThreadNT(pszProcess: PChar;
  g_hModule: HMODULE; EntryPoint: pointer): boolean;
var
        dwProcID: DWORD;
        hToolHelp: THandle;
pe: PROCESSENTRY32;
        hProc: THandle;
        dwSize: DWORD;
        pMem: Pointer;
dwOldProt, dwNumBytes, i: DWORD;
        mbi: TMemoryBasicInformation;
        dwRmtThdID: DWORD;
        hRmtThd: THandle;
begin
hToolHelp := CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
pe.dwSize := sizeof(pe);


        Result := false;
If (not Process32First(hToolHelp, pe)) Then exit;

        dwProcID := 0;
while (Process32Next(hToolHelp, pe)) do
begin
  If (lstrcmpi(pe.szExeFile, pszProcess) = 0) Then
  begin
  dwProcID := pe.th32ProcessID;
  break;
  end;
end;

If (dwProcID = 0) Then exit;

If (GetCurrentProcessId() = dwProcID) Then exit;

hProc := OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwProcID);
If (hProc = 0) Then exit;

VirtualFreeEx(hProc, ptr(g_hModule), 0, MEM_RELEASE);

dwSize := OptHdrOffSet(g_hModule);
pMem := VirtualAllocEx(hProc, ptr(g_hModule), dwSize, MEM_COMMIT or MEM_RESERVE, PAGE_EXECUTE_READWRITE);
if (pMem = nil) Then exit;

VirtualQueryEx(hProc, pMem, mbi, sizeof(MEMORY_BASIC_INFORMATION));
while ((mbi.Protect <> PAGE_NOACCESS) and (mbi.RegionSize <> 0)) do
        begin
 If ((mbi.Protect and PAGE_GUARD) = 0) then
         begin
           i := 0;
           while(i < mbi.RegionSize) do
   begin
      If (not VirtualProtectEx(hProc, ptr(DWORD(pMem) + i), $1000, PAGE_EXECUTE_READWRITE, dwOldProt))then
                   exit;
If (not WriteProcessMemory(hProc, ptr(DWORD(pMem) + i), Pointer(DWORD(g_hModule) + i), $1000, dwNumBytes)) Then
                   exit;
                i := i + $1000;
           end;
          pMem := Pointer(DWORD(pMem) + mbi.RegionSize);
  VirtualQueryEx(hProc, pMem, mbi, sizeof(MEMORY_BASIC_INFORMATION));
  end;
end;

hRmtThd := CreateRemoteThread(hProc, nil, 0, EntryPoint, ptr(g_hModule), 0, dwRmtThdID);
If (hRmtThd = 0) Then exit;
CloseHandle(hProc);
        Result := TRUE;
end;


procedure TForm1.Button1Click(Sender: TObject);
 Function GetHw: THandle;
 Begin
    Result := $002901C4;
 End;

 Function Entry: Boolean;
  Var
    Len: Integer;
    hw: THandle;
    hText: array[0..20] of char;
 Begin
    hw := GetHw();
    Len := SendMessage(hw, WM_GETTEXTLENGTH, 0, 0) + 1;
    If (Len > 1) Then
    Begin
        SendMessage(hw, WM_GETTEXT, 19, Integer(PChar(@hText)));
        messagebox(0, pchar(@htext), 'Passwd', 0);
    End;
    Result := True;
 End;

begin
 If IsNt() Then
 Begin
  SpawnThreadNT('EXPLORER.EXE', GetModuleHandle(nil), @Entry);
 End;
end;

end.

И самое главное, что бы этот проект РАБОТАЛ необходимо собрать его с ImageBase отличным от 400000. Я сделал $03140000.

Для того что бы его сменить делаем следущее: Shift+Ctrl+F11, закладка Linker, поле ImageBass, либо Ctrl+O+O и меняйте параметр директивы $IMAGEBASE на нужный!

Удачи!



 Desingn by Шишкин Алексей (Лёха).
 ©2004-2008 by sources.ru.