I am trying to interface my Nokia N95 with Proteus. It works almost fine, except of one thing. When I want to get the response from the modem, I use unsigned char input[20] and scanf("%s",input). When the modem receives a call, it send RING to the port, but what I get with scanf is RIG or RNG. What might be the problem?
#include <regx51.h>
#include <stdio.h>
#include <string.h>
sbit TE = P2^4;//for transmitting
unsigned char ch;
unsigned char ch2;
long i;
short bakar=0;
unsigned char Command_AT[]="AT\r";
unsigned char xdata Command_CPIN[]="AT+CPIN =\"0000\"\r";
unsigned char Command_CMGF[]="AT+CMGF=1\r";
unsigned char Command_CMGS[]="AT+CMGS =\"5555\"\r";
unsigned char msg_report[]="Ok";
unsigned char CtrlZ=0x1A;
unsigned char xdata Status_Ok[]="AT\rOK";
unsigned char Command_CHUP[]="AT+CHUP\r";
unsigned char input[10];
void iniSerial()
{
TMOD=0x20;
TH1=0XFD;
SCON=0x50;
TR1=1;
TI=1;
RI=0;
}
void delay()
{
for(i=1;i<=30000;i++); //Dont know how much exactly
}
void delay2()
{
for(i=1;i<=50000;i++);
}
void sendDeliveryReport()
{
puts(Command_AT);
delay();
puts(Command_CMGF);
delay();
puts(Command_CMGS);
delay();
puts(msg_report);
while(TI == 0);
SBUF = 0x1A;
}
void checkRing()
{
while(bakar!=1)
{
scanf("%s",&input);//problem is here
if(strcmp(input,"RING") == 0)
{
bakar=1;
delay();
puts(Command_CHUP);
}
delay2();
}
}
void main()
{
delay2(); //Wait for GSM modem to start.
TE=1; //Don't trasmit yet
iniSerial();
checkRing();
TE=0;
iniSerial();
sendDeliveryReport();
while(1); //Pause forever
}
Does that code really compile? The if-statement in void checkRing() has mismatched paranthesis.
ps. Sorry for the "answer" instead of a comment, but my reputation does not allow comments.
Your line
scanf("%s",&input);
is simply wrong. A good compiler should have told you if you have decent warning level.
&input is of type unsigned char (*)[10], that is a pointer to a unsigned char array. Use
scanf("%s",input);
instead. Here input decays to a unsigned char*, which is about what you want if what you expect is really a string and not arbitrary data. If your data may contain 0 bytes, you'd have to use read or something equivalent.
Edit: If your input is really a string use char instead of unsigned char.
I must say that this code seems to invite a hacker attack.
The line scanf("%s",&input); reads bytes until a newline, into the buffer on the stack. If more than 10 bytes are read, the buffer overflows and the stack is corrupted.
From there, the way to overwriting the return address and executing arbitrary code is short.
You must either use fgets, which allows you to limit the number of bytes read, followed by fscanf to stop at a delimiter, or use, as Daniel Fischer suggested, the format string "%9s" which won't store more than 10 bytes in the buffer (9 + terminating null).
Related
I'm making PE file format analyzer in C language.
When I used Visual Studio, I could make it much easier.
BUT, I have tired to make it without Visual Studio to improve my C programing.
It was made by GCC(My laptop is macbook).
To analyze PE file format, as you know I have to use file pointer and read file as 'rb' type.
I did it and it looks like worked well.... I wanted to print first and second words("MZ") but It printed unkown(to me) numbers.
P.S I write little different code refer to previous one to smaller than before. But It print NULL.
It means that I wrote code really wrong... PLZ tell me which parts are wrong
#include <stdio.h>
#include <stdlib.h>
// struct to save info of PE_File format
typedef struct _IMAGE_DOS_HEADER
{
unsigned short e_magic;
unsigned short e_cblp;
unsigned short e_cp;
unsigned short e_crlc;
unsigned short e_cparhdr;
unsigned short e_minalloc;
unsigned short e_maxalloc;
unsigned short e_ss;
unsigned short e_sp;
unsigned short e_csum;
unsigned short e_ip;
unsigned short e_cs;
unsigned short e_lfarlc;
unsigned short e_ovno;
unsigned short e_res[4];
unsigned short e_oemid;
unsigned short e_oeminfo;
unsigned short e_res2[10];
unsigned long e_lfanew;
} DOS_HEADER;
// I use two different functions.
// First one was made to import PE File format info from file that I used.
// Another was made to print some imformation. I use some comment because I didn't realize those.
DOS_HEADER get_dos_header(FILE *fp, char* fp_buffer);
void print_data_of_structures(DOS_HEADER/*, NT_HEADER, FILE_HEADER, OPTIONAL_HEADER, DATA_DIRECTORY*/);
int main(void)
{
DOS_HEADER dos_header;
char file_path[1000];
printf("Please input your file path : ");
scanf("%[^\n]s", file_path);
FILE* fp = NULL;
fp = fopen(file_path, "rb");
if(fp == NULL)
printf("Unalbe to open file :/\n");
// To calculate file size.
long fp_size = 0;
fseek(fp, 0, SEEK_END);
fp_size = ftell(fp);
rewind(fp);
// Declare to use as buffer
char* fp_buffer = malloc(sizeof(char) * (fp_size + 1));
// Use function to save analyzed information.
DOS_HEADER info_dos_header = get_dos_header(fp, fp_buffer);
// Print information.
print_data_of_structures(info_dos_header);
fclose(fp);
free(fp_buffer);
return 0;
}
DOS_HEADER get_dos_header(FILE* fp, char* fp_buffer)
{
DOS_HEADER raw_info_dos_header = {0, };
// Read hex info from fp 2 byte 1 time and save at fp_buffer.
fseek(fp, 0, SEEK_SET);
fread(fp_buffer, 2, 1, fp);
raw_info_dos_header.e_magic = fp_buffer;
return raw_info_dos_header;
}
void print_data_of_structures(DOS_HEADER info_dos_header/*, NT_HEADER info_nt_header, FILE_HEADER info_file_header, OPTIONAL_HEADER info_optional_header, DATA_DIRECTORY info_data_directory*/)
{
// print info_dos_header
printf("Print DOS_HEADER\n");
// I tried several print format(for example %hu, %x, %d) But I coudn't "MZ" or any numbers has realation with "MZ".
printf("%s", info_dos_header.e_magic);
}
You have 2 big problems with your code: you are mixing types.
In DOS_HEADER all members (except the last one) are of type unsigned short.
That's important.
In get_dos_header you are doing
fread(fp_buffer, 2, 1, fp);
raw_info_dos_header.e_magic = fp_buffer;
which is wrong.
Don't use magic numbers, use sizeof to get the correct sizes
Check the return value of fread, specially if you are analyzing a binary
format, you must be sure that you've read exactly what you're expecting.
It's much easier to deal with fread when the size argument is 1, because
only when the size argument is 1 the return value of fread matches the
number of bytes read.
e_magic is a unsigned short, fp_buffer is a char*. This assignment is
not copying the contents pointed to by fp_buffer, you are storing an address
as if it were a unsigned short value. You need to copy the memory pointed to
by fp_buffer.
Also I don't see the point of you allocating a buffer of the size of the file
when you are reading chunk by chunk. It would be easier if you don't allocate a
buffer at all and use an array of a size larger than what you are going to read.
int get_dos_header(FILE* fp, DOS_HEADER *dos)
{
unsigned char buffer[8];
size_t ret = fread(buffer, 1, sizeof(dos->e_magic), fp);
if(ret != sizeof(dos->e_magic))
{
fprintf(stderr, "Invalid file size\n");
return 0;
}
memcpy(&dos->e_magic, buffer, sizeof(dos->e_magic));
// DO the others fread operation
...
return 1;
}
Then in main you can do this:
DOS_HEADER raw_info_dos_header = {0, };
if(get_dos_header(fp, &raw_info_dos_header) == 0)
{
fprintf(stderr, "failed to get the DOS header\n");
return 1;
}
...
The second problem is in print_data_of_structures:
printf("%s", info_dos_header.e_magic);
e_magic is a unsigned short, %s expects a pointer to char, it expects a
string. e_magic is definitively not a string. This yield undefined behaviour.
The printf should look like this:
printf("e_magic: %hu\n", info_dos_header.e_magic);
or
printf("e_magic: 0x%04hx\n", info_dos_header.e_magic);
to print it in hexadecimal format.
I also advice you to use pointers instead. Your struct is big and passing a
pointer to a function is much cheaper than passing a copy of a large struct to a
functions. So instead of
void print_data_of_structures(DOS_HEADER info_dos_header);
declare it as
void print_data_of_structures(DOS_HEADER *info_dos_header);
And also don't declare function that can fail (like get_dos_header) as
void, otherwise how do you tell the calling function that it failed? It's
better for such functions to return an int (1 for success, 0 for failure) and
expect a pointer to the struct where the information is stored (see how I
changed get_dos_header above.
I have to receive a UDP packet from the socket. In this packet hour, min and sec are sent as UNSIGNED CHAR. When I receive it in a char[] and put in TextBox for displaying it is not displaying the actual data which are sent, but different values.
char buffer[10];
udpSocketRxCDP->readDatagram(buffer, sizeof(buffer));
ui->textEditsec->setText(buffer[2]);
Please suggest how I can get the actual data.
When you read from a socket, you are reading raw data. If you read it into a char[] buffer and use it as-is then the data is going to be interpreted as char. So either typecast the data to unsigned char when needed:
ui->textEditsec->setText( (unsigned char) buffer[2] );
Or define a suitable struct and typecast to that instead:
struct mypkt
{
unsigned char hour;
unsigned char minute;
unsigned char second;
...
};
ui->textEditsec->setText( ((mypkt*)buffer)->second );
Either way, assuming setText() actually expects a char* string as input, then use sprintf() or similar function to format a string:
char str[12];
sprintf(str, "%d", (int) ((mypkt*)buffer)->second);
ui->textEditsec->setText(str);
With the little given information, you might want to explicitly convert unsigned char to char.
Consider that some data may get corrupted. However, unless you really need it, you can send the data directly as signed char. We can't know whether it's a good choice or not though.
Edit: I am not sure if this code does what I think it does. Could someone tell me how to test it? I.e. what should the buffer in my main function look like? I am assuming that a buffer has data of two fields in the following order type(16 bits), length(32 bits). I'm assuming that the buffer is read in from a file and each of the fields is separated by a space. The fields are stored in network byte order and when I read them I have to convert them back to host byte order.
I'm expecting that the code will read the contents from the file (which should be in network byte order) and display the contents in host byte order. I'm a bit confused about type conversions and what the network byte order will be inside of a file, so I don't know what values to use to test it. Also, I'm not sure if my code is written correctly, could someone who does this sort of thing or knows a bit more about such conversions tell me if my code is correct?
Here's the code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void printRecords(char *buffer)
{
unsigned int recordType;
unsigned long recordLength;
char *data;
char *index;
if (!buffer)
printf("Empty buffer\n");
while(*buffer)
{
memcpy(&recordType,(const void *) buffer,2);
buffer += 3;
recordType = ntohs(recordType);
printf("Record type normal: %u\n",recordType);
memcpy(&recordLength,(const void *) buffer,4);
buffer += 5;
recordLength = ntohl(recordLength);
printf("Record Length normal: %l\n",recordLength);
break;
}
}
void main()
{
char * buffer = "0000000000000001 00000000000000000000000000000001";
printRecords(buffer);
}
char *buffer = malloc(sizeof(buf));
sizeof means "size of buf's type", ie the size of a pointer to char; you probably want
malloc(strlen(buf) + 1); /* 1 for trailing '\0' */
Then you are mistaking the value of the bytes for their conversion to string:
"256" is byte '2' followed by byte '5' and '6' -- '2' is not equals to 2, '5' is not equals to 5 etc.
The 256 you are talking about is 00000001 00000000 instead (try dumping the bytes to stdout and you'll see).
Also, recordType should be of type uint16_t, not unsigned -- you're never too paranoid.
EDIT: atoi takes a pointer to char, as in
atoi("123")
not a pointer to int!
void callback(const unsigned char* data, int len) {
unsigned char copydatahere;
}
data is a pointer-to-const situation, that is allocated in library outside. len is a size of data, guessing it to be sizeof(unsigned char)*N.
How I allocate copydatahere to size of len and copy the whole memory behind data including null bytes, string termination chars and anything other that has byte representation? What would be the difference between bcopy and memcpy in this situation?
Addition:
memcpy(pointer+offset, sourcedata, size);that's how you can do 'memcpy append' guys. Thank you all!
Use memcpy. bcopy is only supported on some platforms, and is deprecated in newer standards.
void callback(const unsigned char* data, int len) {
unsigned char* copydatahere = malloc(len);
if (!copydatahere) {
exit(1);
}
memcpy(copydatahere, data, len);
/* ... */
free(copydatahere);
}
Allocate with malloc(3), release with free(3). bcopy(3), while deprecated (so prefer memmove(3)), handles overlapping memory regions, memcpy(3) doesn't.
#include <assert.h>
#include <stdlib.h>
void callback(const unsigned char *data, int len) {
assert(len >= 0);
unsigned char *copy = malloc(len);
if (copy == NULL) { abort(); }
memcpy(copy, data, len);
/* TODO: Store the length somewhere, since otherwise the pointer is useless. */
/* TODO: pass the pointer "copy" somewhere, so it is used. */
}
Usually the second argument to such a callback function is some unsigned type like unsigned int or size_t. Therefore I added the assert, just to be sure that there won't be any undefined behavior.
memcpy is well-defined in the C standard, while bcopy is the old version and is not guaranteed to exist or even work as you expect. (Though usually if it exists it will do what you expect.)
Just create an array
void callback(const unsigned char* data, int len) {
unsigned char copydatahere[len];
memcpy(copydatahere, data, len);
}
If len can be arbitrarily large (say, like 4 million), it's better to use malloc though, because it can tell you whether allocation succeeded or not (although some operation systems in certain configurations will lie to you, telling you enough memory is available, only to then later crash when you try to access it). If the above array's allocation fails, behavior is undefined.
Not all compiles support arrays with a variable size, though.
What's the best/recommended way to copy data between a byte array and an integer in C? Currently I'm using memcpy, which doesn't feel right to me. A sample of the sort of thing I'm doing is below.
struct alpha {
unsigned char byte_array[20];
}
void function(struct alpha *st) {
unsigned long num;
/* Do some stuff */
memcpy(st->byte_array, &num, sizeof(unsigned long));
/* Do more stuff */
memcpy(&num, st->byte_array, sizeof(unsigned long));
}
I assume I want to use casts somehow, but I'm not confident of how casting and pointer (de)referencing interacts, particularly when arrays get involved.
memcpy is the standard and portable tool for that effect. Modern optimized compilers will inline this call to something well adapted to your situation, e.g data types, allignement, size (if known at compile time), processor... So I think you should definitively stick to that and not mess around with some handmade optimizations.
It looks exactly the right way to me. Which is to say, when I had to do this, it was the way I did it.
Here's how to do it with casts:
/* Do some stuff */
*(unsigned long *)st = num;
/* Do more stuff */
num = *(unsigned long *)st;
You're casting your struct pointer to a pointer to an unsigned long, then dereferencing the pointer in the assignment statements.
It is not wrong, unless you know that "who" wrote the data into the array wrote them in an endianness different from the one used on your system. Say, e.g., if those data come from a "stream" sent by "someone" over the net. Then, if the protocol uses the so called "network byte order" (namely big endian), and your machine is not big endian, then you obtain wrong values.
Is there any particular reason you need to copy instead of just aliasing the two? e.g.:
union XXX {
char byte_array[20];
unsigned long num;
};
In theory, you don't get defined results when you write to one member of the union then read from the other member. In reality, there's essentially no possibility of getting anything different from what you're getting now -- except (of course) that you don't have to copy data to get from one view to the other -- you just use x.num to look at it as an unsigned long, and x.byte_array to look at it as an array of bytes.
memcpy is the safest way to do this sort of thing. If speed matters though, you can do some cast magic to let the compiler handle the copy natively for you:
*((unsigned long *)&st->byte_array[0]) = num;
num = *((unsigned long *)&st->byte_array[0]);
Both these will use built in register type copies instead of a function call of 4 bytes. If you want to read further into the byte_array, you must be careful of byte alignment issues with this though.
I prefer some default functions for this requirement,
for string to integer
int atoi ( const char * str );
and
for integer to string
char * itoa ( int value, char * str, int base );
#include <stdio.h>
#include <stdlib.h>
int main()
{
unsigned long int number;
unsigned char string[256];
printf ("Enter a number: ");
fgets ( string, 256, stdin );
number = atoi (string);
printf("number = %d\n",number);
//converting int to string
itoa (number,string,10); //10 is base here for decimal, 16 is used for Hex and 2 for Binary
printf ("string = %s\n",string);
return 0;
}
as per me atoi() function is fine. But in case you don't want to use itoa() or it is not available to you then you can just use sprintf()
sprintf (string,"%ld",number);
I hope it helps
Thanks
Alok.kr.