Why does printf() print ffffff before actual data. C [duplicate] - c

This question already has answers here:
printf adds extra `FFFFFF` to hex print from a char array [duplicate]
(3 answers)
Closed 7 years ago.
printf() function prints leading ffffff (technically I understand that most significant bit carries sign so it gets carried all the way to where data starts). But how to get rid of them I have no idea and why is it happening?
int mem_display(Cmd *cp, char *arguments)
{
int i;
char *adr;
if (!sscanf(arguments,"%x",&adr))
{
return 0;
}
printf("%#0.8s ",arguments);
for (i=0; i<16; i++) {
printf("%02.x ",(unsigned int)*(adr+i));
}
...
the output:
% UNIX> md 10668
/*calling function show memory location 0x10668*/
OUT:
10668 ffffffbc 10 20 ffffffe0 ffffffa0 40 ffffffa2 ffffffa0 44 ffffff9c 23 ffffffa0 20
solved:
printf("%0.2x ",(unsigned int)*(adr+i));
output:
UNIX> md 10000
10000 7f 45 4c 46 01 02 01 00 00 00 00 00 00 00 00 00 .ELF............

Cast to unsigned char to have the system consider *(adr+i) as unsigned, so that no sign expansion will be done.
for (i=0; i<16; i++) {
printf("%02.x ",(unsigned char)*(adr+i));
}

Please read the printf() manual, this is the correct way
printf("%02x ", (unsigned char) adr[i]);
Note: don't use this *(a + i) notation, and specially when you are casting it. It's not a bad way to dereference a pointer, it's just not appropriate in this particular situation.

Related

Reading data pointed to by an address

working on my reversing skillset here and I came upon something I thought i understood but I managed to confuse myself.
Working in C mainly
My function returns me an address for the information I want to access.
LRESULT ret = SendMessage(hComboBox, CB_GETITEMDATA, (WPARAM)0 , (LPARAM) 0);
// the exact function doesn't really matter here.
printf("Address: %p\n", ret); // Output is 09437DF8
A dump of this address results in
09437DF8 A0 55 E8 12
This is the address (note endianness) of the data I really want to read.
12e855A0
12 E8 55 A0 - 30 00 3A 00 30 00 33 00 3A 00 32 00 32 00 00 00 - UNICODE "0:03:22"
Now I'm fairly certain this is just basic pointers/referencing/de-referencing but i cant wrap my head what I have to do to read this value pragmatically.
wprintf(L"%s\n", <value at address pointed to by ret>);
// Yes its a null terminated string
// Im working via injected dll, so no access violations
// string is unicode
Perhaps something like this?
#include <stdio.h>
#include <wchar.h>
int main()
{
wchar_t *name = L"UNICODE String";
void **ret = (void **)&name;
wprintf(L"%ls \n", *(wchar_t **)ret);
return 0;
}

Convert Decimal to Hex and store to array in C

I've been trying to convert decimal from 1 to 99 to hexadecimal and store them into an array.
What I have is something like this:
int main(){
int i =1;
char dump_holder[3];
char hex_holder[100];
for (i=1;i<100;i++){
sprintf(dump_holder, "%02x",i);
hex_holder[i] = atoi(dump_holder);
printf("this: %02x\n", hex_holder[i]);
}
return 0;}
I'm getting correct value a certain number. This code returns:
this: 01
this: 02
this: 03
this: 04
this: 05
this: 06
this: 07
this: 08
this: 09
this: 00
this: 00
this: 00
this: 00
this: 00
this: 00
this: 0a
this: 0b
this: 0c
this: 0d
this: 0e
this: 0f
this: 10
this: 11
this: 12
this: 13
this: 01
this: 01
this: 01
this: 01
this: 01
this: 01
this: 14
this: 15
this: 16
this: 17
this: 18
this: 19
this: 1a
this: 1b
this: 1c
this: 1d
I think the stray values are the null terminator, but I'm not sure.
well, the basic thing is I cannot understand what you are actually trying to achive
but I will try my best:
int main(){
int i =1;
char dump_holder[3];
char hex_holder[100];
for (i=1;i<100;i++){
/* convert numerical value to string */
sprintf(dump_holder, "%02x",i);
/* convert string value back to numerical value */
//hex_holder[i] = atoi(dump_holder); //won't work
hex_holder[i] = strtol(dump_holder, NULL, 16); // this will
/* print the numerical value in hex representation */
printf("this: %02x\n", hex_holder[i]);
}
return 0;}
are you trying to create a string representation of the values in hex format?
if so, you are going about this the wrong way
right now you are not doing much except wasting proccessing power
even so i added a small code that will actuallt conver the code to a string representation of the values. Maybe that is what you actually intended to do
int main()
{
int i = 1;
char dump_holder[3];
/* the array should be an array of strings (restricted here to 2chars) */
char hex_holder[100][2];
for (i=1;i<100;i++){
/* convert numerical value to string representation */
sprintf(hex_holder[i], "%02x",i);
/* print the string produced */
printf("this: %s\n", hex_holder[i]);
}
return 0;
}
atoi assumes decimal representation, try strtol(dump_holder, NULL, 16); instead.
To understand the problem in your code, you first need to understand -
How atoi works?
Read about atoi and go through the example demonstrating its behavior
here.
In your program output, after 09 you are getting six times 00 because the atoi is returning 0 for the hex values 0a, 0b, 0c, 0d, 0e and 0f.
After this the program output is:
this: 0a
this: 0b
this: 0c
this: 0d
this: 0e
this: 0f
Reason is -
The hex value after 0f is 10. 10 is stored in dump_holder variable which is passed to atoi.
atoi returned integer value 10 which is stored in hex_holder[i].
Your program is printing the value stored in hex_holder[i], which is of type char, using %x format specifier. So, the value 10 is getting printed as 0a.
Using incorrect format specifier is undefined behavior which includes it may do exactly what the programmer intended or silently generating incorrect results or anything else.
Just to convert decimal from 1 to 99 to hexadecimal and store them into an array, you can do:
#include <stdio.h>
int main() {
char hex_holder[100][3];
for (int i = 1; i < 100; i++) {
snprintf (hex_holder[i], 3, "%02x", i);
printf("this: %s\n", hex_holder[i]);
}
return 0;
}

Pointer arithmetic around cast

I am currently enrolled in a CS107 class which makes the following assumptions:
sizeof(int) == 4
sizeof(short) == 2
sizeof(char) == 1
big endianness
My professor showed the following code:
int arr[5];
((short*)(((char*) (&arr[1])) + 8))[3] = 100;
Here are the 20 bytes representing arr:
|....|....|....|....|....|
My professor states that &arr[1] points here, which I agree with.
|....|....|....|....|....|
x
I now understand that (char*) makes the pointer the width of a char (1 byte) instead of the width of an int (4 bytes).
What I don't understand is the + 8, which my professor says points here:
|....|....|....|....|....|
x
But shouldn't it point here, since it is going forwards 8 times the size of a char (1 byte)?
|....|....|....|....|....|
x
Let's take it step by step. Your expression can be decomposed like this:
((short*)(((char*) (&arr[1])) + 8))[3]
-----------------------------------------------------
char *base = (char *) &arr[1];
char *base_plus_offset = base + 8;
short *cast_into_short = (short *) base_plus_offset;
cast_into_short[3] = 100;
base_plus_offset points at byte location 12 within the array. cast_into_short[3] refers to a short value at location 12 + sizeof(short) * 3, which, in your case is 18.
The expression will set the two bytes 18 bytes after the start of arr to the value 100.
#include <stdio.h>
int main() {
int arr[5];
char* start=(char*)&arr;
char* end=(char*)&((short*)(((char*) (&arr[1])) + 8))[3];
printf("sizeof(int)=%zu\n",sizeof(int));
printf("sizeof(short)=%zu\n",sizeof(short));
printf("offset=%td <- THIS IS THE ANSWER\n",(end-start));
printf("100=%04x (hex)\n",100);
for(size_t i=0;i<5;++i){
printf("arr[%zu]=%d (%08x hex)\n",i,arr[i],arr[i]);
}
}
Possible Output:
sizeof(int)=4
sizeof(short)=2
offset=18 <- THIS IS THE ANSWER
100=0064 (hex)
arr[0]=0 (00000000 hex)
arr[1]=0 (00000000 hex)
arr[2]=0 (00000000 hex)
arr[3]=0 (00000000 hex)
arr[4]=6553600 (00640000 hex)
In all your professors shenanigans he's shifted you 1 integer, 8 chars/bytes and 3 shorts that 4+8+6=18 bytes. Bingo.
Notice this output reveals the machine I ran this on to have 4 byte integers, 2 byte short (common) and be little-endian because the last two bytes of the array were set to 0x64 and 0x00 respectively.
I find your diagrams dreadfully confusing because it isn't very clear if you mean the '|' to be addresses or not.
|....|....|....|....|
012345678901234567890
^ 1 ^ ^ 2
A X C S B
Include the bars ('|') A is the start of Arr and B is 'one past the end' (a legal concept in C).
X is the address referred to by the expression &Arr[1].
C by the expression (((char*) (&arr[1])) + 8).
S by the whole expression.
S and the byte following are assigned to and what that means depends on the endian-ness of your platform.
I leave it as an exercise to determine what the output on a similar but big-endian platform who output. Anyone?
I notice from the comments you're big-endian and I'm little-endian (stop sniggering).
You only need to change one line of the output.
Here's some code that can show you which byte gets modified on your system, along with a breakdown of what is happening:
#include <stdio.h>
int main( int argc, char* argv[] )
{
int arr[5];
int i;
for( i = 0; i < 5; i++ )
arr[i] = 0;
printf( "Before: " );
for( i = 0; i < sizeof(int)*5; i++ )
printf( "%2.2X ", ((char*)arr)[i] );
printf( "\n" );
((short*)(((char*) (&arr[1])) + 8))[3] = 100;
printf( "After: " );
for( i = 0; i < sizeof(int)*5; i++ )
printf( "%2.2X ", ((char*)arr)[i] );
printf( "\n" );
return 0;
}
Start from the inner most:
int pointer to (arr + 4)
&arr[1]
|...|...|...|...|...
Xxxx
char pointer to (arr + 4)
(char*)(&arr[1])
|...|...|...|...|...
X
char pointer to (arr + 4 + 8)
((char*)(&arr[1])) + 8)
|...|...|...|...|...
X
short pointer to (arr + 4 + 8)
(short*)((char*)(&arr[1])) + 8)
|...|...|...|...|...
Xx
short at (arr + 4 + 8 + (3 * 2)) (this is an array index)
((short*)((char*)(&arr[1])) + 8))[3]
|...|...|...|...|...
Xx
Exactly which byte gets modified here depends on the endianess of your system. On my little endian x86 I get the following output:
Before: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
After: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 64 00
Good Luck with your course.

c get data from BMP

I find myself writing a simple program to extract data from a bmp file. I just got started and I am at one of those WTF moments.
When I run the program and supply this image: http://www.hack4fun.org/h4f/sites/default/files/bindump/lena.bmp
I get the output:
type: 19778
size: 12
res1: 0
res2: 54
offset: 2621440
The actual image size is 786,486 bytes. Why is my code reporting 12 bytes?
The header format specified in,
http://en.wikipedia.org/wiki/BMP_file_format matches my BMP_FILE_HEADER structure. So why is it getting filled with wrong information?
The image file doesn't appear to be corrupt and other images are giving equally wrong outputs. What am I missing?
#include <stdio.h>
#include <stdlib.h>
typedef struct {
unsigned short type;
unsigned int size;
unsigned short res1;
unsigned short res2;
unsigned int offset;
} BMP_FILE_HEADER;
int main (int args, char ** argv) {
char *file_name = argv[1];
FILE *fp = fopen(file_name, "rb");
BMP_FILE_HEADER file_header;
fread(&file_header, sizeof(BMP_FILE_HEADER), 1, fp);
if (file_header.type != 'MB') {
printf("ERROR: not a .bmp");
return 1;
}
printf("type: %i\nsize: %i\nres1: %i\nres2: %i\noffset: %i\n", file_header.type, file_header.size, file_header.res1, file_header.res2, file_header.offset);
fclose(fp);
return 0;
}
Here the header in hex:
0000000 42 4d 36 00 0c 00 00 00 00 00 36 00 00 00 28 00
0000020 00 00 00 02 00 00 00 02 00 00 01 00 18 00 00 00
The length field is the bytes 36 00 0c 00`, which is in intel order; handled as a 32-bit value, it is 0x000c0036 or decimal 786,486 (which matches the saved file size).
Probably your C compiler is aligning each field to a 32-bit boundary. Enable a pack structure option, pragma, or directive.
There are two mistakes I could find in your code.
First mistake: You have to pack the structure to 1, so every type size is exactly the size its meant to be, so the compiler doesn't align it for example in 4 bytes alignment. So in your code, short, instead of being 2 bytes, it was 4 bytes. The trick for this, is using a compiler directive for packing the nearest struct:
#pragma pack(1)
typedef struct {
unsigned short type;
unsigned int size;
unsigned short res1;
unsigned short res2;
unsigned int offset;
} BMP_FILE_HEADER;
Now it should be aligned properly.
The other mistake is in here:
if (file_header.type != 'MB')
You are trying to check a short type, which is 2 bytes, with a char type (using ''), which is 1 byte. Probably the compiler is giving you a warning about that, it's canonical that single quotes contain just 1 character with 1-byte size.
To get this around, you can divide this 2 bytes into 2 1-byte characters, which are known (M and B), and put them together into a word. For example:
if (file_header.type != (('M' << 8) | 'B'))
If you see this expression, this will happen:
'M' (which is 0x4D in ASCII) shifted 8 bits to the left, will result in 0x4D00, now you can just add or or the next character to the right zeroes: 0x4D00 | 0x42 = 0x4D42 (where 0x42 is 'B' in ASCII). Thinking like this, you could just write:
if (file_header.type != 0x4D42)
Then your code should work.

C Convert String to Ints Issue

I'm trying to parse some input on an embedded system.
I'm expecting something like this:
SET VARNAME=1,2,3,4,5,6,7,8,9,10\0
When I'm converting the separate strings to ints, both atoi() and strtol() seem to be returning 0 if the string begins with 8.
Here is my code:
char *pch, *name, *vars;
signed long value[256];
int i;
#ifdef UARTDEBUG
char convert[100];
#endif
if(strncmp(inBuffer, "SET",3)==0)
{
pch = strtok(inBuffer," ");
pch = strtok(NULL," ");
name = strtok(pch, "=");
vars = strtok(NULL,"=");
pch = strtok(vars,",");
i = 0;
while(pch != NULL)
{
value[i] = atoi(pch);
#ifdef UARTDEBUG
snprintf(convert, sizeof(convert), "Long:%d=String:\0", value[i]);
strncat(convert, pch, 10);
SendLine(convert);
#endif
i++;
pch = strtok(NULL,",");
// Check for overflow
if(i > sizeof(value)-1)
{
return;
}
}
SetVariable(name, value, i);
}
Passing it:
SET VAR=1,2,3,4,5,6,7,8,9,10\0
gives the following in my uart debug:
Long:1=String:1
Long:2=String:2
Long:3=String:3
Long:4=String:4
Long:5=String:5
Long:6=String:6
Long:7=String:7
Long:0=String:8
Long:9=String:9
Long:10=String:10
UPDATE:
I've checked the inBuffer both before and after 'value[i] = atoi(pch);' and it's identical and appears to have been split up to the right point.
S E T V A R 1 2 3 4 5 6 7 8 9 , 1 0
53 45 54 00 56 41 52 00 31 00 32 00 33 00 34 00 35 00 36 00 37 00 38 00 39 2c 31 30 00 00 00 00
UPDATE 2:
My UARTDEBUG section currently reads:
#ifdef UARTDEBUG
snprintf(convert, 20, "Long:%ld=String:%s", value[i], pch);
SendLine(convert);
#endif
If I comment out the snprintf() line, everything works perfectly. So what's going on with that?
can't you try to write your own atoi?
it's like ten lines long and then you can debug it easily (and check where the problem really is)
'0' = 0x30
'1' = 0x31
and so on, you just need to do something like
string[x] - 0x30 * pow(10, n)
for each digit you have
Not related, but
if(i > sizeof(value)-1)
{
return;
}
should be
if(i == sizeof(value)/sizeof(value[0]) )
{
return;
}
May be the cause of the problem if other pieces of code do the overflow checking in the wrong way and because of that they overwrite part of your string
I've just tried compiling and running your sample code on my own system. The output is correct (i.e. '8' appears where it should be in the output string) which indicates to me that something else is going on outside of the scope of the code you've provided to us.
I'm going to go out on a limb and say that one of your variables or functions is trampling your input string or some other variable or array. SendLine and SetVariable are places to look.
But more importantly, you haven't given us the tools to help you solve your problem. When asking people to help you debug your program, provide a simple test case, with full source, that exemplifies the problem. Otherwise, we're left to guess what the problem is, which is frustrating for us and unproductive for you.
atoi returns 0 for something that it can't render as numeric -- this is just a hunch, but have you tried dumping the binary representation of the string (or even checking that the string lengths match up)?

Resources