발로 만든 Win32 Memory Dumper
Study/System Programming :
2012/01/19 02:44
종종 프로세스의 메모리를 덤프해야될때가 있는데, 이 프로그램은 특정 프로세스의 COMMIT && READ 가능한 영역은 모두다 찾아서 덤프해줍니다. 참고로 유저모드 프로그램이며, 커널 영역으로는 내려가지 않습니다.
(커널에서 후킹이 이루어지는 프로세스인 경우, (ex. 자가보호) 덤프가 안될수 있음)
잘못된 점이 있으면 알려주세요 !
(커널에서 후킹이 이루어지는 프로세스인 경우, (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;
}
'Study > System Programming' 카테고리의 다른 글
| 발로 만든 Win32 Memory Dumper (2) | 2012/01/19 |
|---|---|
| WinDDK에서 Intrinsics 사용하기 (0) | 2012/01/06 |
| [Linux] System Call을 이용한 Simple Round-Robin Scheduler (0) | 2010/11/09 |
| Introduction to x64 Assembly Programming (2) | 2010/09/24 |
| GetThreadContext를 이용한 하드웨어 중단점 탐지 (2) | 2010/05/23 |
| WinDbg로 배우는 Windows Debugging (2) | 2009/09/21 |


댓글을 달아 주세요
잘 봤습니다 ㅋ 형은 Multi Byte 기반으로 프로그래밍 잘 하시네요..
전 귀찮아서 잘 안하게 되는데 ㅠㅠ
습관 들이는게 좋은거같다 ㅋㅋ 그래야 나중에 편해질듯~