#ifndef _MEMGREP_H
#define _MEMGREP_H
#include <elf.h>
/**
* @defgroup memgrep The memory manglement library interface.
*
* The memory manglement library interface.
*/
/**
* @addtogroup memgrep
*
* @{
*/
/**
* @example simple.c
* Example for using memgrep as a library.
*/
/**
* Initialize from a given medium.
*
* Initializes a given memgrep context to a given medium. The 'param' argument should
* be one of the enumerations in the MemoryMedium enum. The 'data' argument should
* be the arbitrary value associated with the medium. For MEMORY_MEDIUM_PID it will
* be the process id. For MEMORY_MEDIUM_CORE it will be the core file.
*/
#define MEMGREP_CMD_INITIALIZE 0x00000001
/**
* Deinitialize from a given medium.
*
* Deinitializes a given memgrep context. This will free up any resources that had
* incurred over the time of its use.
*/
#define MEMGREP_CMD_DEINITIALIZE 0x00000002
/**
* Set parameters on a context.
*
* The 'param' argument can be one of the following:
*
* @li MEMGREP_PARAM_FLAGS
* The data argument should be set to the flags that are to be enabled on the context.
* @li MEMGREP_PARAM_LENGTH
* The data argument should be set to the length that is to be used when dumping/searching.
* @li MEMGREP_PARAM_PADDING
* The data argument should be set to the length that is to be used with padding.
*/
#define MEMGREP_CMD_SET 0x00000003
/**
* Get parameters that have been set on a context.
*
* The 'param' argument can be one of the following:
*
* @li MEMGREP_PARAM_FLAGS
* The flags the context is using will be returned.
* @li MEMGREP_PARAM_LENGTH
* The length associated with dumping/searching will be returned.
* @li MEMGREP_PARAM_PADDING
* The padding associated with dumping will be returned.
*/
#define MEMGREP_CMD_GET 0x00000004
/**
* Populate the address array from supplied address(es).
*
* The 'param' argument can be one of the following:
*
* @li A string
* If the param argument is a string it should have addresses formatted
* with each address being seperated by commas. Addresses can be specified in hex
* as well as in the form of a keyword such as: bss, stack, rodata, data, all.
* The 'data' parameter should be set to 0.
* @li An array
* If the param argument is an array it should be an array of unsigned long's
* which hold the addresses that are to be used. The 'data' argument should
* have the number of elements the array contains.
*/
#define MEMGREP_CMD_POPULATE 0x00000005
/**
* Search for a given criteria in the addresses specified by MEMGREP_CMD_POPULATE.
*
* The 'param' argument is used in conjunction with the search criteria.
* It can be in the following format:
*
* @li s,example
* This will search for the string 'example' in the addresses specified in MEMGREP_CMD_POPULATE
* @li i,47
* This will search for the integer 47 in the addresses specified in MEMGREP_CMD_POPULATE
* @li x,656667
* This will search for the hex \x65\x66\x67 in the addresses specified in MEMGREP_CMD_POPULATE.
*
* The 'data' argument is undefined and should be set to 0.
*/
#define MEMGREP_CMD_SEARCH 0x00000006
/**
* Replace memory with the specified data at the addresses specified by MEMGREP_CMD_POPULATE.
*
* The 'param' argument is used in conjunction with the replace criteria.
* It can be in the following format:
*
* @li s,example
* This will replace for the string 'example' in the addresses specified in MEMGREP_CMD_POPULATE
* @li i,47
* This will replace for the integer 47 in the addresses specified in MEMGREP_CMD_POPULATE
* @li x,656667
* This will replace for the hex \x65\x66\x67 in the addresses specified in MEMGREP_CMD_POPULATE.
*
* The 'data' argument is undefined and should be set to 0.
*
* Results are optionally returned in the 'result' argument if it is not null of type MEMGREP_RESULT_TYPE_SEARCH.
*/
#define MEMGREP_CMD_REPLACE 0x00000007
/**
* Search and replace memory that matches the criteria for the addresses specified by MEMGREP_CMD_POUPLATE.
*
* The 'param' argument is used in conjunction with the search criteria.
* It can be in the following format:
*
* @li s,example
* This will search for the string 'example' in the addresses specified in MEMGREP_CMD_POPULATE
* @li i,47
* This will search for the integer 47 in the addresses specified in MEMGREP_CMD_POPULATE
* @li x,656667
* This will search for the hex \x65\x66\x67 in the addresses specified in MEMGREP_CMD_POPULATE.
*
* The 'data' argument is used in conjunction with the replace criteria.
* It can be in the following format:
*
* @li s,example
* This will replace for the string 'example' in the addresses that match the search criteria.
* @li i,47
* This will replace for the integer 47 in the addresses that match the search criteria.
* @li x,656667
* This will replace for the hex \x65\x66\x67 in the addresses that match the search criteria.
*
* Results are optionally returned in the 'result' argument if it is not null of type MEMGREP_RESULT_TYPE_REPLACE.
*/
#define MEMGREP_CMD_SEARCHREPLACE 0x00000008
/**
* Dump memory for the addresses specified in MEMGREP_CMD_POPULATE.
*
* No parameters are required.
*
* Results are optionally returned in the 'result' argument if it is not null of type MEMGREP_RESULT_TYPE_DUMP.
*/
#define MEMGREP_CMD_DUMP 0x00000009
/**
* List all the segments of a given medium such as rodata, stack, bss, etc.
*
* No parameters are required.
*/
#define MEMGREP_CMD_LISTSEGMENTS 0x0000000A
/**
* Destroy the contents of a result that was handed back by a command
*
* The 'param' argument should be a pointer to a result structure.
*
* The 'data' argument is undefined and should be 0.
*/
#define MEMGREP_CMD_DESTROYRESULT 0x0000000B
/**
* Enumerate the heap of a running process
*
* The 'param' argument is the minimize size of the heap unit, or 0.
*
* The 'data' argument is undefined and should be 0.
*/
#define MEMGREP_CMD_HEAPENUMERATE 0x0000000C
/**
* Specifies that the data parameter will be flags when used in conjunction with MEMGREP_CMD_SET.
*/
#define MEMGREP_PARAM_FLAGS 0x00000001
/**
* Specifies that the data parameter will be the length when used in conjunction with MEMGREP_CMD_SET.
*/
#define MEMGREP_PARAM_LENGTH 0x00000002
/**
* Specifies that the data parameter will be dump padding size when used in conjunction with MEMGREP_CMD_SET.
*/
#define MEMGREP_PARAM_PADDING 0x00000003
/**
* Specifies that the data parameter will be the format to use when dumping.
*/
#define MEMGREP_PARAM_DUMPFORMAT 0x00000004
/**
* The derived instance of this row is a MEMGREP_RESULT_ROW_SEARCH and should be cast as such.
*/
#define MEMGREP_RESULT_TYPE_SEARCH 0x00000001
/**
* The derived instance of this row is a MEMGREP_RESULT_ROW_REPLACE and should be cast as such.
*/
#define MEMGREP_RESULT_TYPE_REPLACE 0x00000002
/**
* The derived instance of this row is a MEMGREP_RESULT_ROW_DUMP and should be cast as such.
*/
#define MEMGREP_RESULT_TYPE_DUMP 0x00000003
/**
* The derived instance of this row is a MEMGREP_RESULT_ROW_HEAP and should be cast as such.
*/
#define MEMGREP_RESULT_TYPE_HEAP 0x00000004
/**
* Flag used to enable verbose output when performing actions.
*/
#define MEMGREP_FLAG_VERBOSE (1 << 0)
/**
* Flag used to enable prompting before replacing memory.
*/
#define MEMGREP_FLAG_PROMPT (1 << 1)
/**
* Flag used to enable output of dumping memory in a clear-text format rather than hex.
*/
#define MEMGREP_FLAG_DUMPCLEAN (1 << 2)
/**
* Mediums used when operating with memgrep.
*
* @short memory access mediums
*/
enum MemoryMedium {
/**
* An unknown medium
*/
MEMORY_MEDIUM_UNKNOWN = 0,
/**
* Access memory via a process id
*/
MEMORY_MEDIUM_PID = 1,
/**
* Access memory via a core file
*/
MEMORY_MEDIUM_CORE = 2
};
/**
* The format to use when dumping memory
*
* @short memory dumping format
*/
enum MemoryDumpFormat {
/**
* Dump as hex integers (0xabcdef00)
*/
MEMORY_DUMP_FORMAT_HEXINT = 0,
/**
* Dump as hex shorts (0xabcd)
*/
MEMORY_DUMP_FORMAT_HEXSHORT = 1,
/**
* Dump as hex characters (0xab)
*/
MEMORY_DUMP_FORMAT_HEXBYTE = 2,
/**
* Dump as decimal integers (1234)
*/
MEMORY_DUMP_FORMAT_DECINT = 3,
/**
* Dump as decimal shorts (65535)
*/
MEMORY_DUMP_FORMAT_DECSHORT = 4,
/**
* Dump as decimal characters (127)
*/
MEMORY_DUMP_FORMAT_DECBYTE = 5,
/**
* Dump as ascii printable characters
*/
MEMORY_DUMP_FORMAT_PRINTABLE = 6,
};
/**
* Holds the addresses that signify the start of a given logical section.
*
* @short Section addresses
*/
typedef struct _process_section_addrs {
/**
* 0.8.0+: Text section of the binary image.
*/
unsigned long text;
/**
* 0.8.0+: The length of the text section of the binary image.
*/
unsigned long textLength;
/**
* Read-only data, commonly associated with static text.
*/
unsigned long rodata;
/**
* 0.8.0+: The length of the read-only data section.
*/
unsigned long rodataLength;
/**
* Data, commonly associated with global or static variables.
*/
unsigned long data;
/**
* 0.8.0+: The length of the data section.
*/
unsigned long dataLength;
/**
* bss, commonly associated with the 'heap'.
*/
unsigned long bss;
/**
* stack, self explanatory.
*/
unsigned long stack;
} PROCESS_SECTION_ADDRS;
/**
* Holds virtual memory segments of a core file as well as their length.
*
* @short Core file virtual-memory segments.
*/
typedef struct _core_memory_sections {
/**
* The virtual memory addresses of the segment
*/
unsigned long vma;
/**
* The length of the segment
*/
unsigned long length;
/**
* The mmap()'d address of the segment.
*/
unsigned long rma;
} CORE_MEMORY_SECTIONS;
/**
* Extended data structure holding information about a core file.
*
* @short Core file information.
*/
typedef struct _mem_ctx_core_data {
/**
* The file descriptor associated with the core file.
*/
int fd;
/**
* The elf header of the core file.
*/
Elf32_Ehdr elfHeader;
/**
* The array of program headers.
*/
Elf32_Phdr *programHeaders;
/**
* The array of virtual memory segments.
*/
CORE_MEMORY_SECTIONS *sections;
/**
* The number of segments.
*/
unsigned long numSections;
} MEM_CTX_CORE_DATA;
struct _mem_ctx;
/**
* The medium-independant function table used internally by memgrep.
*
* @short Medium-independant function table.
*/
typedef struct _memgrep_functions {
/**
* Open the medium and prepare it for operation.
*
* @param ctx [in] The memgrep context.
* @return On success, 1 is returned, otherwise 0 is returned.
*/
unsigned long (*open)(struct _mem_ctx *ctx);
/**
* Closes the medium, releasing any resources used.
*
* @param ctx [in] The memgrep context.
* @return On success, 1 is returned, otherwise 0 is returned.
*/
unsigned long (*close)(struct _mem_ctx *ctx);
/**
* Get the sections (rodata, bss, data, stack) associated with a given medium.
*
* @param ctx [in] The memgrep context.
* @return On success, 1 is returned, otherwise 0 is returned.
*/
unsigned long (*getSections)(struct _mem_ctx *ctx);
/**
* Gets a memory address for a specified number of bytes.
*
* @param ctx [in] The memgrep context.
* @param addr [in] The address to start from.
* @param length [in] The number of bytes to get.
* @return On success, a buffer containing the data at the specified address is returned. Otherwise, NULL is returned.
*/
unsigned char *(*get)(struct _mem_ctx *ctx, unsigned long addr, unsigned long length);
/**
* Puts arbitrary data into memory at the specified address for a given length.
*
* @param ctx [in] The memgrep context.
* @param addr [in] The address to start from.
* @param buf [in] The buffer to write from.
* @param bufLength [in] The number of bytes to write.
* @return On success, 1 is returned, otherwise 0 is returned.
*/
unsigned long (*put)(struct _mem_ctx *ctx, unsigned long addr, unsigned char *buf, unsigned long bufLength);
/**
* Populate the addresses array from a given keyword.
*
* @param ctx [in] The memgrep context.
* @param keyword [in] The keyword to replace (such as 'bss').
* @return If the keyword is valid, 1 is returned, otherwise 0 is returned.
*/
unsigned long (*populateKeyword)(struct _mem_ctx *ctx, const char *keyword);
/**
* List the segments of a given medium.
*
* @param ctx [in] The memgrep context.
* @return On success, 1 is returned, otherwise 0 is returned.
*/
unsigned long (*listSegments)(struct _mem_ctx *ctx);
/**
* Enumerate the heap of the given medium.
*
* @param ctx [in] The memgrep context.
* @param current [in] The current node in the list, or 0 if the first node.
* @param addr [out] The adderss of the allocation unit at this point.
* @param size [out] The size of the allocation unit at this point.
* @return On success, 1 is returned, otherwise 0 is returned.
*/
unsigned long (*heapEnumerate)(struct _mem_ctx *ctx, unsigned long current, unsigned long *addr, unsigned long *size);
} MEMGREP_FUNCTIONS;
/**
* The base for all rows in a result
*
* @short Result row base structure.
*/
typedef struct _memgrep_result_row {
/**
* The length in bytes of the structure.
*/
unsigned long length;
/**
* The type of structure. This can be one of the following:
*
* @li MEMGREP_RESULT_TYPE_SEARCH
* The derived structure is 'MEMGREP_RESULT_ROW_SEARCH'
* @li MEMGREP_RESULT_TYPE_REPLACE
* The derived structure is 'MEMGREP_RESULT_ROW_REPLACE'
* @li MEMGREP_RESULT_TYPE_DUMP
* The derived structure is 'MEMGREP_RESULT_ROW_DUMP'
*/
unsigned long type;
} MEMGREP_RESULT_ROW;
/**
* The result from a given operation, including any rows that were returned.
*
* @short The result of a given operation.
*/
typedef struct _memgrep_result {
/**
* The error code, 0 if no error.
*/
unsigned long error;
/**
* The number of rows returned by the query.
*/
unsigned long numRows;
/**
* The array of rows.
*/
MEMGREP_RESULT_ROW **rows;
} MEMGREP_RESULT;
/**
* Used in association with MEMGREP_CMD_SEARCH.
*
* @short Row for search results.
*/
typedef struct _memgrep_result_row_search {
/**
* The base structure for all rows
*/
MEMGREP_RESULT_ROW base;
/**
* The address that a matching instance of the search criteria was found at
*/
unsigned long addr;
} MEMGREP_RESULT_ROW_SEARCH;
/**
* Used in association with MEMGREP_CMD_HEAPENUMERATE
*
* @short Row for heap enumeration results.
*/
typedef struct _memgrep_result_row_heap {
/**
* The base structure for all rows
*/
MEMGREP_RESULT_ROW base;
/**
* The base address of the allocation in the heap
*/
unsigned long addr;
/**
* The size of the allocation
*/
unsigned long size;
} MEMGREP_RESULT_ROW_HEAP;
/**
* Used in association MEMGREP_CMD_SEARCHREPLACE and MEMGREP_CMD_REPLACE
*
* @short Row for replace reuslts.
*/
typedef struct _memgrep_result_row_replace {
/**
* The base structure for all rows
*/
MEMGREP_RESULT_ROW base;
/**
* The address where an instance of memory was replaced at.
*/
unsigned long addr;
} MEMGREP_RESULT_ROW_REPLACE;
/**
* Used in association with MEMGREP_CMD_DUMP
*
* @short Row for memory dump results.
*/
typedef struct _memgrep_result_row_dump {
/**
* The base structure for all rows
*/
MEMGREP_RESULT_ROW base;
/**
* The adderss that the dump occured at.
*/
unsigned long addr;
/**
* The memory at that address
*/
unsigned char *buf;
/**
* The number of bytes held in buf
*/
unsigned long bufLength;
} MEMGREP_RESULT_ROW_DUMP;
/**
* The memgrep context.
*
* @short memgrep context
*/
typedef struct _mem_ctx {
/**
* Holds the flags for the conetxt. These can be a combination of the following:
*
* @li MEMGREP_FLAG_VERBOSE
* Be verbose. This enables output for given commands.
* @li MEMGREP_FLAG_PROMPT
* Prompt before overwriting memory.
* @li MEMGREP_FLAG_DUMPCLEAN
* Dump the memory in human read-able format. This is only useful with verbose set.
*/
unsigned long flags;
/**
* The medium that will be operated upon. This can be:
*
* @li MEMORY_MEDIUM_PID
* Operate on a process id.
* @li MEMORY_MEDIUM_CORE
* Operate on a core file.
*/
enum MemoryMedium medium;
/**
* The process id to operate on.
*/
int pid;
/**
* The core file to operate on.
*/
char *core;
/**
* Medium specific function table.
*/
MEMGREP_FUNCTIONS functions;
/**
* Section addresses associated with the medium.
*/
PROCESS_SECTION_ADDRS sections;
/**
* Array of addresses populated by MEMGREP_CMD_POPULATE
*/
unsigned long *addrs;
/**
* Number of elements in the 'addrs' array.
*/
unsigned long numAddrs;
/**
* The length used when searching, and dumping.
*/
unsigned long length;
/**
* Padding used when dumping memory.
*/
unsigned long padding;
/**
* Format for use when dumping
*/
enum MemoryDumpFormat dumpFormat;
/**
* Extended data related to core files
*/
MEM_CTX_CORE_DATA coreData;
/**
* MISC:
*
* procFd => Solaris fd for proc access
*/
int procCtlFd;
int procAsFd;
} MEM_CTX;
/**
* The method used to operate memgrep.
*
* @param ctx [in] The memgrep context.
* @param cmd [in] The command to execute. See each command for a description of its parameters.
* @param result [out] The result of a given action. This can be NULL.
* @param param [in] An arbitrary parameter for a given command.
* @param data [in] An arbitrary parameter for a given command.
* @return Return values vary from one command to another.
*/
unsigned long memgrep(MEM_CTX *ctx, unsigned long cmd, MEMGREP_RESULT *result, unsigned long param, unsigned long data);
/*
* These functions should not be called directly.
*/
unsigned long memgrep_initialize(MEM_CTX *ctx, enum MemoryMedium medium, void *data); // 1 for success, 0 for failure
unsigned long memgrep_deinitialize(MEM_CTX *ctx); // 1 for success, 0 for failure
unsigned long memgrep_set(MEM_CTX *ctx, unsigned long param, unsigned long data); // 1 for success, 0 for failure
unsigned long memgrep_get(MEM_CTX *ctx, unsigned long param); // the value associated w/ the param
unsigned long memgrep_populate_string(MEM_CTX *ctx, const char *addresses); // number of addresses populated
unsigned long memgrep_populate_array(MEM_CTX *ctx, unsigned long *array, unsigned long elements); // number of addresses populated
unsigned long memgrep_search(MEM_CTX *ctx, MEMGREP_RESULT *result, const char *searchPhrase); // number of addresses found
unsigned long memgrep_replace(MEM_CTX *ctx, MEMGREP_RESULT *result, const char *replacePhrase); // number of addresses replaced
unsigned long memgrep_searchreplace(MEM_CTX *ctx, MEMGREP_RESULT *result, const char *searchPhrase, const char *replacePhrase); // number of addresses search/replaced
unsigned long memgrep_dump(MEM_CTX *ctx, MEMGREP_RESULT *result); // 1 for success, 0 for failure
unsigned long memgrep_listSegments(MEM_CTX *ctx); // 1 for success, 0 for failure
unsigned long memgrep_destroy(MEM_CTX *ctx, MEMGREP_RESULT *result); // Destroy a resultant value, 1 for success 0 for failure
unsigned long memgrep_heapenumerate(MEM_CTX *ctx, MEMGREP_RESULT *result, unsigned long minSize); // 1 for success, 0 for failure
/**
* @}
*/
#endif
syntax highlighted by Code2HTML, v. 0.9.1