Created
August 5, 2016 09:53
-
-
Save wuyongzheng/f5f621e0c10e9d57af9c876d2f17fca0 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <windows.h> | |
#include <psapi.h> // for GetMappedFileName | |
#include <stdio.h> | |
static const struct memprot_name_type { | |
unsigned int value; | |
const char *short_name; | |
const char *desc; | |
} memprot_names[] = { | |
{PAGE_NOACCESS, "noa", "PAGE_NOACCESS"}, | |
{PAGE_READONLY, "ro", "PAGE_READONLY"}, | |
{PAGE_READWRITE, "rw", "PAGE_READWRITE"}, | |
{PAGE_WRITECOPY, "wc", "PAGE_WRITECOPY"}, | |
{PAGE_EXECUTE, "x", "PAGE_EXECUTE"}, | |
{PAGE_EXECUTE_READ, "rx", "PAGE_EXECUTE_READ"}, | |
{PAGE_EXECUTE_READWRITE, "rwx", "PAGE_EXECUTE_READWRITE"}, | |
{PAGE_EXECUTE_WRITECOPY, "rwc", "PAGE_EXECUTE_WRITECOPY"}, | |
{PAGE_GUARD, "g", "PAGE_GUARD"}, | |
{PAGE_NOCACHE, "nc", "PAGE_NOCACHE"}, | |
{PAGE_WRITECOMBINE, "wb", "PAGE_WRITECOMBINE"}, | |
{PAGE_REVERT_TO_FILE_MAP, "f", "PAGE_REVERT_TO_FILE_MAP"}, | |
#ifdef PAGE_TARGETS_INVALID | |
{PAGE_TARGETS_INVALID, "t", "PAGE_TARGETS_INVALID"}, | |
#else | |
{0x40000000, "t", "PAGE_TARGETS_INVALID"}, | |
#endif | |
}; | |
const char *memprot_name (unsigned int mem_protect) | |
{ | |
static char buff[100]; | |
buff[0] = '\0'; | |
int i; | |
for (i = 0; i < sizeof(memprot_names) / sizeof(memprot_names[0]); i ++) { | |
if (memprot_names[i].value & mem_protect) { | |
if (buff[0]) | |
strncat(buff, ",", sizeof(buff)); | |
strncat(buff, memprot_names[i].short_name, sizeof(buff)); | |
} | |
} | |
return buff; | |
} | |
const char *memtype_name (unsigned int mem_type) | |
{ | |
switch (mem_type) { | |
case MEM_IMAGE: return "i"; | |
case MEM_MAPPED: return "m"; | |
case MEM_PRIVATE: return "p"; | |
default: return "?"; | |
} | |
} | |
void do_list (int pid) | |
{ | |
HANDLE proc = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_OPERATION | PROCESS_VM_READ, 0, pid); | |
if (proc == NULL) { | |
printf("error: OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_OPERATION | PROCESS_VM_READ , 0, %d) failed\n", pid); | |
return; | |
} | |
SYSTEM_INFO sysinfo; | |
GetSystemInfo(&sysinfo); | |
char *addr = sysinfo.lpMinimumApplicationAddress; | |
while (addr < sysinfo.lpMaximumApplicationAddress) { | |
MEMORY_BASIC_INFORMATION meminfo; | |
if (VirtualQueryEx(proc, addr, &meminfo, sizeof(MEMORY_BASIC_INFORMATION)) == 0) { | |
printf("VirtualQueryEx(%p) failed.\n", addr); | |
break; | |
} | |
if (meminfo.RegionSize == 0) { | |
printf("VirtualQueryEx(%p) failed. RegionSize=0\n", addr); | |
break; | |
} | |
if (meminfo.State != MEM_COMMIT) goto next; | |
char file_name[512]; | |
file_name[0] = ' '; | |
if (GetMappedFileName(proc, addr, file_name+1, sizeof(file_name)-1) == 0) | |
file_name[0] = '\0'; | |
#ifdef _WIN64 | |
printf("base=%p addr=%p size=0x%Ix prot=%s type=%s%s\n", | |
#else | |
printf("base=%08p addr=%08p size=0x%x prot=%s type=%s%s\n", | |
#endif | |
meminfo.AllocationBase, | |
meminfo.BaseAddress, | |
meminfo.RegionSize, | |
memprot_name(meminfo.Protect), | |
memtype_name(meminfo.Type), | |
file_name); | |
next: | |
addr += meminfo.RegionSize; | |
} | |
} | |
void do_dump1 (int pid, void *addr, size_t size, const char *filename) | |
{ | |
HANDLE proc = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_OPERATION | PROCESS_VM_READ, 0, pid); | |
if (proc == NULL) { | |
printf("error: OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_OPERATION | PROCESS_VM_READ , 0, %d) failed\n", pid); | |
return; | |
} | |
unsigned char *buffer = (unsigned char *)malloc(size); | |
if (buffer == NULL) { | |
printf("error: out of memory\n"); | |
return; | |
} | |
SIZE_T bytes_read; | |
if (ReadProcessMemory(proc, addr, buffer, size, &bytes_read) == 0) { | |
printf("error: ReadProcessMemory error\n"); | |
return; | |
} | |
FILE *fp = fopen(filename, "wb"); | |
if (fp == NULL) { | |
printf("error: can't create output file\n"); | |
return; | |
} | |
fwrite(buffer, size, 1, fp); | |
fclose(fp); | |
} | |
void do_dump (int pid, char *filters[], int nfilter) | |
{ | |
} | |
void usage (const char *cmd) | |
{ | |
printf("Usage:\n"); | |
printf(" %s help\n", cmd); | |
printf(" %s list pid\n", cmd); | |
printf(" %s dump pid [filter1] [filter2] ...\n", cmd); | |
printf(" %s dump1 pid addr-in-hex size-in-hex outfile\n", cmd); | |
printf("Example:\n"); | |
printf(" %s list 4235\n", cmd); | |
printf(" %s dump 4235 rw\n", cmd); | |
printf(" %s dump 4235 rx rwx\n", cmd); | |
printf(" %s dump1 4235 77BA0000 107000 ntdll-code.dat\n", cmd); | |
printf("Filters:\n"); | |
printf(" noa: PAGE_NOACCESS\n"); | |
printf(" writable: same for \"rw wc rwx rwc\"\n"); | |
printf(" executable: same for \"x rx rwx\"\n"); | |
} | |
int main (int argc, char *argv[]) | |
{ | |
if (argc == 3 && strcmp(argv[1], "list") == 0) { | |
do_list(atoi(argv[2])); | |
} else if (argc >= 3 && strcmp(argv[1], "dump") == 0) { | |
do_dump(atoi(argv[2]), argv+3, argc-3); | |
} else if (argc == 6 && strcmp(argv[1], "dump1") == 0) { | |
do_dump1(atoi(argv[2]), (void *)strtol(argv[3], NULL, 16), strtol(argv[4], NULL, 16), argv[5]); | |
} else { | |
usage(argv[0]); | |
} | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment