저번시간에 FindProcessID라는 함수를 분석해보았는데요.
이번시간에는 실제로 PID [ Process ID ] 에 dll을 인젝션시키는 코드를 설명하도록 할게요.
HANDLE는 수없이 설명해왔기에, 넘어갑니다.
HMODULE 는, 해당 dll의 핸들을 담는 자료형입니다.
LPVOID는, API의 far* 라는게있는데, 그부분에 대해서는 저도 잘 모르니.
일반 포인터보다 더 큰 포인터라는것만 알아두시면 될듯합니다.
DWORD 는 저번시간에 설명하였기에, 넘어갑니다.
LPTHREAD_START_ROUTINE 는 unsigned long 값으로, createThread() 이용할때 인자로 사용됩니다.
먼저, OpenProcess API란, 해당 PID로 프로세스 핸들을 구하는 API 입니다.
hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, PID);
해당 코드에서는 OpenProcess로, 첫번째인수에는 해당 프로세스핸들의 메모리조작권한을 얻기위해 사용한 인수입니다.
여기서 PROCESS_ALL_ACCESS보다 더많은것을 조작하기위해서는 MAXIMUM_ALLOWED를 대입하시면 됩니다.
두번째 인수로는 False를 대입하시면 되며, 세번째 인수에는 Process ID를 넣어야합니다.
bool DLLInjection(DWORD PID, char* PathDLL);
이렇게 선언되있듯이 첫번째인수에는 PID를 입력받아서 처리하면 됩니다.
pRemoteBuf = VirtualAllocEx(hProcess, NULL, dwBufSize, MEM_COMMIT, PAGE_READWRITE);
VritualAllocEx API는, 해당 프로세스의 메모리 공간을 할당할때 이용됩니다.
우리가 포인터를 동적할당하듯이, 프로세스의 공간할당을 할때 이용이 됩니다.
첫번째 인수에는, 해당 프로세스 핸들을 넣어주시면됩니다.
두번째 인수에는, NULL값을 넣어주시면되며,
세번째 인수에는, 공간을 할당할 사이즈를 넣어주시면됩니다.
네번째 인수에는 MEM_COMMIT 을 넣어주시면 되며. MEM_COMMIT이라는 값은 &H1000& 이라고 API Viewer에 나와있습니다.
마지막 인수에는 PAGE_READWRITE 를 넣어주시면 되며, PAGE_READWRITE이라는 값은 &H4&로 나와있습니다.
WriteProcessMemory API는, 해당 프로세스의 메모리를 조작할때 사용됩니다.
첫번째 인수에는 해당프로세스핸들을 넣어주시면 됩니다.
두번째 인수에는 VirtualAllocEx 을 이용한 할당 받은 버퍼에 세번째 인수를 통해 DLL 경로를 입력합니다.
3번째 인수에는 실제 인젝션시킬 DLL 파일 경로를 입력해주시면됩니다.
우리가 DLLINJECTION 이라는 함수를 선언할적에 두번쨰 인수에 파일경로를 입력해주었습니다.
C드라이브의 showmine.dll 이라는 dll파일을 인젝션하도록 설정해주시면됩니다.
4번째 인수에는 해당 DLL파일의 버퍼사이를 넣어주시면 됩니다.
마지막 인수에는 NULL 값을 넣어주시면 됩니다.
GetModuleHandle API는 해당 DLL의 핸들 및 주소를 담습니다.
GetProcAddress 를 이용해 해당 핸들 및 주소에서 LoadLibraryA API를 구해옵니다.
GetProcAddress API는 해당 프로세스에게 스레드를 실행시킵니다.
첫번째 인수에는 해당 프로세스 핸들을 입력해주면됩니다.
두번쨰 인수에는 NULL을 넣어주고, 세번째 인수에는 0을 넣어주면 됩니다.
네번쨰 인수에는 스레드 함수의 주소를 넣어주시면되고,
다섯번째 인수에는 스레드 인수의 주소를 넣어주면 됩니다.
그리고 마지막 두개의 인수에는 0, NULL을 넣어주시면 됩니다.
WaitForSingleObject API는 스레드가 종료될때까지 기다려주는 API입니다.
첫번째 인자에는 기다릴 스레드를 넣어주면 되며,
두번째 인자에는 타임아웃시간을 입력해주면 됩니다 INFINITE는 시간제한없이 기다리겠다는뜻으로 넣어주었습니다.
CloseHandle API는 해당 핸들을 닫아줄때 이용됩니다.
첫번째인수에는 닫아줄 핸들을 넣어주시면됩니다.
그럼 이 코드가 정상적으로 돌아가는 지 봐야곘지요.
해당 첨부파일인 showmine.dll 파일을 C드라이브에 넣어준뒤,
지뢰찾기를 실행하고, 소스코드를 컴파일 해보시기 바랍니다.
어떤 결과가 나타나는지 보여질겁니다.
해당 예제소스는 dll을 인젝션시키는 소스이므로,
지뢰찾기에는 해가 되지 않는 소스입니다.
지뢰를 찾아주는 코드는 dll 안에 숨어져있음을 미리 밝힙니다.
이렇게 API 강좌를 마칩니다.
다음강좌부터는 알고리즘 강좌를 시작하도록 하겠습니다.
후. 시간도시간이라 졸면서 적은 내용들이 많이있군요.
모르는부분은 MSDN을 참고하며 적었으니, 코드를 보고 모르는부부분이나
이부분은 잘 되지않는다. 이런부분은 덧글로 남겨주시기 바랍니다.
#include <cstdio>
#include <Windows.h>
#include <TlHelp32.h>
DWORD FindProcessID(LPCTSTR szProcessName);
bool DLLInjection(DWORD PID, char* PathDLL);
int main()
{
DLLInjection(FindProcessID("winmine.exe"), "C:\\showmine.dll");
}
bool DLLInjection(DWORD PID, char* PathDLL)
{
HANDLE hProcess, hThread;
HMODULE hMod;
LPVOID pRemoteBuf;
DWORD dwBufSize = lstrlen(PathDLL) + 1;
LPTHREAD_START_ROUTINE pThreadProc;
hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, PID);
pRemoteBuf = VirtualAllocEx(hProcess, NULL, dwBufSize, MEM_COMMIT, PAGE_READWRITE);
WriteProcessMemory(hProcess, pRemoteBuf, (LPVOID)PathDLL, dwBufSize, NULL);
hMod = GetModuleHandle("kernel32.dll");
pThreadProc = (LPTHREAD_START_ROUTINE)GetProcAddress(hMod, "LoadLibraryA");
hThread = CreateRemoteThread(hProcess, NULL, 0, pThreadProc, pRemoteBuf, 0, NULL);
WaitForSingleObject(hThread, INFINITE);
CloseHandle(hThread);
CloseHandle(hProcess);
return TRUE;
}
DWORD FindProcessID(LPCTSTR szProcessName)
{
DWORD dwPID = 0xFFFFFFFF;
HANDLE hSnapShot = INVALID_HANDLE_VALUE;
PROCESSENTRY32 pe;
pe.dwSize = sizeof( PROCESSENTRY32 );
hSnapShot = CreateToolhelp32Snapshot( TH32CS_SNAPALL, NULL );
Process32First(hSnapShot, &pe);
do{
if(!_stricmp(szProcessName, pe.szExeFile)){
dwPID = pe.th32ProcessID;
break;
}
}
while(Process32Next(hSnapShot, &pe));
CloseHandle(hSnapShot);
return dwPID;
}
출처 : http://cafe.naver.com/funcc.cafe?iframe_url=/ArticleRead.nhn%3Farticleid=4490&
'Algorithm' 카테고리의 다른 글
재귀 없는 퀵소트 (non recursive quick sort) (0) | 2013.04.07 |
---|---|
DFS (0) | 2012.07.29 |
DLL INJECTION - 1 (0) | 2012.07.29 |
DFS ; Depth-First-Search (0) | 2012.07.29 |
그래프 탐색 알고리즘 (3) | 2012.07.29 |