When I run my CLI program on my iphone i get a Segment fault: 11 error. I dunno what to do, I'm a noob at C.
int main (int argc, const char * argv[])
{
if (argc > 1 && (!strcmp(argv[1],"--help") || !strcmp(argv[1],"-h"))) {
printf("#### redhai 1.2 ####\n");
printf("-j Jailbreak\n");
printf("-i Device info\n");
printf("-a About\n");
printf("*END OF HELP*\n");
printf("####################\n");
return 0;
}else if (!strcmp(argv[1],"-j")) {
printf("Coding the jailbreak portion!\n");
return 0;
}
return 0;
}
You are accessing argv[1] without first checking if it exists. You need to first check if argc > 1.
} else if (argc > 1 && !strcmp(argv[1],"-j")) {
// ^^^^^^^^^^^^
The problem is in the logic. It is possible that you pass NULL to strcmp in case argc is less or equal to 1. To fix it, re-order the checks like this:
int main (int argc, const char * argv[])
{
if (argc > 1) {
if (!strcmp(argv[1],"--help") || !strcmp(argv[1],"-h")) {
printf("#### redhai 1.2 ####\n");
printf("-j Jailbreak\n");
printf("-i Device info\n");
printf("-a About\n");
printf("*END OF HELP*\n");
printf("####################\n");
} else if (!strcmp(argv[1],"-j")) {
printf("Coding the jailbreak portion!\n");
}
}
return 0;
}
Related
So I am working on a project and we take in input with argc. So what is happening is that we need to have a total of 5 argc in one of the methods and in the second method we need only 3 argc. So I tested it out and noticed if I change the checker from !=5 to !=3 it works for the method that uses 3 argc but not the one that uses 5 argc. Is there a way that lets me use both method?
int moveFile(struct filesystem_volume volume, struct arguments command) {
/* Checking argc */
if(command.argc < 5) {
printf("\t***ERROR - TOO FEW ARGS***\n");
return 0; // check
}
else if(command.argc > 5){
printf("\t***ERROR - TOO MANY ARGS***\n");
return 0; //check
}
/* copy file */
strcpy(command.args[0], "cp");
if (copyFile(volume, command) == 0) {
printf("\t***ERROR - COPYING FILE***\n");
return 0;
}
/* remove file */
strcpy(command.args[0], "rm");
command.argc = 3;
if (removeFile(volume, command) == 0) {
printf("\t***ERROR - REMOVING FILE***\n");
return 0;
}
return 1;
}
Here's the code but I don't think you would need code
I'm writing a C program that accepts a system resource name (e.g. RLIMIT_NOFILE) and prints some resource limit info for it.
The resource constants are defined in <sys/resource.h>, e.g.
#define RLIMIT_NOFILE 5
I'm looking for a good way to map the command-line argument (e.g. RLIMIT_NOFILE) to the corresponding numeric value (e.g. 5).
I originally planned to do something like:
int resource = -1;
char *resource_names[] = {
"RLIMIT_NOFILE", "RLIMIT_NPROC", "RLIMIT_RSS"
};
for (i = 0; i < sizeof(resource_names)/sizeof(char *); i++) {
if (strcmp(argv[1], resource_names[i]) == 0) {
resource = eval(resource_names[i]);
break;
}
}
But C doesn't seem to have anything like eval, and even if it did, the compile-time constants wouldn't be available at run-time.
For now, I'm doing the following, but I'm curious if there's a better approach.
#include <stdio.h>
#include <string.h>
#include <sys/resource.h>
int main(int argc, char *argv[])
{
if (argc != 2) {
printf("Usage: %s <resource>\n", argv[0]);
return 1;
}
char *resource_names[] = {
"RLIMIT_NOFILE", "RLIMIT_NPROC", "RLIMIT_RSS"
};
int resources[] = {
RLIMIT_NOFILE, RLIMIT_NPROC, RLIMIT_RSS
};
int i, resource = -1;
for (i = 0; i < sizeof(resources)/sizeof(int); i++) {
if (strcmp(argv[1], resource_names[i]) == 0) {
resource = resources[i];
break;
}
}
if (resource == -1) {
printf("Invalid resource.\n");
return 1;
}
struct rlimit rlim;
getrlimit(resource, &rlim);
printf("%s: %ld / %ld\n", argv[1], rlim.rlim_cur, rlim.rlim_max);
return 0;
}
The RLIMIT_x constants are all low-value integers that can be used as indexes into an array, or (for your problem) use an array to find the index and it will correspond to the value you want.
Or you could have an array of structures, containing both the value and the string. Something like
static const struct
{
int limit;
char *name;
} rlimits[] = {
{ RLIMIT_NOFILE, "RLIMIT_NOFILE" },
{ RLIMIT_NPROC, "RLIMIT_NPROC" },
// Etc.
};
Then it's easy to iterate over the array and "map" a string to a value (or do the opposite).
I have my program and it runs like I expected, however, I want to call it again but this time I want to use different arguments. How can I do that?
It seems I cant just use main(filename1,filename2)and then follow the same routine I did last before.
My main looks like this
int main(int argc,char* argv[])
{
if (argc<3)
{
printf("Error no filenames\n");
return -1;
}
char* filename=argv[1];
char* fileout=argv[2];
int count_Pharmacy;
int count_Surgicaly;
int count_General;
int count_Counselling;
char pick;
patient* Pharmacy_head=NULL;
patient* General_head=NULL;
patient* Surgical_head=NULL;
patient* Counselling_head=NULL;
dep* dep_head=NULL;
Counselling_head=get_patient(Pharmacy_head,filename,"Counselling");
Surgical_head=get_patient(Pharmacy_head,filename,"Surgical");
General_head=get_patient(Pharmacy_head,filename,"General");
Pharmacy_head=get_patient(Pharmacy_head,filename,"Pharmacy");
count_Pharmacy=count_patient(Pharmacy_head);
count_Surgicaly=count_patient(Surgical_head);
count_General=count_patient(General_head);
count_Counselling=count_patient(Counselling_head);
dep_head=make_deparments(dep_head,"Counselling","Dr. Willy",Counselling_head,count_Counselling);
dep_head=make_deparments(dep_head,"Surgical","Dr. Neo Cortex",Surgical_head,count_Surgicaly);
dep_head=make_deparments(dep_head,"General","Dr. Ann Imezechara",General_head,count_General);
dep_head=make_deparments(dep_head,"Pharmacy","Dr. Charles Xavier",Pharmacy_head,count_Pharmacy);
treatment(dep_head,fileout);
printf("The patients have been treated would you like to add another file?(Y/N)\n");
pick=fgetc(stdin);
if (pick=='y' || pick =='Y')
{
//this is where i would like to call main again but with diffrent arguments
}
else if(pick =='N' || pick=='n')
{
printf("Goodbye have a marvelous day\n");
}
else
{
printf("Thats not a valid input but ill take that as a no\n");
}
return 1;
}
The two arguments I called main with the first time are file names.
char * new_argv [4];
int new_argc = 3;
new_argv [0] = argv [0]; // program name
new_argv [1] = "file1";
new_argv [2] = "file2";
new_argv [3] = 0;
main (new_argc, new_argv);
I need to pass a 'key' as a parameter from terminal. It should run as ./a.out -k100101001
where 10011001 is the key and -k is the flag to specify it.
If I need to pass a filename along with the key it should run as ./a.out -k10011001 -iparameter.txt where parameter.txt is the filename and -i is the flag to specify that.
NOTE: I have several parameters to pass and parameter values are followed after the flag without space(-iparameter.txt), plus I don't know the order of the flags so doing something like this won't help.
int main(int argc, char **argv) {
if (argc == 2) {
if (!strcmp(argv[1], "-k")) something();
if (!strcmp(argv[1], "-i")) something();
}
Any suggestion for C? I'm using Ubuntu to run my program.
Thanks.
Using a loop through argv should do it.
int main(int argc, char *argv[])
{
int numArg;
for (numArg = 1; numArg < argc; numArg++)
{
if (argv[numArg][0] == '-')
{
switch (argv[numArg][1])
{
case 'k' : somethingAboutKey(argv[numArg] + 2); // The parameter's value is passed directly to the function
break;
case 'i' : somethingAboutFile(argv[numArg] + 2);
break;
}
}
}
}
I'm currently attempting to read in keyfiles my code has outputted for an example implementation of RSA-2048.
My output code reads as follows:
void generate_rsa_key(arguments args) {
FILE* fp_pub;
fp_pub = fopen("rsa_key.pub", "wb");
FILE* fp_pri;
fp_pri = fopen("rsa_key.pri", "wb");
rsa_keygen(args.m_n, args.m_pri_exp, args.m_pub_exp);
gmp_fprintf(fp_pub, "%ZX.%ZX", args.m_pub_exp, args.m_n);
gmp_fprintf(fp_pri, "%ZX.%ZX", args.m_pri_exp, args.m_n);
fprintf(stdout, "\nRSA key pair generated.\n\n");
}
Resulting in a hex-encoded output that looks like:
10001.9F959C28250AF2197AE7B1638AA1CC464B4D4E091B2182830D4020267F68D1DDDBB7E8E1039
C9CEDFE6FD58BA0CA4E16D47D586CC66C2D86DCD3171D7CB5B7A12EDBAEC9E6FB944094519D9A6EAC
7CD6D43B1E1EA8C068FAA3BD0C9C4A703FF6A72782C4A3C8214BCECA8FF9F7B044D51ECB6B11DEB3B
80D0835B6518669742EDC116EF929334DF647A59D2AF395BDBECB6DA74C660B1DAF3D4C25432C6B11
D9C4A6A5D29302D50039F15B1850ED57DA7F9C701BA18141A9E0A6761E88B59E1A01C908A60E4A143
EDC67DE94AD8132305F9B28F2AA3B581E9BE0336D3B34AD0D874B92C51E9A2C074608EB3CD0119CC8
6701BA9667FC1AE00CBEC2DE8932DCEF
My code for reading in a keyfile is:
typedef struct arguments {
mpz_t m_pri_exp;
mpz_t m_pub_exp;
mpz_t m_n;
mpz_t o_pub_exp;
mpz_t o_n;
} arguments;
void read_rsa_keyfile(char* path, arguments args, int pri) {
FILE *fp;
fp = fopen(path, "rb");
if (pri) {
gmp_fscanf(fp, "%ZX.%ZX", args.m_pri_exp, args.m_n);
} else {
gmp_fscanf(fp, "%ZX.%ZX", args.o_pub_exp, args.o_n);
}
}
arguments parse_args(int argc, char* argv[]) {
int i;
arguments args;
for (i = 0; i < argc; i++) {
if (!strcmp(argv[i], "-g") || !strcmp(argv[i], "--gen-key")) {
mpz_inits(args.m_pri_exp, args.m_pub_exp, args.m_n, NULL);
generate_rsa_key(args);
exit(-1);
} else if (!strcmp(argv[i], "-f") || !strcmp(argv[i], "--my-key-file")) {
read_rsa_keyfile(argv[i+1], args, T);
} else if (!strcmp(argv[i], "-p") || !strcmp(argv[i], "--other-key-file")) {
read_rsa_keyfile(argv[i+1], args, F);
} else if (!strcmp(argv[i], "-h") || !strcmp(argv[i], "--help")) {
print_help();
}
}
if (!mpz_cmp_ui(args.m_pri_exp, (unsigned long)0) || \
!mpz_cmp_ui(args.m_n, (unsigned long)0) || \
!mpz_cmp_ui(args.o_pub_exp, (unsigned long)0) || \
!mpz_cmp_ui(args.o_n, (unsigned long)0)) {
print_help();
} else {
return args;
}
}
Note that I do not initialize the mpz_t variables and that I give the variable itself, not the address, for the gmp_fscanf calls, both of which are consistent with the GMP docs.
However, when I run the code it segfaults within the GMP library, and gives the error output:
*** glibc detected *** ./dhe_rsa: realloc(): invalid pointer: 0x00007fff9c0342b8 ***
======= Backtrace: =========
/lib/x86_64-linux-gnu/libc.so.6(+0x76a16)[0x7fe3dfb1da16]
/lib/x86_64-linux-gnu/libc.so.6(realloc+0x312)[0x7fe3dfb23c22]
/usr/lib/x86_64-linux-gnu/libgmp.so.10(__gmp_default_reallocate+0x1c)[0x7fe3e009ca1c]
/usr/lib/x86_64-linux-gnu/libgmp.so.10(__gmpz_realloc+0x3a)[0x7fe3e00b2bba]
/usr/lib/x86_64-linux-gnu/libgmp.so.10(__gmpz_set_str+0x301)[0x7fe3e00b3ef1]
/usr/lib/x86_64-linux-gnu/libgmp.so.10(__gmp_doscan+0xda7)[0x7fe3e00ed777]
/usr/lib/x86_64-linux-gnu/libgmp.so.10(__gmp_fscanf+0x94)[0x7fe3e00ed8c4]
./dhe_rsa[0x40164f]
./dhe_rsa[0x400fa9]
/lib/x86_64-linux-gnu/libc.so.6(__libc_start_main+0xfd)[0x7fe3dfac5ead]
./dhe_rsa[0x4011b1]
Is there anything I'm visibly doing wrong with my code? It seems to me to match what is in the docs properly. I've tried a number of different things to try and debug it, and haven't gotten anywhere.
EDIT:
As pointed out by Grzegorz Szpetkowski, I had misunderstood the docs and I do need to initialize the variables. However, the reason I believed that the variables didn't need to be initialized is that I was getting 0 as the result of the my fscanf reads. As such, that is now my problem. I've edited my function to instead be:
arguments parse_args(int argc, char* argv[]) {
int i;
arguments args;
mpz_inits(args.m_pri_exp, args.m_pub_exp, args.m_n, args.o_pub_exp, args.o_n, NULL);
for (i = 0; i < argc; i++) {
if (!strcmp(argv[i], "-g") || !strcmp(argv[i], "--gen-key")) {
generate_rsa_key(args);
exit(-1);
} else if (!strcmp(argv[i], "-f") || !strcmp(argv[i], "--my-key-file")) {
read_rsa_keyfile(argv[i+1], args, T);
} else if (!strcmp(argv[i], "-p") || !strcmp(argv[i], "--other-key-file")) {
read_rsa_keyfile(argv[i+1], args, F);
} else if (!strcmp(argv[i], "-h") || !strcmp(argv[i], "--help")) {
print_help();
}
}
gmp_fprintf(stdout, "%ZX\n", args.m_pri_exp);
gmp_fprintf(stdout, "%ZX\n", args.m_n);
gmp_fprintf(stdout, "%ZX\n", args.o_pub_exp);
gmp_fprintf(stdout, "%ZX\n", args.o_n);
if (!mpz_cmp_ui(args.m_pri_exp, (unsigned long)0) || \
!mpz_cmp_ui(args.m_n, (unsigned long)0) || \
!mpz_cmp_ui(args.o_pub_exp, (unsigned long)0) || \
!mpz_cmp_ui(args.o_n, (unsigned long)0)) {
print_help();
} else {
return args;
}
}
And I get the output:
0
0
0
0
The rest remains the same.
It is not obvious what is going wrong, since we don't know how program is called and there are missing pieces of code. However what seems pretty clear to me is that you are calling mpz_inits() function only for first option (-g or --gen-key). As there is exit(-1) call, it's obvious that other options lack required initialization (read_rsa_keyfile() is clearly such candidate). To do anything with mpz_t objects you have to initialize them at first.