VC++ DLL 주입
hRemoteProcess = OpenProcess(PROCESS CREATE THREAD |//원격으로 스레드 생성 허용
PROCESS_VM_OPERATION |//원격 VM 작업 허용
PROCESS_VM_WRITE,//원격 VM 쓰기 허용
FALSE, dwRemoteProcessId )
원격 프로세스의 메모리 주소 공간을 쓰고 원격 스레드를 설정해야 하기 때문에 충분한 권한(PROCESS CREATE THREAD, VM OPERATION, VM WRITE)을 요청해야 합니다.
만약 프로세스가 열리지 않는다면, 이후의 조작은 생각하지 마라.프로세스를 열면 원거리 스레드를 만들 수 있습니다. 하지만 서두르지 마십시오. 이 원거리 스레드의 스레드 함수가 무엇인지 먼저 생각해 보십시오.우리의 목적은 DLL을 주입하는 것이다.또한 LoadLibrary를 사용하면 DLL을 이 프로세스에 불러올 수 있는 주소 공간을 알고 있습니다.따라서 대상 프로세스에서 LoadLibrary를 호출할 수 있다면 DLL을 대상 프로세스의 주소 공간에 불러올 수 있지 않겠는가?맞아요!그렇습니다.원격 스레드는 여기서 한 번 사용되었다. 원격 스레드의 스레드 함수는 LoadLibrary이고, 매개 변수는 주입할 DLL의 파일 이름이다.(여기서 스스로 생각해 봐야 한다. 눈치챘니? 스레드 함수ThreadProc와LoadLibrary 함수는 매우 비슷하고 반환값, 매개 변수의 개수는 모두 같다) 그리고 질문이 하나 더 있다. LoadLibrary라는 함수의 주소는 어디에 있니?아마 너는 이것이 간단하다고 말할 수 있을 것이다. GetProcAddress는 얻을 수 있을 것이다.그래서 코드가 나왔어요.
char *pszLibFileRemote="my.dll";
PTHREAD_START_ROUTINE pfnStartAddr = (PTHREAD_START_ROUTINE)GetProcAddress(GetModuleHandle("Kernel32"), "LoadLibraryA");
CreateRemoteThread( hRemoteProcess, NULL, 0, pfnStartAddr, pszLibFileRemote, 0, NULL);
그런데 아니야!잊지 마세요. 이것은 먼 라인입니다. 당신의 프로세스에 있는 것이 아니라 pszLibFile Remote가 가리키는 것은 당신의 프로세스에 있는 데이터입니다. 목표 프로세스에 가면 이 바늘이 어디로 향하는지 모릅니다. 마찬가지로 pfnStartAddr라는 주소의 코드가 목표 프로세스에 들어와도 무엇인지 모르겠습니다. 당신이 원하는 LoadLibraryA인지 모르겠습니다.그러나 문제는 항상 해결할 수 있다. 윈도에는 강력한 API 함수가 있다. 그들은 목표 프로세스에 메모리를 분배할 수 있고, 당신의 프로세스의 데이터를 목표 프로세스로 복사할 수 있다.따라서 pszLibFileRemote 문제는 해결할 수 있습니다.
char *pszLibFileName="my.dll";//시스템 디렉터리에 없는 경우, 이것은 반드시 전체 경로 파일 이름이어야 합니다.원인은 다들 생각해 보세요.
//DLL 경로 이름을 계산하는 데 필요한 메모리 공간
int cb = (1 + lstrlenA(pszLibFileName)) * sizeof(char);
//VirtualAllocEx 함수를 사용하여 원격 프로세스의 메모리 주소 공간에 DLL 파일 이름 버퍼를 할당
pszLibFileRemote = (char *) VirtualAllocEx( hRemoteProcess, NULL, cb, MEM_COMMIT, PAGE_READWRITE);
//WriteProcessMemory 함수를 사용하여 DLL의 경로 이름을 원격 프로세스의 메모리 공간으로 복사
iReturnCode = WriteProcessMemory(hRemoteProcess, pszLibFileRemote, (PVOID) pszLibFileName, cb, NULL);
OK, 현재 목표 프로세스도 pszLibFile Remote를 알고 있지만 pfnStartAddr는 하기 어려울 것 같아요. 제가 어떻게 LoadLibraryA가 목표 프로세스에 있는 주소를 알 수 있을까요?사실 Windows는 이 문제를 해결해 주었습니다. LoadLibraryA라는 함수는Kernel32입니다.dll 이 핵심 DLL의 경우, 이 DLL은 매우 특수합니다. Windows는 어떤 프로세스에 대해서도 같은 주소로 불러옵니다.따라서 프로세스의 LoadLibraryA 주소와 대상 프로세스의 LoadLibraryA 주소는 동일합니다. (사실 이 DLL의 모든 함수는 이렇습니다.)이제 DLL 주입이 끝났습니다.
/*
explorer.exe, Beep, 。
*/
#include <windows.h>
#include <stdio.h>
#include <tlhelp32.h>
#include <Shlwapi.h>
#include <tchar.h>
#pragma comment(lib,"Shlwapi.lib")
#pragma comment(linker, "/BASE:0x14000000")
//#define NoWindow
#ifdef NoWindow
#pragma comment(linker,"/subsystem:windows /FILEALIGN:0x200 /ENTRY:main")
#pragma comment(linker,"/INCREMENTAL:NO /IGNORE:4078")
#pragma comment(linker,"/MERGE:.idata=.text /MERGE:.data=.text /MERGE:.rdata=.text /MERGE:.text=Anskya /SECTION:Anskya,EWR")
#endif
typedef int (__stdcall *fnMessageBoxA)(HWND, LPCSTR, LPCSTR, UINT);
typedef int (__stdcall *fnBeep)(int,int);
#define ProcessName "services.exe"//"rundll32.exe"//"svchost.exe"//"explorer.exe"//"avp.exe"//"lsass.exe"//
//■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
// , ID
DWORD GetProcessID(char *FileName)
{
HANDLE hProcess;
PROCESSENTRY32 pe;
BOOL bRet;
//
hProcess=::CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0);
//
bRet=::Process32First(hProcess,&pe);
// , ProcessID
while(bRet)
{
if(strcmp(FileName,pe.szExeFile)==0)
return pe.th32ProcessID;
else
bRet=::Process32Next(hProcess,&pe);
}
// ProcessID
// printf("Process not found!
");
return 9999;
}
//■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
//
void __stdcall RmoteThread()
{
HMODULE hMod,hMod2;
fnMessageBoxA myMessageBoxA;
fnBeep myBeep;
char* path[MAX_PATH];
hMod = GetModuleHandle("user32.dll");
hMod2 = GetModuleHandle("kernel32.dll");
myMessageBoxA = (fnMessageBoxA)GetProcAddress(hMod, (LPCSTR)"MessageBoxA");
myBeep = (fnBeep)GetProcAddress(hMod2, (LPCSTR)"Beep");
/*for(int i=0;i<30;i++)
{
myBeep(800,400);
}
*/
// while(1)
for(int i=0;i<6;i++)
{
Beep(600,100);
Sleep(200);
}
GetModuleFileName(NULL,(char*)path,MAX_PATH);
// myMessageBoxA(NULL, (char*)path, NULL, 64);
}
//■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
//
BOOL EnablePrivilege(HANDLE hToken,LPCTSTR szPrivName,BOOL fEnable)
{
TOKEN_PRIVILEGES tp;
tp.PrivilegeCount = 1;
LookupPrivilegeValue(NULL,szPrivName,&tp.Privileges[0].Luid);
tp.Privileges[0].Attributes = fEnable ? SE_PRIVILEGE_ENABLED:0;
AdjustTokenPrivileges(hToken,FALSE,&tp,sizeof(tp),NULL,NULL);
return((GetLastError() == ERROR_SUCCESS));
}
//■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
/// : , RmoteThread()
/// : Pid = PID
/// : True, False
bool InjectExe(DWORD Pid)
{
bool status = false;
LPVOID pBaseAddr = NULL;
HMODULE hMod = GetModuleHandle(NULL);
LONG hNHOffset = PIMAGE_DOS_HEADER(hMod)->e_lfanew;
HANDLE hThread,
hProcess,
hToken;
DWORD cbImage;
//cbImage= PE
cbImage= PIMAGE_NT_HEADERS((DWORD)hMod + (DWORD)hNHOffset)->OptionalHeader.SizeOfImage;
// , lsass
OpenProcessToken(GetCurrentProcess(),TOKEN_ADJUST_PRIVILEGES,&hToken);
EnablePrivilege(hToken,SE_DEBUG_NAME,TRUE);
hProcess = OpenProcess(PROCESS_ALL_ACCESS, TRUE, Pid);
if (hProcess == NULL)
{
#ifdef debug
MessageBoxA(NULL, " OpenProcess", NULL, 64);
#endif
goto Err;
}
//
VirtualFreeEx(hProcess, LPVOID(hMod), 0, MEM_RELEASE);
//
pBaseAddr = VirtualAllocEx(hProcess, LPVOID(hMod), cbImage, MEM_COMMIT | MEM_RESERVE,
PAGE_EXECUTE_READWRITE);
if (pBaseAddr == NULL)
{
#ifdef debug
MessageBoxA(NULL, "VirtualAllocEx failed", NULL, 64);
#endif
goto Err;
}
// , PE , ~
if (!WriteProcessMemory(hProcess, pBaseAddr, LPVOID(hMod), cbImage, NULL))
{
#ifdef debug
MessageBoxA(NULL, "WriteProcessMemory failed", NULL, 64);
#endif
goto Err;
}
hThread = CreateRemoteThread(hProcess, NULL, NULL, \
(LPTHREAD_START_ROUTINE)&RmoteThread, NULL, NULL, NULL);
if (hThread == NULL)
{
#ifdef debug
MessageBoxA(NULL, "CreateRemoteThread failed", NULL, 64);
#endif
goto Err;
}
// WaitForSingleObject(hThread, INFINITE);
CloseHandle(hThread);
CloseHandle(hProcess);
status = TRUE;
return status; // , VirtualFreeEx;, !
Err:
if (pBaseAddr != NULL)
VirtualFreeEx(hProcess, pBaseAddr, 0, MEM_RELEASE);
if (hProcess != NULL)
CloseHandle(hProcess);
return status;
}
//■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
int main()
{
char aa[]="aBcDdddFFFF asfd";
strupr((char*)aa);
printf(aa);
if (!InjectExe(GetProcessID(ProcessName)))
Beep(1800,500);
return 0;
}
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
제한된 크기의 디렉토리를 만드는 방법오늘 저는 장치에 공간이 없을 때 백업 중에 응용 프로그램이 어떻게 작동하는지 테스트(및 수정)하는 작업이 있습니다. 결과적으로 "남은 공간 없음"오류로 백업이 실패하면 새 파일이 없어야 합니다. 지금까지 문제를 재...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.