Показать сообщение отдельно
Старый 21.01.2012, 00:10   #476
Пользователь
 
Аватар для Silent
 
Регистрация: 07.02.2011
Сообщений: 32
Сказал Спасибо: 8
Имеет 4 спасибок в 4 сообщенях
Silent пока неопределено
По умолчанию Need help

Доброго времени суток. Прошу подсказать неучу где я накосячил и как нужно правильно делать.
Почитал статьи Ms-Rem-а на wasm.ru по перехвату API функций, написал небольшой тестовый пример по перехвату функций из библиотеки wtsapi32, опробовал на своем проекте все нормально отрабатывает.
Код:
library WTSSession;

uses
  Windows,
  NativeAPI, Dialogs;

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


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

  _WTS_CONNECTSTATE_CLASS = (
    WTSActive,              // User logged on to WinStation
    WTSConnected,           // WinStation connected to client
    WTSConnectQuery,        // In the process of connecting to client
    WTSShadow,              // Shadowing another WinStation
    WTSDisconnected,        // WinStation logged on without client
    WTSIdle,                // Waiting for client to connect
    WTSListen,              // WinStation is listening for connection
    WTSReset,               // WinStation is being reset
    WTSDown,                // WinStation is down due to error
    WTSInit);               // WinStation in initialization
  {$EXTERNALSYM _WTS_CONNECTSTATE_CLASS}
  WTS_CONNECTSTATE_CLASS = _WTS_CONNECTSTATE_CLASS;
  {$EXTERNALSYM WTS_CONNECTSTATE_CLASS}
  TWtsConnectStateClass = WTS_CONNECTSTATE_CLASS;

  PWTS_SESSION_INFOW = ^WTS_SESSION_INFOW;
  {$EXTERNALSYM PWTS_SESSION_INFOW}
  _WTS_SESSION_INFOW = record
    SessionId: DWORD;              // session id
    pWinStationName: LPWSTR;       // name of WinStation this session is connected to
    State: WTS_CONNECTSTATE_CLASS; // connection state (see enum)
  end;
  {$EXTERNALSYM _WTS_SESSION_INFOW}
  WTS_SESSION_INFOW = _WTS_SESSION_INFOW;
  {$EXTERNALSYM WTS_SESSION_INFOW}
  TWtsSessionInfoW = WTS_SESSION_INFOW;
  PWtsSessionInfoW = PWTS_SESSION_INFOW;

var
 JmpWTS: far_jmp;
 OldWTS: OldCode;
 PtrWTS: pointer;

function WTSEnumerateSessionsW(hServer: THandle; Reserved: DWORD; Version: DWORD;
  var ppSessionInfo: PWTS_SESSION_INFOW; var pCount: DWORD): BOOL; stdcall; external 'wtsapi32.dll';

{$R *.res}

function TrueWTSEnumerateSessionsW(hServer: THandle; Reserved: DWORD; Version: DWORD;
  var ppSessionInfo: PWTS_SESSION_INFOW; var pCount: DWORD): BOOL; stdcall;
var Written: dword;
begin
WriteProcessMemory(INVALID_HANDLE_VALUE, PtrWTS, @OldWTS, SizeOf(OldCode), Written);
Result := WTSEnumerateSessionsW(hServer, Reserved, Version, ppSessionInfo,pCount);
WriteProcessMemory(INVALID_HANDLE_VALUE, PtrWTS, @JmpWTS, SizeOf(far_jmp), Written);
end;

function NewWTSEnumerateSessionsW(hServer: THandle; Reserved: DWORD; Version: DWORD;
  var ppSessionInfo: PWTS_SESSION_INFOW; var pCount: DWORD): BOOL; stdcall;
var i:Integer;
    SI: PWTS_SESSION_INFOW;
begin
Result := TrueWTSEnumerateSessionsW(hServer, Reserved, Version, ppSessionInfo, pCount);
SI := ppSessionInfo;
if Result then
  begin
    for i:= 0 to Pred(pCount) do
      begin
        ShowMessage(SI.pWinStationName);
        inc(SI);
      end;
  end
else
  ShowMessage('False');
end;

Procedure SetHook();
var
 Bytes: dword;
begin
  PtrWTS  := GetProcAddress(GetModuleHandle('wtsapi32.dll'), 'WTSEnumerateSessionsW');
  ReadProcessMemory(INVALID_HANDLE_VALUE, PtrWTS, @OldWTS, SizeOf(OldCode), Bytes);
  JmpWTS.PuhsOp  := $68;
  JmpWTS.PushArg := @NewWTSEnumerateSessionsW;
  JmpWTS.RetOp   := $C3;
  WriteProcessMemory(INVALID_HANDLE_VALUE, PtrWTS, @JmpWTS, SizeOf(far_jmp), Bytes);
end;

Procedure Unhook();
var
 Bytes: dword;
begin
  WriteProcessMemory(INVALID_HANDLE_VALUE, PtrWTS, @OldWTS, SizeOf(OldCode), Bytes);
end;

Function MessageProc(code : integer; wParam : word;
                    lParam : longint) : longint; stdcall;
begin
 CallNextHookEx(0, Code, wParam, lparam);
 Result := 0;
end;

procedure DLLEntryPoint(dwReason: DWord);
begin
  case dwReason of
    DLL_PROCESS_ATTACH: begin SetHook(); end;
    DLL_PROCESS_DETACH: begin Unhook(); end;
  end;
end;

begin
  DllProc := @DLLEntryPoint;
  DLLEntryPoint(DLL_PROCESS_ATTACH);
end.
Решил попробовать на примере Л2 перехватить функции и зашел в тупик, клиент постоянно валится в крит, причем перехват происходит т.к. валится уже при вызове оригинальной функции. Возможно кто-то сможет растолковать неучу где я накосячил.
Код:
library Red;

uses
  Windows,
  NativeAPI, Dialogs;

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


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

var
 JmpWTS: far_jmp;
 OldWTS: OldCode;
 PtrWTS: pointer;
 OriginalF: procedure(i:Integer); stdcall;

{$R *.res}

procedure CallF(i: Integer); stdcall;
asm
    mov     ecx, PtrWTS
    mov     esp, ebp
    pop     ebp
    jmp     [OriginalF]
end;

procedure NewF(i: Integer); stdcall;
begin
  CallF(i);
end;

procedure HookF(i: Integer); stdcall;
asm
  push    ecx
  push    [ebp+8]
  push    ecx
  call    NewF
  pop     ecx
end;

Procedure SetHook();
var
 Bytes: dword;
begin
  PtrWTS  := GetProcAddress(GetModuleHandle('engine.dll'), '?OnAcceptGameStart@UGameEngine@@UAEXH@Z');
  OriginalF := GetProcAddress(GetModuleHandle('engine.dll'), '?OnAcceptGameStart@UGameEngine@@UAEXH@Z');
  ReadProcessMemory(INVALID_HANDLE_VALUE, PtrWTS, @OldWTS, SizeOf(OldCode), Bytes);
  JmpWTS.PuhsOp  := $68;
  JmpWTS.PushArg := @HookF;
  JmpWTS.RetOp   := $C3;
  WriteProcessMemory(INVALID_HANDLE_VALUE, PtrWTS, @JmpWTS, SizeOf(far_jmp), Bytes);
end;

Procedure Unhook();
var
 Bytes: dword;
begin
  WriteProcessMemory(INVALID_HANDLE_VALUE, PtrWTS, @OldWTS, SizeOf(OldCode), Bytes);
end;

procedure DLLEntryPoint(dwReason: DWord);
begin
  case dwReason of
    DLL_PROCESS_ATTACH: begin SetHook(); end;
    DLL_PROCESS_DETACH: begin Unhook(); end;
  end;
end;

begin
  DllProc := @DLLEntryPoint;
  DLLEntryPoint(DLL_PROCESS_ATTACH);
end.
Буду признателен за любую помощь.
Silent вне форума   Ответить с цитированием