종종 프로세스의 메모리를 덤프해야될때가 있는데, 이 프로그램은 특정 프로세스의 COMMIT && READ 가능한 영역은 모두다 찾아서 덤프해줍니다. 참고로 유저모드 프로그램이며, 커널 영역으로는 내려가지 않습니다.
(커널에서 후킹이 이루어지는 프로세스인 경우, (ex. 자가보호)  덤프가 안될수 있음)
잘못된 점이 있으면 알려주세요 !





#include <stdio.h>
#include <Windows.h>
#include <Tlhelp32.h>
#include <tchar.h>


//to set super privilege for current process
VOID SetSuperPrivilege(IN LPCTSTR PrivilegeName)
{
HANDLE hToken = NULL;
TOKEN_PRIVILEGES tp;

//get token handle from current process
if ( !OpenProcessToken( 
GetCurrentProcess(), 
TOKEN_ADJUST_PRIVILEGES, 
&hToken)
) {
_tprintf(_T("OPToken error. %d\n"), GetLastError());
return;
}
__try {


//query debug privilege
if ( !LookupPrivilegeValue(
NULL, 
PrivilegeName, 
&tp.Privileges[0].Luid)
) {
_tprintf(_T("LUPPrivilege error. %d\n"), GetLastError());
return;
}


tp.PrivilegeCount = 1; //must be 1
tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; //privilege enabled


//adjust token privilege
if ( !AdjustTokenPrivileges(
hToken, 
FALSE, 
&tp, 
sizeof(TOKEN_PRIVILEGES), 
NULL, 
NULL)
) {
_tprintf(_T("ADJUPrivilege error. %d\n"), GetLastError());
return;
}

}
__finally {
CloseHandle(hToken);
}
}


//Enum process list on display
BOOL EnumerateProcessList(VOID)
{
HANDLE hSnapShot = INVALID_HANDLE_VALUE;
PROCESSENTRY32 pe32;

//get a snapshot handle
hSnapShot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if ( hSnapShot == INVALID_HANDLE_VALUE ) {
_tprintf(_T("CTHelp32 error. %d\n"), GetLastError());
return FALSE;
}

__try {

//initialize PROCESSENTRY structure
ZeroMemory(&pe32, sizeof(PROCESSENTRY32));
pe32.dwSize = sizeof(PROCESSENTRY32);

//call first
if ( !Process32First(hSnapShot, &pe32) ) {
_tprintf(_T("PE32First error. %d\n"), GetLastError());
return FALSE;
}

//call next until ERROR_FILE_NOT_FOUND or failed to call next
while( Process32Next(hSnapShot, &pe32) ) {

if ( GetLastError() == ERROR_FILE_NOT_FOUND ) {
break;
}

//Enum process list on display
_tprintf(
_T("%-30s\t\t%-4d\n"), 
pe32.szExeFile, 
pe32.th32ProcessID
);

}

return TRUE;

}
__finally {
CloseHandle(hSnapShot);
}

}

//dump memory which is on target process
VOID DumpAllMemory(IN HANDLE hProcess)
{
HANDLE hFile;
LPVOID lpMem, lpBuffer;
DWORD NumberofBytesWritten;
TCHAR szFileName[MAX_PATH];
SYSTEM_INFO si;
MEMORY_BASIC_INFORMATION mbi;

if ( hProcess == NULL ) {
_tprintf(_T("hProcess is an invalid value.\n"));
return;
}


/* Get maximum address range from system info */
GetSystemInfo(&si);
//initialize MBI
ZeroMemory(&mbi, sizeof(MEMORY_BASIC_INFORMATION));
lpMem = NULL;

while (lpMem < si.lpMaximumApplicationAddress) {
if ( !VirtualQueryEx(
hProcess, 
lpMem, 
&mbi, 
sizeof(MEMORY_BASIC_INFORMATION)) 
) {

_tprintf(_T("VQuery failed. %d\n"), GetLastError());
CloseHandle(hProcess);
return;

}

/* Increase lpMem to next region of memory */
lpMem = (PVOID)( ( (DWORD_PTR)mbi.BaseAddress + 
(DWORD_PTR)mbi.RegionSize) );


if ( (mbi.BaseAddress != NULL) &&
(mbi.State == MEM_COMMIT) ) {


switch (mbi.Protect)
{
case PAGE_EXECUTE_READ:
case PAGE_EXECUTE_READWRITE:
case PAGE_EXECUTE_WRITECOPY:
case PAGE_READONLY:
case PAGE_READWRITE:
case PAGE_WRITECOPY:

//allocate temp buffer to save data
lpBuffer = VirtualAlloc(
NULL, 
mbi.RegionSize, 
MEM_COMMIT, 
PAGE_READWRITE
);

//read data from target process's memory, data is gonna be saved into lpBuffer
if ( !ReadProcessMemory(
hProcess, 
mbi.BaseAddress, 
lpBuffer, 
mbi.RegionSize, 
NULL) 
) {
_tprintf(_T("ReadMemory failed. %d\n"), GetLastError());
VirtualFree(lpBuffer, mbi.RegionSize, MEM_FREE);
break;
}
//generate file name
_stprintf_s(
szFileName, 
sizeof(szFileName), 
_T("%X - %X.dmp"), 
mbi.BaseAddress, 
((DWORD_PTR)mbi.BaseAddress + (DWORD_PTR)mbi.RegionSize)
);

//create file
hFile = CreateFile(
szFileName, 
GENERIC_WRITE, 
0, 
NULL, 
CREATE_ALWAYS, 
FILE_ATTRIBUTE_NORMAL, 
NULL
);

//write data into file
if ( WriteFile(
hFile, 
lpBuffer, 
(DWORD_PTR)mbi.RegionSize, 
&NumberofBytesWritten, 
NULL) 
) {
_tprintf(_T("Dumped successfully : %s\n"), szFileName);
} else _tprintf(_T("failed to dump : %s,  %x\n"), szFileName, GetLastError());

//return resources
VirtualFree(lpBuffer, mbi.RegionSize, MEM_FREE);
CloseHandle(hFile);
break;

default:
break;
}


}


}

CloseHandle(hProcess);
return;
}


int _tmain( int argc, TCHAR* argv[] )
{
DWORD target_pid;

//obtain super privilege
SetSuperPrivilege(SE_DEBUG_NAME);

//enum process list on display
if ( !EnumerateProcessList() ) {
return EXIT_FAILURE;
}

//input target PID
_tprintf(_T("\n\n ### Choose target PID : "));
_tscanf(_T("%d"), &target_pid);

//dump
DumpAllMemory ( 
OpenProcess(
PROCESS_ALL_ACCESS, 
FALSE, 
target_pid
);

//end
system("pause");
return EXIT_SUCCESS;
}
저작자 표시 비영리 변경 금지
신고
크리에이티브 커먼즈 라이선스
Creative Commons License
by Sone 2012.01.19 02:44
| 1 |

티스토리 툴바