#include <windows.h>
#include <tlhelp32.h>
#include <stdio.h>
#include <string.h>
//进程的第一个模块即为进程的 基址 (这里顺便获取进程内存映像的大小)
DWORD GetProcessBaseAndImageSize(DWORD dwPID, DWORD *dwImageSize)
{
HANDLE hModuleSnap = INVALID_HANDLE_VALUE;
MODULEENTRY32 me32;
// Take a snapshot of all modules in the specified process.
hModuleSnap = CreateToolhelp32Snapshot( TH32CS_SNAPMODULE, dwPID );
if( hModuleSnap == INVALID_HANDLE_VALUE )
{
printf( "CreateToolhelp32Snapshot (of modules) ,error code :%d\n",GetLastError() );
return FALSE;
}
// Set the size of the structure before using it.
me32.dwSize = sizeof( MODULEENTRY32 );
// Retrieve information about the first module,
// and exit if unsuccessful
if( !Module32First( hModuleSnap, &me32 ) )
{
printf( "Module32First" ); // show cause of failure
CloseHandle( hModuleSnap ); // clean the snapshot object
return FALSE;
}
//printf( "\n Base address = 0x%08X", (DWORD) me32.modBaseAddr ); //第一个模块即进程基址
CloseHandle( hModuleSnap );
if(dwImageSize != NULL)
*dwImageSize = me32.modBaseSize; //进程映像大小
return (DWORD)me32.modBaseAddr;
}
//对所有进程进行快照,找出指定进程的pid
DWORD GetProcessPid(char strPocName[])
{
HANDLE hProcessSnap;
HANDLE hProcess;
PROCESSENTRY32 pe32;
// Take a snapshot of all processes in the system.
hProcessSnap = CreateToolhelp32Snapshot( TH32CS_SNAPPROCESS, 0 );
if( hProcessSnap == INVALID_HANDLE_VALUE )
{
printf("Failed to CreateToolhelp32Snapshot...\n");
return FALSE;
}
// Set the size of the structure before using it.
pe32.dwSize = sizeof( PROCESSENTRY32 );
// Retrieve information about the first process,
// and exit if unsuccessful
if( !Process32First( hProcessSnap, &pe32 ) )
{
printf("error in Process32First...\n");
CloseHandle( hProcessSnap ); // clean the snapshot object
return FALSE;
}
// Now walk the snapshot of processes, and
// display information about each process in turn
do
{
//printf("process name : %s\n",pe32.szExeFile);
if(stricmp(strPocName, pe32.szExeFile) == 0) //忽略大小写
{
//printf("process name : %s\n",pe32.szExeFile);
CloseHandle(hProcessSnap);
return pe32.th32ProcessID;
}
} while( Process32Next( hProcessSnap, &pe32 ) );
CloseHandle( hProcessSnap );
return FALSE;
}
//方式一:
//通过PE文件头确定镜像的大小,如果文件头被壳修改则无法得到镜像大小
DWORD GetImageSize(HANDLE hProc, DWORD dwImageBase)
{
DWORD dwRetSize;
IMAGE_DOS_HEADER ImageDosHeader;
IMAGE_NT_HEADERS ImageNtHeader;
if(ReadProcessMemory(hProc, (char*)dwImageBase, &ImageDosHeader, sizeof(IMAGE_DOS_HEADER), NULL) == 0)
{
printf("lasterror : %d\n", GetLastError());
}
PIMAGE_NT_HEADERS pNTHeader = (PIMAGE_NT_HEADERS)(dwImageBase + ImageDosHeader.e_lfanew);
if(ReadProcessMemory(hProc, (char*)(pNTHeader), &ImageNtHeader, sizeof(IMAGE_NT_HEADERS), NULL) == 0)
{
printf("lasterror : %d\n", GetLastError());
return FALSE;
}
dwRetSize = ImageNtHeader.OptionalHeader.SizeOfImage;
return dwRetSize;
}
方式二:
通过抓取进程快照获取程序镜像大小(参见函数GetProcessBaseAndImageSize)
//DWORD GetImageSize(DWORD dwPid)
//{
// HANDLE hMoudleSnap = INVALID_HANDLE_VALUE;
// MODULEENTRY32 me32;
// memset(&me32, 0, sizeof(MODULEENTRY32));
// me32.dwSize = sizeof(MODULEENTRY32);
// //对进程所有模块进行快照处理
// hMoudleSnap = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, dwPid);
// if(hMoudleSnap == INVALID_HANDLE_VALUE)
// {
// printf("failed to CreateToolhelp32Snapshot of process modules...\n");
// return FALSE;
// }
// //retrieve information about the first module
// //and exit if unsucessful
// if(!Module32First(hMoudleSnap, &me32))
// {
// printf("Failed to Module32First...\n");
// CloseHandle(hMoudleSnap);
// return FALSE;
// }
// CloseHandle(hMoudleSnap);
// return me32.modBaseSize; //进程镜像的大小
//}
//修改dump文件的区段头结构中 文件偏移 文件大小 值 ,使其与内存偏移,内存大小相等
BOOL ModifySectionHeader(char *strDumpFileName)
{
HANDLE hFile;
HANDLE hFileMapping;
LPVOID lpFileBase;
hFile = CreateFile(strDumpFileName,
GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
0);
if(hFile == INVALID_HANDLE_VALUE)
{
printf("Failed to CreateFile ...\n");
return FALSE;
}
//将文件映射到内存
hFileMapping = CreateFileMapping(hFile,
NULL,
PAGE_READWRITE,
0, 0, NULL);
if(hFileMapping == 0)
{
CloseHandle(hFile);
printf("Failed to CreateFileMapping...\n");
return FALSE;
}
lpFileBase = MapViewOfFile(hFileMapping,
FILE_MAP_ALL_ACCESS,
0, 0, 0);
if(lpFileBase == 0)
{
CloseHandle(hFileMapping);
CloseHandle(hFile);
printf("Failed to MapViewOfFile...\n");
return FALSE;
}
PIMAGE_DOS_HEADER pDosHeader = (PIMAGE_DOS_HEADER)lpFileBase;
PIMAGE_NT_HEADERS pNtHeader = (PIMAGE_NT_HEADERS)((DWORD)lpFileBase + pDosHeader->e_lfanew);
DWORD dwSectionCount;
dwSectionCount = pNtHeader->FileHeader.NumberOfSections;
PIMAGE_SECTION_HEADER pSectionHeader = (PIMAGE_SECTION_HEADER)((DWORD)pNtHeader + sizeof(IMAGE_NT_HEADERS));
for (int i = 0; i < dwSectionCount; i++)
{
//printf("before:\nsection%d VOffset : %x VSize : %x ROffset : %x RSize : %x \n",
// i,
// pSectionHeader->VirtualAddress,
// pSectionHeader->Misc.VirtualSize,
// pSectionHeader->PointerToRawData,
// pSectionHeader->SizeOfRawData);
//modify data
//因为从内存中dump出来后,值都应该保持与区段内存偏移和大小一致
pSectionHeader->PointerToRawData = pSectionHeader->VirtualAddress;
pSectionHeader->SizeOfRawData = pSectionHeader->Misc.VirtualSize;
pSectionHeader++; //next section
}
//FlushViewOfFile()
UnmapViewOfFile(lpFileBase);
CloseHandle(hFileMapping);
CloseHandle(hFile);
return TRUE;
}
//dump process
DWORD DumpProcess(char strProcName[])
{
DWORD dwPid;
DWORD dwImageSize;
DWORD dwProcBase;
dwPid = GetProcessPid(strProcName);
if(dwPid == FALSE)
return FALSE;
dwProcBase = GetProcessBaseAndImageSize(dwPid, &dwImageSize);
if(dwProcBase == FALSE)
return FALSE;
printf( "\nBase address = 0x%08X , pid = %d, ImageSize = %d ...\n", dwProcBase, dwPid, dwImageSize ); //第一个模块即进程基址
//dump进程映像
HANDLE hProc = OpenProcess( PROCESS_VM_READ, FALSE, dwPid );
if(hProc == NULL)
{
printf("Failed to open %d process...\n",dwPid);
return false;
}
//dwImageSize = 0;
//dwImageSize = GetImageSize(hProc, dwProcBase);
//if(dwImageSize == 0)
// return false;
//printf("Image size:%d\n",dwImageSize);
char *procBuff = (char*)malloc(dwImageSize);
if(ReadProcessMemory(hProc, (char*)dwProcBase, procBuff, dwImageSize, NULL) == 0)
{
printf("lasterror : %d\n", GetLastError());
return false;
}
char strFile[MAX_PATH] = "dump.";
strcat(strFile, strProcName);
FILE *fp;
fp = fopen(strFile, "wb");
fwrite(procBuff, dwImageSize, 1, fp);
fclose(fp);
if(procBuff != NULL)
free(procBuff);
CloseHandle(hProc);
ModifySectionHeader(strFile);
return true;
}
void main( int argc, char** argv )
{
if(argc != 2)
{
printf("error argv...\n");
return;
}
printf("dump %s...\n",argv[1]);
DumpProcess(argv[1]);
system("pause");
}
LordPe dump进程内存实现
最新推荐文章于 2023-02-21 20:16:25 发布