2016-02-13 55 views
0

注入DLL调用过程已翻了出来,但仍需要调用函数在此DLL中,如何实现呢? 但更特别的,在这个过程中注入后,我要打电话去送价值setHWND功能,从我的应用程序注入的工艺......进样DLL,并从另一个进程这个dll

片DLL

procedure Init(Reason: integer); 
    begin 
     Dll_reason := Reason; 
     HookPoint_Address := 0; 
     if (Reason = DLL_PROCESS_ATTACH) then 
     begin 
     ShowMessage('Прикрепились'); 
     InitHook; 
     end; 
    end; 

    procedure setHWND(hwnd: Cardinal); 
    begin 
    hwnd_param:=hwnd; 
    end; 

    exports 
     setHWND; 

    begin 
     DLLProc := Init; 
     Init(DLL_PROCESS_ATTACH); 

片注入

function InjectDLL(dwPID: DWORD; DLLPath: PWideChar): integer; 
var 
    dwThreadID: Cardinal; 
    hProc, hThread, hKernel: THandle; 
    BytesToWrite, BytesWritten: SIZE_T; 
    pRemoteBuffer, pLoadLibrary: Pointer; 
begin 
    hProc := OpenProcess(PROCESS_CREATE_THREAD or PROCESS_QUERY_INFORMATION or 
    PROCESS_VM_OPERATION or PROCESS_VM_WRITE or PROCESS_VM_READ, False, dwPID); 
    if hProc = 0 then 
    exit(0); 
    try 
    BytesToWrite := SizeOf(WideChar) * (Length(DLLPath) + 1); 
    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(0); 
     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; 
    exit(1); 
end; 

procedure TForm1.Button1Click(Sender: TObject); 
var 
    PID: DWORD; 
    dir: string; 
begin 
    SetSeDebugPrivilege; 
    PID := GetPID('zorron.exe'); 
    if (PID > 0) then 
    begin 
    dir := GetCurrentDir; 
    InjectDLL(PID, PWideChar(dir + '\trans.dll')); 
    end; 

end; 

Thx

+1

不要在DllMain中显示UI。调用CreateThread并在那里完成工作。 –

+0

我,米需要从主应用程序呼叫setHWND – SEModer

+0

那么,那样做。但不是来自DllMain。正如文档所涵盖。在DllMain中调用CreateThread来完成这项工作。 –

回答

0

正如旧/新事物中所解释的那样。你不能在DllMain函数中做真正的工作。
如果你这样做,并且当你在DllMain中忙碌时应用程序停止,应用程序将会陷入僵局。
大量的DllMain中的其他活动也可能导致死锁,请参阅:https://msdn.microsoft.com/en-us/library/windows/desktop/dn633971%28v=vs.85%29.aspx

所以这就是为什么你创建一个新的线程使用CreateThread
只记得不同步线程,因为这将导致死锁。只要你不同步你就是金。

你注入的DLL后,你开始一个新的线程,就像这样:

procedure DoWorkInDLL(data: pointer): bool; stdcall; 
begin 
    ... 
end; 

procedure EntryPoint(Reason: dword); 
var 
    ThreadID: cardinal; 
begin 
    if Reason = DLL_PROCESS_ATTACH then begin 
    Win32Check(CreateThread(nil,0, @Main, nil, 0, ThreadId)); 
    end; 
    Assert(ThreadID <> 0); 
end; 


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

现在我的文档,所以不要使用CreateThread但它真的只有那些问题的同步问题。
这里的问题是,通常一个应用程序启动的dll,但是当你注入一个dll,那就是从来没有的情况,因此,你必须调整你的参考点。 里面的DoWork功能,您可以拨打SetHWnd,因为你现在从DLL加载和死锁的风险分离,但是您仍然无法打电话给你的线程内同步。
如果你想同步,你将不得不创建另一个线程并在那里同步。

0

如果您需要导出setHWND(),请确保您使用STDCALL指令

procedure setHWND(hwnd: Cardinal); stdcall; 
begin 
hwnd_param:=hwnd; 
end; 

利用的Windows调用约定。