proctal

Manipulates the address space of a program on Linux.

Proctal 0.0.0

Proctal provides a command line interface and a C library to manipulate the address space of a program on Linux.

Features: - Reading and writing values in memory - Searching for values in memory - Repeatedly writing a value to memory fast so as to make it seem like it’s never changing - Temporarily freezing execution of a program’s main thread - Detecting reads, writes and execution of memory addresses on a program’s main thread - Disassembling instructions from any memory location - Assembling instructions to write to any memory location - Allocating and deallocating readable/writable/executable memory locations - Stopping the normal flow of execution to run your own instructions - Measure size of assembly instructions and values - Byte pattern search - Memory dump

Planned: - Freezing all threads of execution - Watch points on all threads of execution

Note

This is work in progress and as such the API is unstable and the documentation is done as an afterthought. This will change as the project matures.

It’s currently only tested on x86-64 Linux.

Content

Example

Forces a program — whose Process ID (PID) is 15433 in this example — to print Hello, world!

Note

Accessing sensitive parts of other processes most likely requires you to have higher privileges. Try running as root.

CLI

# Allocates memory to store Hello, world!
$ proctal alloc --pid=15433 -rw 14
7f78fda9c000

# Writes Hello, world! to memory.
$ proctal write --pid=15433 --address=7f78fda9c000 --type=text H e l l o , ' ' w o r l d '!' $'\n'

# Executes code that will print Hello, world! to standard output.
$ proctal execute --pid=15433
	mov	rax, 1
	mov	rdi, 1
	mov	rsi, 0x7f78fda9c000
	mov	rdx, 14
	syscall

# Deallocates memory that was used to store Hello, world!
$ proctal dealloc --pid=15433 7f78fda9c000

C library

#include <stdlib.h>
#include <stdio.h>

#include <proctal.h>

int main (int argc, char **argv)
{
	const char output[] = "Hello, world!\n";
	char code[] = { 0x48, 0xbe, 0xDE, 0xAD, 0xBE, 0xFF, 0xDE, 0xAD, 0xBE, 0xFF, 0x48, 0xc7, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x48, 0xc7, 0xc7, 0x01, 0x00, 0x00, 0x00, 0x48, 0xc7, 0xc2, 0x0f, 0x00, 0x00, 0x00, 0x0f, 0x05 };

	proctal p = proctal_create();

	if (proctal_error(p)) {
		proctal_destroy(p);
		fprintf(stderr, "Failed to create an instance of Proctal.\n");
		return EXIT_FAILURE;
	}

	proctal_set_pid(p, 15433);

	void *allocated_memory = proctal_alloc(p, sizeof output, PROCTAL_ALLOC_PERM_READ);

	if (proctal_error(p)) {
		proctal_destroy(p);
		fprintf(stderr, "Failed to allocate memory in process %d.\n", proctal_pid(p));
		return EXIT_FAILURE;
	}

	proctal_write(p, allocated_memory, output, sizeof output);

	if (proctal_error(p)) {
		proctal_dealloc(p, allocated_memory);
		proctal_destroy(p);
		fprintf(stderr, "Failed to write to memory in process %d.\n", proctal_pid(p));
		return EXIT_FAILURE;
	}

	code[2] = ((unsigned long long) allocated_memory >> 0x8 * 0) & 0xFF;
	code[3] = ((unsigned long long) allocated_memory >> 0x8 * 1) & 0xFF;
	code[4] = ((unsigned long long) allocated_memory >> 0x8 * 2) & 0xFF;
	code[5] = ((unsigned long long) allocated_memory >> 0x8 * 3) & 0xFF;
	code[6] = ((unsigned long long) allocated_memory >> 0x8 * 4) & 0xFF;
	code[7] = ((unsigned long long) allocated_memory >> 0x8 * 5) & 0xFF;
	code[8] = ((unsigned long long) allocated_memory >> 0x8 * 6) & 0xFF;
	code[9] = ((unsigned long long) allocated_memory >> 0x8 * 7) & 0xFF;

	proctal_execute(p, code, sizeof code);

	if (proctal_error(p)) {
		proctal_dealloc(p, allocated_memory);
		proctal_destroy(p);
		fprintf(stderr, "Failed to execute code in process %d.\n", proctal_pid(p));
		return EXIT_FAILURE;
	}

	proctal_dealloc(p, allocated_memory);
	proctal_destroy(p);

	return EXIT_SUCCESS;
}

Usage

CLI

The command line interface can be used in the following ways:

proctal read [--type=<type>] --pid=<pid> --address=<address>

proctal write [--type=<type>] --pid=<pid> --address=<address> <value>

proctal search [--type=<type>] [--eq=<val>] [--gt=<val>] [--gte=<val>]
	[--lt=<val>] [--lte=<val>] [--inc=<val>] [--dec=<val>]
	[--changed] [--unchanged] [--increased] [--decreased]
	[--input] --pid=<pid> --address=<address>

proctal watch [--read] [--write] [--execute] [--unique] --pid=<pid>
	--address=<address>

proctal freeze [--input] --pid=<pid>

proctal execute [--format=<format>]--pid=<pid>

proctal alloc [--read] [--write] [--execute] --pid=<pid> <size>

proctal dealloc --pid=<pid> <address>

proctal measure [--type=<type>] --address=<address> <value>

proctal dump --pid=<pid> [--read] [--write] [--execute]
	[--program-code]

For more details run proctal -h or read the man page:

man 1 proctal

C library

Can be used by linking to libproctal and including proctal.h

Functions, types and macros are documented in the header file.

Installation

Note

If you have a clean state of the source repository you will need to follow some instructions given in the Development section.

Dependencies:

  • GCC [9]
  • libtool [10]
  • capstone [3]
  • keystone [4]

Proctal provides a 3 step installation process employed by many C/C++ programs on Linux:

$ ./configure

$ make

$ make install

The configure script checks whether your system meets the minimum necessary requirements and allows you to define how you want Proctal to be compiled and installed. For more information type ./configure -h.

Read the INSTALL file for more details.

Development

Besides requiring the same dependencies found in the Installation section, you will also need:

  • yuck [5]
  • php [6]
  • python [11]
  • autoconf [7]
  • automake [8]

Proctal uses the autotools to generate build systems for UNIX like operating systems. This section will not go into too much detail but will show you how you can create a development build to tinker with the source code.

First we need certain files and directories for the tools to work. Those can be created by running the autoreconf command with the -i option in the root directory of the project:

$ autoreconf -i

You can now create a build. At this point you can follow the instructions in the Installation section but as a developer you will most likely want to have everything working from the project directory. You might even be interested in working with different build settings, like having a release or a debug build. This is actually possible. Here’s how you would create and compile a build that suppresses optimizations and adds debugging symbols.

$ mkdir -p build/debug

$ cd build/debug

$ ../../configure 'CFLAGS=-g -O0'

$ make

If you modify a source file and run make again it should detect the change and compile again.

For more details on what else you can do with the autotools go read the manuals over at gnu.org [1]

Contributing

Found a bug or want to contribute code? Feel free to create an issue or send a pull request on GitHub [2].

License

This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.

Related Repositories

proctal

proctal

Manipulates the address space of a program on Linux. ...