Hi i'm just trying to use posix_spawn on OSX , this should work find (as for *nix) anyway after posix_spawn syscall the process will receive SIGTRAP i really cannot uderstand why.
#include <spawn.h>
#include <stdio.h>
#include <stdlib.h>
int main()
{
while(1){
char *newargv[] = { "/usr/bin/id", 0 };
char *newenviron[] = {0};
posix_spawnattr_t * a;
posix_spawn_file_actions_t * fa;
fa = malloc(0x80);
a = malloc(336);
//printf("size: %d\n", sizeof(posix_spawnattr_t));
posix_spawnattr_init(a);
posix_spawnattr_setflags(a, 0x40);
posix_spawn_file_actions_init(fa);
pid_t pid;
int status = 0;
posix_spawn(&pid, "/usr/bin/id", fa, a, newargv, newenviron);
waitpid(pid, &status, 0);
printf("pid: %d\n", pid);
}
//printf("pid: %d\n", pid);
return 0;
}
It should run forever but the output from id will be printed just one time.
Thanks for your support!
Not sure what you are actually trying to do, because you have hard-coded constants and sizes in that may not be relevant on macOS.
The main problem is that your 0x40 flag means that /usr/bin/id is exec'ed - just once and replaces the current process so it doesn't go around the loop again!
Other problems should be visible from the version below:
#include <spawn.h>
#include <stdio.h>
#include <stdlib.h>
int main()
{
char *newargv[] = { "/usr/bin/id", 0 };
char *newenviron[] = {0};
posix_spawnattr_t a;
posix_spawnattr_init(&a);
// posix_spawnattr_setflags(&a, 0x40); exec & replace the current process !!!
pid_t pid;
int status = 0;
while(1){
posix_spawn(&pid, "/usr/bin/id", NULL, &a, newargv, newenviron);
waitpid(pid, &status, 0);
printf("pid: %d\n", pid);
}
return 0;
}
The difference between what you have:
posix_spawnattr_t * a;
a = malloc(336);
and what I have:
posix_spawnattr_t a;
is that firstly, mine is the correct size no matter how the structure is defined on any particular OS, whereas yours is a hard-coded number that may or may not be correct for any particular OS, and secondly, your method leaks 336 bytes of memory every time through the loop which, given that there is no delay or anything else in the loop, might mean more of a gushing tap/faucet than a minor leak ;-)
Related
I have an assignment and I am not quite sure how to go about it. Basically I have to create a coordinator process which creates 5 working processes which are waiting to be awakened. The coordinator passes a marker(integer) to the first process, then that process increments the marker by 1 and passes it to the next process. The coordinator process awakens the next process which does the same and so on. The so called marker should go through all the processes 10 times and in the end its value should be printed by the coordinator. Signals should be used as well as shared memory for the marker.
So I created 5 processes and I am thinking that on every iteration there should be a signal and a handler should be passed which will basically do all the work with the marker.
This is my first time working with processes. This is what I have so far:
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/shm.h>
#include <signal.h>
#define numOfProcesses 5
pid_t procIDs[5];
void handler(int signum){
//marker and all work here
}
void createProcesses(){
int i;
for(i = 0; i < numOfProcesses; i++){
procIDs[i] = fork();
if(procIDs[i] < 0 ){
perror("Fork error!");
}else if(procIDs == 0){
pause();
}
}
}
int main(){
createProcesses();
int i;
for(i = 0; i < numOfProcesses; i++){
pkill(SIGUSR1, handler);
}
return 0;
}
I honestly don't know how to go about this. I would really appreciate a piece of advice. Thanks in advance!
This is what I have come up with. Sorry for answering, I couldn't find out how to format code in a comment. Anyway:
It should be 10 times each process. I am using shared memory so I guess I don't need a global variable for the marker? This is what I have come up with:
#include<stdio.h>
#include<unistd.h>
#include<stdlib.h>
#include<sys/types.h>
#include<sys/wait.h>
#include<sys/shm.h>
#include<signal.h>
#include<sys/ipc.h>
#define numOfProcesses 5
#define numOfLoops 10
pid_t* procIDs[5];
void createProcesses(){
int i;
for(i = 0; i < numOfProcesses; i++){
procIDs[i] = fork();
if(procIDs[i] < 0 ){
perror("Fork error!");
}
else if(procIDs == 0){
pause();
}
}
}
void init(){//init marker = 0
key_t mykey = ftok(".", 0);
int shID = shmget(mykey, sizeof(int), 0666 | IPC_CREAT);
int *data;
data = (int*) shmat(shID, 0, 0);
*data = 0;
}
int* getValue(){//get value of marker
key_t mykey = ftok(".", 0);
int shID = shmget(mykey, sizeof(int), 0666 | IPC_CREAT);
int *data = shmat(shID, 0, 0);
return data;
}
void increment(int sig){//increment + 1
if(sig == SIGUSR1){
int temp;
int* data;
data = getValue();
temp = *data;
temp++;
*data = temp;
}
}
void yourFunc(int count, pid_t* mypid, int mysig){
if(count == 0){
return;
}else{
printf("Signal sent :: to PID : %d\n", mypid);
kill(*mypid, SIGUSR1);
yourFunc(count -1, ++mypid, SIGUSR1);
}
}
int main(){
signal(SIGUSR1, increment);
init();
int i,j;
createProcesses();
for(j = 0; j < numOfLoops; j++){//loop every pid 10 times
pid_t* currProcess = procIDs[0];
yourFunc(numOfProcesses, currProcess, SIGUSR1);
}
int* data = getValue();
printf("Marker: %d\n", *data);
return 0;
}
I tried your problem, but I am really baffled by the structure of your question, its really unclear what your problem statement is.
10 times each(10 times per process or a total of 10 times(2 times per process)
You say the processes are waiting to be awakened, which hints that they are not child processes rather other processes running on the system, and would require a fifo to communicate.
Nevertheless, the following is what I could conclude from the limited information.
You need to create a function which would be invoked 10 times(loop) by the coordinator on the first process(waiting to be awakened)
The function would recursively invoke the second process and so on till the last sleeping process.
You'll have to use SIGUSR1, and define action for it in a custom signal handler,
eg.
signal(SIGUSR1,custom_handler)
You will need to keep marker as a global variable.
Because C is a procedural language and kernel's scheduling is not in your hands once a process terminates you cannot recall it or ensure same PID for a process on forking.
So if you are thinking of creating processes inside functions which will be paused and on getting a signal shall resume, fine.....!, But it would be a one-off.
That's all I can say by the limited information your question presents.
Following is the above idea in C.
Initialise count = 5 (no. of processes)in the caller.
mypid points to the first process's PID.
void party_time(int count, pid_t* mypid, int mysig)
{
if(count == 0)
return;
else
{
printf("Signal sent :: to PID : %d\n",*mypid);
kill(*mypid,SIGUSR1);
party_time(count - 1 ,++mypid,SIGUSR1);
}
}
I'm trying my hand at some reverse engineering, and I'm a bit stumped on how to do in-memory patching. My target binary is a simple Hello World app that's signed. So while I can easily patch the binary, gatekeeper blows up (as it should).
The string is in-memory, so I thought I'd just use posix_spawn() with POSIX_SPAWN_START_SUSPENDED, patch the memory of the process with xnumem, and resume it. For some reason, that seems to fail as well. My test code;
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <spawn.h>
#include <sys/wait.h>
#include "xnumem.h"
extern char **environ;
void run_cmd(char *cmd)
{
pid_t pid;
char *argv[] = {NULL};
int status;
printf("Run command: %s\n", cmd);
status = posix_spawn(&pid, cmd, NULL, NULL, argv, environ);
if (status == 0) {
printf("Child pid: %i\n", pid);
if (waitpid(pid, &status, 0) != -1) {
printf("Child exited with status %i\n", status);
} else {
perror("waitpid");
}
} else {
printf("posix_spawn: %s\n", strerror(status));
}
}
int main (int argc, const char * argv[]) {
char *arg;
arg = "./hello-world";
run_cmd(arg);
return 0;
}
I don't seem to be getting any errors, just a loop of;
Run command: ./hello-world
Child pid: 53209
Run command: ./hello-world
Child pid: 53210
...
and then it terminates.
Can someone point me in the right direction? How can I start a process in a suspended state, alter its memory, and resume without tripping gatekeeper?
I made the following simple example to read memory from a child process using ptrace.
I want to see the value at a specific address, 0x601050, every second during the execution of a small matrix multiplication program. I use PTRACE_PEEKDATA followed by PTRACE_CONT and sleep for 1 second, in an infinite loop, to do so.
However, the matrix multiplication program never proceeds--it should print to stdout in the first instruction, but it never seems to execute. I understood that ptrace(PTRACE_CONT,pid) would signal the child to resume execution and that sleep(1) would allow it to execute for a second (until the next ptrace call), but that is not the case.
#include <string.h>
#include <errno.h>
#include <inttypes.h>
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/ptrace.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/user.h>
#include <sys/reg.h>
int read_mem(long *out, pid_t pid, long addr, size_t sz)
{
long tmp;
size_t copied = 0;
while(copied < sz)
{
tmp = ptrace(PTRACE_PEEKDATA, pid, addr+copied);
if(errno)
{
fprintf(stderr,"ptrace: error : %s\n",strerror(errno));
return copied;
}
memcpy(out,&tmp,sizeof(long));
copied += sizeof(long);
out++;
printf("ptrace: copied %d bytes\n",copied);
}
return copied;
}
int main()
{
pid_t child;
long result;
struct user_regs_struct regs;
int status;
long addr = 0x601050;
size_t sz = sizeof(double);
long *buf = (long*)malloc(sz);
child = fork();
if(child == 0)
{
ptrace(PTRACE_TRACEME);
execl("./matmul", "matmul", NULL);
}
else
{
ptrace(PTRACE_GETREGS, child, ®s);
printf("ptrace: regs.rip : 0x%lx\n", regs.rip);
while(1)
{
read_mem(buf, child, addr, sz);
printf("ptrace: read(0x%lx) : %f\n", addr, (double)(*buf));
ptrace(PTRACE_CONT, child);
sleep(1);
}
}
return 0;
}
You don't seem to set a PTRACE_O_TRACEEXEC option. Failing to do so results in SIGTRAP being sent to tracee upon a call to exec; if it is not prepared, the default action is a termination with a core dump.
I try to wait the main function, till the threads finish their work. But the main function finish its work and exit. I think because of that the threads has not the correct pointers/values in the variables.(tally and steps)
Does someone know how to use waitpid/wait properly in this case?
my Code:
#define _GNU_SOURCE
#include <stdio.h>
#include <inttypes.h> /* for PRIu64 and uint64_t */
/* you'll need further includes */
#include <sched.h>
#include <stdlib.h>
#include "tally.h"
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#define STACK_SIZE 32768
#define THREADS 2
struct clone_args{
uint64_t steps;
uint64_t* tally;
};
int incHelper(void* arg){
struct clone_args *args = (struct clone_args*)arg;
uint64_t steps= args->steps;
uint64_t* tally = args->tally;
increment(tally,steps);
(void) arg;
(void) tally;
(void) steps;
exit(2);
return 0;
}
int main ()
{
uint64_t N = 10000000;
uint64_t tally = 1;
tally_init();
int thread_pid[THREADS];
int status;
for(int i= 0; i<THREADS;i++){
void *child_stack = malloc(STACK_SIZE);
struct clone_args *arguments = malloc(sizeof(struct clone_args));
arguments->steps = N;
arguments->tally = &tally;
void* arg = (void*) &arguments;
thread_pid[i] = clone(incHelper, child_stack+STACK_SIZE,CLONE_VM, arg);
pid_t pid = waitpid(thread_pid[i],&status,SIGCHLD);
printf("C-PID [%d]\n", thread_pid[i]);
(void) pid;
}
tally_clean();
printf( "\nTally is %" PRIu64 "\n", tally );
(void) N;
(void) thread_pid;
(void) tally;
(void) status;
printf("\n MAIN PROGRAMM END\n");
return 0;
}
The increment function:
/* modify this function to achieve correct parallel incrementation */
void increment ( uint64_t *tally, uint64_t steps )
{
printf("\nTALLY: %"PRIu64"\n",*tally);
printf("STEPS: %"PRIu64"\n",steps);
for( uint64_t i = 0; i < steps; i++ )
{
*tally += 1;
}
return;
}
The Result i got after running the code:
C-PID [29819]
C-PID [29820]
Tally is 1
MAIN PROGRAMM END
root#...(~/Downloads/asst3/asst3-clone)$
TALLY: 0
STEPS: 140714329004032
TALLY: 888309
STEPS: 140714329004032
The code should increment a variable with two threads. To avoid criticalsection Problem i should use semaphores. But thats an other exercise. First exercise it to use clone() function to create two threads. I dont understand, if the flags of clone() are wrong or my code is completely wrong. I am new at programming language C.
I spent last 12 hours of searching with google.
I thank for every answer :).
Sorry for bad english.
Regards
Per default a clone()ed process does not signal the parent about its end.
If you want the parent to be signalled about the child's end you need to explicitly pass the signal to be sent on its end when clone()ing ORed to the 3rd parameter passed.
If you use SIGCHLD then use waitpid() as usual.
In this latter case clone and wait like so:
thread_pid[i] = clone(incHelper, child_stack+STACK_SIZE, CLONE_VM | SIGCHLD, arg);
pid_t pid = waitpid(thread_pid[i], &status, 0);
If you want to use another signal to be sent on the child's end like for example SIGUSR1 you need to tell this to waitpid() using the option __WCLONE:
thread_pid[i] = clone(incHelper, child_stack+STACK_SIZE, CLONE_VM | SIGUSR1, arg);
pid_t pid = waitpid(thread_pid[i], &status, __WCLONE);
This
void* arg = (void*) &arguments;
takes the address of arguments. As arguments already is an address of the required structure, it should be:
void * arg = arguments;
Note: As the main thread waitpid()s for the clone()ed thread to finish before the next call to clone(), there is no parallel processing of increment()
Suppose we have expression g=(a+b)*(c+d)-(e/f) with hard-coded arbitrary numbers for variables. I would like to calculate this expression using multiple child processes in order to better understand how fork() works.
My first attempt was to calculate (a + b) on child pid1, (c + d) on child pid2, (e / f) on child pid3, and then do summation & subtraction in the parent process.
Well, to my disappointment, (a + b) calculation done in the child process pid1 did not affect double expression1 variable in the parent process. I think the reason behind that - each fork() creates a separate memory space; as soon as a child process exits, all calculations done in that child process are gone.
What do you usually do in a situation like this? I thought maybe I could nest fork() child process within a child process to calculate (a + b) first; wait; then (c + d); wait; (e / f); wait; the first child calculates the entire expression; child return(0); parent terminates.
But I think there's an easier solution to this problem, am I right?
If you insist on using fork() , so here is my answer now using child process and shared memory
Note that exit() is used here the way it is expected by the system: to signalize if the child has exited normally or not.
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
struct shared{
int a_b;
int c_d;
int e_f;
};
const int a=1,b=2,c=3,d=4,e=6,f=2;
const key_t key = 1234;
pid_t pab,pcd,pef;
void* shared_mem;
int main(){
//Parent process create the shared memory
int shmid = shmget(key,sizeof(struct shared), 0666|IPC_CREAT);
if(shmid == -1) exit(EXIT_FAILURE);
//Fork child
pab = fork();
if(pab == 0){
//Inside process ab
//attach to shared memory
shared_mem = shmat(shmid,(void*) 0,0);
if(shared_mem == (void*) -1) exit (EXIT_FAILURE);
struct shared* shared_data = (struct shared*) shared_mem;
shared_data->a_b = a +b;
//detach
if(shmdt(shared_mem) == -1) exit (EXIT_FAILURE);
exit(EXIT_SUCCESS);
}else {
pcd = fork();
if(pcd == 0){
//Inside process cd
//attach to shared memory
shared_mem = shmat(shmid,(void*) 0,0);
if(shared_mem == (void*) -1) exit (EXIT_FAILURE);
struct shared* shared_data = (struct shared*) shared_mem;
shared_data->c_d = c+d;
//detach
if(shmdt(shared_mem) == -1) exit (EXIT_FAILURE);
exit(EXIT_SUCCESS);
}else{
pef = fork();
if(pef == 0){
//Inside process ef
//attach to shared memory
shared_mem = shmat(shmid,(void*) 0,0);
if(shared_mem == (void*) -1) exit (EXIT_FAILURE);
struct shared* shared_data = (struct shared*) shared_mem;
shared_data->e_f = e/f;
//detach
if(shmdt(shared_mem) == -1) exit (EXIT_FAILURE);
exit(EXIT_SUCCESS);
}
}
}
//Wait child process termination
int status_ab,status_cd,status_ef;
waitpid(pab,&status_ab,0);
waitpid(pcd,&status_cd,0);
waitpid(pef,&status_ef,0);
//Check if all child exited normally
if(!WIFEXITED(status_ab) || !WIFEXITED(status_cd)||!WIFEXITED(status_ef)){
exit(EXIT_FAILURE);
}
//Parent attaches to memory
shared_mem = shmat(shmid,(void*) 0,0);
if(shared_mem == (void*) -1) exit (EXIT_FAILURE);
struct shared* shared_data = (struct shared*) shared_mem;
//Calculate result
int result = (shared_data->a_b)*(shared_data->c_d)-(shared_data->e_f);
printf("Result is %d\n", result);
//Parent detaches from shared memory and deletes
if(shmdt(shared_mem) == -1) exit (EXIT_FAILURE);
if(shmctl(shmid,IPC_RMID,0) == -1) exit(EXIT_FAILURE);
return EXIT_SUCCESS;
}
fork()ing the processes, then waitpid()ing on their return values:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main()
{
//whatever values you like:
int a = 1;
int b = 2;
int c = 3;
int d = 4;
int e = 15;
int f = 6;
int a_plus_b_pid;
int c_plus_d_pid;
int e_div_f_pid;
int a_plus_b;
int c_plus_d;
int e_div_f;
a_plus_b_pid = fork();
if(a_plus_b_pid)
{
c_plus_d_pid = fork();
if(c_plus_d_pid)
{
e_div_f_pid = fork();
if (e_div_f_pid)
{
//wait for our processes to exit, with our results, and stash the computed values.
waitpid(a_plus_b_pid, &a_plus_b, 0);
waitpid(c_plus_d_pid, &c_plus_d, 0);
waitpid(e_div_f_pid, &e_div_f, 0);
//The 8 least-significant bits carry info that we're not interested in here, so shift them out:
a_plus_b >>= 8;
c_plus_d >>= 8;
e_div_f >>= 8;
printf("%d %d %d %d\n", a_plus_b, c_plus_d, e_div_f, a_plus_b * c_plus_d - e_div_f);
}
else
{
exit (e/f);
}
}
else
{
exit (c+d);
}
}
else
{
exit (a+b);
}
}
This is a version using pthreads:
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <pthread.h>
volatile int a_b;
volatile int c_d;
volatile int e_f;
const int a=1,b=2,c=3,d=4,e=6,f=2;
void* calc_ab(void*);
void* calc_cd(void*);
void* calc_ef(void*);
int main(){
pthread_t ab_thread, cd_thread, ef_thread;
pthread_create(&ab_thread,NULL,calc_ab,NULL);
pthread_create(&cd_thread,NULL,calc_cd,NULL);
pthread_create(&ef_thread,NULL,calc_ef,NULL);
pthread_join(ab_thread, NULL);
pthread_join(cd_thread, NULL);
pthread_join(ef_thread,NULL);
int result = a_b*c_d-e_f;
printf("Result is %d\n", result);
return EXIT_SUCCESS;
}
void* calc_ab(void* arg){ a_b = a+b;pthread_exit(NULL);}
void* calc_cd(void* arg){ c_d = c+d;pthread_exit(NULL);}
void* calc_ef(void* arg){ e_f = e/f;pthread_exit(NULL);}
To compile you have to link against pthread:
gcc pthread.c -lpthread -o teste
Notes
Note that variables that are shared between the main thread and a child thread are declared volatile. This prevent the compiler of doing some memory optimizations that could prevent a write done in one thread not to be seen by others.
Each child thread writes to a different shared variable. I wanted to keep the code simple, not having to handle synchronization explicitly.
The main thread only reads the shared variable only after it has returned from a pthread_join for the thread that changed it. Again I wanted to keep the code simple, not having to handle synchronization explicitly.
First, you don't need processes at all to do arbitrary computation. Emabedding an interpreter like e.g. lua might be simpler.
Of course, each process has its own address space. Type cat /proc/self/maps to get information about the process running that cat command.
If you insist on using processes to learn how they can communicate thru pipes, you might use something like popen(3) which will use some syscalls to start and pipe a command.
char cmd[80];
int a, b, sum;
/// fill a & b
snprintf (cmd, sizeof(cmd), "echo $[%d + %d]", a, b);
FILE* pcmd = popen(cmd, "r");
if (fscanf (pcmd, "%d", &sum)>0) {
// do something with sum
};
pclose(pcmd);
And you should read a good book like Advanced Unix Programming and Advanced Linux Programming. The real thing is to understand syscalls like fork(2), waitpid(2), execve(2), pipe(2), dup(2), etc.... To understand what syscalls(2) are done by some command or program, use strace