GDB: Why can I not print this? - gdb

(gdb) print argv[1]
$5 = 0xbffffb1d "hello"
(gdb) step
21 sz = strlen(argv[1]) + 1;
(gdb) print sz
$6 = 0
(gdb) printf "%s", sz
Cannot access memory at address 0x0
(gdb) printf "%i", sz
0
I am expecting 4 in sz, why is it coming out as 0?

I am not sure why you are expecting 4. You get 5 from strlen(argv[1]) because hello has 5 characters. And then you are adding 1 to it which is why the answer is 6.
sz = strlen(argv[1]) + 1; // 5 + 1 = 6

Related

Parsing G-code with arduino from an sd card

As the title suggests, I am using the following function to read the parameters of some g-code files present on the SD card:
long parseParameters(String data, char* c){
int offset = data.indexOf(c);
int offset1 = data.lastIndexOf(" ", offset + 1);
return offset1 > 0 ? data.substring(offset + 1, offset + offset1 + 1).toInt() : data.substring(offset + 1).toInt();
}
void setup(){
Serial.begin(9600);
String q = "P3 S255"; // input
Serial.println(parseParameters(p, "S")); // output
}
void loop(){
}
Only today, in an attempt to read the value of S in the string P3 S255 has emerged in a small bug:
INPUT -> OUTPUT
P3 S255 -> 25 (wrong)
A20 P3 S255 -> 255 (Correct)
S255 -> 255 (Correct)
Why? Yet the code would seem correct to me..where did I go wrong?
Thanks in advance to everyone.. :)
Thats the explanation:
int offset = data.indexOf(c); //in your example S
"P3 S255";
^
offset = 3
then you parse for offset1 but take another param namely " " after offset - but there is no " " in the string from offset+1 see above where the index is so it returns -1 why?
myString.lastIndexOf(val, from) The index of val within the String, or -1 if not found. But we find something:
offset = 3;
offset1 = 2 ==> offset1 > 0 ==> data.substring(offset + 1, offset + offset1 + 1).toInt()
which leads to
data.substring(3 + 1, 3 + 2 + 1).toInt()
"P3 S*4*25*6*5"; which results to 25 as you already know
to (optional): the index to end the substring before.
So you have correct for the S in the begin by changing to
data.substring(offset + 1, offset + 1 + offset1 + 1).toInt()
Explanation: You start at offset + 1 this has to be equal in from and to (= same starting point for your calculation)

Using bit wise operators

Am working on a C++ app in Windows platform. There's a unsigned char pointer that get's bytes in decimal format.
unsigned char array[160];
This will have values like this,
array[0] = 0
array[1] = 0
array[2] = 176
array[3] = 52
array[4] = 0
array[5] = 0
array[6] = 223
array[7] = 78
array[8] = 0
array[9] = 0
array[10] = 123
array[11] = 39
array[12] = 0
array[13] = 0
array[14] = 172
array[15] = 51
.......
........
.........
and so forth...
I need to take each block of 4 bytes and then calculate its decimal value.
So for eg., for the 1st 4 bytes the combined hex value is B034. Now i need to convert this to decimal and divide by 1000.
As you see, for each 4 byte block the 1st 2 bytes are always 0. So i can ignore those and then take the last 2 bytes of that block. So from above example, it's 176 & 52.
There're many ways of doing this, but i want to do it via using bit wise operators.
Below is what i tried, but it's not working. Basically am ignoring the 1st 2 bytes of every 4 byte block.
int index = 0
for (int i = 0 ; i <= 160; i++) {
index++;
index++;
float Val = ((Array[index]<<8)+Array[index+1])/1000.0f;
index++;
}
Since you're processing the array four-by-four, I recommend that you increment i by 4 in the for loop. You can also avoid confusion after dropping the unnecessary index variable - you have i in the loop and can use it directly, no?
Another thing: Prefer bitwise OR over arithmetic addition when you're trying to "concatenate" numbers, although their outcome is identical.
for (int i = 0 ; i <= 160; i += 4) {
float val = ((array[i + 2] << 8) | array[i + 3]) / 1000.0f;
}
First of all, i <= 160 is one iteration too many.
Second, your incrementation is wrong; for index, you have
Iteration 1:
1, 2, 3
And you're combining 2 and 3 - this is correct.
Iteration 2:
4, 5, 6
And you're combining 5 and 6 - should be 6 and 7.
Iteration 3:
7, 8, 9
And you're combining 8 and 9 - should be 10 and 11.
You need to increment four times per iteration, not three.
But I think it's simpler to start looping at the first index you're interested in - 2 - and increment by 4 (the "stride") directly:
for (int i = 2; i < 160; i += 4) {
float Val = ((Array[i]<<8)+Array[i+1])/1000.0f;
}

Socket recv in c++

My code is as below
char *inBuffer = new char[5];
int recvReturn = recv(Socket, inBuffer, sizeof(inBuffer) - 1, 0);
if (recvReturn <= 0)
{
m_manager->log("Socket receive error",HIGH_IMPORTANCE);
}
else
{
std::stringstream ss2;
ss2<<std::hex;
for(int i(0);i<5;++i)
ss2<<(int)inBuffer[i] << ' ';
m_manager->log(ss2.str(),HIGH_IMPORTANCE);
}
The result in my log is
1 1 6 0 0
The values on 1 1 6 are correct but 0 0 is wrong. Instead of 0 0 I expect 8 9. Is there something wrong in the code?
I can see 2 problems in your code.
you print 5 characters without ensuring you recieved at least 5. You should display recvBuffer and/or limit the number of chars written to that.
if you received bytes with value 1, 6, 8, 9 they are not printable characters. The (ASCII) code of 0 is 0x30 or 48. So ss2.str could be weird as a printable string.

Python: Index in for loop is resetting without a reason

First of all, I would like to apologize for my english since it is not my native language.
I'm having a quite crazy problem with the following code:
linecounter = []
for i in range(20):
linecounter.append("Color "+str(i)+"\n")
for line in linecounter:
color_list = range(20)
for j in range(len(color_list)):
stri = "Color " + str(j+1)
if stri in line:
print j
The result I expect:
0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
The result I'm getting:
0
1
2
3
4
5
6
7
8
0
9
0
10
0
11
0
12
0
13
0
14
0
15
0
16
0
17
0
18
Can somebody tell me how I get this result or how I get the result I want?
I would like to thank everyone who answers.
Sincerely, Nikster
Those extra zeroes are being printed because of the way the in operator works for strings. When line is "Color10" and stri is "Color1", then if stri in line evaluates to True, and prints the value of j, which is zero at the time.
Try using an equality comparison instead of in. You would also need to add a newline to the end of stri so that they compare properly.
stri = "Color " + str(j+1) + "\n"
if stri == line:
print j
This will print the numbers from 0 through 18. I don't entirely understand what you're trying to do, but if you want 19 to get printed, you could try not adding 1 to j:
stri = "Color " + str(j) + "\n"
if stri == line:
print j
Strange logic but:
linecounter = []
for i in range(20):
linecounter.append("Color "+str(i))
for line in linecounter:
color_list = range(20)
for j in range(len(color_list)):
stri = "Color " + str(j+1)
if stri == line:
print j

buffer overflow that shouldnt happen (?)

I have the following program
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <string.h>
4
5 int check_authentication(char *password){
6 char password_buffer[16];
7 int auth_flag =0;
8
9
10 strcpy(password_buffer, password);
11
12 if(strcmp(password_buffer, "brillig" ) == 0 )
13 auth_flag = 1;
14 if(strcmp(password_buffer, "outgrabe") == 0)
15 auth_flag = 1;
16
17 return auth_flag;
18 }
19
20 int main(int argc, char *argv[]){
21 if (argc<2){
22 printf("Usage: %s <password>\n", argv[0]);
23 exit(0);
24 }
25
26 if(check_authentication(argv[1])){
27 printf("\n-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=\n");
28 printf(" Access Granted.\n");
29 printf("\n-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=\n");
30 }
31 else {
32 printf("\n Access Denied. \n");
33 }
34 }
I am running it supplying 30 bytes of As through gdb... and I am setting the following breakpoints
(gdb) break 9
Breakpoint 1 at 0x80484c1: file auth_overflow2.c, line 9.
(gdb) break 16
Breakpoint 2 at 0x804850f: file auth_overflow2.c, line 16.
(gdb) run AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
So far so good. Everything goes as it was supposed to go even till the next breakpoint
Breakpoint 1, check_authentication (password=0xbffff6d2 'A' <repeats 30 times>)
at auth_overflow2.c:10
10 strcpy(password_buffer, password);
(gdb) x/s password_buffer
0xbffff484: "\364\237\374\267\240\205\004\b\250\364\377\277\245", <incomplete sequence \352\267>
(gdb) x/x &auth_flag
0xbffff494: 0x00
Now we see the following information:
variable auth_flag is in address 0xbffff494 and variable buffer is in the address 0xbffff484. Since address of var auth_flag is greater than the address of buffer and the stack grows towards lower addresses that means that additional (overrun of the buffer) bytes in the buffer variable WILL NOT OVERWRITE auth_flag. Right ?
But gdb has a different opinion...
(gdb) cont
Continuing.
Breakpoint 2, check_authentication (
password=0xbf004141 <Address 0xbf004141 out of bounds>)
at auth_overflow2.c:17
17 return auth_flag;
(gdb) x/s password_buffer
0xbffff484: 'A' <repeats 30 times>
(gdb) x/x &auth_flag
0xbffff494: 0x41
and ...
(gdb) x/16xw &auth_flag
0xbffff494: 0x41414141 0x41414141 0x41414141 0xbf004141
0xbffff4a4: 0x00000000 0xbffff528 0xb7e8bbd6 0x00000002
0xbffff4b4: 0xbffff554 0xbffff560 0xb7fe1858 0xbffff510
0xbffff4c4: 0xffffffff 0xb7ffeff4 0x080482bc 0x00000001
We see that auth_flag was overwritten with these 0x41 (=A) although this variable was in a lower position in stack. Why this happened?
Stack growth direction has nothing to do with where the extra bytes go when you overrun a buffer. Overruns from strcpy are always going to be into higher addresses (unless overrun so far that you wrap around to address 0, which is pretty unlikely)
Objects are stored in memory from lower udresses up to higher addresses. As you can not guarantee that the length of the string refered to by parameter password is less than 16 then your code is invalid.
In fact there is no any need in the local buffer password_buffer.
The function could be written the following way
_Bool check_authentication( const char *password )
{
return ( strcmp( password, "brillig" ) == 0 || strcmp( password, "outgrabe" ) == 0 );
}
Instead of the return type _Bool you may use type int as in your function realization. In any case either 1 or 0 will be returned.
the compiler can freely reorder the stack of variables therefore in this case it's always char array before int variable. This makes the program vulnerable for stack-based buffer overflow.
In order to change the following:
(gdb) x/s password_buffer
0xbffff484: 'A' <repeats 30 times>
(gdb) x/x &auth_flag
0xbffff494: 0x41
into expected answer as below:
(gdb) x/s password_buffer
0xbffff494: 'A' <repeats 30 times>
(gdb) x/x &auth_flag
0xbffff484: 0x00
We simply add a -fstack-protector-all argument during compilation and the result will be as expected. To be vice-versa, perhaps you can use -O0 or -fno-stack-protector.
Answer from: https://stackoverflow.com/a/21215205/3205268
If you are reading in more then 15 bytes you will get that. strcpy will look for the end of the string. You could use something like strncpy to only copy a limited number of characters.