summaryrefslogtreecommitdiffstats
path: root/docs
diff options
context:
space:
mode:
Diffstat (limited to 'docs')
-rw-r--r--docs/forensics/image_convolution.txt2
-rw-r--r--docs/re/arch_x86.txt60
-rw-r--r--docs/re/rep_prefix.txt18
-rw-r--r--docs/re/test_v_cmp.txt17
-rw-r--r--docs/writeups/2024/BraekerCTF/misc/e.txt103
-rw-r--r--docs/writeups/2024/BraekerCTF/misc/eye_doctor.pngbin0 -> 53001 bytes
6 files changed, 165 insertions, 35 deletions
diff --git a/docs/forensics/image_convolution.txt b/docs/forensics/image_convolution.txt
new file mode 100644
index 0000000..419389b
--- /dev/null
+++ b/docs/forensics/image_convolution.txt
@@ -0,0 +1,2 @@
+https://medium.com/analytics-vidhya/image-convolution-from-scratch-d99bf639c32a
+https://docs.gimp.org/2.6/en/plug-in-convmatrix.html
diff --git a/docs/re/arch_x86.txt b/docs/re/arch_x86.txt
index 5d526b2..85cf22f 100644
--- a/docs/re/arch_x86.txt
+++ b/docs/re/arch_x86.txt
@@ -105,3 +105,63 @@ The function return value is stored in the a register.
Stack pointer register: rsp
Base pointer register: rbp
Return value in: rax
+
+
+
+Specific Callouts
+============================================================
+
+TEST vs. CMP
+------------
+CMP subtracts operands and sets internal flags. Among these, it sets the
+zero flag if the difference is zero (operands are equal).
+
+TEST sets the zero flag (ZF) when the result of the AND operation is zero. If
+the two operands are equal, their bitwise AND is zero only when the operands
+themselves are zero. TEST also sets the sign flag (SF) when the most
+significant bit is set in the result, and the parity flag (PF) when the number
+of set bits is even.
+
+JE (alias of JZ) tests the zero flag and jumps if it is set. This creates the
+following equivalencies:
+
+test eax, eax
+je <somewhere> ----> if (eax == 0) {}
+
+cmp eax, ebx
+je <somewhere> ----> if (eax == ebx) {}
+
+
+REP prefix
+----------
+The "rep" prefix on a string instruction repeats that string instruction for CX
+block loads.
+
+e.g. STOS is "Store String"
+It will store the value in AX at the address in RDI
+(technically, STOSB, STOSW, STOD, and STOSQ use AL, AX, EAX, and RAX respectively)
+If RCX = 0x20, RDI = some buffer, and RAX = 0,
+
+`rep stosq` is equivalent to:
+
+```
+buf_ptr = buf
+for(i = 0x20; i != 0; i--)
+ *buf_ptr = 0;
+ buf_ptr++;
+```
+
+
+LOOP instruction
+----------------
+#from stack overflow:
+#https://stackoverflow.com/questions/46881279/how-exactly-does-the-x86-loop-instruction-work
+
+LOOP is exactly like `dec ecx / jnz`, except it doesn't set flags.
+
+It's like the bottom of a `do {} while (--ecx != 0);` loop in C. If execution
+enters the loop with ecx=0, wrap-around means the loop will run 2**32 times
+(2**64 times in 64-bit mode).
+
+Unlike `rep movsb/stosb/etc`, it doesn't check for ecx=0 before decrementing,
+only after.
diff --git a/docs/re/rep_prefix.txt b/docs/re/rep_prefix.txt
deleted file mode 100644
index 23e0cec..0000000
--- a/docs/re/rep_prefix.txt
+++ /dev/null
@@ -1,18 +0,0 @@
-The "rep" prefix on a string instruction repeats that string instruction for CX block loads.
-e.g.
-STOS is "Store String"
-It will store the value in AX at the address in RDI
-(technically, STOSB, STOSW, STOD, and STOSQ use AL, AX, EAX, and RAX respectively)
-If RCX = 0x20, RDI = some buffer, and RAX = 0,
-
-`rep stosq`
-
-is equivalent to:
-
-```
-buf_ptr = buf
-for(i = 0x20; i != 0; i--)
- *buf_ptr = 0;
- buf_ptr++;
-```
-
diff --git a/docs/re/test_v_cmp.txt b/docs/re/test_v_cmp.txt
deleted file mode 100644
index c98424f..0000000
--- a/docs/re/test_v_cmp.txt
+++ /dev/null
@@ -1,17 +0,0 @@
-CMP subtracts operands and sets internal flags. Among these, it sets the
-zero flag if the difference is zero (operands are equal).
-
-TEST sets the zero flag (ZF) when the result of the AND operation is zero. If
-the two operands are equal, their bitwise AND is zero only when the operands
-themselves are zero. TEST also sets the sign flag (SF) when the most
-significant bit is set in the result, and the parity flag (PF) when the number
-of set bits is even.
-
-JE (alias of JZ) tests the zero flag and jumps if it is set. This creates the
-following equivalencies:
-
-test eax, eax
-je <somewhere> ----> if (eax == 0) {}
-
-cmp eax, ebx
-je <somewhere> ----> if (eax == ebx) {}
diff --git a/docs/writeups/2024/BraekerCTF/misc/e.txt b/docs/writeups/2024/BraekerCTF/misc/e.txt
new file mode 100644
index 0000000..5b7f455
--- /dev/null
+++ b/docs/writeups/2024/BraekerCTF/misc/e.txt
@@ -0,0 +1,103 @@
+"Grrrrr". This robot just growls. The other bots tell you that it is angry
+because it can't count very high. Can you teach it how?
+
+
+
+Overview
+--------
+The challenge provides a C++ source file and a netcat port. The program code
+appears to be a short series of prompts, which passing all of them will print
+the flag. At each stage, our input is taken as a single-precision floating
+point number which must pass various rounding error and precision checks.
+
+
+
+Level 1
+-------
+bool flow_start() {
+ // Get user input
+ float a = get_user_input("Number that is equal to two: ");
+
+ // Can't be two
+ if (a <= 2)
+ return false;
+
+ // Check if equal to 2
+ return (unsigned short)a == 2;
+}
+
+I saw some solutions take advantage of the fact that large numbers would
+"overflow" when truncated via the (unsigned short) cast, giving a valid input
+like 65538 (0x10002).
+
+My solution leveraged the floating point truncation (aka: loss of decimal
+places): 2.0000002384
+
+
+
+Level 2
+-------
+bool round_2() {
+ float total = 0;
+
+ // Sum these numbers to 0.9
+ for (int i = 0; i < 9; i++)
+ total += 0.1;
+
+ // Add user input
+ total += get_user_input("Number to add to 0.9 to make 1: ");
+
+ // Check if equal to one
+ return total == 1.0;
+}
+
+During the for-loop, precision errors accumulate and the total will overshoot
+0.9. Less than 0.1 must be given: 0.09999990
+
+
+
+Level 3
+-------
+bool level_3() {
+ float total = 0;
+
+ unsigned int *seed;
+ vector<float> n_arr;
+
+ // Random seed
+ seed = (unsigned int *)getauxval(AT_RANDOM);
+ srand(*seed);
+
+ // Add user input
+ add_user_input(&n_arr, "Number to add to array to equal zero: ");
+
+ // Add many random integers
+ for (int i = 0; i < 1024 * (8 + rand() % 1024); i++)
+ n_arr.push_back((rand() % 1024) + 1);
+
+ // Add user input
+ add_user_input(&n_arr, "Number to add to array to equal zero: ");
+
+ // Get sum
+ for (int i = 0; i < n_arr.size(); i++)
+ total += n_arr[i];
+
+ // Check if equal to zero
+ return total == 0;
+}
+
+Many random numbers between [1, 1024] are summed up in this function, and we are
+asked for two more, for all of them to sum to zero. Since the range of random
+numbers is known (<=1024), we can provide relatively large numbers to squeeze
+out the randomness.
+
+Given the fixed-precision, yet floating decimal point of floats, adding a large
+value to a small value can potentially reduce the smaller value to zero as its
+exponent and mantissa are adjusted to match the other.
+
+10000000000000000
+-10000000000000000
+
+
+
+brck{Th3_3pS1l0n_w0rkS_In_M15t3riOuS_W4yS}
diff --git a/docs/writeups/2024/BraekerCTF/misc/eye_doctor.png b/docs/writeups/2024/BraekerCTF/misc/eye_doctor.png
new file mode 100644
index 0000000..58e27d3
--- /dev/null
+++ b/docs/writeups/2024/BraekerCTF/misc/eye_doctor.png
Binary files differ