2013-08-21 3 views
1

У меня есть простая DLL, которую я вставляю внутри блокнота только для тестирования. Мой код для инжектора, как это:DLL Injection and Access Violation

uses 
    Windows; 

var 
    BytesWritten: cardinal; 
    PID, Process, Thread, ThreadId, hKernel: dword; 
    pLoadLibrary, Paramaters: pointer; 
    DLL: AnsiString; 

    begin 
     DLL := 'C:\test.dll'; // Must be full path name. 
     PID := 3160; 
     Process := OpenProcess(PROCESS_ALL_ACCESS, 
          False, 
          PID); 

     Paramaters := VirtualAllocEx(Process, 
           nil, 
            Length(DLL), 
            MEM_COMMIT, 
           PAGE_EXECUTE_READWRITE); 

     WriteProcessMemory(Process, 
         Paramaters, 
         PAnsiChar(DLL), 
         Length(DLL), 
         BytesWritten); 

     hKernel := GetModuleHandle('KERNEL32.DLL'); 

     pLoadLibrary := GetProcAddress(hKernel, 
            'LoadLibraryA'); 

     Thread := CreateRemoteThread(Process, 
            nil, 
            0, 
            pLoadLibrary, 
            Paramaters, 
            0, 
            ThreadId); 

     WaitForSingleObject(Thread, INFINITE); 

     VirtualFreeEx(Process, 
        Paramaters, 
        0, 
        MEM_RELEASE); 

     CloseHandle(Thread); 
     CloseHandle(Process); 
end. 

Мой DLL код прост, как это:

uses 
    SysUtils, 
    Classes, 
    Windows; 

{$R *.res} 


procedure EntryPoint(Reason: dword); stdcall; 
begin 
    if Reason = DLL_PROCESS_ATTACH then 
    begin 
    MessageBox(0, 'DLL Injected', 'DLL Injected', 0); 
    end; 
end; 


begin 
    DLLProc:= @EntryPoint; 
    EntryPoint(DLL_PROCESS_ATTACH); 
end. 

Когда я впрыснуть DLL в процессе блокнота, я получаю MessageBox говорю DLL Введенный, но через несколько секунд это сообщение об ошибке: Исключение EAccessViolation в модуле test.dll на 00FFE102. Нарушение прав доступа по адресу 00FFF102. Запись адреса 00FFF102. Я использую Delphi 2010, Windows 7 x64, права администратора, без UAC, блокнот и dll оба x32 ...

+1

Вы не выделяете пространство для нуль-терминатора параметра «lpFileName» вызова «LoadLibrary». Это не поможет решить проблему, просто скажу .. –

+0

@Sertac Выключено, чтобы вызвать несоответствие конвенции, и еще один случай оператора @ по процедурным переменным, скрывающим проблему. –

ответ

6

Ваша функция EntryPoint объявлена ​​неправильно. Он не должен использовать stdcall. Правильная декларация:

procedure EntryPoint(Reason: Integer); 

Проверьте в исходном коде RTL для объявления TDLLProc, или обратитесь к documentation, чтобы подтвердить, что это точно.

Если бы вы не использовали оператор @ при назначении DLLProc, компилятор мог бы сказать вам об этом.

Как сказал Сертак, вы также должны указать нулевой терминатор в имени файла, который вы записываете в целевой процесс.

+0

Я проверял это как причину с тестовым случаем. Не то чтобы я думал, что это не вызовет неприятностей, но крушение, произошедшее через несколько секунд (* после показа диалогового окна *), показалось странным. Однако, как это не удается, возможно, WER занимает свое время. +1, очень проницательный. Я прочитал код несколько раз вверх и вниз, но не заметил его. –

+0

Да, он работает прямо сейчас, даже не добавляя +1 для нуль-терминатора. В любом случае, я добавлю его позже и посмотрю, как это работает ... Спасибо, ребята, очень полезно! – user1526124

+1

Вы сможете избежать этого случайно, потому что будет отображаться целая страница. Но вы должны обязательно добавить нулевой ограничитель. Мог бы это сделать правильно! –