VC++ DLL 주입

DLL 주입이란 어떤 프로세스의 주소 공간에 DLL을 넣어서 그 프로세스의 일부가 되도록 하는 것이다.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; }

좋은 웹페이지 즐겨찾기