Penulis Topik: [Delphi] Hidden Thread Detection  (Dibaca 10502 kali)

Offline meong

  • Pro100
  • ****
  • Tulisan: 121
  • Reputation: 203
    • Lihat Profil
[Delphi] Hidden Thread Detection
« pada: Juni 11, 2011, 04:02:30 PM »
Got borred today so code some snippet, maybe bisa dijadikan referensi...

Apa yang saya coding hari ini merupakan implementasi dari chat dengan teman saya ( fajar anggiawan ) 2 bulan yang lalu. Waktu itu saya tanya2 about bagaimana sih pcmedia mendeteksi stealty virus (virus yang menggunakan teknologi untuk menyembunyikan dirinya like code injection) berhubung pada waktu itu lagi gempar2nya virus ramnit. Om Fuajar pun memberikan kisi2 dalam mendeteksi virus like ramnit tersebut yaitu dengan :

- query all process
- query all thread in process
- each thread we check startaddress and get modulename
- thread yang tidak berada pada module tertentu kita bisa qoute sebagai suspicius thread

and the code looks like this

Kode: [Pilih]
program Project1;

uses
  windows, SysUtils, codesitelogging,
  JwaNative, JwaNtStatus, JwaWinType, JwaWinNt;

function NtSuccess(AStatus: LongInt): Boolean;
begin
  Result := AStatus >= 0;
  if not Result then
    SetLastError(RtlNtStatusToDosError(AStatus));
end;

Function GetInformation(Table: TSystemInformationClass): Pointer;
var
  mSize: dword;
  mPtr: Pointer;
  St: NTStatus;
begin
  Result := nil;
  mSize := $4000;
  repeat
    GetMem(mPtr, mSize);
    St := NTQuerySystemInformation(Table, mPtr, mSize, nil);
    if (St = STATUS_INFO_LENGTH_MISMATCH) then
    begin
      FreeMem(mPtr);
      mSize := mSize * 2;
    end;
  until St <> STATUS_INFO_LENGTH_MISMATCH;
  if (St = STATUS_SUCCESS) then
    Result := mPtr
  else
    FreeMem(mPtr);
end;

function ExOpenProcess(dwDesiredAccess: DWord; Id : DWord):THANDLE;
var
  hProcess: THANDLE;
  attr: OBJECT_ATTRIBUTES;
  cli: CLIENT_ID;
begin
  InitializeObjectAttributes(@attr, nil, 0, 0, nil);
  cli.UniqueProcess := THandle(Id);
  cli.UniqueThread := 0;
  result := 0;
  if NtSuccess(NtOpenProcess(@hProcess, dwDesiredAccess, @attr, @cli)) then result := hProcess
end;


function ExOpenThread(dwDesiredAccess: dword; Id: dword): THANDLE;
var
  hThread: THANDLE;
  attr: OBJECT_ATTRIBUTES;
  cli: CLIENT_ID;
begin
  InitializeObjectAttributes(@attr, nil, 0, 0, nil);
  cli.UniqueProcess := 0;
  cli.UniqueThread := THANDLE(Id);
  Result := 0;
  if NtSuccess(NtOpenThread(@hThread, dwDesiredAccess, @attr, @cli)) then
    Result := hThread
end;

Function GetThreadAddress(Handle: THANDLE): dword;
begin
  if not NtSuccess(NtQueryInformationThread(Handle,
    ThreadQuerySetWin32StartAddress, @Result, sizeof(dword), nil)) then
    exit(0);
end;

Function GetModuleFileNameByAddres(ph:THandle; Address : DWord):String;
var
  mSize,back: dword;
  mPtr: pointer;
  St: NTStatus;
begin
  result := '';
  mSize := 512;
  mPtr := AllocMem(mSize);
  St := NtQueryVirtualMemory(ph, Pointer(Address), MemorySectionName, mPtr,mSize,@back);
  if NtSuccess(st) then result :=strpas(PMEMORY_SECTION_NAME(mPtr).SectionFileName.Buffer);
  FreeMem(mPtr,mSize);
end;


Procedure ScanAllProcess;
var
  buffer: Pointer;
  pInfo: PSystemProcesses;
  i, ta: DWord;
  th, ph: THANDLE;
  modulename : string;
begin

  { Get SystemProcessesAndThreads Information }
  buffer := GetInformation(SystemProcessesAndThreadsInformation);
  if not assigned(buffer) then
  begin
{$IFDEF DebugMode}codesite.SendWinError('Get SystemProcessesAndThreadsInformation', getlasterror); {$ENDIF}
    exit;
  end;
  pInfo := PSystemProcesses(buffer);

  try

    { Enum All Process Info }
    repeat

      with pInfo^ do
      begin

        if (ProcessId <> 0) then
        begin

          { Check the processid, if not our process we need openaccess }
          if (ProcessId <> GetCurrentProcessID) then
          begin
            ph := ExOpenProcess(PROCESS_QUERY_INFORMATION or PROCESS_VM_READ, ProcessId);
            if (ph = INVALID_HANDLE_VALUE) or (ph=0) then
            begin
              //Skip the process if we cant open access
              if pInfo^.NextEntryDelta = 0 then break;
              pInfo := Pointer(dword(pInfo) + pInfo^.NextEntryDelta);
              continue;
            end;
          end else ph := GetCurrentProcess;

          { Process All Thread, in current process }
          for i := 0 to ThreadCount - 1 do
          begin

            { Open Access to thread }
            th := ExOpenThread(THREAD_QUERY_INFORMATION, Threads[i].ClientId.UniqueThread);
            if (th <> INVALID_HANDLE_VALUE) or (th <> 0) then
            begin

              { Get thread address and module name }
              ta := GetThreadAddress(Th);
              modulename := GetModuleFileNameByAddres(ph, ta);
              if modulename = '' then begin
                {process your suspisius thread handling here}
              end;
              codesite.Send('Procid %d / threadid %d / Address %d / %s ',[ProcessId,Threads[i].ClientId.UniqueThread, ta, modulename]);
            end;
          end;
        end;
      end;

      { Next Process }
      if pInfo^.NextEntryDelta = 0 then break;
      pInfo := Pointer(dword(pInfo) + pInfo^.NextEntryDelta);
    until false;

  finally
    FreeMem(buffer);
  end;

end;

begin
  try
    ScanAllProcess;
  except
    on E: Exception do
      Writeln(E.ClassName, ': ', E.Message);
  end;

end.

for salah2 coding mohon di fix sendiri yah, and big thumbs buat om fuajar and pcmav team...

linkinmyblog
http://cybercoding.wordpress.com/2011/05/25/delphi-hidden-thread-detection/

originalthread
http://virusindonesia.com/forum/viewtopic.php?id=930

Offline nova_edp

  • Pro500
  • ******
  • Tulisan: 817
  • Reputation: 26823
    • Lihat Profil
    • Toko Software dan Source Code Online
Re: [Delphi] Hidden Thread Detection
« Jawab #1 pada: Juni 13, 2011, 08:26:49 AM »
mantap om meong, ilmu yg sangat mahal nih...
tp syg om dsni coder delphi minim bgt...

Offline meong

  • Pro100
  • ****
  • Tulisan: 121
  • Reputation: 203
    • Lihat Profil
Re: [Delphi] Hidden Thread Detection
« Jawab #2 pada: Juni 14, 2011, 02:58:27 AM »
code itu soal gampang, konsep yang penting  \m/ \m/ \m/