📄 dllinject.dpr
字号:
{
(c) Janis Elsts AKA White Shadow
Updated : 21.09.2006
See also : http://w-shadow.com/
DLL injection code based on dllinject sample by Rezmond (www.projectbionet.com).
Freeware for noncommercial use.
This sample application demonstrates how you can use DLL-injection
to hide from NT Task Manager. Basically what you need to do is
place most of your code in a dll (see testdll.dpr for a simple example),
inject that DLL in an inconspicious process and create a thread for
your code to run in. Then you can do almost anything you could do
in a normal Delphi application. See uDLLForm.pas for some notes and
examples.
This only works on Windows NT.
To preserve system stability, the library is injected to
calc.exe (so make sure you have Calculator running if you run this
demo unmodified). In a real application you'd probably want to
use explorer.exe as your host process.
To run the demo :
1. Compile testdll.dpr
2. Compile dllinject.dpr
3. Run calc.exe
4. Run dllinject.exe
}
program dllinject;
uses
SysUtils,
windows,
forms,
procs in 'procs.pas';
type
{Lets define some function types that will simplify our job when
writing the injected procedure}
TfuncLoadLibrary=function(lpFileName:PAnsiChar):cardinal;stdcall;
TfuncGetProcAddress=function(hModule:cardinal;lpProcName:PAnsiChar):cardinal;stdcall;
TfuncMessageBox=function(hwnd:cardinal;lpText,lpCaption:PAnsiChar;aType:cardinal):cardinal;stdcall;
TInjectDllData = record
pLoadLibrary : pointer; //pointer to the loadLibrary function
pGetProcAddress : pointer; //pointer to the GetProcAddress function
pGetModuleHandle : pointer; //pointer to the GetModulhandle function
lib_name : pointer; //pointer to the name of the dll we will load
pMessageBox:pointer; //pointer to MessageBox function
end;
{This is the procedure that will be written to host process}
procedure InjectedProc( parameter : Pointer ) ; stdcall;
var
InjectDllData : TInjectDllData;
hMod:cardinal;
mFunc:procedure;stdcall;
mLoadLibrary:TfuncLoadLibrary;
mGetProcAddress:TfuncGetProcAddress;
mMessageBox:TfuncMessageBox;
begin
InjectDllData := TInjectDllData(parameter^);
mLoadLibrary:=injectDllData.pLoadLibrary;
mGetProcAddress:=injectDllData.pGetProcAddress;
mMessageBox:=injectDllData.pMessageBox;
hmod:=mLoadLibrary(InjectDllData.lib_name);
if hmod<>0 then begin
{DLL loaded, find the function (fRunApp from uDllForm.pas).
It is unadvisable to use literal function names as parameters
to GetProcAddress here, as they have not been copied to the host
process and may cause it to crash. So we use an index instead.
The index is defined in testdll.dpr.
}
@mfunc:=pointer(mGetProcAddress(hmod,PAnsiChar(2)));
if @mfunc<>nil then mFunc;
end;
end;
{
this basically allocates some memory in the target process
is then uses create remote thread to execute it.
Note : the allocated memory isn't freed so the thread can keep running
when this application has shut down.
}
function InjectDllToTarget(dllName : string; TargetProcessID : DWORD ; code : pointer; CodeSize : integer ): boolean;
var
InitDataAddr , WriteAddr : pointer;
hProcess , ThreadHandle : Thandle;
BytesWritten , TheadID : DWORD;
InitData : TInjectDllData;
begin
result := false;
{
Getting function addresses this way is okay because kernel32.dll is
always loaded in the same memory location (I think).
References :
http://blogs.msdn.com/larryosterman/archive/2005/12/05/500151.aspx
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dllproc/base/dllmain.asp
}
InitData.pLoadLibrary := GetProcAddress(LoadLibrary('kernel32.dll'), 'LoadLibraryA');
InitData.pGetProcAddress := GetProcAddress(LoadLibrary('kernel32.dll'), 'GetProcAddress');
InitData.pGetModuleHandle := GetProcAddress(LoadLibrary('kernel32.dll'), 'GetModuleHandleA');
//Not really needed :
InitData.pMessageBox := GetProcAddress(LoadLibrary('user32.dll'), 'MessageBoxA');
hProcess := OpenProcess( PROCESS_ALL_ACCESS, FALSE, TargetProcessID );
if (hProcess = 0) then exit;
// alocate and write the dll name to the remote process
InitData.lib_name := VirtualAllocEx(hProcess , 0, length(dllName) + 5 , MEM_COMMIT , PAGE_READWRITE) ;
if ( InitData.lib_name <> nil) then
begin
WriteProcessMemory(hProcess , InitData.lib_name , pchar(dllName) , length(dllName)+1 , BytesWritten );
end ;
// write the initdata strucutre to the remote prcess
InitDataAddr := VirtualAllocEx(hProcess , 0, sizeof(InitData) , MEM_COMMIT , PAGE_READWRITE) ;
if ( InitDataAddr <> nil) then
begin
WriteProcessMemory(hProcess , InitDataAddr , (@InitData) , sizeof(InitData) , BytesWritten );
end ;
// write our proc that loads the dll into the remote process
// then execute it
WriteAddr := VirtualAllocEx(hProcess , 0, CodeSize , MEM_COMMIT , PAGE_READWRITE) ;
if (WriteAddr <> nil) then
begin
WriteProcessMemory(hProcess , WriteAddr , code , CodeSize , BytesWritten );
if BytesWritten = CodeSize then
begin
ThreadHandle := CreateRemoteThread( hProcess , nil , 0, WriteAddr , InitDataAddr ,0 , TheadID );
result := true;
end;
end;
CloseHandle(hProcess);
end;
var InitData : TInjectDllData;
PID : Dword;
dll_to_inject : string;
begin
GetDebugPrivs; // give us debug privileges
dll_to_inject:=ExtractFilePath(application.ExeName)+'testdll.dll';
PID:=FindProcess('calc.exe');
if PID=0 then begin
MessageBox(0,'calc.exe not found','ws',MB_OK or MB_ICONINFORMATION);
exit;
end;
if InjectDllToTarget(dll_to_inject, PID , @InjectedProc , 1000) then
MessageBox(0,'DLL injected','ws',MB_OK or MB_ICONINFORMATION)
else
MessageBox(0,'DLL injection failed','ws',MB_OK or MB_ICONINFORMATION);
end.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -