Link to home
Start Free TrialLog in
Avatar of Simon336697
Simon336697Flag for Australia

asked on

Compiling and producing an exe

Hi guys hope you can help.

Im a total newbie to this, so please bear with me.

I have a file with a .c extension.

Let's say it is called

tobeexe.c

I want to turn this .c file into an executable to run on a windows machine.

I think i have to use a compiler like...

gcc -o tobeexe tobeexe.c

I ran this on a linux box and this makes a file called tobeexe

Can I do this guys, and what other steps do I need to do in order to produce an exe file to run this on a windows machine?

Thank you.
ASKER CERTIFIED SOLUTION
Avatar of Infinity08
Infinity08
Flag of Belgium image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Command line syntax for Microsoft's compiler (CL): -
http://msdn2.microsoft.com/en-us/library/610ecb4h.aspx
SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of Simon336697

ASKER

Hi guys!
Thank you so much for your help to ALL of you.

Guys, the file I have to work with is a <file>.c file.

From my reading (if you could confirm), do I have to do the following?

I have a linux and windows box, so I tried this on my linux box....

1) Make an object file.

gcc -o <filetomake> tobeexe.c

2) Something called a linker or something which makes the exe?

Sorry having problems here..
The linker is being run for you. The -o option on gcc tells it to invoke the linker and generate an output file, which will be the executable.
>> The linker is being run for you. The -o option on gcc tells it to invoke the linker and generate an output file, which will be the executable.
This is default behavior unless you provide the -c flag, which tell sit to only compile but not link.
-c 
Compile or assemble the source files, but do not link. The compiler output is an object file corresponding to each source file. 
 
-o file 
Place output in file file . This applies regardless to whatever sort of output GCC is producing, whether it be an executable file, an object file, an assembler file or preprocessed C code. 

Open in new window

The same will be true on Windows ;) Just try it, and you'll see how easy it is :)
Hi Infinity08.
I ran this on linux, and it produced a file.
[root@rupert temp]# gcc -o <filetomake> <file>.c --sysroot=/temp/head/
exe2perl.c:16:19: error: stdio.h: No such file or directory
exe2perl.c:17:20: error: stdlib.h: No such file or directory
exe2perl.c:18:23: error: sys/types.h: No such file or directory
exe2perl.c:19:22: error: sys/stat.h: No such file or directory
exe2perl.c:20:22: error: sys/mman.h: No such file or directory
exe2perl.c:21:19: error: fcntl.h: No such file or directory
exe2perl.c:22:20: error: unistd.h: No such file or directory
exe2perl.c:23:19: error: errno.h: No such file or directory
What about just : gcc -o <filetomake> <file>.c   ?
Hi evil....youre right I did that, but the thing is I dont know how to actually go from there, that is, use the file its created....it doesnt like it accepts any arguments.
What do you mean "use the file"? Do you mean run it?

./<filetomake>

Will run it.
Thx evil :>)

I ran it as you said. it came back with
signature not found, exiting
Well, I guess that's the behavior of the program you've built. I have no way of knowing what it's meant to do without seeing the source code.
Evil can I send you the source code?
Paste it here under the "Attach Code Snippet" section.
Try something simple first. Create a source file with the following contents, and compile and run it in the same way as said above :


#include <stdio.h>
 
int main(void) {
  printf("Hello world !!");
  return 0;
}

Open in new window

Hi Infinity!

[root@rupert temp]# gcc -o runplease helloguys.c
[root@rupert temp]# ./runplease
Hello world !![root@rupert temp]#
That looks good to me :)
>> Hi Infinity!

Great ... Now we just have to get your program to work ... What code is it ? Did you write it ? Or did you get it somewhere ? What is it supposed to do ?
Guys should i post the source code here?
What this is is an exe2perl tool.
I have some perl scripts that have been converted to an exe but I dont have the original perl script, and wish to look at the original perl code to learn from.
oh, btw :

>> [root@rupert temp]# ./runplease

be careful with running things as root, especially if you're not sure what the code will do ... It's best to do your daily work as a different unprivileged user, and use root only for system management tasks.

[/end of side note ;) ]
I did not write this exe2perl tool, nor the scripts that have been converted.
It simply is for my own learning, as it is to learn this gcc stuff from you great people here. :>)
So the thing is I spose being stupid as I am, when I ran the gcc -o on this exe2perl, it created a file, but I dont know what else it did to my system :<(
Thanks for bearing with me on this everyone.
>> What this is is an exe2perl tool.

This might only work on Windows (after a short look using Google).

Can you post the code ?
Okay....ill put it here :>
---------------------------------------------- exe2perl.c
------------------------ start of file...
/******************************************************************************
 * exe2perl (AKA perl2exe v5.xx unpacker)                                     *
 * --------------------------------------                                     *                                        *
 *                                                                            *
 * Compile using the following command: gcc -o exe2perl exe2perl.c            *
 *                                                                            *
 * Distributed under the terms of the GPL v2 licence.                         *
 *                                                                    -- (GM) *
 ******************************************************************************/
#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/mman.h>
#include <fcntl.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
 
 
#define SIGNATURE "dbload 1.0 signature\r\n\r\n\200\200\200\200\200\200\200" \
			"\200\r\n-p2x_noshow_includes  "
#define OUTPUT_SUFFIX ".unpacked"
 
void *
binsearch(void *where, size_t where_size, void *what, size_t what_size)
{
    void *p;
    for (p = where; p <= (where + where_size - what_size); p++)
        if (!memcmp(p, what, what_size))
            return p;
 
    return 0;
}
 
char *
getstr(char *source, size_t source_size)
{
    char *entry_name = source;
    char *entry_name_end = binsearch(entry_name, source_size, "\r\n", 2);
    if (!entry_name_end)
        return 0;
 
    if (!(entry_name =
	    strndup(entry_name, (size_t)(entry_name_end - entry_name))))
        return 0;
 
    return entry_name;
}
 
char *
getblock(char *source, size_t amount)
{
    char *block;
 
    if (!((block = (char *)malloc(amount)) && (memcpy(block, source, amount))))
       return 0;
 
    return block;
}
 
void decrypt_block(char *block, size_t block_size)
{
    const char *crypt_string = "For more information visit www.indigostar.com";
    char *p;
 
    for (p = block; p < block + block_size; p++)
        *p ^= crypt_string[((p - block) % strlen(crypt_string))];
}
 
int make_dir(const char *filename)
{
    char *path, *p, *h;
    size_t path_length;
    int cwd_fd;
 
    if (!(p = strrchr(filename, '/'))) /* there is no leading directory */
        return 0;
 
    if (!(path = strndup(filename, p - filename)))
        return 1;
 
    /* save cwd */
    if ((cwd_fd = open(".", O_DIRECTORY)) == -1) /* Linux-specific */
    {
        free(path);
        return 1;
    }
 
    h = p = path;
    path_length = strlen(path);
    do
    {
        if ((p = strchr(h, '/'))) /* if several directories are given */
            *p = 0;
 
        while (*h == '/') /* we don't want absolute paths */
            h++;
 
        if (!(strcmp(h, "..") && strcmp(h, "."))) /* just a safety measure */
        {
            free(path);
            close(cwd_fd);
            return 0;
        }
 
        mkdir(h, 0777);
        if (chdir(h))
        {
            free(path);
            fchdir(cwd_fd);
            close(cwd_fd);
            return 1;
        }
 
        if (!p) break; /* there was one leading directory */
 
        h = p + 1; /* advance to the next name */
    } while (h < (path + path_length));
 
    free(path);
    fchdir(cwd_fd);
    close(cwd_fd);
    return 0;
}
 
int save_file(const char *name, const char *buffer, size_t buffer_size)
{
   int fd;
 
   if (make_dir(name))
       return 1;
 
   if ((fd = open(name, O_WRONLY | O_CREAT | O_EXCL, 0666)) == -1)
       return 1;
 
   if (write(fd, buffer, buffer_size) == -1)
       return 1;
 
   if (close(fd) == -1)
       return 1;
 
   return 0;
}
 
int
main(int argc, char *argv[])
{
    char *source, *p, *output_dir;
    struct stat st;
    int source_fd = 0;
    int cwd_fd = -1;
 
    printf("perl2exe unpacker;  Written by (GalaxyMaster)\n---\n");
 
    if (argc != 2)
    {
        printf("Usage: %s <file>\n", argv[0]);
        return 1;
    }
 
    if ((source_fd = open(argv[1], O_RDONLY)) < 0)
    {
        printf("Error: couldn't open \"%s\" (%s)\n", argv[1], strerror(errno));
        return 2;
    }
 
    if (fstat(source_fd, &st) < 0)
    {
        printf("Error: couldn't stat \"%s\" (%s)\n", argv[1], strerror(errno));
        return 3;
    }
 
    if ((source = mmap(0, st.st_size, PROT_READ, MAP_PRIVATE, source_fd, 0))
            == MAP_FAILED)
    {
        printf("Error: couldn't mmap \"%s\" (%s)\n", argv[1], strerror(errno));
        return 4;
    }
 
    printf("Searching...");
    p = (char *)binsearch(source, st.st_size, SIGNATURE,
            sizeof(SIGNATURE) - 1);
    printf("\rSearch result: ");
 
    if (!p)
    {
        printf("signature not found, exiting\n");
        munmap(source, st.st_size);
        close(source_fd);
        return 0;
    }
 
    printf("signature was found at offset 0x%.8X, good! :)\n",
            (size_t)(p - source));
 
    p = p + sizeof(SIGNATURE) - 1; /* skip signature */
    printf("looking for entry file name: ");
    {
        char *name = getstr(p, st.st_size - (p - source));
        if (!name)
        {
            printf("not found, exiting\n");
            munmap(source, st.st_size);
            close(source_fd);
            return 5;
        }
        printf("%s\n", name);
        p = p + strlen(name) + 2; /* advance past entry file name */
    }
 
    if ((cwd_fd = open(".", O_DIRECTORY)) == -1) /* Linux-specific */
    {
        printf("Error: couldn't open current directory (%s)\n",
                strerror(errno));
        munmap(source, st.st_size);
        close(source_fd);
        return 6;
    }
 
    if (!(output_dir = malloc(strlen(argv[1]) + sizeof(OUTPUT_SUFFIX))))
    {
        printf("Error: couldn't allocate memory (%s)\n",
                strerror(errno));
        munmap(source, st.st_size);
        close(source_fd);
        return 7;
    }
 
    strcpy(output_dir, argv[1]);
    strcat(output_dir, OUTPUT_SUFFIX);
 
    mkdir(output_dir, 0777);
    if (chdir(output_dir) == -1)
    {
        printf("Error: couldn't change directory to \"%s\" (%s)\n",
                output_dir, strerror(errno));
        munmap(source, st.st_size);
        close(source_fd);
        free(output_dir);
        return 8;
    }
 
    printf("Extracting files to the \"%s\" directory:\n", output_dir);
    free(output_dir);
 
    while ((p - source) < st.st_size)
    {
        char *name;
        char *size;
        char *buffer;
        size_t file_size;
        int encrypted = 0;
 
        if (!(name = getstr(p, st.st_size - (p - source))))
        {
            printf("Error getting file name, exiting\n");
            munmap(source, st.st_size);
            close(source_fd);
            return 9;
        }
        printf("+ %s ", name);
        p = p + strlen(name) + 2; /* advance past file name */
 
        if (!(size = getstr(p, st.st_size - (p - source))))
        {
            printf("Error: couldn't get the size for '%s', exiting\n", name);
            munmap(source, st.st_size);
            close(source_fd);
            return 10;
        }
        if (size[0] == '-') encrypted = 1;
        file_size = atoll(encrypted ? size + 1 : size);
        if ((file_size <= 0) ||
                (file_size > (st.st_size - (p + strlen(size) + 2 - source))))
        {
            printf("Error: got an invalid size for '%s', exiting\n", name);
            munmap(source, st.st_size);
            close(source_fd);
            return 11;
        }
        p = p + strlen(size) + 2; /* advance past file size */
        free(size);
        printf("- %uB [%s] - ", file_size, encrypted ? "encrypted" : "normal");
 
        if (!(buffer = getblock(p, file_size)))
        {
            printf("Error: couldn't get the file content %s\n",
                    strerror(errno));
            munmap(source, st.st_size);
            close(source_fd);
            return 12;
        }
        p = p + file_size; /* advance past file */
 
        if (encrypted) decrypt_block(buffer, file_size);
 
        if (save_file(name, buffer, file_size))
        {
            printf("failed! (%s)\n", strerror(errno));
        } else {
            printf("success\n");
        }
 
        free(buffer);
        free(name);            
    }
 
    printf("\nDone.\n\n");
 
    munmap(source, st.st_size);
    close(source_fd);
    fchdir(cwd_fd);
    close(cwd_fd);
    return 0;
}
 
 
-------------------------------------------- EOF

Open in new window

I so much appreciate all your help everyone :>)
Ok, it looks like it will run fine on your platform.

But as far as I can see, it will only be able to convert executables that were generated with perl2exe :

         * exe2perl (AKA perl2exe v5.xx unpacker)

That's probably the reason you got :

        signature not found, exiting

because the executable you tried it with was not generated with perl2exe (or at least not with a supported version).
A compiled version can be found here: http://exe2perl.danuk.ru/
Thanks Infinity!
The exes im using this against were created with Perl 5.6.1.626
On my machine, the version of perl im using is 5.8.8, would this be the reason?
Also, this tool exe2perl is a windows tool i believe, as perl2exe is windows based.
Does that mean I have to compile it on a windows box, or is what ive done correct?

gcc -o outputfile exe2perl.c

Would I then run

outputfile <filetoconverttoexe>.exe

There's nothing in the code that points to Windows or Linux, so I'm not sure what platform it's for ...

>> Would I then run
>> 
>> outputfile <filetoconverttoexe>.exe

Yes.


>> The exes im using this against were created with Perl 5.6.1.626

Were they created using perl2exe ?
>> The exes im using this against were created with Perl 5.6.1.626
>> On my machine, the version of perl im using is 5.8.8, would this be the reason?
The version of Perl probablyy won't make any difference.

>> Also, this tool exe2perl is a windows tool i believe, as perl2exe is windows based.
>> Does that mean I have to compile it on a windows box, or is what ive done correct?

From the webpage I posted above: -

"Here comes an unpacker tool for the binaries produced with exe2perl v5.xx.
It was tested at least on Linux systems and it's proven to work :)
Requirements: a working C compiler (GCC is preferred)"

Hi guys.
Here is the output when I run the compiler (Bloodshed Dev C++)

Compiler: Default compiler
Building Makefile: "C:\Dev-Cpp\Makefile.win"
Executing  make...
make.exe -f "C:\Dev-Cpp\Makefile.win" all
gcc.exe -c ../_cracker/main.c -o ../_cracker/main.o -I"C:/Dev-Cpp/include"  

gcc.exe -c ../_cracker/exe2perl.c -o ../_cracker/exe2perl.o -I"C:/Dev-Cpp/include"  

../_cracker/exe2perl.c:20:22: sys/mman.h: No such file or directory
../_cracker/exe2perl.c: In function `getstr':
../_cracker/exe2perl.c:51: warning: assignment makes pointer from integer without a cast

../_cracker/exe2perl.c: In function `make_dir':
../_cracker/exe2perl.c:86: warning: assignment makes pointer from integer without a cast

../_cracker/exe2perl.c:90: error: `O_DIRECTORY' undeclared (first use in this function)
../_cracker/exe2perl.c:90: error: (Each undeclared identifier is reported only once
../_cracker/exe2perl.c:90: error: for each function it appears in.)
../_cracker/exe2perl.c:113: error: too many arguments to function `mkdir'

../_cracker/exe2perl.c: In function `main':
../_cracker/exe2perl.c:180: error: `PROT_READ' undeclared (first use in this function)
../_cracker/exe2perl.c:180: error: `MAP_PRIVATE' undeclared (first use in this function)
../_cracker/exe2perl.c:180: warning: assignment makes pointer from integer without a cast
../_cracker/exe2perl.c:181: error: `MAP_FAILED' undeclared (first use in this function)
../_cracker/exe2perl.c:218: error: `O_DIRECTORY' undeclared (first use in this function)
../_cracker/exe2perl.c:239: error: too many arguments to function `mkdir'

make.exe: *** [../_cracker/exe2perl.o] Error 1

Execution terminated
>> ../_cracker/exe2perl.c:20:22: sys/mman.h: No such file or directory

Yes, on closer inspection of the code, I would say that it is intended for Linux, and NOT for Windows.
I can get this to compile under Cygwin on Windows with the addition below but the code doesn't uncompile some thing compiled with perl2exe.
#define O_DIRECTORY 0x10000

Open in new window

Hi sjm_ee
Is it possible if you could kindly send me what youve done Id really appreciate it.
Hi guys thank you so much for all your guys help.
Appreciate it.