Noob <
ro...@127.0.0.1> writes:
> Typically, executables are stored in files, and one runs them using
> one of the exec* functions.
>
>
http://pubs.opengroup.org/onlinepubs/9699919799/functions/execlp.html
>
> (I do note that fexecve expects a fd, instead of a file or path.)
>
> I'll reduce the scope of my question by noting:
>
> - I am running Linux (2.6.28)
> - By "executable", I mean "ELF executable with shared object dependencies"
>
> One such "executable" of mine is stored encrypted.
>
> I have a program that decrypts it, and stores the clear-text
> version to a tmpfs. Then I run the program from the tmpfs.
>
> But I was wondering: since I'm decrypting the program to memory
> in my decryption program, why not...
>
> 1) decrypt the program to a large-enough buffer
> 2) exec the program "directly from memory"
Hmm ... why not "create a sufficiently large file on the tmpfs
(ftruncate is sufficient here), mmap that and decrypt into the mmap'ed
area"?
[...]
Assuming that you're also using Linux for this, a shared memory object
created via shm_open is really nothing but a file residing on a tmpfs
mounted on /dev/shm. At least on Linux 3.2.9, the shared memory object
must neither be open for writing nor mapped with PROT_WRITE for the
fexecve to suceed:
-----------
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <unistd.h>
static char *args[] = {
"hic et nunc",
"-l",
"/dev/shm",
NULL
};
extern char **environ;
int main(void)
{
struct stat st;
void *p;
int fd, shm_fd, rc;
shm_fd = shm_open("wurstverschwendung", O_RDWR | O_CREAT, 0777);
if (shm_fd == -1) {
perror("shm_open");
exit(1);
}
rc = stat("/bin/ls", &st);
if (rc == -1) {
perror("stat");
exit(1);
}
rc = ftruncate(shm_fd, st.st_size);
if (rc == -1) {
perror("ftruncate");
exit(1);
}
p = mmap(NULL, st.st_size, PROT_READ | PROT_WRITE, MAP_SHARED,
shm_fd, 0);
if (p == MAP_FAILED) {
perror("mmap");
exit(1);
}
fd = open("/bin/ls", O_RDONLY, 0);
if (fd == -1) {
perror("openls");
exit(1);
}
rc = read(fd, p, st.st_size);
if (rc == -1) {
perror("read");
exit(1);
}
if (rc != st.st_size) {
fputs("Strange situation!\n", stderr);
exit(1);
}
munmap(p, st.st_size);
close(shm_fd);
shm_fd = shm_open("wurstverschwendung", O_RDONLY, 0);
fexecve(shm_fd, args, environ);
perror("fexecve");
return 0;
}