Injected DLL Call Function

Delphi'de kod yazma ile ilgili sorularınızı bu foruma yazabilirsiniz.
anonymousdelphicoder
Üye
Mesajlar: 152
Kayıt: 16 May 2014 11:23

Injected DLL Call Function

Mesaj gönderen anonymousdelphicoder »

Kod: Tümünü seç

function TForm1.FindProcessByName(exeFileName: string): PPROCESSENTRY32;
var
  ContinueLoop: BOOL;
  FSnapshotHandle: THandle;
  FProcessEntry32: TProcessEntry32;
begin
Result := nil;
  FSnapshotHandle := CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
  FProcessEntry32.dwSize := SizeOf(FProcessEntry32);
  ContinueLoop := Process32First(FSnapshotHandle, FProcessEntry32);

  while Integer(ContinueLoop) <> 0 do
  begin
    if ((UpperCase(ExtractFileName(FProcessEntry32.szExeFile)) =
      UpperCase(ExeFileName)) or (UpperCase(FProcessEntry32.szExeFile) =
      UpperCase(ExeFileName))) then
    begin
     New(Result);
     Result^ := FProcessEntry32;
    end;
    ContinueLoop := Process32Next(FSnapshotHandle, FProcessEntry32);
  end;
  CloseHandle(FSnapshotHandle);
end;
Bu kod ile ilgili exenin Process ini buluyorum.

Kod: Tümünü seç

function TForm1.InjectDLL(dwPID: DWORD; DLLPath: PWideChar): integer;
var
  dwThreadID: Cardinal;
  hProc, hThread, hKernel: THandle;
  BytesToWrite, BytesWritten: SIZE_T;
  pRemoteBuffer, pLoadLibrary: Pointer;
  hExitCode:Cardinal;
begin
  hProc := OpenProcess(PROCESS_ALL_ACCESS, False, dwPID);
  if hProc = 0 then Exit;
  try

    BytesToWrite := SizeOf(WideChar) * (Length(DLLPath) + 0);


    pRemoteBuffer := VirtualAllocEx(hProc, nil, BytesToWrite, MEM_COMMIT, PAGE_READWRITE);
    if pRemoteBuffer = nil then
      exit(0);
    try
      if not WriteProcessMemory(hProc, pRemoteBuffer, DLLPath, BytesToWrite, BytesWritten) then
        Exit;

      hKernel := GetModuleHandle('kernel32.dll');
      pLoadLibrary := GetProcAddress(hKernel, 'LoadLibraryW');
      hThread := CreateRemoteThread(hProc, nil, 0, pLoadLibrary, pRemoteBuffer, 0, dwThreadID);



      try
        WaitForSingleObject(hThread, INFINITE);

      finally
        CloseHandle(hThread);
      end;
    finally
      VirtualFreeEx(hProc, pRemoteBuffer, 0, MEM_RELEASE);
    end;
  finally
    CloseHandle(hProc);
  end;

end;


Burada ise bulduğum Process'e DLL imi inject ediyorum
DLL imde CallMsg isminde StdCall mekanizmasına sahip Export edilmiş bir Prosedürüm var.

Benim yapmak istediğim şu örneğin ben "notepad.exe" ye DLL i Inject ettim ve daha sonra "notepad.exe" içinde bulunan DLL in yine o proses de çalışcak sekilde CallMsg methodumu çağırmak istiyorum. Eğer parametreli yapabilirsem yapmak istediğim tam olacak 2 gün dür uğraşıyorum internette aramadığım yer kalmadı ama çalışan bir örnek bulamadım yardımlarınızı bekliyorum.

Saygılar
thelvaci
Kıdemli Üye
Mesajlar: 770
Kayıt: 11 Tem 2010 07:17
Konum: Istanbul
İletişim:

Re: Injected DLL Call Function

Mesaj gönderen thelvaci »

Inject ettiğin DLL'in içinde tanımlı olan metodun; hangi durumda çağrılacak ? Eğer istediğin herhangi bir an çağrılabilsin diyorsan; bu durumda DLL'in Process Attach bölümünde bir thread create edip, içinde bir soket oluşurup (yada IPC mekanizmalarından herhangi birisini kullanıp) istediğini yapabilirsin diye düşünüyorum.
Kullanıcı avatarı
G.Arkas
Üye
Mesajlar: 829
Kayıt: 01 Eki 2007 07:16
Konum: İstanbul
İletişim:

Re: Injected DLL Call Function

Mesaj gönderen G.Arkas »

daha sonra "notepad.exe" içinde bulunan DLL in yine o proses de çalışcak sekilde CallMsg methodumu çağırmak istiyorum
Buradan anladığım kadarıyla açıklamaya çalışacağım. (Yanlışşam düzelt lütfen)

Zaten Notepad.exe'ye enjekte olan dll. O prosess'de notepad.exe'nin ID si ile çalışır. Yani PID değeri = Notepad.exe nin PID'i;

Burada senin aynı process içerisinde demekten kastın notepad.exe üzerinden fonksiyonu çağırmak demek oluyor herhalde :?:

Bunun için MemoryExecute kullanabilirsin. Memory deki ilgili çalışan process'in üzerinden enjekte olan dll yada .exe nin içerinden uygulamayı çalıştırabilirsin.

Aşağıda ki Unit işini görecektir.

Kod: Tümünü seç

unit uExecFromMem;

interface

uses Windows;

function ExecuteFromMem(szFilePath:string; pFile:Pointer):DWORD;

type
  PImageBaseRelocation = ^TImageBaseRelocation;
  TImageBaseRelocation = packed record
     VirtualAddress: DWORD;
     SizeOfBlock: DWORD;
  end;

function NtUnmapViewOfSection(ProcessHandle:DWORD; BaseAddress:Pointer):DWORD; stdcall; external 'ntdll';

implementation

procedure PerformBaseRelocation(f_module: Pointer; INH:PImageNtHeaders; f_delta: Cardinal); stdcall;
var
  l_i: Cardinal;
  l_codebase: Pointer;
  l_relocation: PImageBaseRelocation;
  l_dest: Pointer;
  l_relInfo: ^Word;
  l_patchAddrHL: ^DWord;
  l_type, l_offset: integer;
begin
  l_codebase := f_module;
  if INH^.OptionalHeader.DataDirectory[5].Size > 0 then
  begin
    l_relocation := PImageBaseRelocation(Cardinal(l_codebase) + INH^.OptionalHeader.DataDirectory[5].VirtualAddress);
    while l_relocation.VirtualAddress > 0 do
    begin
      l_dest := Pointer((Cardinal(l_codebase) + l_relocation.VirtualAddress));
      l_relInfo := Pointer(Cardinal(l_relocation) + 8);
      for l_i := 0 to (trunc(((l_relocation.SizeOfBlock - 8) / 2)) - 1) do
      begin
        l_type := (l_relInfo^ shr 12);
        l_offset := l_relInfo^ and $FFF;
        if l_type = 3 then
        begin
          l_patchAddrHL := Pointer(Cardinal(l_dest) + Cardinal(l_offset));
          l_patchAddrHL^ := l_patchAddrHL^ + f_delta;
        end;
        inc(l_relInfo);
      end;
      l_relocation := Pointer(cardinal(l_relocation) + l_relocation.SizeOfBlock);
    end;
  end;
end;

function AlignImage(pImage:Pointer):Pointer;
var
  IDH:          PImageDosHeader;
  INH:          PImageNtHeaders;
  ISH:          PImageSectionHeader;
  i:            WORD;
begin
  IDH := pImage;
  INH := Pointer(DWORD(pImage) + IDH^._lfanew);
  GetMem(Result, INH^.OptionalHeader.SizeOfImage);
  ZeroMemory(Result, INH^.OptionalHeader.SizeOfImage);
  CopyMemory(Result, pImage, INH^.OptionalHeader.SizeOfHeaders);
  for i := 0 to INH^.FileHeader.NumberOfSections - 1 do
  begin
    ISH := Pointer(DWORD(pImage) + IDH^._lfanew + 248 + i * 40);
    CopyMemory(Pointer(DWORD(Result) + ISH^.VirtualAddress), Pointer(DWORD(pImage) + ISH^.PointerToRawData), ISH^.SizeOfRawData);
  end;
end;

function ExecuteFromMem(szFilePath:string; pFile:Pointer):DWORD;
var
  PI:           TProcessInformation;
  SI:           TStartupInfo;
  CT:           TContext;
  IDH:          PImageDosHeader;
  INH:          PImageNtHeaders;
  dwImageBase:  DWORD;
  pModule:      Pointer;
  dwNull:       DWORD;
begin
  Result := 0;
  IDH := pFile;
  if IDH^.e_magic = IMAGE_DOS_SIGNATURE then
  begin
    INH := Pointer(DWORD(pFile) + IDH^._lfanew);
    if INH^.Signature = IMAGE_NT_SIGNATURE then
    begin
      FillChar(SI, SizeOf(TStartupInfo), #0);
      FillChar(PI, SizeOf(TProcessInformation), #0);
      SI.cb := SizeOf(TStartupInfo);
      if CreateProcess(nil, PChar(szFilePath), nil, nil, FALSE, CREATE_SUSPENDED, nil, nil, SI, PI) then
      begin
        CT.ContextFlags := CONTEXT_FULL;
        if GetThreadContext(PI.hThread, CT) then
        begin
          ReadProcessMemory(PI.hProcess, Pointer(CT.Ebx + 8), @dwImageBase, 4, dwNull);
          if dwImageBase = INH^.OptionalHeader.ImageBase then
          begin
            if NtUnmapViewOfSection(PI.hProcess, Pointer(INH^.OptionalHeader.ImageBase)) = 0 then
              pModule := VirtualAllocEx(PI.hProcess, Pointer(INH^.OptionalHeader.ImageBase), INH^.OptionalHeader.SizeOfImage, MEM_COMMIT or MEM_RESERVE, PAGE_EXECUTE_READWRITE)
            else
              pModule := VirtualAllocEx(PI.hProcess, nil, INH^.OptionalHeader.SizeOfImage, MEM_COMMIT or MEM_RESERVE, PAGE_EXECUTE_READWRITE);
          end
          else
            pModule := VirtualAllocEx(PI.hProcess, Pointer(INH^.OptionalHeader.ImageBase), INH^.OptionalHeader.SizeOfImage, MEM_COMMIT or MEM_RESERVE, PAGE_EXECUTE_READWRITE);
          if pModule <> nil then
          begin
            pFile := AlignImage(pFile);
            if DWORD(pModule) <> INH^.OptionalHeader.ImageBase then
            begin
              PerformBaseRelocation(pFile, INH, (DWORD(pModule) - INH^.OptionalHeader.ImageBase));
              INH^.OptionalHeader.ImageBase := DWORD(pModule);
              CopyMemory(Pointer(DWORD(pFile) + IDH^._lfanew), INH, 248);
            end;
            WriteProcessMemory(PI.hProcess, pModule, pFile, INH.OptionalHeader.SizeOfImage, dwNull);
            WriteProcessMemory(PI.hProcess, Pointer(CT.Ebx + 8), @pModule, 4, dwNull);
            CT.Eax := DWORD(pModule) + INH^.OptionalHeader.AddressOfEntryPoint;
            SetThreadContext(PI.hThread, CT);
            ResumeThread(PI.hThread);
            FreeMem(pFile, INH^.OptionalHeader.SizeOfImage);
            Result := PI.hThread;
          end;
        end;
      end;
    end;
  end;
end;

end.
Resim
anonymousdelphicoder
Üye
Mesajlar: 152
Kayıt: 16 May 2014 11:23

Re: Injected DLL Call Function

Mesaj gönderen anonymousdelphicoder »

Sayin tugrul hocam tesekkur ederim soket uygulamasi biraz tuhaf geliyor bana fakat guzel yontem evet istedigim zaman methodu cagirip return yapmak istiyorum ipc mekanizmasi nedir bilmiyorum imkaniniz varsa bi ornek verebilir misiniz ?

Sayin G.Arkas ilgili ornek icin tesekkur ederim dogru anlamissiniz yani Injecte olmus DLL in icindeki methodlari cagirmak istiyorum ama orneginizde bunu.goremedim

Saygilar
anonymousdelphicoder
Üye
Mesajlar: 152
Kayıt: 16 May 2014 11:23

Re: Injected DLL Call Function

Mesaj gönderen anonymousdelphicoder »

Yardim etcek kimse yok mu
thelvaci
Kıdemli Üye
Mesajlar: 770
Kayıt: 11 Tem 2010 07:17
Konum: Istanbul
İletişim:

Re: Injected DLL Call Function

Mesaj gönderen thelvaci »

IPC dediğimiz şey Interprocess Communication'un kısaltılmış hali. Yani process'ler arası haberleşme diyelim biz kabaca. Bunun için pek çok yöntem mevcut.

Interprocess Communications

Yukarıdaki msdn linkinden de görebileceğin üzere uygulamalar arası haberleşmenin pek çok yolu var, bunlardan birisini seç beğen kullan ;)
anonymousdelphicoder
Üye
Mesajlar: 152
Kayıt: 16 May 2014 11:23

Re: Injected DLL Call Function

Mesaj gönderen anonymousdelphicoder »

çok sagolun hocam teşekkür ederim araştıracağım :)
anonymousdelphicoder
Üye
Mesajlar: 152
Kayıt: 16 May 2014 11:23

Re: Injected DLL Call Function

Mesaj gönderen anonymousdelphicoder »

bu arada hocam soket haberlesmesi kullanmak bi yerde mantıklı fakat söyle bi engel var soketi dinlemeye aldığımız zaman ilk dinlemede izin isteyecek kullanıcın karşısına bunu çıkartması sorun aksi halde çok basit ve kullanıslı bir yol aslında.
anonymousdelphicoder
Üye
Mesajlar: 152
Kayıt: 16 May 2014 11:23

Re: Injected DLL Call Function

Mesaj gönderen anonymousdelphicoder »

bilgilendirme açısından muhteşem bir IPC Server Client kütüphanesi buldum

http://www.cromis.net/blog/downloads/cromis-ipc/


senkron ve asenkron desteği mevcut integer,float, datetime, string vs en önemlisi Stream yazabilme kabiliyetine sahip kullanımı oldukçada basit ilgili arkadaslara duyurulur :)
thelvaci
Kıdemli Üye
Mesajlar: 770
Kayıt: 11 Tem 2010 07:17
Konum: Istanbul
İletişim:

Re: Injected DLL Call Function

Mesaj gönderen thelvaci »

anonymousdelphicoder yazdı:bilgilendirme açısından muhteşem bir IPC Server Client kütüphanesi buldum

http://www.cromis.net/blog/downloads/cromis-ipc/


senkron ve asenkron desteği mevcut integer,float, datetime, string vs en önemlisi Stream yazabilme kabiliyetine sahip kullanımı oldukçada basit ilgili arkadaslara duyurulur :)
İyi bir kaynaktır ama önce temellerini öğrenmeni beklerdim, senin yapına ters al kullan olayı.
xxxjedixxx
Üye
Mesajlar: 216
Kayıt: 10 Ara 2013 03:50

Re: Injected DLL Call Function

Mesaj gönderen xxxjedixxx »

Merhaba,

İlave olarak ben de bir öneride bulunmak istiyorum.

1. Aşama: Dll'i kontrol edeceğin programa gizli bir form yap ve adını farklı olacak şekilde mesela "MyDllControlWindow" gibi bir şey yap. Yaptırmak istediğin komutları bu formun Caption'ına yazacaksın.

2. Aşama: Dll'i enjekte ettikten sonra thread içerisinde belli aralıklarda FindWindow('TMyDllControlWindow', nil) ile bu gizli formun handle'ını yakala ve GetwindowText api'si ile bu formun text'ini (Caption) oku.

Çok amatör gibi görünebilir ama pratik bir çözüm. Bu yöntemi bizzat denedim çalışıyor.
anonymousdelphicoder
Üye
Mesajlar: 152
Kayıt: 16 May 2014 11:23

Re: Injected DLL Call Function

Mesaj gönderen anonymousdelphicoder »

Tugrul hocam banada ters zaten size kesinlikle katiliyorum fakat oncelik olarak isin tamamlanmasina yon verdim daha sonra es gectigim noktalara donup ogrenecegim.

Jedi arkadasim cok tesekkur.ederim fikrin oldukca guzel cift yonlu alisveris yaptiracagim dll den.exe ye.exeden dll e. Sanirim dll de de bir form acarak bu isi halledebilirim
thelvaci
Kıdemli Üye
Mesajlar: 770
Kayıt: 11 Tem 2010 07:17
Konum: Istanbul
İletişim:

Re: Injected DLL Call Function

Mesaj gönderen thelvaci »

AutoReset Event yada mutex'de kullanabilirsin; bir fikir vereyim dedim ;)
anonymousdelphicoder
Üye
Mesajlar: 152
Kayıt: 16 May 2014 11:23

Re: Injected DLL Call Function

Mesaj gönderen anonymousdelphicoder »

Hocam teşekkür ederim bi konuda çok ciddi yardıma ihtiyacım var DirectX in en önemli interface methodunu hook edebildim ve kendi exe m üzerinden harici olarak bütün bufferlarına çizim yaptırabiliyorum herşey çok güzel fakat 2. adıma geçtim 2. adım ise şu bir DLL yazdım bu DLL in içinde DirectX i hook eden kodlarım ve çizim yapan kodlarım var ve burada bir CreateDevice ile Device create ediyorum.

Kendi projemin içinde DLL i loadlibrary ile çağırıp getprocaddr ile hook yapan ve çizimi başlatan methodu çağırıyorum burdada hiç bir sıkıntı yok gayet başarılı hook edip çizim yapıyor FAKAT DLL i kendi projem içinden çağırmak yerine bir Injector yazdım ve bu Injector le CreateDevice ile Device oluşturmaya çalışıyorum fakat Invalid Call hatası veriyor burada çakıldım kaldım yani anlıyacağın DLL i proje içinde direk kullandığımda sorun yok fakat Inject ettiğim zaman hata veriyor ve Device oluşturmadan imkansız bunu başarmam acaba neden Inject edince Device oluşturamıyorum yardımcı olursan çok sevinirim. :(
anonymousdelphicoder
Üye
Mesajlar: 152
Kayıt: 16 May 2014 11:23

Re: Injected DLL Call Function

Mesaj gönderen anonymousdelphicoder »

Acaba DLL Inject olunca farklı bir Thread da çalışıyor tıpkı Thread da çizim yaptığımızda Canvas allow drawing hatası vermesi gibi birşey mi acaba ?
Cevapla