나는 오후에 MSDN을 뒤집고 안전을 위해이 예를 썼다.
TestDll.dll은 로그 함수 만 있는데, 가장 중요한 프로그램 인 Project1.exe는 주입하는 데 사용됩니다.
테스트 환경 : WindowsServer2003+delphi7.0
이 프로그램은 매우 간단하므로 전문가는 말도 안되는 말을 할 필요가 없습니다.
testdll.dll 테스트 용 소스 코드 (prjzzhost.exe에 주입) :
프로그램 코드LibraryTestDll;
용도
sysutils,
체계,
창문,
수업;
Procedurelog (s : pchar); stdcall;
var
F : TextFile;
시작하다
할액 파일 (f, 'test.txt');
iffileExists ( 'test.txt') thenAppend (f)
elserewrite (f);
WriteLn (f, s);
근접 파일 (f);
끝;
ProcessEdLlEntryPoint (dworseason : dword);
시작하다
CaseDwereasonof
dll_process_attach :
log ( 'dllprocessattach');
dll_process_detach :
log ( 'dllProcessDetach');
dll_thread_attach :
log ( 'dllthreadattach');
dll_thread_detach :
log ( 'dllthreaddetach');
끝;
끝;
수출
통나무;
시작하다
dllproc : =@dllentrypoint;
dllentrypoint (dll_process_attach);
끝.
주입 된 호스트 프로세스 prjzzhost.exe (아무것도하지 않습니다.
마지막으로 가장 중요한 것은 다음과 같습니다.
project1.exe의 소스 코드 :
프로그램 코드unitunit1;
인터페이스
용도
창, 메시지, 시스템, 변형, 클래스, 그래픽, 컨트롤, 양식,
대화 상자, stdctrls, tlhelp32;
유형
tlog = 절차 (s : pchar); stdcall;
tservicemain = procedure (argc : integer; varargv : pchar); stdcall;
edllloaderror = 클래스 (예외);
tform1 = 클래스 (tform)
버튼 3 : tbutton;
processubutton3click (sender : tobject);
사적인
{privatedeclarations}
공공의
{publicdeclarations}
끝;
var
form1 : tform1;
구현
{$ r*.dfm}
{프로세스 등록}
ProcedureGetMyProcessId (ConstaFiLename : String; ConstPathMatch : Boolean; varProcessId : dword);
var
LPPE : tprocessentry32;
Sshandle : Thandle;
Foundaproc, Foundok : 부울;
시작하다
ProcessID : = 0;
{시스템 스냅 샷 만들기}
sshandle : = CreateToolHelp32SnapShot (TH32CS_SNAPROCESS, 0);
{스냅 샷에서 첫 번째 프로세스 받기}
{구조의 크기를 설정하십시오. 그렇지 않으면 거짓이 반환됩니다}
lppe.dwsize : = sizeof (tprocessentry32);
FoundApRoc : = Process32First (Sshandle, LPPE);
whilefoundaprocdo
시작하다
{경기}
ifpathmatchthen
foundok : = ansistricomp (lppe.szexefile, pchar (afilename)) = 0
또 다른
foundok : = ansistricomp (pchar (extractfilename (lppe.szexefile)), pchar (extractfilename (afilename)) = 0;
iffoundokthen
시작하다
processID : = lppe.th32processId;
부서지다;
끝;
{찾을 수 없음, 다음 과정을 계속하십시오}
FoundApRoc : = process32next (sshandle, lppe);
끝;
CloseHandle (sshandle);
끝;
{권한 설정}
functionableddebugprivilege (constenabled : boolean) : 부울;
var
htk : thandle; {오픈 토큰 손잡이}
rtntemp : dword; {value value retureded rebough}}
Tokenpri : Token_privileges;
Const
se_debug = 'sedebugprivilege'; {query value}
시작하다
결과 : = 거짓;
{프로세스 토큰 핸들 받기, 권한 설정}}
if (OpenProcessToken (getCurrentProcess (), token_adjust_privileges, htk))
시작하다
tokenpri.privilegecount : = 1;
{luid value get}
LookUpPrivilegeValue (nil, se_debug, tokenpri.privileges [0] .luid);
ifenabledthen
tokenpri.privileges [0] .attributes : = se_privilege_enabled
또 다른
tokenpri.privileges [0] .attributes : = 0;
rtntemp : = 0;
{새로운 권한 설정}
AdvernTokenPrivileges (htk, false, tokenpri, sizeof (tokenpri), nil, rtntemp);
결과 : = getLasterror = ERROR_SUCCESS;
CloseHandle (HTK);
끝;
끝;
{디버그 함수}
ProcedureOutPutText (VARCH : PCHAR);
var
파일 핸들 : TextFile;
시작하다
할액 파일 (파일 핸들, 'zztest.txt');
부록 (파일 핸들);
Writeln (FileHandle, Ch);
플러시 (파일 핸들);
CloseFile (FileHandle);
끝;
{원격 프로세스 주입}
functionInjectto (consthost, Guest : String; constpid : dword = 0) : dword;
var
{주입 프로세스 핸들, 프로세스 ID}}
Hremoteprocess : Thandle;
dwremoteprocessid : dword;
{원격 프로세스에 작성된 컨텐츠 크기}
memsize : dword;
{원격 프로세스에 작성한 후 주소}
pszlibfileremote : 포인터;
IreturnCode : 부울;
Tempvar : dword;
{함수의 주소를 가리키면 LoadLibraryw}
pfnstartaddr : tfnthreadstartroutine;
{DLL Full Path, 원격 프로세스의 메모리에 기록해야}}
pszlibafilename : pwidechar;
시작하다
결과 : = 0;
{권한 설정}
enabledDeBugPrivilege (True);
{주입 된 DLL 파일 경로에 대한 메모리 크기를 할당하십시오. WideChar이므로 2를 곱해야합니다.
getmem (pszlibafilename, 길이 (게스트)*2+1);
StringTowIdeChar (게스트, PSZLIBAFILENAME, 길이 (게스트)*2+1);
{프로세스 ID 받기}
ifpid> 0then
dwremoteprocessid : = pid
또 다른
getmyProcessId (호스트, false, dwremoteprocessid);
{원격 프로세스 핸들 가져 오기, 쓰기 허가}}
hremoteprocess : = OpenProcess (process_create_thread+{스레드의 원격 생성 허용}}
Process_vm_Operation+{원격 VM 작업 허용}
Process_VM_WRITE, {원격 VM 쓰기 허용}
false, dwremoteprocessid);
{virtualAllocex 함수를 사용하여 원격 프로세스에 공간을 할당하고 WriteProcessMemory에 DLL 경로를 작성하십시오}}
memsize : = (1+lstrlenw (pszlibafilename))*sizeof (wchar);
pszlibfileremote : = pwidestring (virtualallocex (hremoteprocess, nil, memsize, mem_commit, page_readwrite));
tempvar : = 0;
IreturnCode : = WriteProcessMemory (HremoteProcess, pszlibfileremote, pszlibafilename, memsize, tempvar);
ifireturncodethen
시작하다
pfnstartAddr : = getProcadDress (getModuleHandle ( 'kernel32'), 'loadlibraryw');
tempvar : = 0;
{원격 프로세스에서 DLL 시작}
결과 : = CreateRemoteThread (HremoteProcess, Nil, 0, PfnstartAddr, Pszlibfileremote, 0, Tempvar);
끝;
{무료 메모리 공간}
프리 메미 (pszlibafilename);
끝;
{시험}
ProcedUreTform1.Button3Click (sender : tobject);
시작하다
injectto ( 'prjzzhost.exe', extractfilepath (paramstr (0))+'testdll.dll');
끝;
끝.
코드는 DLL의 여파를로드하는 것을 고려하지 않습니다.