Penulis Topik: Example Monitor Api  (Dibaca 21632 kali)

Offline meong

  • Pro100
  • ****
  • Tulisan: 121
  • Reputation: 203
    • Lihat Profil
Example Monitor Api
« pada: Maret 08, 2010, 05:42:32 AM »
sebelum baca source codenya diharapkan dengan sangat membaca article yang saya buat about hooking disini :
http://jasakom.com/content.php?393-Hooking-With-Import-Table-Patching-in-Delphi

nah source codenya begini :
Kode: [Pilih]
library MyHooking;

uses
  windows;

const
Slotname = 'Info';

Type
  TApiMsg = record
    Pid :Dword;
    Apicall : array[0..89] of char;
  end;

  PIMAGE_OPTIONAL_HEADER32 = ^IMAGE_OPTIONAL_HEADER32;
  _IMAGE_OPTIONAL_HEADER = record
    Magic: Word;
    MajorLinkerVersion: Byte;
    MinorLinkerVersion: Byte;
    SizeOfCode: DWORD;
    SizeOfInitializedData: DWORD;
    SizeOfUninitializedData: DWORD;
    AddressOfEntryPoint: DWORD;
    BaseOfCode: DWORD;
    BaseOfData: DWORD;
    ImageBase: DWORD;
    SectionAlignment: DWORD;
    FileAlignment: DWORD;
    MajorOperatingSystemVersion: Word;
    MinorOperatingSystemVersion: Word;
    MajorImageVersion: Word;
    MinorImageVersion: Word;
    MajorSubsystemVersion: Word;
    MinorSubsystemVersion: Word;
    Win32VersionValue: DWORD;
    SizeOfImage: DWORD;
    SizeOfHeaders: DWORD;
    CheckSum: DWORD;
    Subsystem: Word;
    DllCharacteristics: Word;
    SizeOfStackReserve: DWORD;
    SizeOfStackCommit: DWORD;
    SizeOfHeapReserve: DWORD;
    SizeOfHeapCommit: DWORD;
    LoaderFlags: DWORD;
    NumberOfRvaAndSizes: DWORD;
    DataDirectory: array [0..IMAGE_NUMBEROF_DIRECTORY_ENTRIES - 1] of IMAGE_DATA_DIRECTORY;
  end;
  IMAGE_OPTIONAL_HEADER32 = _IMAGE_OPTIONAL_HEADER;

  PIMAGE_OPTIONAL_HEADER64 = ^IMAGE_OPTIONAL_HEADER64;
  _IMAGE_OPTIONAL_HEADER64 = record
    Magic: Word;
    MajorLinkerVersion: Byte;
    MinorLinkerVersion: Byte;
    SizeOfCode: DWORD;
    SizeOfInitializedData: DWORD;
    SizeOfUninitializedData: DWORD;
    AddressOfEntryPoint: DWORD;
    BaseOfCode: DWORD;
    ImageBase: Int64;
    SectionAlignment: DWORD;
    FileAlignment: DWORD;
    MajorOperatingSystemVersion: Word;
    MinorOperatingSystemVersion: Word;
    MajorImageVersion: Word;
    MinorImageVersion: Word;
    MajorSubsystemVersion: Word;
    MinorSubsystemVersion: Word;
    Win32VersionValue: DWORD;
    SizeOfImage: DWORD;
    SizeOfHeaders: DWORD;
    CheckSum: DWORD;
    Subsystem: Word;
    DllCharacteristics: Word;
    SizeOfStackReserve: Int64;
    SizeOfStackCommit: Int64;
    SizeOfHeapReserve: Int64;
    SizeOfHeapCommit: Int64;
    LoaderFlags: DWORD;
    NumberOfRvaAndSizes: DWORD;
    DataDirectory: array [0..IMAGE_NUMBEROF_DIRECTORY_ENTRIES - 1] of IMAGE_DATA_DIRECTORY;
  end;
  IMAGE_OPTIONAL_HEADER64 = _IMAGE_OPTIONAL_HEADER64;

  PIMAGE_NT_HEADERS32 = ^IMAGE_NT_HEADERS32;
  _IMAGE_NT_HEADERS = record
    Signature: DWORD;
    FileHeader: IMAGE_FILE_HEADER;
    OptionalHeader: IMAGE_OPTIONAL_HEADER32;
  end;
  IMAGE_NT_HEADERS32 = _IMAGE_NT_HEADERS;

  PIMAGE_NT_HEADERS64 = ^IMAGE_NT_HEADERS64;
  _IMAGE_NT_HEADERS64 = record
    Signature: DWORD;
    FileHeader: IMAGE_FILE_HEADER;
    OptionalHeader: IMAGE_OPTIONAL_HEADER64;
  end;
  IMAGE_NT_HEADERS64 = _IMAGE_NT_HEADERS64;

  TIIDUnion = record
    case Integer of
      0: (Characteristics: DWORD);         // 0 for terminating null import descriptor
      1: (OriginalFirstThunk: DWORD);      // RVA to original unbound IAT (PIMAGE_THUNK_DATA)
  end;

  PIMAGE_IMPORT_DESCRIPTOR = ^IMAGE_IMPORT_DESCRIPTOR;
  _IMAGE_IMPORT_DESCRIPTOR = record
    Union: TIIDUnion;
    TimeDateStamp: DWORD;                  // 0 if not bound,
                                           // -1 if bound, and real date\time stamp
                                           //     in IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT (new BIND)
                                           // O.W. date/time stamp of DLL bound to (Old BIND)

    ForwarderChain: DWORD;                 // -1 if no forwarders
    Name: DWORD;
    FirstThunk: DWORD;                     // RVA to IAT (if bound this IAT has actual addresses)
  end;
  IMAGE_IMPORT_DESCRIPTOR = _IMAGE_IMPORT_DESCRIPTOR;

  PIMAGE_THUNK_DATA32 = ^IMAGE_THUNK_DATA32;
  _IMAGE_THUNK_DATA32 = record
    case Integer of
      0: (ForwarderString: DWORD);   // PBYTE
      1: (Function_: DWORD);         // PDWORD
      2: (Ordinal: DWORD);
      3: (AddressOfData: DWORD);     // PIMAGE_IMPORT_BY_NAME
  end;
  IMAGE_THUNK_DATA32 = _IMAGE_THUNK_DATA32;

  PIMAGE_THUNK_DATA64 = ^IMAGE_THUNK_DATA64;
  _IMAGE_THUNK_DATA64 = record
    case Integer of
      0: (ForwarderString: ULONGLONG);   // PBYTE
      1: (Function_: ULONGLONG);         // PDWORD
      2: (Ordinal: ULONGLONG);
      3: (AddressOfData: ULONGLONG);     // PIMAGE_IMPORT_BY_NAME
  end;
  IMAGE_THUNK_DATA64 = _IMAGE_THUNK_DATA64;


{****PointerCheck*********************************************************************}
function MakePtr( AAddr: Pointer; Shift: Integer ): Pointer;
begin
  Result := Pointer( Integer(AAddr)+Shift );
end;
{---------------}
function IsBadReadPtrSize( Ptr: Pointer; Size: DWORD): Boolean;
var
  mbi: TMemoryBasicInformation;
const
  PAGE_READABLE = PAGE_READONLY or PAGE_EXECUTE_READWRITE or
                  PAGE_READWRITE or PAGE_EXECUTE_READ;
begin
  Result := VirtualQuery(Ptr, mbi, SizeOf(mbi)) <> 0;
  if Result then begin
    Result := (mbi.Protect = PAGE_NOACCESS) or ((mbi.Protect and PAGE_READABLE) = 0);
    if Result then exit;
    if Ptr<>mbi.BaseAddress then Inc(Size, DWORD(Ptr) - DWORD(mbi.BaseAddress) );
    if (Size<= mbi.RegionSize) then exit;
    while True do begin
      Result := (mbi.Protect = PAGE_NOACCESS) or ((mbi.Protect and PAGE_READABLE) = 0);
      if Result or (Size<= mbi.RegionSize) then break;
      Dec(Size, mbi.RegionSize);
      Ptr := Pointer(DWORD(mbi.BaseAddress) + mbi.RegionSize + 1);
      if VirtualQuery(Ptr, mbi, SizeOf(mbi)) = 0 then begin
        Result := True;
        break;
      end;
    end;
  end;
end;
{---------------}
function IsBadWritePtrSize( Ptr: Pointer; Size: DWORD): Boolean;
var
  mbi: TMemoryBasicInformation;
const
  PAGE_WRITABLE = PAGE_EXECUTE_WRITECOPY or PAGE_EXECUTE_READWRITE or
                  PAGE_READWRITE or PAGE_WRITECOPY;
begin
  Result := VirtualQuery(Ptr, mbi, SizeOf(mbi)) <> 0;
  if Result then begin
    Result := (mbi.Protect = PAGE_NOACCESS) or ((mbi.Protect and PAGE_WRITABLE)= 0);
    if Result then exit;
    if Ptr<>mbi.BaseAddress then Inc(Size, DWORD(Ptr) - DWORD(mbi.BaseAddress) );
    if (Size<= mbi.RegionSize) then exit;
    while True do begin
      Result := (mbi.Protect = PAGE_NOACCESS) or ((mbi.Protect and PAGE_WRITABLE)= 0);
      if Result or (Size<= mbi.RegionSize) then break;
      Dec(Size, mbi.RegionSize);
      Ptr := Pointer(DWORD(mbi.BaseAddress) + mbi.RegionSize + 1);
      if VirtualQuery(Ptr, mbi, SizeOf(mbi)) = 0 then begin
        Result := True;
        break;
      end;
    end;
  end;
end;
{******************************************************************************}

Function HookIAT(Handle :THandle; oldfunction,Newfunction:pointer):boolean;
var
ppfn: ppointer;
IDH : PImageDosHeader absolute Handle;
INH32 : PIMAGE_NT_HEADERS32;
INH64 : PIMAGE_NT_HEADERS64;
IID : PIMAGE_IMPORT_DESCRIPTOR;
ITD32 : PIMAGE_THUNK_DATA32;
ITD64 :PIMAGE_THUNK_DATA64;
FileIs64 : bool;
num_written,SaveFlag : DWORD;
begin
  result := false;
  if (Handle = 0 ) or IsBadCodePtr(oldfunction)  or IsBadCodePtr(Newfunction) then exit;
  if IsBadReadPtrSize( IDH, SizeOf(TImageDosHeader) ) or
    (IDH.e_magic <> IMAGE_DOS_SIGNATURE ) then exit;
  INH32 := MakePtr(IDH, IDH._lfanew);
  if IsBadReadPtrSize( INH32, SizeOf(PIMAGE_OPTIONAL_HEADER32)) or
  (INH32.Signature <> IMAGE_NT_SIGNATURE) then exit;
  if (INH32.OptionalHeader.Magic = $10B) then FileIs64 := false
  else if (INH32.OptionalHeader.Magic = $20B) then FileIs64 := false
  else exit;
  if (not FileIs64) then begin
    if (INH32.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress = 0) then exit;
    IID := MakePtr(IDH,INH32.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress);
    while (IID.Name <> 0) do begin
      ITD32 := MakePtr(IDH, Integer(IID.FirstThunk));
      while (ITD32 <> nil) and (ITD32.Function_ <> 0) do begin
        ppfn := @(ITD32.Function_);
        if PDWORD(ppfn^) = PDWORD(oldfunction) then begin
          VirtualProtect(ppfn, sizeof(dword), PAGE_READWRITE, @SaveFlag);
          WriteProcessMemory( GetCurrentProcess(), ppfn, @Newfunction, SizeOf(dword),num_written);
          VirtualProtect(ppfn, sizeof(dword), SaveFlag , @SaveFlag);
          result := true;
        end;
        inc(ITD32);
      end;
      inc(IID);
    end;
  end else begin
    INH64 := MakePtr(IDH, IDH._lfanew);
    if IsBadReadPtrSize( INH64, SizeOf(PIMAGE_OPTIONAL_HEADER64)) or
      (INH64.Signature <> IMAGE_NT_SIGNATURE) then exit;
    if (INH64.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress = 0) then exit;
    IID := MakePtr(IDH,INH64.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress);
    while (IID.Name <> 0) do begin
      ITD64 := MakePtr(IDH, Integer(IID.FirstThunk));
      while (ITD64 <> nil) and (ITD64.Function_ <> 0) do begin
        ppfn := @(ITD64.Function_);
        if PDWORD(ppfn^) = PDWORD(oldfunction) then begin
          VirtualProtect(ppfn, sizeof(ULONGLONG), PAGE_READWRITE, @SaveFlag);
          WriteProcessMemory( GetCurrentProcess(), ppfn, @Newfunction, sizeof(ULONGLONG),num_written);
          VirtualProtect(ppfn, sizeof(ULONGLONG), SaveFlag , @SaveFlag);
          result := true;
        end;
        inc(ITD64);
      end;
      inc(IID);
    end;
  end;
end;

function IsWin9x:Boolean;
asm
 MOV     EAX, FS:[030H]
 TEST    EAX, EAX
 SETS    AL
end;

function PHandleToPID(dwProcessHandle:DWord):DWord;
type
 TPI=packed record
       Reserved1      : Pointer;
       PebBaseAddress : Pointer;
       Reserved2      : array[0..1] of Pointer;
       UniqueProcessId: DWord;
       Reserved3      : Pointer;
     end;
 PPI=^TPI;
var
 NtQueryInformationProcess: function(dwHandle: DWord; dwInfo: DWord; pbi: PPI; dwSize: DWord; pData: Pointer): DWord; stdcall;
 pbi: TPI;
 dwDupCP: DWord;
begin
 Result:=0;
 if IsWin9x then Exit;
 @NtQueryInformationProcess:=GetProcAddress(GetModuleHandle('ntdll.dll'),'NtQueryInformationProcess');
 if (@NtQueryInformationProcess<>nil) then
   if DuplicateHandle(GetCurrentProcess, dwProcessHandle, GetCurrentProcess, @dwDupCP, PROCESS_ALL_ACCESS, False, 0) then begin
     if NtQueryInformationProcess(dwDupCP,0,@pbi,SizeOf(pbi),nil)=0 then
       Result:=pbi.UniqueProcessId;
     CloseHandle(dwDupCP);
   end;
end;

Procedure SendInfo(Msg: TApiMsg);
var
MailSlot: THandle;
BytesWritten: DWord;
begin
  MailSlot := CreateFile(PChar('\\.\mailslot\' +Slotname),
    GENERIC_WRITE, FILE_SHARE_READ, nil,
    OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
  if (MailSlot <> INVALID_HANDLE_VALUE) then begin
    WriteFile(MailSlot, Msg, SizeOf(Msg), BytesWritten, nil);
    CloseHandle(MailSlot);
  end;
end;

var
  OldMessageBox: function (hWnd: HWND; lpText, lpCaption: PWidechar; uType: UINT): Integer; stdcall;

function HookMessageBox(hWnd: HWND; lpText, lpCaption: PWidechar; uType: UINT): Integer; stdcall;
var
info :TApiMsg;
begin
  Result := OldMessageBox(hWnd,lpText,lpCaption,uType);
  info.Pid := PHandleToPID(getcurrentprocess);
  info.Apicall := 'MessageBoxW';
  SendInfo(info);
end;

procedure SetAPIHook;
begin
  oldmessagebox := GetProcAddress(GetModuleHandle('User32.dll'), 'MessageBoxW');
  HookIAT(hInstance,@oldmessagebox,@HookMessageBox);
end;

Procedure resethook;
begin
  HookIAT(hInstance,@HookMessageBox,@oldmessagebox);
end;

begin
  MessageBox(0, 'Test Message', 'Test Caption', 0);
  SetAPIHook;
  MessageBox(0, 'Test Message', 'Test Caption', 0);
  MessageBox(0, 'Test Message', 'Test Caption', 0);
  MessageBox(0, 'Test Message', 'Test Caption', 0);
  MessageBox(0, 'Test Message', 'Test Caption', 0);
  MessageBox(0, 'Test Message', 'Test Caption', 0);
  MessageBox(0, 'Test Message', 'Test Caption', 0);
  MessageBox(0, 'Test Message', 'Test Caption', 0);
  MessageBox(0, 'Test Message', 'Test Caption', 0);
  MessageBox(0, 'Test Message', 'Test Caption', 0);
  MessageBox(0, 'Test Message', 'Test Caption', 0);
end.

compile dan hasil compilednya diinject ke applikasi lain... pada applikasi yang telah terinject semua pemanggilan messagebox akan terrekam dan akan dikirimkan ke applikasi reader (interprocess communication using mailslot method).

adapun code dari applikasi reader
Kode: [Pilih]
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, ComCtrls, ExtCtrls;

type
  TForm1 = class(TForm)
    ListView1: TListView;
    Timer1: TTimer;
    procedure Timer1Timer(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

const
Slotname = 'Info';

Type
  TApiMsg = record
    Pid :Dword;
    Apicall : array[0..89] of char;
  end;

var
Slot : Thandle;
Msg:TapiMsg;

function MailSlotCreate( var MailSlot: THandle): Boolean;
var
  MailSlotName: string;
begin
  MailSlotName := ('\\.\mailslot\' +Slotname);
  MailSlot := CreateMailSlot(pchar(MailSlotName), 0, MAILSLOT_WAIT_FOREVER, nil);
  Result := (MailSlot <> INVALID_HANDLE_VALUE);
end;

function MailSlotRead(MailSlot: THandle; var Msg: TApiMsg): Boolean;
var
  BytesRead, Size: DWord;
  TmpMsg: TApiMsg;
  i: Integer;
begin
  Result := (GetMailSlotInfo(MailSlot, nil, Size, nil, nil)) and
    (Size <> MAILSLOT_NO_MESSAGE) and
    (ReadFile(MailSlot, Msg, SizeOf(Msg), BytesRead, nil)) and
    (BytesRead = SizeOf(Msg));
  for i := 1 to 3 do
  begin
    if not ((GetMailSlotInfo(MailSlot, nil, Size, nil, nil)) and
    (Size <> MAILSLOT_NO_MESSAGE) and
    (ReadFile(MailSlot, TmpMsg, SizeOf(Msg), BytesRead, nil)) and
    (BytesRead = SizeOf(TmpMsg))) then Break;
  end;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  if not MailSlotCreate(slot) then exit;
  timer1.Enabled := true;
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
  CloseHandle(slot);
end;

procedure TForm1.Timer1Timer(Sender: TObject);
var
a : Tlistitem;
begin
  if MailSlotRead(slot,msg) then begin
    a := listview1.Items.Add;
    a.Caption := inttostr(msg.Pid);
    a.SubItems.Add(msg.Apicall);
  end;
end;

end.

atau anda bisa mendownloadnya dibawah ini

http://rapidshare.com/files/360378516/test.rar atau attchement dibawah.

INFO:
- ini hanya contoh dari article saya sebelumnya
- pembelajaran tentang interprocess communication :D
- anda bisa menggunakan teknik hooking ini sebagai realtime protection pada antivirus but tentu saja dengan perubahan yang signifikan.
- hanya menggunakan method replace iat yang pastinya penuh dengan kekurangan

terakhir thanks and terimah kasi

Offline Ryan BeKaBe

  • Admin
  • Pro500
  • *******
  • Tulisan: 1.925
  • Reputation: 65534
  • ToS (Team of SmadAV)
    • Lihat Profil
    • BeKaBe
Re: Example Monitor Api
« Jawab #1 pada: Maret 09, 2010, 04:32:23 AM »
Wew, nice info.
Pakai Delphi (Pascal) ya?
Waduh, saya belum begitu ngerti nih mnerjemahkannya. Rekan Meong tau gak gmana alih bahasanya agar bisa diimplementasikan di VB?
Terima kasih banyak.
Kembangkan dan aplikasikan imajinasi mu!
Janganlah kau biarkan layu!
I believe you can do it!

Offline meong

  • Pro100
  • ****
  • Tulisan: 121
  • Reputation: 203
    • Lihat Profil
Re: Example Monitor Api
« Jawab #2 pada: Maret 09, 2010, 04:50:51 AM »
coba liat api yang digunakan and mesti ngerti strcuture pe

oh iya coba check attachement disini
http://www.vbforums.com/showthread.php?t=357051

keknya menarik untuk dipelajari tuh (vb code)

Offline Ryan BeKaBe

  • Admin
  • Pro500
  • *******
  • Tulisan: 1.925
  • Reputation: 65534
  • ToS (Team of SmadAV)
    • Lihat Profil
    • BeKaBe
Re: Example Monitor Api
« Jawab #3 pada: Maret 09, 2010, 01:43:05 PM »
Oke deh. Makasih yo! ;)
Kembangkan dan aplikasikan imajinasi mu!
Janganlah kau biarkan layu!
I believe you can do it!

Offline afnigates

  • Pro10
  • ***
  • Tulisan: 13
  • Reputation: 60
  • Jenis kelamin: Wanita
    • Lihat Profil
Re: Example Monitor Api
« Jawab #4 pada: Juni 05, 2012, 08:50:22 PM »
api itu apaan sih ?? :D
knowledge just for share

Offline RifqiSah

  • Pro500
  • ******
  • Tulisan: 919
  • Reputation: 820
  • Jenis kelamin: Pria
  • © 2016 Alrif Technology
    • Lihat Profil
    • Alrif Technology
Re: Example Monitor Api
« Jawab #5 pada: Agustus 22, 2012, 04:24:04 AM »
api itu apaan sih ?? :D

API = Application Programming Interface :D

CMIIW :D

Offline derit

  • Pro10
  • ***
  • Tulisan: 22
  • Reputation: 52
  • Jenis kelamin: Pria
    • Lihat Profil
Re: Example Monitor Api
« Jawab #6 pada: Desember 09, 2012, 01:28:59 PM »
api itu yg merah2 menyala ... ;D