Skip to content

carlosz1986/mod_hasivo_switch_firmware

Repository files navigation

Hasivo S110W-8XGT-SE Firmware Mod Tools

Simple scripts to unpack and repack the embedded Linux firmware image for the Hasivo S110W-8XGT-SE router. In addition this repo includes patch files that change the right bytes to make the firmware more chatty.

NOTE: The helper scripts are genated with the help of a LLM, but the instruction patches for the logging are not.

The firmware for this Hasivo managed switch is compatible with different devices ...

Prerequisites

Before using these scripts, install the necessary dependencies via apt:

sudo apt update && apt install squashfs-tools cpio lzma python3 gzip xxd

Tutorial

1. Unpack the Firmware

Place your original firmware file (e.g., fw_sh.bin or others) in the right directory, or use the existing one and run it:

./unpack_fw.sh ./firmware/original_s1100wp-8gt-se.bin

This will create:

  • extracted_fs/: The root filesystem of the router.
  • extracted_fs/squashfs-root/: The main application filesystem.
  • extracted_fs/modsquashfs-root/: The kernel modules filesystem.

2. Modify

You can now navigate into the extracted_fs/ folders and add, remove, or edit files.

2.1 Modify Binaries & Reverse engineer

Some commands that help to figure out what to do

  • strings -t x rtcore.ko | grep Log
  • mips-linux-gnu-objdump -D -j .text rtcore.ko | grep -C 10 "rt_log"

Example:

000007ec <rt_log>:
     7ec:	27bdffd0 	addiu	sp,sp,-48
     7f0:	afbf002c 	sw	ra,44(sp)
     7f4:	afb30028 	sw	s3,40(sp)
     7f8:	afb20024 	sw	s2,36(sp)
     7fc:	afb10020 	sw	s1,32(sp)
     800:	afb0001c 	sw	s0,28(sp)
     804:	3c180000 	lui	t8,0x0
     808:	8f180454 	lw	t8,1108(t8)
     80c:	00808021 	move	s0,a0
     810:	00c09021 	move	s2,a2
     814:	13000026 	beqz	t8,8b0 <rt_log+0xc4>
     818:	00e08821 	move	s1,a3
     81c:	3c180000 	lui	t8,0x0
     820:	8f180448 	lw	t8,1096(t8)
     824:	13000010 	beqz	t8,868 <rt_log+0x7c>
     828:	24030009 	li	v1,9
     82c:	24020001 	li	v0,1
     830:	1702002b 	bne	t8,v0,8e0 <rt_log+0xf4>
     834:	3c020000 	lui	v0,0x0
     838:	8c43044c 	lw	v1,1100(v0)
     83c:	0098c004 	sllv	t8,t8,a0
     840:	0303c024 	and	t8,t8,v1
     844:	17000012 	bnez	t8,890 <rt_log+0xa4>
     848:	3402f011 	li	v0,0xf011
     84c:	8fbf002c 	lw	ra,44(sp)
     850:	8fb30028 	lw	s3,40(sp)
     854:	8fb20024 	lw	s2,36(sp)
     858:	8fb10020 	lw	s1,32(sp)
     85c:	8fb0001c 	lw	s0,28(sp)
     860:	03e00008 	jr	ra
     864:	27bd0030 	addiu	sp,sp,48
     868:	3c180000 	lui	t8,0x0
     86c:	8f180450 	lw	t8,1104(t8)
     870:	1303fff6 	beq	t8,v1,84c <rt_log+0x60>
     874:	3402f011 	li	v0,0xf011
     878:	28830009 	slti	v1,a0,9
     87c:	1060fff4 	beqz	v1,850 <rt_log+0x64>
     880:	8fbf002c 	lw	ra,44(sp)
     884:	0304c02b 	sltu	t8,t8,a0
     888:	1700fff2 	bnez	t8,854 <rt_log+0x68>
     88c:	8fb30028 	lw	s3,40(sp)
     890:	3c180000 	lui	t8,0x0
     894:	8f030440 	lw	v1,1088(t8)
     898:	8f180444 	lw	t8,1092(t8)
     89c:	00721824 	and	v1,v1,s2
     8a0:	0311c024 	and	t8,t8,s1
     8a4:	0078c025 	or	t8,v1,t8
     8a8:	1300ffe8 	beqz	t8,84c <rt_log+0x60>
     8ac:	3402f011 	li	v0,0xf011
     8b0:	27b80044 	addiu	t8,sp,68
     8b4:	8fa60040 	lw	a2,64(sp)
     8b8:	3c130000 	lui	s3,0x0
     8bc:	03003821 	move	a3,t8
     8c0:	afb80014 	sw	t8,20(sp)
     8c4:	3c180000 	lui	t8,0x0
     8c8:	26640030 	addiu	a0,s3,48
     8cc:	27180000 	addiu	t8,t8,0
     8d0:	0300f809 	jalr	t8
     8d4:	240503ff 	li	a1,1023
     8d8:	04410009 	bgez	v0,900 <rt_log+0x114>
     8dc:	3c180000 	lui	t8,0x0
     8e0:	8fbf002c 	lw	ra,44(sp)
     8e4:	8fb30028 	lw	s3,40(sp)
     8e8:	8fb20024 	lw	s2,36(sp)
     8ec:	8fb10020 	lw	s1,32(sp)
     8f0:	8fb0001c 	lw	s0,28(sp)
     8f4:	2402ffff 	li	v0,-1
     8f8:	03e00008 	jr	ra
     8fc:	27bd0030 	addiu	sp,sp,48
     900:	8f030440 	lw	v1,1088(t8)
     904:	8f020444 	lw	v0,1092(t8)
     908:	00729024 	and	s2,v1,s2
     90c:	2e581000 	sltiu	t8,s2,4096
     910:	13000017 	beqz	t8,970 <rt_log+0x184>
     914:	00518824 	and	s1,v0,s1
     918:	0000c021 	move	t8,zero
     91c:	00122040 	sll	a0,s2,0x1
     920:	0800024c 	j	930 <rt_log+0x144>
     924:	2403002c 	li	v1,44
     928:	1303000d 	beq	t8,v1,960 <rt_log+0x174>
     92c:	3c020000 	lui	v0,0x0
     930:	00183827 	nor	a3,zero,t8
     934:	03111006 	srlv	v0,s1,t8
     938:	00e43804 	sllv	a3,a0,a3
     93c:	33060020 	andi	a2,t8,0x20
     940:	03122806 	srlv	a1,s2,t8
     944:	00e21025 	or	v0,a3,v0
     948:	00a6100b 	movn	v0,a1,a2
     94c:	30420001 	andi	v0,v0,0x1
     950:	1040fff5 	beqz	v0,928 <rt_log+0x13c>
     954:	27180001 	addiu	t8,t8,1
     958:	2718ffff 	addiu	t8,t8,-1
     95c:	3c020000 	lui	v0,0x0
     960:	0018c080 	sll	t8,t8,0x2
     964:	24420000 	addiu	v0,v0,0
     968:	0800025e 	j	978 <rt_log+0x18c>
     96c:	0058c021 	addu	t8,v0,t8
     970:	3c180000 	lui	t8,0x0
     974:	271800b0 	addiu	t8,t8,176
     978:	8f060000 	lw	a2,0(t8)
     97c:	3c040000 	lui	a0,0x0
     980:	3c180000 	lui	t8,0x0
     984:	24840000 	addiu	a0,a0,0
     988:	02002821 	move	a1,s0
     98c:	27180000 	addiu	t8,t8,0
     990:	0300f809 	jalr	t8
     994:	26670030 	addiu	a3,s3,48
     998:	08000213 	j	84c <rt_log+0x60>
     99c:	00001021 	move	v0,zero
     9a0:	27bdffe0 	addiu	sp,sp,-32
     9a4:	afbf001c 	sw	ra,28(sp)
     9a8:	24180001 	li	t8,1
     9ac:	afb80010 	sw	t8,16(sp)
     9b0:	3c180000 	lui	t8,0x0
     9b4:	24050200 	li	a1,512
     9b8:	2406000b 	li	a2,11
     9bc:	27180000 	addiu	t8,t8,0
     9c0:	0300f809 	jalr	t8

and a lot of ghidra ...

  • Use Ghex or any other Hex Editor to change the needed bytes...
  • Changing in ghidra is not recommended (because export the file again changes the binary), but using ghidra to try out what could make sense is a good approach.
  • To find the right bytes in the Hex Editor, you can search for bytes sequences (detected from ghidra or objdump) directly occuring before the section that has to be changed. Verify if you found the right piece (the search result should occurs just once).
  • After patching check the logic in ghidra and a lot of tryouts & patiences is required.
  • There are multiple ways to patch:

2.1.1 Change a value of a variable or constant

Simply change hex values. For strings keep in mind that you can't overwrite the length as this breaks the code.

2.1.2 Remove jumps, e.g. if conditions to manipulate the flow ...

Search for conditional branches, like bne/beq and others that send you somewhere. You can easily replace with NOP (no operation), so the area is never executed.

2.1.3 Use the "Trampoline approach"

This is helpful if you for example want to log the parameters that a function receives, or you want to apply complex logic changes:

  1. Search for the use of function (JMP) for that you want to log the parameters - For example a(c,d,e)...
  2. Find now any other function that has a similar structure like trampoline(c,d,e). Make sure it is rarely used (with ghidra).
  3. Change the JMP of (a) to the address of the trampoline function.
  4. Remove logic with (NOP) or change the code of the trampoline. If you want to add print, find a string that is usable for that (correct length). Changing strings is easy and does not harm anything.
  5. Writing complex bytecode is hard, so use ghidra or write yourself a simple application with the function (+logic), compile it for the right architecture, decompile and copy the instructions from there... I also learned that LLMs are pretty good here...
  6. Call the function a(c,d,e) from the trampoline(c,d,e) again to keep the logic intact. So basically there is one layer between the execution of a(a,b,c) injected.
  7. The cool part is that you can access the same set of registers in the trampoline function from before. That makes the change easy.

3.2 Make the Firmware more chatty & apply the patch:

Apply patches automatically

# Just uncomment all unneeded parts in the script & run it:

./patch_firmware.sh

Manual way

For example: Copy the rtcore.ko from the ./extracted_fs/modsquashfs-root/lib/modules/3.18.24/kernel/drivers/net/switch/rtcore/rtcore.ko folder to project base folder.

Binary to hex:

xxd rtcore.ko > rtcore.hex

Apply patch:

patch rtcore.hex < ./patches/rtcore_enable_debug_logging.patch

Convert to binary:

xxd -r original.hex > rtcore_patched.ko

Copy the file back to the firmware folder:

cp rtcore_patched.ko ./extracted_fs/modsquashfs-root/lib/modules/3.18.24/kernel/drivers/net/switch/rtcore/rtcore.ko

3. Repack the Firmware

Once your changes are done, run the packing script to generate a new flashable image:

./pack_fw.sh firmware/original_s1100wp-8gt-se.bin patched.bin

Your new image will be saved as patched.bin.

About

some tools to add more debug to the stock linux firmware of hasivo switches

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors