The errata list is a list of errors and their corrections that were found after the product was released.
The following errata were submitted by our customers and have not yet been approved or disproved by the author or editor. They solely represent the opinion of the customer.
Version |
Location |
Description |
Submitted by |
Date submitted |
PDF, Other Digital Version |
Page xi
1st paragraph |
The printed book comes with a live Linux CD with example code as stated in the Preface: "[...] This edition features a bootable LiveCD based on Ubuntu Linux [..]". Also, in the publisher page there are links to example code files and errata/updates.
Your product page should contain (current it does not) links to:
- Download an ISO image of the Live CD
- Example code
- Errata
|
Alessandro Piovaccari |
Nov 14, 2011 |
Printed |
Page 17
First function example on page |
I am no expert in C so I could be off. I compiled a program with the function as is on the page and it would continue to loop and finally return x to the caller as -1899959296.
Running the program and placing a printf ("%d\n", x); in the function showed x to reach as high as 199584000.
In the function I am referring to the statement:
for (i=1; i < x; i++)
x *= i;
It is as if the "x" in the for parenthesis was continuously being modified. I declared "int j;" in the function and set it "j = x;" then modified the for label as "(int=1; int<j; i++) and that returned the 120 to the caller.
So perhaps my code is off or is the parenthesis always re-read in a for loop?
My initial program test1.c that returned -1899959296:
#include <stdio.h>
int main()
{
int a=5, b;
b = factorial(a);
printf ("b is %d\n", b);
return 0;
}
int factorial(int x)
{
int i;
for(i=1; i<x; i++)
x *= i;
return x;
}
My program that returned 120
#include <stdio.h>
int main()
{
int a=5, b;
b = factorial(a);
printf ("b is %d\n", b);
return 0;
}
int factorial(int x)
{
int i;
int j;
j = x;
for(i=1; i<j; i++)
x *= i;
return x;
}
|
Joseph |
Aug 27, 2011 |
PDF |
Page 19
Within the code snippet. |
Under the "Getting your hands dirty" section, the firstprog.c has a typo, which would not allow the code to be compiled and executed correctly. The code however is corrected within the livecd, and sourcebook documents.
Here is the typo:
firstprog.c
#include<stdio.h>
int main()
{
int i;
for (i=0; i < 10; i++) // Loop 10 times.
{
puts("Hello, world!\n"); // put the string to the output.
}
return 0; // Tell OS the program exited without errors
}
How it should read:
firstprog.c
#include<stdio.h>
int main()
{
int i;
for (i=0; i < 10; i++) // Loop 10 times.
{
printf("Hello, world!\n"); // printf the string to the output.
}
return 0; // Tell OS the program exited without errors
}
|
Brian Anderson |
Apr 25, 2015 |
Printed, PDF |
Page 25
2nd paragraph |
2nd paragraph says:
"The EIP register is the Instruction Pointer register, which points to the current instruction the processor is reading. Like a child pointing his finger at each word as he reads, the processor reads each instruction using the EIP register as its finger. Naturally, this register is quite important and will be used a lot while debugging. Currently, it points to a memory address at 0x804838a"
Memory address for the EIP register shown in the example code llocated on page 22 is <0x804837a> and not <0x804838a>
|
Anonymous |
Aug 29, 2020 |
Printed, PDF |
Page 25
2nd paragraph |
2nd paragraph says:
"The EIP register is the Instruction Pointer register, which points to the current instruction the processor is reading. Like a child pointing his finger at each word as he reads, the processor reads each instruction using the EIP register as its finger. Naturally, this register is quite important and will be used a lot while debugging. Currently, it points to a memory address at 0x804838a"
Memory address for the EIP register shown in the example code llocated on page 22 is <0x804837a> and not <0x804838a>
|
Anonymous |
Aug 29, 2020 |
Printed |
Page 31
Last line |
Memory address is given as 0x8048393 when it should be 0x80483a3.
|
Amol Vaidya |
Aug 20, 2024 |
PDF |
Page 39
1st paragraph |
In this example, an array is initialized and contains a "Hello World!\n\0" string. The author then proceeds to explain that the null byte tells the function to stop reading a string when it is encountered.
Then, we have the following line: " If a null byte is inserted in the fifth element
of the character array, only the characters Hello would be printed by the
printf() function.".
This is actually incorrect. If the null byte was inserted in the fifth element, we would only see Hell, as the fifth element is str[4], and contains 'o'. In order for printf to print Hello, the null byte should be inserted in str[5], which is the sixth element, and not the fifth.
|
Terry Finkel |
Apr 21, 2019 |
PDF |
Page 50
Line 5; input.c program |
#include <stdio.h>
#include <string.h>
int main() {
char message[10];
int count, i;
strcpy(message, "Hello, world!");
printf("Repeat how many times? ");
scanf("%d", &count);
for(i=0; i < count; i++)
printf("%3d - %s\n", i, message);
}
In the above code, the char array message is of length 10. When strcpy is used to transfer the string "Hello, world!", message may not be long enough to fit the 14 bytes needed.
|
Jacob Shin |
May 22, 2018 |
Printed, PDF |
Page 94
Line 45 in notesearch.c program |
In the 'notesearch.c' program shown on pages 93-95, there is an error on line 45 that reads:
"read(fd, note_buffer, note_length); // read note data"
The problem is that read will not reach the newline character, and will therefore not carry down to the next line properly. One way to fix the error is to change the line to read as:
"read(fd, note_buffer, note_length+1); // read note data"
so that the newline character is read.
Another separate but closely related error I ran into that was within the same 'notesearch.c' program was the lseek command used on line 74:
"lseek(fd, length * -1, SEEK_CUR); // rewind file reading by length bytes"
The SEEK_CUR variable isn't defined in any of the libaries included in the program. To fix this, add unistd.h to your includes at top of page:
"#include <unistd.h>"
Also, to get rid of the warnings about the malloc and fatal commands listed in the 'hacking.h' header file, add this include to 'notesearch.c' as well:
"#include <stdlib.h>"
These fixes will allow the program to work as intended.
Hope this saves someone else some time. :)
|
Brian Schmoker |
Oct 24, 2015 |
PDF |
Page 97
function search_note in the program notesearch.c |
The function search_note in the program notesearch.c in the book is an incorrect implementation of string search/pattern matching. For instance it will say the following pattern "aab" is not in the string "aaab" even though it is really present.
|
Anonymous |
Nov 24, 2011 |
Printed |
Page 114
first (only) paragraph |
In the Find the Ace game (based on the Monty Hall Problem), you in fact increase your chances of finding the ace from 33% to 66% (not 33% to 50%) by switching your choice. This is a minor error and doesn't affect the point being made in the section.
|
Anonymous |
May 23, 2008 |
Printed |
Page 121-122
2nd paragraph-3rd paragraph |
When executing exploit_notesearch.c, I had a "Permission denied" Error, which comes from the "notesearch.c". The /var/notes directory can't be read by the exploit so I had to change its permission in order to run the exploit (using "sudo chmod g+r /var/notes" command).
I don't know if it's a mistake from the book or if I did something wrong (despite the fact that I followed it correctly)
|
Nayk0 |
May 21, 2014 |
PDF |
Page 128
illustration |
Illustration of the stack lists a "return_value" variable. The variable is called "auth_flag".
|
Anonymous |
Mar 20, 2016 |
PDF |
Page 145
Bolded "Shellcode" portion |
The address shown for the envioronmental variable "SHELLCODE" seems to be incorrect, showing 0xbffffd56 instead of 0xbffff8e3
|
Anonymous |
Mar 15, 2014 |
Printed, PDF |
Page 175
2nd and 3rd paragraph |
"must be located after the first arbitrary memory address of 0x08049754," the address is actually 0x08049794. In the third paragraph "After that, the next memory address to be written to, 0x08049755," the address is actually 0x08049795.
|
Anonymous |
Sep 13, 2016 |
Printed |
Page 197
First paragraph, second sentence. |
This is a very minor mistake.
For context, this is in the OSI Model section.
Here is the error:
"The next later is the data link layer."
The typo is the word "later" which should be "layer".
|
Kevin Goforth |
Jan 04, 2019 |
Printed |
Page 203
3rd example at the beggining |
It reads "ntohs (long value) Network-to-Host Short" when it should read "ntohs (short value) Network-to-Host Short"
|
Anonymous |
Aug 24, 2019 |
Printed, PDF |
Page 205
Below 3rd paragraph in sample code |
host_addr.sin_addr.s_addr = 0; // Automatically fill with my IP
-- The assigned value should be changed to the macro INADDR_ANY, which will eliminate any errors produced from variation in network interfaces. This error is fixed in the practice machine for the book, but remains unchanged in document form.
|
Anonymous |
Sep 21, 2016 |
Printed, PDF |
Page 205
Below 3rd paragraph in sample code |
host_addr.sin_addr.s_addr = 0; // Automatically fill with my IP
-- The assigned value should be changed to the macro INADDR_ANY, which will eliminate any errors produced from variation in network interfaces. This error is fixed in the practice machine for the book, but remains unchanged in document form.
|
Anonymous |
Sep 21, 2016 |
Printed |
Page 237
function decode_ip in decode_sniff.c program |
Calling inet_ntoa() with ip_hdr->src_addr as argument, which is unsigned int.
It should be called with a in_addr struct instead.
Create two structures of in_addr type:
struct in_addr src_addr, dest_addr;
And assign their s_addr field to the ip header address needed
src_addr.s_addr = ip_header->src_addr;
dest_addr.saddr = ip_header->dest_addr;
then use them in inet_ntoa instead of the raw unsigned integer:
printf("SRC: %s DEST: %s", inet_ntoa(src_addr), inet_ntoa(dest_addr);
Or simply typecast it's address to struct in_addr * then deference it (ugly but effective)
inet_ntoa(* ( (struct in_addr*) &ip_header->src_addr))
|
Anonymous |
Feb 17, 2015 |
PDF |
Page 237
decode_sniff.c |
The errata has errors.
Page 237
Here follows the corrected entire text.
Six former errors have been corrected.
Calling inet_ntoa() with ip_header->ip_src_addr as argument, which is unsigned int.
It should be called with a in_addr struct instead.
Create two structures of in_addr type:
struct in_addr src_addr, dest_addr;
And assign their s_addr field to the ip header address needed
src_addr.s_addr = ip_header->ip_src_addr;
dest_addr.s_addr = ip_header->ip_dest_addr;
then use them in inet_ntoa instead of the raw unsigned integer:
printf("SRC: %s DEST: %s", inet_ntoa(src_addr), inet_ntoa(dest_addr));
Or simply typecast it's address to struct in_addr * then deference it (ugly but effective)
inet_ntoa(* ( (struct in_addr*) &ip_header->src_addr))
|
donPablo |
Jul 20, 2020 |
PDF |
Page 240
In the diagram |
Within the attacker system, the second IP (192.168.0.22) should be equal to system B's IP (192.168.0.200). One of those IP must be changed.
|
Anonymous |
Aug 26, 2019 |
Printed, PDF |
Page 290
Last sentence "This instruction jumps execution..." |
"forward by 19 (0x13) bytes" should be changed to "forward by 20 (0x14) bytes"
|
Anonymous |
Oct 14, 2016 |
Printed, PDF |
Page 308
bind_shell1.s source, execve() section |
There is a small typo in the execve() section of the bind_shell1.s source code:
push ecx ; push 32-bit null terminator to stack
should be
push edx ; push 32-bit null terminator to stack
Because $ecx is not really null, this shellcode will cause segmentation fault when connecting to the socket. edx should be used instead.
|
iphelix |
Mar 24, 2011 |
Printed, PDF |
Page 315
connectback_shell.s source, dup2() section |
There is a small typo in the dup2() section of the connectback_shell.s source code:
xchg eax, ebx; Put socket FD in ebx and 0x00000003 in eax.
should be
xchg esi, ebx; Put socket FD in ebx and 0x00000003 in esi.
Because we are using the same socket FD created using socket(), we should restore it from esi instead of eax which is null after successful connect().
|
iphelix |
Mar 24, 2011 |
Printed |
Page 335
Last line - 4 |
The exploit script “xtool_tinywebd_stealth.sh” is subsequently referred to as “xtool_tinywebd_steath.sh (stealth is missing the l). The program is referenced incorrectly on page 335, 340,345,347,349. Possibly other occurrences.
|
Emily Bagwell |
Mar 06, 2023 |
Printed |
Page 360
Near the end of the page |
push BYTE 0x8 should be push BYTE 0x7
String "/bin/sh\x00" consists of 8 characters. The first character is pointed by [ebx+0] and the 8th by [ebx+7]. Consequently, if we push BYTE 0x8 we decode one more chararacter (byte) outside the bounds of the string and may mangle some important data (which does not happen in this case, at least on my vm)
|
Alexios Voulimeneas |
Aug 22, 2015 |