Noves Castro has asked for the wisdom of the Perl Monks concerning the following question:

Hello to all

i am new to perl.

I embed Perl in C and now I have two problems.

1. Blocks like END are not working after embedding

2. I need a mechanism to prevent from trace or debug the program like strace

i used this script to embed:
https://marginalhacks.com/Hacks/perlc/

Replies are listed 'Best First'.
Re: Embed perl problem
by Corion (Patriarch) on Jan 28, 2019 at 14:07 UTC

    If END { ... } blocks are not working, you are not properly cleaning up the Perl interpreter from your C code. See perlembed for how to clean up.

    You cannot prevent a program from being traced or being run under strace. Maybe you want to read How can I hide the source for my Perl program?. In general it is very hard to hide the source code of a Perl program from somebody determined. There are approaches to make it harder, but no way to make it impossible.

Re: Embed perl problem
by bliako (Abbot) on Jan 28, 2019 at 17:17 UTC

    Here is something to get you started and how to make END blocks work (just slightly modified from a example in perlembed):

    #include <EXTERN.h> #include <perl.h> /* * embedex.c * based on https://perldoc.perl.org/perlembed.html * slightly modified by bliako for https://perlmonks.org/?node_id=1229 +069 * actually, bliako just inserted the perl code. */ static PerlInterpreter *my_perl; int main (int argc, char **argv, char **env){ char *embedding[] = { "", "-e", "0" }; PERL_SYS_INIT3(&argc,&argv,&env); my_perl = perl_alloc(); perl_construct( my_perl ); perl_parse(my_perl, NULL, 3, embedding, NULL); PL_exit_flags |= PERL_EXIT_DESTRUCT_END; perl_run(my_perl); eval_pv("BEGIN{ print q(in BEGIN\n); } print q(running\n); END { +print q(in END\n); }; 1;", TRUE); perl_destruct(my_perl); perl_free(my_perl); PERL_SYS_TERM(); }

    You need to compile the above using CC, CFLAGS and LDFLAGS best supplied by Perl itself via Config and ExtUtils::Embed like so (assuming bash shell):

    Update: Just to clarify that the above is about embedding a perl interpreter inside a C program. The interpreter is then used to execute a perl script. This has nothing to do with taking a Perl script and converting it into C code. Or converting a Perl script into assembly. Or converting a Perl optree to C code or assembly.

    $(perl -MConfig -e 'print $Config{cc}') embedex.c $(perl -MExtUtils::E +mbed -e ccopts -e ldopts) -o embedex
    $ ./embedex in BEGIN running in END

    Regarding detecting when a perl script is run under a debugger, read perlvar

    bw, bliako

      you rock man, END block now working!

      Just one thing about anti debugging , i added this snippet in my code:

      https://reverseengineering.stackexchange.com/a/1931

      but when i run it i get:

      [1]+  Stopped                 ./test

      and when i run it with strace its working:

      write(1, "don't trace me !!\n", 18don't trace me !!

      and can you explain how to use perlvar for anti debugging?

        A program can only be traced by one process, so if it is being traced (before anyone else) by itself, it will not allow any other tracer to trace it (lots of workarounds here...). Additionally, when a trace is initiated a SIGSTOP is sent. Try installing a handler for SIGSTOP. It worked for me but I don't know why.

        /* bliako modified https://reverseengineering.stackexchange.com/a/1931 for https://perlmonks.org/?node_id=3333;parent=1229102 KILL it with SIGKILL (kill -9) 29/01/2019 */ #include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/ptrace.h> #include <unistd.h> #include <signal.h> void intHandler(int sig) { printf("got signal %d\n", sig); } int main(void){ printf("my pid: %d\n", getpid()); char *e; if( (e=getenv("TRACEME")) != NULL && (strcmp(e,"0")==0) ){ printf("Will not be traced...\n"); signal(SIGSTOP, intHandler); if (ptrace(PTRACE_TRACEME, 0, 1, 0) == -1) { printf("don't trace me !!\n"); return 1; } } // normal execution for(int i=0;;i++){ printf("i=%d\n", i); sleep(1); } return 0; }
        gcc tracee.c -o tracee && TRACEME=0 tracee strace -p <PID-from-traceed> strace: attach: ptrace(PTRACE_SEIZE, 11091): Operation not permitted

        while tracee continues counting on

        or

        TRACEME=1 tracee strace -p <PID-from-tracee>

        bw, bliako

        ps. Please share your findings. Most answers are in the manual and let's keep to Perl less the reaper traces us. brrrrr