- A process is a container for execution. A thread is what the OS schedules to execute on a single core
- A process consists of one or more threads
- Multiple threads can run on a single core. And although only one thread is executing on a core at a time, since threads are multiplexed so quickly (exact mechanism is based on the particular OS scheduling algorithm), it seems to us as if multiple threads are running at the same time
- For a multi-core CPU, a multi-threaded process can have all its threads running on the same core or splitted between different cores. The decision for which core a thread will run on is made by the OS
- Each thread will have its own registers set and stack
- Entry point of a binary (start function) is not main. A program's startup code (how main is set up and called) depends on the compiler and the platform that the binary is compiled for
- For C binary compiled by gcc, crt0 is usually linked into the program to perform initialization before main
- Randomness requires a source of entropy (seed), which is an unpredictable sequence of bits that can come from the OS observing its internal operations or ambient factors. Algorithms using a seemingly unpredictable sequence of bits as seed are known as pseudorandom number generators, because while their output are not random, they still pass the statistical tests of randomness
- basic pseudorandom number generator using srand, rand, and time
“Anyone who considers arithmetical methods of producing random digits is, of course, in a state of sin.” - John Von Neumann
- Intel x86 and x86-64 use little-endian format. It is a format where multi-bytes datatype (e.g. integer) has its least significant byte stored in the lower address of main memory
- Value stored in RAM is in little-endian but when moved into a register will be in big-endian. This is why even though bytes representing an integer is flipped in memory, it will be in its original form when moved into a register
- Debugger reads and stores an instruction's first byte and then overwrites that first byte with 0xCC (INT3) to set a breakpoint at that instruction. When CPU hits the breakpoint (0xCC), OS kernel sends SIGTRAP signal to process, process execution is paused by the debugger, and debugger's internal lookup occurs to flip the original byte back
- Set at CPU level in special registers called debug registers
- Debug registers (DR0 through DR7)
- DR0-DR3: stores addresses of hardware breakpoints
- DR4-DR5: reserved
- DR6: status register that contains information on which debugging event has occurred
- DR7: stores breakpoint conditions and the lengths of breakpoints for DR0-DR3
- Before CPU attempts to execute an instruction, it first checks whether the address is currently enabled for a hardware breakpoint. If the address is stored in debug registers DR0–DR3 and the read, write, or execute conditions are met, an INT1 is fired and the process halts
- Changes the permissions on a region, or page, of memory
- Guard page: Any access to a guard page results in a one-time exception, and then the page returns to its original status. Memory breakpoint changes permission of the page to guard
Data Encoding <- RERM[.general] -> IDA Tips