0

I made a program to practice a simple memory injection, here is the code:

unsigned char   g_payload[] = "\x31\xC0\x31\xDB\x31\xD2\xB0\x04\xB3\x01\x68\x72\
\x6C\x64\x21\x68\x6F\x20\x57\x6F\x68\x48\x65\x6C\x6C\x89\xE1\xB2\x0C\xCD\x80";

int main(int argc, char **argv)
{
    pid_t   target_pid;
    void    *remote_address;

    if (argc != 2)
        exit(EXIT_FAILURE);
    target_pid = atoi(argv[1]);
    if (ptrace(PTRACE_ATTACH, target_pid, NULL, NULL) < 0)
        ft_error("ptrace attach");
    waitpid(target_pid, NULL, 0);
    info("Attached to process (%d)", target_pid);
    remote_address = mmap(NULL, sizeof(g_payload), PROT_READ | PROT_WRITE,
            MAP_SHARED | MAP_ANONYMOUS, -1, 0);
    if (remote_address == MAP_FAILED)
        ft_error("mmap");
    info("Allocated %ld bytes in %p", sizeof(g_payload), remote_address);
    if (ptrace(PTRACE_POKEDATA, target_pid, remote_address,
            (void *)g_payload) < 0)
        ft_error("ptrace pokedata");
    info("Payload loaded into process");
    if (ptrace(PTRACE_SETREGS, target_pid, NULL, remote_address) < 0)
        ft_error("ptrace setregs");
    info("Entry point of the new thread set");
    if (ptrace(PTRACE_CONT, target_pid, NULL, NULL) < 0)
        ft_error("ptracce continue");
    waitpid(target_pid, NULL, 0);
    if (ptrace(PTRACE_DETACH, target_pid, NULL, NULL) < 0)
        ft_error("ptrace detach");
    exit(EXIT_SUCCESS);
}

Also made another program to test it:

int main(void)
{
    pid_t   current_pid;

    current_pid = getpid();
    printf("PID: %d\n", current_pid);
    while (1)
    {
    }
    return (0);
}

When running the injector I get the following output:

[*] Attached to process (60120)
[*] Allocated 32 bytes in 0x7f3f5ac42000
ptrace pokedata: Input/output error

Don't know why I'm getting the error when writing to memory.

I'm compiling with gcc -Wall -Wextra -Werror -std=gnu11 btw

PacoFrost
  • 11
  • 4
  • 1
    `mmap()` is creating a memory region in the current process, not the remote process. Why do you think that address is meaningful in PTRACE_POKEDATA? – Barmar Jun 02 '23 at 19:34
  • 1
    `PTRACE_POKEDATA` only writes one word. You need a loop if you want to write the entire `g_payload`. – Barmar Jun 02 '23 at 19:36
  • related: [Map pages in a different process's address space](https://stackoverflow.com/q/64320217) - Linux has no equivalent to Windows `VirtualAllocEx` to allocate a new page in another process's address-space. Only read and write of existing memory via ptrace or `process_vm_writev`. (`process_vm_writev` respects permissions, like read-only mappings, unlike ptrace POKETEXT, but can copy a whole buffer at once.) – Peter Cordes Jun 02 '23 at 21:24

0 Answers0