Конференция "WinAPI" » своя dll в чужем процессе
 
  • cad (11.04.13 14:14) [0]
    добрый день, сразу оговорюсь, пишется не вредоносное ПО... нужно от имени блокнота выполнить некоторые действия, т.е. в недрить свою библиотеку в его процесс. вот функция внедрения (мне кажется она многим знакома будет)):


    function Load_DLL(DllName: PChar; PID: dword): boolean;
    //DllName - имя библиотеки, PID - id блокнота
    var
    hProc: dword;
    lpStartAddress, pmem: pointer;
    wrb, lpThId: dword;
    begin
    if not FileExists(DLLName) then
     ShowMessage('dll not found')
    else
     begin
      hProc:=OpenProcess(PROCESS_ALL_ACCESS or PROCESS_VM_WRITE, true, PID);
      if (hProc<>0) then
       begin
        lpStartAddress:= GetProcAddress(GetModuleHandle('kernel32.dll'), 'LoadLibraryA');
        pmem:= VirtualAllocEx(hProc, nil, 255, MEM_COMMIT, PAGE_READWRITE);
        if (pmem=nil) then
         result:=false
        else
         begin
          if not WriteProcessMemory(hProc, pmem, DllName, Length(DllName), wrb) then
           result:=false
          else
           if (dword(Length(DllName)) = wrb) then
            result:=CreateRemoteThread(hProc, nil, 0, lpStartAddress, pmem, 0, lpThId)<>0
           else
            result:=false;
         end;
       end
      else
       result:=false;
     end;
    end;



    Функция отрабатывается с результатом true, но до библиотеки дело не доходит(( т.е. если я, при компиляции dll, укажу в host application свое приложение, подгружающее dll, поставлю в начале библиотеки точку остановки... приложение отрабатывает, но в dll не суется...
    Подскажите что не так?
  • Rouse_ © (11.04.13 14:17) [1]
    Вероятно просто отладочная информация к библиотеке не подключилась - это давний известный глюк дельфевого отладчика.
    В самой библиотеке MessageBox выведи и увидишь что она внедрилась нормально.
  • cad (11.04.13 14:24) [2]
    ну вот пока элементарный код библиотеки:

    library ShowMe;

    uses
     Windows, Dialogs;

    begin
    try
     ShowMessage('dll is load');
    except
    end;
    end.



    ставлю точку останова на ShowMessage... фиг(..
  • cad (11.04.13 14:28) [3]
    ну и собственно сообщения тоже нет
  • Rouse_ © (11.04.13 14:33) [4]
    а нукась сделай так:

    lpStartAddress:= GetProcAddress(GetModuleHandle('kernel32.dll'), 'LoadLibraryW');

  • cad (11.04.13 14:40) [5]
    тот же эффект, вернее его отсутствие)
  • cad (11.04.13 14:41) [6]
    сначала грешил на Win 7, думал может че поменяли при работе с потоками, проверил на ХР - тоже самое..
  • Rouse_ © (11.04.13 14:45) [7]
    Выкладывай проект архивом.
  • cad (11.04.13 14:51) [8]
    программа, внедряющая dll:


    program rp;

    uses
     Windows,
     Tlhelp32,
     SysUtils,
     Dialogs;

    function Load_DLL(DllName: PChar; PID: dword): boolean;
    var
    hProc: dword;
    lpStartAddress, pmem: pointer;
    wrb, lpThId: dword;
    begin
    if not FileExists(DLLName) then
     ShowMessage('dll not found')
    else
     begin
      hProc:=OpenProcess(PROCESS_ALL_ACCESS or PROCESS_VM_WRITE, true, PID);
      if (hProc<>0) then
       begin
        lpStartAddress:= GetProcAddress(GetModuleHandle('kernel32.dll'), 'LoadLibraryW');
        pmem:= VirtualAllocEx(hProc, nil, 255, MEM_COMMIT, PAGE_READWRITE);
        if (pmem=nil) then
         result:=false
        else
         begin
          if not WriteProcessMemory(hProc, pmem, DllName, Length(DllName), wrb) then
           result:=false
          else
           if (dword(Length(DllName)) = wrb) then
            result:=CreateRemoteThread(hProc, nil, 0, lpStartAddress, pmem, 0, lpThId)<>0
           else
            result:=false;
         end;
       end
      else
       result:=false;
     end;
    end;

    function SetSeDebugPrivilege:boolean;
    var
    ht:THandle;
    luid:TLargeInteger;
    tkp:TTokenPrivileges;
    rl:Cardinal;
    begin
    if OpenProcessToken(GetCurrentProcess, TOKEN_ADJUST_PRIVILEGES, ht) then
     begin
      LookupPrivilegeValue(nil, 'SeDebugPrivilege', luid);
      tkp.Privileges[0].Luid:=luid;
      tkp.PrivilegeCount:=1;
      tkp.Privileges[0].Attributes:=SE_PRIVILEGE_ENABLED;
      if AdjustTokenPrivileges(ht, false, tkp, 0, nil, rl) then
       result:=true
      else
       result:=false;
     end
    else
     result:=false;
    end;

    function GetPID(ExeFileName: string): dword;
    var
    ContinueLoop, ffound: boolean;
    FSnapshotHandle: THandle;
    FProcessEntry32: TProcessEntry32;
    UpEFN: string;
    begin
    result:=0;
    ffound:=false;
    UpEFN:=UpperCase(ExeFileName);
    FSnapshotHandle:=CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
    FProcessEntry32.dwSize:=Sizeof(FProcessEntry32);
    ContinueLoop:=Process32First(FSnapshotHandle, FProcessEntry32);
    while integer(ContinueLoop) <> 0 do
     begin
      if ((UpperCase(ExtractFileName(FProcessEntry32.szExeFile)) = UpEFN)
          or (UpperCase(FProcessEntry32.szExeFile) = UpEFN)) then
       begin
        result := FProcessEntry32.th32ProcessID;
        ffound:=true;
        break;
       end;
      ContinueLoop := Process32Next(FSnapshotHandle, FProcessEntry32);
     end;
    CloseHandle(FSnapshotHandle);
    if not ffound then
     ShowMessage('notepad.exe is not runing');
    end;

    const DllName = 'ShowMe.dll';

    var
    PID: dword;

    begin
    SetSeDebugPrivilege;
    PID:=GetPID('notepad.exe');
    if (PID>0) then
     Load_DLL(DllName, PID);
    end.



    ну и сама dll:


    library ShowMe;

    uses
     Windows, Dialogs;

    begin
    try
     ShowMessage('dll is load');
    except
    end;
    end.



    весь проект) застрял на начальном этапе..
  • Rouse_ © (11.04.13 19:01) [9]
    Путь к библиотеке неправильно передаешь, он должен быть полный:
    Load_DLL(PChar(ExtractFilePath(ParamStr(0)) + DllName), PID);

  • Rouse_ © (11.04.13 19:19) [10]
    ЗЫ: еще до кучи материал для изучения: http://alexander-bagel.blogspot.ru/2013/01/intercept.html#inject
  • cad (12.04.13 09:32) [11]
    путь к библиотеке может и некоректно прописан, но тем не менее, она все равно лежит в папке с проектом... да и в функции, до попытки ее загрузки есть проверка ее присутствия.. так что дело не в этом
  • cad (12.04.13 09:34) [12]
    за ссылку - отдельное спасибо... сколько не искал в поисковиках - на нее не выходил.
  • Rouse_ © (12.04.13 10:19) [13]

    > так что дело не в этом

    Что значит не в этом? :)
    Обьясняю на пальцах, допустим твой экзешник и библиотека лежат в папке C:\tmp\. Путь к библиотеке у тебя не указан, указано только ее имя. Когда выполняется FileExists, раз пути нет - используется текущий, который как раз и равен C:\tmp\.
    Когда ты инжектируешь библиотеку в блокнот, то с какой радости ты предполагаешь что его путь по умолчанию тоже равен твоему C:\tmp\?
    Нет, он у него свой и равен C:\Windows\ и в этой папке твоей библиотеки ShowMe.dll нет, поэтому ничего и не загружается.

    Это только первый нюанс.

    Во вторых ты не сказал какую версию дельфи ты используешь? Если Delphi 2010 и выше, то там PChar по умолчанию юникодный, поэтому загружать нужно функцию LoadLibraryW, если же используется Delphi версии 2007 и ниже, то использовать нужно LoadLibraryA

    Когда поправишь все эти моменты - все заработает.
  • cad (12.04.13 10:49) [14]
    delphi 2010, 1 нюанс - согласен, не додумал, 2 - даже не знал...  тем нее менее:


    begin
    SetSeDebugPrivilege;
    PID:=GetPID('notepad.exe');
    if (PID>0) then
     begin
      Load_DLL(PChar(ExtractFilePath(ParamStr(0)) + DllName), PID);
     end;
    end.



    и тут:


    lpStartAddress:= GetProcAddress(GetModuleHandle('kernel32.dll'), 'LoadLibraryW');



    неработает...
  • cad (12.04.13 10:55) [15]
    для возможности отладки библиотеки, пока сделал так:


    const DllName = 'E:\projects\DLL Injecting\dll\ShowMe.dll';
    //конкретный путь к проекту с dll



    и вызов оставил таким:


    Load_DLL(DllName, PID);



    не подгружается
  • Rouse_ © (12.04.13 11:15) [16]
  • cad (12.04.13 11:49) [17]
    о как... все оказалось странно). messagebox отрабатывается, а showmessage нет...
  • cad (12.04.13 11:50) [18]
    но вопрос остается: как отлаживать dll?
  • Rouse_ © (12.04.13 12:03) [19]
    Сначала делай отладку на своем тестовом приложении, а потом можешь уже подключаться к удаленному...
    Мне всегда на тестовом отладки хватало.
 
Конференция "WinAPI" » своя dll в чужем процессе
Есть новые Нет новых   [118230   +17][b:0][p:0.003]