Changes

Jump to navigation Jump to search
300 bytes added ,  14:43, 29 August 2018
m
Line 1: Line 1: −
'''Compel''' is a utility to execute arbitrary code in a context of a foreign process. Compel is part of CRIU, and its sources are available from [https://github.com/xemul/criu/tree/criu-dev/compel the criu-dev branch of CRIU repo, subdirectory compel].
+
'''Compel''' is a utility to execute arbitrary code in a context of a foreign process. Compel is part of CRIU, and its sources are available from [https://github.com/checkpoint-restore/criu/tree/criu-dev/compel the criu-dev branch of CRIU repo, subdirectory compel].
    
The code to be executed is called '''parasite code'''. Once compiled with compel flags and packed, it can be executed in other task's context. Note the code is run in environment without glibc, thus it can not call the usual stdio/stdlib/etc. functions.
 
The code to be executed is called '''parasite code'''. Once compiled with compel flags and packed, it can be executed in other task's context. Note the code is run in environment without glibc, thus it can not call the usual stdio/stdlib/etc. functions.
Line 26: Line 26:  
</pre>
 
</pre>
   −
Don't forget to put <code>compel/include/uapi/</code> directory into include paths.
+
Then link the parasite binary. Include all the .o files needed.  
 
  −
Then link the parasite binary. Include all the .o files needed and compel plugins <code>std</code> and <code>fds</code> by using compel linker script.
      
<pre>
 
<pre>
$ ld foo1.o foo2.o compel/plugins/std.built-in.o compel/plugins/fds.built-ind.o -T compel/arch/$ARCH/scripts/compel-pack.lds.S -o parasite.po  
+
$ ld $(compel ldflags) foo1.o foo2.o $(compel plugins) -o parasite.po  
 
</pre>
 
</pre>
   Line 44: Line 42:  
=== Using libcompel.a library ===
 
=== Using libcompel.a library ===
   −
In libcompel.a there's currently only one way to load the blob into victim task, it's called 'c-header'. So first you should make a header out of you .po file
+
Currently there is only one way to load the blob into victim task using libcompel.a, called ''c-header'' <ref>This is done for historical reasons. It was the most handy way to load [[parasite code]] by CRIU. In plans we have loading the .po ELF file itself</ref>. First you should make a header out of your .po file with the <code>hgen</code> action of compel tool:
   −
<pre>
+
compel hgen -f parasite.po -o parasite.h
compel hgen -f parasite.po -v parasite_relocs -p parasite_sym -s parasite_blob -r parasite_nr_gotpcrel -u compel/include/uapi/ -o parasite.h
+
 
</pre>
+
Options meaning is the following:
 +
* <code>-f</code> tells which binary to turn into header
 +
* <code>-o</code> tells where to write the resulting header
   −
After this the <code>parasite.h</code> file should be included into the infecting program and compiled with it.
+
Once <code>parasite.h</code> file is ready, it should be included into the infecting program source code to be compiled with it.
    
== Running parasite code ==
 
== Running parasite code ==
   −
So, in order to infect a task with parasite one must.
+
So, in order to infect a task with parasite one must do the following.
   −
* Stop the task with <code>compel_stop_task(int pid)</code> call and keep the return value if it's positive (it contains the task state)
+
* Stop the task. This is done by calling <code>compel_stop_task(int pid)</code>. Its return value should be saved in case it's positive (it contains the task state).
* Prepare the infection handler with <code>compel_prepare(int pid)</code> call. The return value is an opaque pointer to <code>struct parasite_ctl</code>
+
* Prepare the infection handler. This is done by calling <code>compel_prepare(int pid)</code>. The return value is an opaque pointer to <code>struct parasite_ctl</code>.
* Run the remote code
+
* Run the remote code:
** Just execute a system call with <code>compel_syscall(ctl, int syscall_nr, long *ret, int arg ... (6 of them))</code>
+
** Execute a system call with <code>compel_syscall(ctl, int syscall_nr, long *ret, int arg ...)</code> (all 6 parameters)
** Infect victim with parasite blob with <code>compel_infect(ctl, nr_thread, size_of_args_area)</code>
+
** Infect the victim with the parasite blob by calling <code>compel_infect(ctl, nr_thread, size_of_args_area)</code>
* Cure the victim with <code>compel_cure(ctl)</code> and stop using the ctl pointer as it's freed by the call
+
* Cure the victim by calling <code>compel_cure(ctl)</code>. Note that <code>ctl</code> pointer is freed by the call so it should not be used thereafter.
* Resume the task with <code>compel_resume_task(pid)</code>
+
* Resume the task by calling <code>compel_resume_task(pid, orig_state, state)</code> with the saved state value from the first step.
    
=== Infecting ===
 
=== Infecting ===
   −
Infecting the victim with parasite blob needs some special treatment. First, the ctl should be configured with the blob information. Currently there's only one type of blobs, generated by <code>compel hgen</code>. To put this info into ctl one should
+
Infecting the victim with a parasite blob needs some special treatment.
   −
* Call <code>compel_parasite_blob_desc(ctl)</code> to get a pointer on <code>struct parasite_blob_desc</code>
+
First, the <code>ctl</code> should be configured with the blob information. For that,
* Fill in the bdesc fields
+
you should call <code>''PREFIX''_setup_c_header()</code> function
** <code>.parasite_type</code> should be set to <code>COMPEL_BLOB_CHEADER</code>
+
with <code>ctl</code> as an argument. Here <code>''PREFIX''</code>
** <code>.hdr.mem</code> should be set to the <code>-s</code> argument of hgen
+
is the same as the argument given to <code>-p</code> option
** <code>.hdr.bsize</code> should be set to the sizeof(this symbol)
+
to <code>compel hgen</code>, and if not given, it is derived
** <code>.hdr.nr_gotpcrel</code> should be set to the <code>-r</code> argument of hgen
+
from the input file name, dropping the path and the suffix
** Three offsets below should be set to respective offsets generated with the <code>-p</code> argument value
+
(in the above example it's <code>parasite</code>).
*** <code>.hdr.parasite_ip_off</code> to <code>COMPEL_H_PARASITE_HEAD(arg)</code>
+
 
*** <code>.hdr.addr_cmd_off</code>  to <code>COMPEL_H_PARASITE_CMD(arg)</code>
+
Second, when infecting a parasite one should specify the amount of threads it will mess with (1, if only the thread leader will be accessed) and the maximum size of the memory area shared between infecting task and parasite used for arguments/result passing.
*** <code>.hdr.addr_arg_off</code>  to <code>COMPEL_H_PARASITE_ARGS(arg)</code>
  −
** <code>.hdr.relocs</code> should be set to <code>-v</code> argument (it's an array)
  −
** <code>.hdr.nr_relocs</code> should be set to the number of elements in this array (<code>sizeof(arr)/sizeof(arr[0])</code>)
      
=== Arguments passing ===
 
=== Arguments passing ===
   −
To pass arguments between the infecting code and parasite one may call <code>compel_parasite_args(ctl, type)</code> and get the pointer where it can put data. Subsequent calls to <code>compel_rpc_call[_sync]</code> would result int this data visible in <code>void *arg</code> address of the <code>parasite_daemon_cmd()</code>.
+
To pass arguments between the infecting code and parasite, one may call <code>compel_parasite_args(ctl, type)</code> and get the pointer where it can put data. Subsequent calls to <code>compel_rpc_call[_sync]()</code> will result in this data visible in <code>void *arg</code> address of the <code>parasite_daemon_cmd()</code>.
    
== See also ==
 
== See also ==
 
* [[Compel/Usage_scenarios]]
 
* [[Compel/Usage_scenarios]]
 
* [[Compel plugins]]
 
* [[Compel plugins]]
 +
* Examples of working code available [https://github.com/checkpoint-restore/criu/tree/criu-dev/compel/test on github] <ref>Clone the repo, build the project by running <code>make</code>, then go to <code>compel/test/$test_name</code> directory and run <code>make</code> there. Running <code>spy</code> bynary runs the example. Then -- RTFS or talk to us on [https://lists.openvz.org/mailman/listinfo/criu criu@openvz.org] :)</ref>
 +
* Info about CRIU [[code blobs]] in which the same technology is used
 +
    +
-----
 +
<references/>
 
[[Category:Compel]]
 
[[Category:Compel]]
 +
[[Category:Editor help needed]]
277

edits

Navigation menu