Since this homework is open-ended, I'll use this file to pass on interesting information found by various students. One student pointed out that objdump takes a flag '-F', which causes it to provide addresses from the beginning of the file. Hence, objdump -d -F a.out will show you a disassembly, with addresses from the beginning of the file. This is useful for knowing the address of a function after you inject a file. ============= Next, if we change the program counter (%rip) to point to the entry of a function, there is a further consideration. If you disassemble the beginning of a function, you will find extra assembly code that creates the call frame for the function. That code assumes things like the stack pointer (%sp) being set to a reasonable location, and perhaps also for a frame pointer. So, here also, it may be necessary to do some additional patching. If anyone discovers more on this, tell me, and I'll continue to add information here. ============= One student (Derick) pointed out that setting the program counter (%rip) using ptrace is not always reliable. (A different student reported that he or she didn't see this issue. So, your mileage may vary.) On doing singlestep, you may find that the program counter is one instruction behind or ahead of where you think you are. A good solution for this is a "nop sled" or "nop slide": https://en.wikipedia.org/wiki/NOP_slide ============= Once you have injected libckpt.a/libc.a (e.g., as part of my_executable), you may see a different problem. We are calling myconstructor to "initialize" libckpt.a. But we have not initialized the copy of libc.a that was included in my_executable. So, libckpt.a (myconstructor) can only call system calls that do not involve initialization of libc.a. As you can guess, malloc() requires an initialization. (For example, we must allocate an initial "malloc arena", typically by using mmap, before we can allocate individual memory through a malloc call.) Any call to fopen() will call malloc(). (This makes sense, since it returns a pointer to an object of type FILE. So, it must allocate the FILE, which can later be freed via fclose.) MORAL: Don't use fopen. printf() is fine. But fopen/fread/fwrite will create problems for you. Second, for weird reasons, libc.a chooses to call malloc() as part of strchr(). MORAL: Don't use strchr(). For this one, it's easy to write your own strchr() in libckpt.a, so that libc:strchr() never gets called. A similar story applies to any other such system calls. )